8174249: Regression in generic method unchecked calls
authormcimadamore
Thu, 09 Feb 2017 15:19:05 +0000
changeset 43761 f50592785b30
parent 43760 bdbe9f1571f0
child 43762 515fe48569fe
8174249: Regression in generic method unchecked calls Summary: Erasure for unchecked call occurs too early after JDK-8078093 Reviewed-by: vromero
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
langtools/test/tools/javac/generics/inference/8174249/T8174249a.java
langtools/test/tools/javac/generics/inference/8174249/T8174249b.java
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Wed Feb 08 19:42:24 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Feb 09 15:19:05 2017 +0000
@@ -3994,10 +3994,16 @@
                         rs.methodArguments(argtypes.map(checkDeferredMap)),
                         kindName(sym.location()),
                         sym.location());
-               owntype = new MethodType(owntype.getParameterTypes(),
-                       types.erasure(owntype.getReturnType()),
-                       types.erasure(owntype.getThrownTypes()),
-                       syms.methodClass);
+                if (resultInfo.pt != Infer.anyPoly ||
+                        !owntype.hasTag(METHOD) ||
+                        !owntype.isPartial()) {
+                    //if this is not a partially inferred method type, erase return type. Otherwise,
+                    //erasure is carried out in PartiallyInferredMethodType.check().
+                    owntype = new MethodType(owntype.getParameterTypes(),
+                            types.erasure(owntype.getReturnType()),
+                            types.erasure(owntype.getThrownTypes()),
+                            syms.methodClass);
+                }
             }
 
             PolyKind pkind = (sym.type.hasTag(FORALL) &&
--- a/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Wed Feb 08 19:42:24 2017 -0800
+++ b/langtools/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Feb 09 15:19:05 2017 +0000
@@ -319,7 +319,8 @@
                  *  need to use it several times: with several targets.
                  */
                 saved_undet = inferenceContext.save();
-                if (allowGraphInference && !warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
+                boolean unchecked = warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED);
+                if (allowGraphInference && !unchecked) {
                     boolean shouldPropagate = shouldPropagate(getReturnType(), resultInfo, inferenceContext);
 
                     InferenceContext minContext = shouldPropagate ?
@@ -338,7 +339,10 @@
                     }
                 }
                 inferenceContext.solve(noWarnings);
-                return inferenceContext.asInstType(this).getReturnType();
+                Type ret = inferenceContext.asInstType(this).getReturnType();
+                //inline logic from Attr.checkMethod - if unchecked conversion was required, erase
+                //return type _after_ resolution
+                return unchecked ? types.erasure(ret) : ret;
             } catch (InferenceException ex) {
                 resultInfo.checkContext.report(null, ex.getDiagnostic());
                 Assert.error(); //cannot get here (the above should throw)
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8174249/T8174249a.java	Thu Feb 09 15:19:05 2017 +0000
@@ -0,0 +1,54 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8174249
+ * @summary Regression in generic method unchecked calls
+ * @compile T8174249a.java
+ */
+
+import java.util.ArrayList;
+import java.util.Collection;
+
+class T8174249a {
+    static <T> T foo(Class<T> c, Collection<? super T> baz) {
+return null;
+    }
+
+    static void bar(String c) { }
+
+    void test() {
+        // this works
+        bar(foo(String.class, new ArrayList<String>()));
+
+        // this works with a warning
+        String s = foo(String.class, new ArrayList());
+        bar(s);
+
+        // this causes an error on JDK9 but should work
+        bar(foo(String.class, new ArrayList()));
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/generics/inference/8174249/T8174249b.java	Thu Feb 09 15:19:05 2017 +0000
@@ -0,0 +1,59 @@
+/*
+ * Copyright (c) 2017, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.  Oracle designates this
+ * particular file as subject to the "Classpath" exception as provided
+ * by Oracle in the LICENSE file that accompanied this code.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8174249
+ * @summary Regression in generic method unchecked calls
+ * @compile T8174249b.java
+ */
+
+import java.util.*;
+
+class T8174249b {
+
+    static void cs(Collection<String> cs) {}
+
+    void test1(Collection c) {
+        cs(rawCollection((Class)null));
+        Collection<String> cs1 = rawCollection((Class)null);
+    }
+
+    void test2(Collection c) {
+        cs(rawCollection2((Class)null));
+        Collection<String> cs2 = rawCollection2((Class)null);
+    }
+
+    void test3(Collection c) {
+        cs(rawCollection3((Class)null));
+        Collection<String> cs3 = rawCollection2((Class)null);
+    }
+
+    Collection<Integer> rawCollection(Class<String> cs) { return null; }
+
+    <Z> Collection<Integer> rawCollection2(Class<Z> cs) { return null; }
+
+    <Z> Collection<Z> rawCollection3(Class<Z> cs) { return null; }
+}