Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix the signature overlap check for parameterized types #563

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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