Skip to content

Commit

Permalink
Fix the signature overlap check for parameterized types (#563)
Browse files Browse the repository at this point in the history
  • Loading branch information
TristonianJones committed Jul 11, 2022
1 parent 12f6801 commit 9ded77e
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 4 deletions.
6 changes: 3 additions & 3 deletions cel/decls.go
Expand Up @@ -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 {
Expand Down Expand Up @@ -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
}
Expand Down
36 changes: 35 additions & 1 deletion cel/decls_test.go
Expand Up @@ -165,7 +165,7 @@ func TestFunctionMerge(t *testing.T) {
if err != nil {
t.Fatalf("NewCustomEnv(size, <custom>) 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)
}
Expand Down Expand Up @@ -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",
Expand Down Expand Up @@ -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())
Expand Down Expand Up @@ -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())
Expand Down

0 comments on commit 9ded77e

Please sign in to comment.