8015505: Spurious inference error when return type of generic method requires unchecked conversion to target
authormcimadamore
Tue, 04 Jun 2013 11:34:31 +0100
changeset 18008 6d75e3886bac
parent 18007 0afa95bd8bc3
child 18009 f47ea7c9c3f4
8015505: Spurious inference error when return type of generic method requires unchecked conversion to target Summary: Use check context compatibility during 15.12.2.8 check (only when JDK 8 inference is enabled) Reviewed-by: jjg
langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java
langtools/test/tools/javac/generics/inference/8015505/T8015505.java
langtools/test/tools/javac/generics/inference/8015505/T8015505.out
langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Jun 04 11:31:12 2013 +0100
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Infer.java	Tue Jun 04 11:34:31 2013 +0100
@@ -218,8 +218,8 @@
         //we need to skip capture?
         Warner retWarn = new Warner();
         if (!resultInfo.checkContext.compatible(qtype1, resultInfo.checkContext.inferenceContext().asFree(to), retWarn) ||
-                //unchecked conversion is not allowed
-                retWarn.hasLint(Lint.LintCategory.UNCHECKED)) {
+                //unchecked conversion is not allowed in source 7 mode
+                (!allowGraphInference && retWarn.hasLint(Lint.LintCategory.UNCHECKED))) {
             throw inferenceException
                     .setMessage("infer.no.conforming.instance.exists",
                     inferenceContext.restvars(), mt.getReturnType(), to);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8015505/T8015505.java	Tue Jun 04 11:34:31 2013 +0100
@@ -0,0 +1,18 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8015505
+ * @summary Spurious inference error when return type of generic method requires unchecked conversion to target
+ * @compile/fail/ref=T8015505.out -Xlint:-options -source 7 -XDrawDiagnostics T8015505.java
+ * @compile T8015505.java
+ */
+
+import java.util.List;
+
+class T8015505 {
+
+    <Z> List m() { return null; }
+
+    void test() {
+        List<?> l = m();
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8015505/T8015505.out	Tue Jun 04 11:34:31 2013 +0100
@@ -0,0 +1,2 @@
+T8015505.java:16:22: compiler.err.prob.found.req: (compiler.misc.infer.no.conforming.instance.exists: Z, java.util.List, java.util.List<?>)
+1 error
--- a/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java	Tue Jun 04 11:31:12 2013 +0100
+++ b/langtools/test/tools/javac/generics/rawOverride/7062745/GenericOverrideTest.java	Tue Jun 04 11:34:31 2013 +0100
@@ -46,6 +46,17 @@
     extends JavacTestingAbstractThreadedTest
     implements Runnable {
 
+    enum SourceLevel {
+        SOURCE_7("-source", "7"),
+        SOURCE_DEFAULT();
+
+        String[] opts;
+
+        SourceLevel(String... opts) {
+            this.opts = opts;
+        }
+    }
+
     enum SignatureKind {
         NON_GENERIC(""),
         GENERIC("<X>");
@@ -112,12 +123,13 @@
             }
         }
 
-        boolean assignableTo(TypeArgumentKind that, SignatureKind sig) {
+        boolean assignableTo(TypeArgumentKind that, SignatureKind sig, SourceLevel level) {
             switch (this) {
                 case NONE:
                     //this case needs to workaround to javac's impl of 15.12.2.8 being too strict
-                    //ideally should be just 'return true' (see 7067746)
-                    return sig == SignatureKind.NON_GENERIC || that == NONE;
+                    //ideally should be just 'return true' (see 7067746/8015505)
+                    return level == SourceLevel.SOURCE_DEFAULT ||
+                            sig == SignatureKind.NON_GENERIC || that == NONE;
                 case UNBOUND:
                     return that == this || that == NONE;
                 case INTEGER:
@@ -143,10 +155,12 @@
                                     for (TypeArgumentKind ta3 : TypeArgumentKind.values()) {
                                         if (!ta3.compatibleWith(SignatureKind.NON_GENERIC))
                                             continue;
-                                        pool.execute(
-                                                new GenericOverrideTest(sig1,
-                                                rt1, ta1, sig2, rt2,
-                                                ta2, rt3, ta3));
+                                        for (SourceLevel level : SourceLevel.values()) {
+                                            pool.execute(
+                                                    new GenericOverrideTest(sig1,
+                                                    rt1, ta1, sig2, rt2,
+                                                    ta2, rt3, ta3, level));
+                                        }
                                     }
                                 }
                             }
@@ -162,12 +176,13 @@
     SignatureKind sig1, sig2;
     ReturnTypeKind rt1, rt2, rt3;
     TypeArgumentKind ta1, ta2, ta3;
+    SourceLevel level;
     JavaSource source;
     DiagnosticChecker diagChecker;
 
     GenericOverrideTest(SignatureKind sig1, ReturnTypeKind rt1, TypeArgumentKind ta1,
             SignatureKind sig2, ReturnTypeKind rt2, TypeArgumentKind ta2,
-            ReturnTypeKind rt3, TypeArgumentKind ta3) {
+            ReturnTypeKind rt3, TypeArgumentKind ta3, SourceLevel level) {
         this.sig1 = sig1;
         this.sig2 = sig2;
         this.rt1 = rt1;
@@ -176,6 +191,7 @@
         this.ta1 = ta1;
         this.ta2 = ta2;
         this.ta3 = ta3;
+        this.level = level;
         this.source = new JavaSource();
         this.diagChecker = new DiagnosticChecker();
     }
@@ -213,7 +229,8 @@
     @Override
     public void run() {
         JavacTask ct = (JavacTask)comp.getTask(null, fm.get(), diagChecker,
-                null, null, Arrays.asList(source));
+                level.opts != null ? Arrays.asList(level.opts) : null,
+                null, Arrays.asList(source));
         try {
             ct.analyze();
         } catch (Throwable ex) {
@@ -271,7 +288,7 @@
             SignatureKind mssig = mostSpecific == 1 ? sig1 : sig2;
 
             if (!msrt.moreSpecificThan(rt3) ||
-                    !msta.assignableTo(ta3, mssig)) {
+                    !msta.assignableTo(ta3, mssig, level)) {
                 errorExpected = true;
             }
         }