ℹ️ Sorry the description is murky -- I'll update it when I understand better what's what here.
With this policy, x.rego:
package test
import future.keywords.if
test_foo {
"1" == f(1)
"1" == f(1.0)
}
f(s) := s if is_string(s)
else := x if {
x := sprintf("%d", [s])
not contains("%!", x)
}
We get this:
$ opa test -t wasm x.rego
x.rego:
data.test.test_foo: FAIL (47.62675ms)
--------------------------------------------------------------------------------
FAIL: 1/1
$ opa test x.rego
PASS: 1/1
Note that the topdown eval of this test passes -- while it should not! Adding a print(x) to the else branch,
else := x if {
x := sprintf("%d", [s])
print(x)
not contains("%!", x)
}
This is what happens: when the second expression is evaluated, topdown will check if the result is already cached. In that lookup, 1.0 and 1 are compared as ast.Terms, and are equal.
The problem is that the function breaks our number type abstraction -- which says that 1 and 1.0 is the same number.
ℹ️ Sorry the description is murky -- I'll update it when I understand better what's what here.
With this policy,
x.rego
:We get this:
Note that the topdown eval of this test passes -- while it should not! Adding a
print(x)
to the else branch,we get this output:
Furthermore, removing the first statement of
test_foo
makes the test fail with both evaluators.:mag: Looking at the compiler's output, we find
Which does not look wrong.
Update
This is what happens: when the second expression is evaluated, topdown will check if the result is already cached. In that lookup, 1.0 and 1 are compared as
ast.Term
s, and are equal.The problem is that the function breaks our number type abstraction -- which says that
1
and1.0
is the same number.