From 9ded77eb7fc111d26e50f1d146cffd31c7c4bf3c Mon Sep 17 00:00:00 2001 From: Tristan Swadell Date: Mon, 11 Jul 2022 09:58:37 -0700 Subject: [PATCH] Fix the signature overlap check for parameterized types (#563) --- cel/decls.go | 6 +++--- cel/decls_test.go | 36 +++++++++++++++++++++++++++++++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/cel/decls.go b/cel/decls.go index 415674fa..12c8f256 100644 --- a/cel/decls.go +++ b/cel/decls.go @@ -650,7 +650,7 @@ func (f *functionDecl) merge(other *functionDecl) (*functionDecl, error) { for _, o := range other.overloads { err := merged.addOverload(o) if err != nil { - return nil, fmt.Errorf("function declration merge failed: %v", err) + return nil, fmt.Errorf("function declaration merge failed: %v", err) } } if other.singleton != nil { @@ -821,8 +821,8 @@ func (o *overloadDecl) signatureOverlaps(other *overloadDecl) bool { for i, argType := range o.argTypes { otherArgType := other.argTypes[i] argsOverlap = argsOverlap && - (argType.IsAssignableRuntimeType(otherArgType.runtimeType) || - otherArgType.IsAssignableRuntimeType(argType.runtimeType)) + (argType.IsAssignableType(otherArgType) || + otherArgType.IsAssignableType(argType)) } return argsOverlap } diff --git a/cel/decls_test.go b/cel/decls_test.go index cf119540..b4289679 100644 --- a/cel/decls_test.go +++ b/cel/decls_test.go @@ -165,7 +165,7 @@ func TestFunctionMerge(t *testing.T) { if err != nil { t.Fatalf("NewCustomEnv(size, ) failed: %v", err) } - prg, err = e.Program(ast) + _, err = e.Program(ast) if err == nil || !strings.Contains(err.Error(), "incompatible with specialized overloads") { t.Errorf("NewCustomEnv(size, size_specialization) did not produce the expected error: %v", err) } @@ -276,6 +276,34 @@ func TestSingletonUnaryImpl(t *testing.T) { } } +func TestSingletonUnaryImplParameterized(t *testing.T) { + // Test the case where the singleton unary impl is merged with the earlier declaration. + e, err := NewCustomEnv( + Variable("x", AnyType), + Function("isSorted", MemberOverload("list_int_is_sorted", []*Type{ListType(IntType)}, BoolType)), + Function("isSorted", MemberOverload("list_uint_is_sorted", []*Type{ListType(UintType)}, BoolType), + SingletonUnaryBinding(func(arg ref.Val) ref.Val { return types.True })), + ) + if err != nil { + t.Errorf("NewCustomEnv() failed: %v", err) + } + ast, iss := e.Parse("x.isSorted()") + if iss.Err() != nil { + t.Fatalf("Parse('x.isSorted()') failed: %v", iss.Err()) + } + prg, err := e.Program(ast) + if err != nil { + t.Fatalf("Program() failed: %v", err) + } + out, _, err := prg.Eval(map[string]interface{}{"x": []int{1, 2, 3}}) + if err != nil { + t.Errorf("prg.Eval(x=[1,2,3]) failed: %v", err) + } + if out != types.True { + t.Errorf("Eval got %v, wanted true", out) + } +} + func TestSingletonBinaryImplRedefinition(t *testing.T) { _, err := NewCustomEnv( Function("right", @@ -419,6 +447,9 @@ func TestUnaryImpl(t *testing.T) { ), Variable("x", ListType(DynType)), ) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } ast, iss := e.Compile("size(x)") if iss.Err() != nil { t.Fatalf("Compile(size(x)) failed: %v", iss.Err()) @@ -499,6 +530,9 @@ func TestBinaryImpl(t *testing.T) { Variable("x", IntType), Variable("y", IntType), ) + if err != nil { + t.Fatalf("NewCustomEnv() failed: %v", err) + } ast, iss := e.Parse("max(x, y)") if iss.Err() != nil { t.Fatalf("Parse(max(x, y))) failed: %v", iss.Err())