While debugging #7722, I discovered this apparent regression in the jump from 3.42.0 to 4.1.0, but again not certain if it was expected or intended from the inference updates in 3.43.0. (Perhaps not, since this kept working under Java 25 until 3.49.5 despite failing under Java 21 as early as 3.43.0.)
$ cat Test.java
public class Test {
record Box<T>(T value) { }
void test() {
Object foo = new Object();
var boxed = new Box<>(foo);
}
}
$ javac --version
javac 21.0.3
Succeeds with 3.42.0:
$ javac \
--release 21 \
-classpath checker-qual-3.42.0.jar \
-processorpath 'checker-3.42.0.jar;checker-qual-3.42.0.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
(no output)
Error with 4.1.0:
$ javac \
--release 21 \
-classpath checker-qual-4.1.0.jar \
-processorpath 'checker-4.1.0.jar;checker-qual-4.1.0.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
error: [type.argument] incompatible type argument for type parameter T of Box.
found : @UnknownInitialization @Nullable Object
required: @Initialized @Nullable Object
Test.java:5: error: [assignment] incompatible types in assignment.
var boxed = new Box<>(foo);
^
found : @Initialized @NonNull Box<@Initialized @NonNull Object>
required: @UnknownInitialization @Nullable Box<@UnknownInitialization @Nullable Object>
2 errors
Earliest error is 3.43.0:
$ javac \
--release 21 \
-classpath checker-qual-3.43.0.jar \
-processorpath 'checker-3.43.0.jar;checker-qual-3.43.0.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
error: [type.argument] incompatible type argument for type parameter T of Box.
found : @UnknownInitialization @Nullable Object
required: @Initialized @Nullable Object
Test.java:5: error: [assignment] incompatible types in assignment.
var boxed = new Box<>(foo);
^
found : @Initialized @NonNull Box<@Initialized @NonNull Object>
required: @UnknownInitialization @Nullable Box<@UnknownInitialization @Nullable Object>
2 errors
Double-checking with Java 25:
$ javac --version
javac 25.0.2
Succeeds with 3.42.0:
$ javac \
--release 25 \
-classpath checker-qual-3.42.0.jar \
-processorpath 'checker-3.42.0.jar;checker-qual-3.42.0.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
(no output)
Error with 4.1.0:
$ javac \
--release 25 \
-classpath checker-qual-4.1.0.jar \
-processorpath 'checker-4.1.0.jar;checker-qual-4.1.0.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.parser=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
Test.java:5: error: [type.argument] incompatible type argument for type parameter T of Box.
var boxed = new Box<>(foo);
^
found : @UnknownInitialization @Nullable Object
required: @Initialized @Nullable Object
Test.java:5: error: [assignment] incompatible types in assignment.
var boxed = new Box<>(foo);
^
found : @Initialized @NonNull Box<@Initialized @NonNull Object>
required: @UnknownInitialization @Nullable Box<@UnknownInitialization @Nullable Object>
2 errors
Curiously, Java 25 succeeds with 3.43.0 where Java 21 failed:
$ javac \
--release 25 \
-classpath checker-qual-3.43.0.jar \
-processorpath 'checker-3.43.0.jar;checker-qual-3.43.0.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
(no output)
Earliest failing version under Java 25 is 3.49.5:
$ javac \
--release 25 \
-classpath checker-qual-3.49.5.jar \
-processorpath 'checker-3.49.5.jar;checker-qual-3.49.5.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
Test.java:5: error: [type.argument] incompatible type argument for type parameter T of Box.
var boxed = new Box<>(foo);
^
found : @UnknownInitialization @Nullable Object
required: @Initialized @Nullable Object
Test.java:5: error: [assignment] incompatible types in assignment.
var boxed = new Box<>(foo);
^
found : @Initialized @NonNull Box<@Initialized @NonNull Object>
required: @UnknownInitialization @Nullable Box<@UnknownInitialization @Nullable Object>
2 errors
$ javac \
--release 25 \
-classpath checker-qual-3.49.4.jar \
-processorpath 'checker-3.49.4.jar;checker-qual-3.49.4.jar' \
-processor org.checkerframework.checker.nullness.NullnessChecker \
-J--add-exports=jdk.compiler/com.sun.tools.javac.api=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.code=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.file=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.main=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.model=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.processing=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.tree=ALL-UNNAMED \
-J--add-exports=jdk.compiler/com.sun.tools.javac.util=ALL-UNNAMED \
-J--add-opens=jdk.compiler/com.sun.tools.javac.comp=ALL-UNNAMED \
Test.java
(no output)
While debugging #7722, I discovered this apparent regression in the jump from 3.42.0 to 4.1.0, but again not certain if it was expected or intended from the inference updates in 3.43.0. (Perhaps not, since this kept working under Java 25 until 3.49.5 despite failing under Java 21 as early as 3.43.0.)
Succeeds with 3.42.0:
Error with 4.1.0:
Earliest error is 3.43.0:
Double-checking with Java 25:
Succeeds with 3.42.0:
Error with 4.1.0:
Curiously, Java 25 succeeds with 3.43.0 where Java 21 failed:
Earliest failing version under Java 25 is 3.49.5: