JDK-8206142 : type inference: javac is incorrectly applying capture conversion during incorporation
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9,10.0.1,11
  • Priority: P4
  • Status: In Progress
  • Resolution: Unresolved
  • OS: generic
  • CPU: generic
  • Submitted: 2018-06-30
  • Updated: 2024-02-23
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
Other
tbd_majorUnresolved
Related Reports
Blocks :  
Duplicate :  
Duplicate :  
Description
ADDITIONAL SYSTEM INFORMATION :
Ubuntu 18.04 LTS

java version "10.0.1" 2018-04-17
Java(TM) SE Runtime Environment 18.3 (build 10.0.1+10)
Java HotSpot(TM) 64-Bit Server VM 18.3 (build 10.0.1+10, mixed mode)



A DESCRIPTION OF THE PROBLEM :
First reported here: https://stackoverflow.com/questions/50928300

Type inference for generics has changed between Java8 and Java9/10 breaking special-case usages e.g. of the hamcrest library. Workarounds seem generally possible by providing more type information.

REGRESSION : Last worked in version 8u172

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Try to compile given code with javac from Java9/10.



EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
Code compiles as it does in Java8.
ACTUAL -
Code does not compile, type errors like:


    Error:(21, 28) java: incompatible types: inference variable U has incompatible bounds
    equality constraints: com.Test.B<? super com.Test.D>
    upper bounds: com.Test.B<? super capture#1 of ? super com.Test.D>,java.lang.Object



---------- BEGIN SOURCE ----------
class Test1 {
    class A<S> { } class B<S> { } class C<S> { } class D { }

    <T> A<B<? super T>> foo() { return null; }

    <U> C<U> bar(A<U> a1, A<? super U> a2) { return null; }

    C<B<? super D>> c = bar(foo(), foo());
}


class Test2 {
    class A<S> { } class B<S> { } class C<S> { } class D { }

    <T> A<B<? super T>> foo() { return null; }

    <U> C<U> bar(A<? super U> a) { return null; }

    C<B<? super D>> c = bar(foo());
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
Provide more type information such as casting arguments.

FREQUENCY : always



Comments
review: http://mail.openjdk.java.net/pipermail/compiler-dev/2018-July/012217.html
20-07-2018

this patch fixes the issue but I'm worried about compatibility issues, checking possible regressions diff -r ae39ec0b0502 -r dc6020be21c7 src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Wed Jul 18 00:23:06 2018 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java Fri Jul 20 14:25:47 2018 -0400 @@ -1003,7 +1003,11 @@ * Is t an unchecked subtype of s? */ public boolean isSubtypeUnchecked(Type t, Type s, Warner warn) { - boolean result = isSubtypeUncheckedInternal(t, s, true, warn); + return isSubtypeUnchecked(t, s, true, warn); + } + + public boolean isSubtypeUnchecked(Type t, Type s, boolean capture, Warner warn) { + boolean result = isSubtypeUncheckedInternal(t, s, capture, warn); if (result) { checkUnsafeVarargsConversion(t, s, warn); } diff -r ae39ec0b0502 -r dc6020be21c7 src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Wed Jul 18 00:23:06 2018 -0700 +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java Fri Jul 20 14:25:47 2018 -0400 @@ -1180,7 +1180,7 @@ IS_SUBTYPE() { @Override boolean apply(Type op1, Type op2, Warner warn, Types types) { - return types.isSubtypeUnchecked(op1, op2, warn); + return types.isSubtypeUnchecked(op1, op2, false, warn); } }, IS_SAME_TYPE() {
20-07-2018

Looks like JDK-8033718 was masking the underlying issue. There were expected behavior changes in 9 to more closely conform to the spec (see release note in JDK-8039214), but this is not one of them. Focusing on Test2, there are the following constraint formulas: A<B<? super t>> --> A<? super u> C<u> --> C<B<? super D>> This should yield u <: B<? super t> u = B<? super D> And then incorporation should lead to t = D. But, somehow, javac performs an incorrect capture, yielding the wrong upper bound for U: equality constraints: B<? super D> upper bounds: B<? super CAP#1>,Object
05-07-2018

It is http://hg.openjdk.java.net/jdk9/jdk9/langtools/rev/54a460e0ac76 from JDK-8033718 causing the regression
04-07-2018

Fairoz, Can you identify which changeset caused the regression in jdk 9 b13 ?
03-07-2018

This is a regression starting from 9 ea b13. Both the test cases fail from 9 ea b13 onwards 8uxx - Pass 9 ea b12 - Pass 9 ea b13 - Fail 10 GA - Fail 10.0.1 GA - Fail 11 ea b19 - Fail Below is the output of Test1.java executed on 11 ea b19 == -sh-4.2$ /scratch/fairoz/JAVA/jdk11/jdk-11-ea+19/bin/javac Test1.java Test error: Class names, 'Test', are only accepted if annotation processing is explicitly requested Test1.java:8: error: incompatible types: inference variable T has incompatible bounds C<B<? super D>> c = bar(foo(), foo()); ^ equality constraints: Test1.D lower bounds: Object where T is a type-variable: T extends Object declared in method <T>foo() 2 errors Test2.java == -sh-4.2$ /scratch/fairoz/JAVA/jdk11/jdk-11-ea+19/bin/javac Test2.java Test error: Class names, 'Test', are only accepted if annotation processing is explicitly requested Test2.java:8: error: incompatible types: inference variable U has incompatible bounds C<B<? super D>> c = bar(foo()); ^ equality constraints: Test2.B<? super Test2.D> lower bounds: Test2.B<? super CAP#1>,Object where U is a type-variable: U extends Object declared in method <U>bar(Test2.A<? super U>) where CAP#1 is a fresh type-variable: CAP#1 extends Object super: Test2.D from capture of ? super Test2.D 2 errors
02-07-2018