-
Notifications
You must be signed in to change notification settings - Fork 262
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
Sequence display with generic type causes Java assertion failure #2071
Comments
Thanks for the detailed bug report! It does look to me like both assertions are overly optimistic and don't always hold given how the type systems are currently mapped. I believe the more correct assertion would be |
That change does seem to fix the issue described here, and my original program passes with it. However, I wonder if it might break other things. The original assertion allows Separately, I wonder if this assertion is providing enough value in terms of catching realistic Dafny bugs to be worth keeping at all, but you're the best one to judge that, not me. |
I came across this problem too. Replacing both assertions in Array.java with However, that doesn't answer @mattmccutchen-amazon's question of compilation tests. I'm not aware of any such tests within Dafny, I'm afraid. |
Dafny does have compilation tests, though not very comprehensive ones; there are in the |
Can we confirm whether or not the failing assertion could lead to soundness bugs? It seems to me that a program written exclusively in Dafny is probably sound even if this assertion fails with |
Users of generic // Tmp.dfy; include/import statements omitted
method Main() {
var arr := [1];
var res := MapWithResult(x => Result<int, ()>.Success(x), arr);
if res.Success? {
print res.value, "\n";
}
} $ dafny -version
Dafny 3.9.1.41027
$ dafny build -t java Tmp.dfy
Dafny program verifier finished with 2 verified, 0 errors
$ java -cp Tmp-java:Tmp-java/DafnyRuntime.jar Tmp
[1]
$ java -cp Tmp-java:Tmp-java/DafnyRuntime.jar -ea Tmp
Exception in thread "main" java.lang.AssertionError
at dafny.Array.<init>(Array.java:29)
at dafny.Array.wrap(Array.java:96)
at dafny.DafnySequence.of(DafnySequence.java:25)
at Seq_Compile.__default.MapWithResult(__default.java:266)
at _System.__default.Main(__default.java:25)
at _System.__default.__Main(__default.java:34)
at Tmp.lambda$main$0(Tmp.java:18)
at dafny.Helpers.withHaltHandling(Helpers.java:214)
at Tmp.main(Tmp.java:18) |
I agree with what's been said above that the assertion seems mistaken and should be removed. Since the JVM does not support type parameters, I don't think it's realistic to be able to provide an alternative assertion that would capture all situations. There are other known problems with compilation of Dafny arrays into Java (see #3055). When those get fixed (and I think the fix is to mimic for Java what we do for Go arrays, see #2818), then the code in |
When Dafny code compiled to Java is run with Java assertions enabled (
java -ea
), evaluation of a sequence display whose element type is generic causes an assertion failure in the Dafny Java runtime library.Java assertions (
assert CONDITION;
statements) are typically disabled by default, including when running the program withdafny /compile:3
; I'm guessing that's why no one noticed the problem yet. But I wanted to run the compiled code under JQF in order to test a larger Java program that uses the Dafny code, and JQF enables Java assertions by default.Example Dafny code that triggers the bug:
Tested with Dafny version: 0e4b2bb (
master
as of a few days ago)Steps to reproduce: (Replace
$DAFNY
with the path to your Dafny working tree.)assertionerror-test.dfy
.$DAFNY/Scripts/dafny /compile:1 /compileTarget:java assertionerror-test.dfy
.java -ea -cp assertionerror-test-java:$DAFNY/Binaries/DafnyRuntime.jar assertionerror_test
.Expected output:
Actual output:
My analysis of the bug:
The failing assertion is here:
dafny/Source/DafnyRuntime/DafnyRuntimeJava/src/main/java/dafny/Array.java
Lines 28 to 33 in 0e4b2bb
This code appears to be checking that the runtime element type of the Java array matches the Dafny type descriptor for the element type. The Java array is being created implicitly by the following varargs call to
DafnySequence.of
in the compiled code:Since
__T
is not reified at runtime, the Java compiler doesn't know any better than to use its upper bound (Object
) as the runtime element type, and this does not match the Dafny type descriptor forMyDatatype
. So the assertion is making an assumption that does not always hold based on the way that Dafny code is currently compiled to Java.As a workaround, I commented out the failing assertion as well as this similar-looking assertion, which IIRC failed under slightly different circumstances. That didn't seem to have any other harmful effects, but I don't know if it's the best solution.
The text was updated successfully, but these errors were encountered: