JDK-8143396 : type inference regression
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 9
  • Priority: P3
  • Status: Resolved
  • Resolution: Not an Issue
  • OS: linux
  • CPU: x86_64
  • Submitted: 2015-09-21
  • Updated: 2015-12-09
  • Resolved: 2015-12-09
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
java full version "1.9.0-ea-b80"


ADDITIONAL OS VERSION INFORMATION :
x86_64 GNU/Linux

A DESCRIPTION OF THE PROBLEM :
The JDK 9 javac fails to perform type inference on the attached program.

REGRESSION.  Last worked in version 8u60

ADDITIONAL REGRESSION INFORMATION: 
java full version "1.8.0_60-ea-b21"

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
$ javac -source 7 -target 7 Test.java 


EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
I expected the compilation to succeed.
ACTUAL -
The compilation did not succeed.

ERROR MESSAGES/STACK TRACES THAT OCCUR :
warning: [options] bootstrap class path not set in conjunction with -source 1.7
Test.java:11: error: incompatible types: Map<Object,CAP#1> cannot be converted to Map<Object,String>
    return h(g(xs, new F<String, Object>() {}));
            ^
  where CAP#1 is a fresh type-variable:
    CAP#1 extends String from capture of ? extends String
1 error
1 warning


REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Map;

abstract class Test {
  interface F<A, V> {}

  abstract <K, V> Map<K, V> g(Iterable<V> xs, F<? super V, K> f);

  abstract <K, V> Map<K, V> h(Map<? extends K, ? extends V> xs);

  Map<Object, String> f(Iterable<? extends String> xs) {
    return h(g(xs, new F<String, Object>() {}));
  }
}

---------- END SOURCE ----------


Comments
The new behavior is consistent with JLS 7: Typing 'g(xs, new F<String, Object>() {})': 'xs' has type Iterable<CAP1>, so Iterable<CAP1> --> Iterable<v> implies { v = CAP1 } F<String,Object> --> F<? super v, k> implies { v = CAP1, v <: String, k = Object } Per 15.12.2.7, we immediately resolve k=Object and v=CAP1 Return type of 'g' is Map<Object,CAP1> Typing 'h(g(...))': 'g(...)' has type Map<Object,CAP1>, per above Map<Object,CAP1> --> Map<? extends k, ? extends v> implies { Object <: k, CAP1 <: v } Per 15.12.2.7, we immediately resolve k=Object and v=CAP1 Return type of 'h' is Map<Object,CAP1> Is 'Map<Object,CAP1>' assignable to 'Map<Object,String>'? No. So, an error occurs. Intuitively, compilation fails for the same reason that this would fail, too: Map<Object, Integer> m1 = null; Map<Object, Number> m2 = h(m1);
09-12-2015

As noted in the JDK-8039214 release notes comment, this program used to compile because of a javac bug that has been fixed: "The javac compiler's behavior when handling wildcards and "capture" type variables has been improved for conformance to the language specification. This improves type checking behavior in certain unusual circumstances. It is also a source-incompatible change: certain uses of wildcards that have compiled in the past may fail to compile because of a program's reliance on the javac bug." We've discussed preserving the buggy behavior under "-source 7", but concluded that there is not a practical path for doing so. (See JDK-8075793.)
09-12-2015

Change in behavior was introduced by JDK-8039214.
09-12-2015

if the source and target releases are valid, it will compile successfully.
20-11-2015

Test Result: ########## OS: Oracle Linux 7 - 64 bit ********************************** JDK: ################################################### 9ea b80 : Pass [-source 9 -target 9] 8u60 b27 : Pass [-source 8 -target 8] 7u80 b15 : Pass [-source 7 -target 7] ################################################### 9ea b80 : Failed with 1 warning & 1 error [-source 7 -target 7] 8u60 b27 : Failed with 1 warning [-source 7 -target 7] 7u80 b15 : Failed with 1 warning [-source 6 -target 6] ----------------------------------------------------------------------------------------------------------------------------------------- 9ea b80 *********** [ababroy@localhost test]$ java -version java version "1.9.0-ea" Java(TM) SE Runtime Environment (build 1.9.0-ea-b80) Java HotSpot(TM) 64-Bit Server VM (build 1.9.0-ea-b80, mixed mode) ----------------------------------------------------------------------------------------------------------------------------------------- [ababroy@localhost test]$ javac -source 7 -target 7 Test.java warning: [options] bootstrap class path not set in conjunction with -source 1.7 Test.java:11: error: incompatible types: Map<Object,CAP#1> cannot be converted to Map<Object,String> return h(g(xs, new F<String, Object>() {})); ^ where CAP#1 is a fresh type-variable: CAP#1 extends String from capture of ? extends String 1 error 1 warning [ababroy@localhost test]$ javac -source 9 -target 9 Test.java [ababroy@localhost test]$ [ababroy@localhost test]$ javac -source 8 -target 8 Test.java warning: [options] bootstrap class path not set in conjunction with -source 1.8 1 warning ----------------------------------------------------------------------------------------------------------------------------------------- 8u60 b27 ************ ababroy@localhost test]$ java -version java version "1.8.0_60" Java(TM) SE Runtime Environment (build 1.8.0_60-b27) Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode) [ababroy@localhost test]$ [ababroy@localhost test]$ javac -source 7 -target 7 Test.java warning: [options] bootstrap class path not set in conjunction with -source 1.7 1 warning [ababroy@localhost test]$ javac -source 1.8 -target 1.8 Test.java [ababroy@localhost test]$ ----------------------------------------------------------------------------------------------------------------------------------------- 7u80 b15 ************ ababroy@localhost test]$ java -version java version "1.7.0_80" Java(TM) SE Runtime Environment (build 1.7.0_80-b15) Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode) [ababroy@localhost test]$ javac -source 7 -target 7 Test.java [ababroy@localhost test]$ [ababroy@localhost test]$ javac -source 1.8 -target 1.8 Test.java javac: invalid source release: 1.8 Usage: javac <options> <source files> use -help for a list of possible options [ababroy@localhost test]$ -----------------------------------------------------------------------------------------------------------------------------------------
20-11-2015