changeset 1885:37abd4f2b379

8008708: Regression: separate compilation causes crash in wildcards inference logic
author mcimadamore
date Fri, 22 Feb 2013 16:57:52 +0000
parents 4a803280d79d
children 2912d9b3bbff
files src/share/classes/com/sun/tools/javac/code/Types.java test/tools/javac/lambda/MethodReference64.java test/tools/javac/lambda/MethodReference64.out test/tools/javac/lambda/TargetType65.java test/tools/javac/lambda/separate/Foo.java test/tools/javac/lambda/separate/Test.java
diffstat 6 files changed, 189 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Feb 22 15:36:54 2013 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Fri Feb 22 16:57:52 2013 +0000
@@ -572,20 +572,24 @@
     }
 
     public Type removeWildcards(Type site) {
-        if (capture(site) != site) {
+        Type capturedSite = capture(site);
+        if (capturedSite != site) {
             Type formalInterface = site.tsym.type;
             ListBuffer<Type> typeargs = ListBuffer.lb();
             List<Type> actualTypeargs = site.getTypeArguments();
+            List<Type> capturedTypeargs = capturedSite.getTypeArguments();
             //simply replace the wildcards with its bound
             for (Type t : formalInterface.getTypeArguments()) {
                 if (actualTypeargs.head.hasTag(WILDCARD)) {
                     WildcardType wt = (WildcardType)actualTypeargs.head;
                     Type bound;
                     switch (wt.kind) {
+                        case EXTENDS:
                         case UNBOUND:
+                            CapturedType capVar = (CapturedType)capturedTypeargs.head;
                             //use declared bound if it doesn't depend on formal type-args
-                            bound = wt.bound.bound.containsAny(formalInterface.getTypeArguments()) ?
-                                    syms.objectType : wt.bound.bound;
+                            bound = capVar.bound.containsAny(capturedSite.getTypeArguments()) ?
+                                    syms.objectType : capVar.bound;
                             break;
                         default:
                             bound = wt.type;
@@ -595,6 +599,7 @@
                     typeargs.append(actualTypeargs.head);
                 }
                 actualTypeargs = actualTypeargs.tail;
+                capturedTypeargs = capturedTypeargs.tail;
             }
             return subst(formalInterface, formalInterface.getTypeArguments(), typeargs.toList());
         } else {
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference64.java	Fri Feb 22 16:57:52 2013 +0000
@@ -0,0 +1,46 @@
+/*
+ * @test /nodynamiccopyright/
+ * @bug 8008540 8008539 8008538
+ * @summary Constructor reference to non-reifiable array should be rejected
+ * @compile/fail/ref=MethodReference64.out -XDrawDiagnostics MethodReference64.java
+ */
+class MethodReference64 {
+    interface ClassFactory {
+        Object m();
+    }
+    
+    interface ArrayFactory {
+        Object m(int i);
+    }
+    
+    @interface Anno { }
+    
+    enum E { }
+    
+    interface I { }
+    
+    static class Foo<X> { }
+    
+    void m(ClassFactory cf) { }
+    void m(ArrayFactory cf) { }
+
+    void testAssign() {
+        ClassFactory c1 = Anno::new; //error
+        ClassFactory c2 = E::new; //error
+        ClassFactory c3 = I::new; //error
+        ClassFactory c4 = Foo<?>::new; //error
+        ClassFactory c5 = 1::new; //error
+        ArrayFactory a1 = Foo<?>[]::new; //ok
+        ArrayFactory a2 = Foo<? extends String>[]::new; //error
+    }
+    
+    void testMethod() {
+        m(Anno::new); //error
+        m(E::new); //error
+        m(I::new); //error
+        m(Foo<?>::new); //error
+        m(1::new); //error
+        m(Foo<?>[]::new); //ok - resolves to m(ArrayFactory)
+        m(Foo<? extends String>[]::new); //error
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/MethodReference64.out	Fri Feb 22 16:57:52 2013 +0000
@@ -0,0 +1,13 @@
+MethodReference64.java:28:27: compiler.err.abstract.cant.be.instantiated: MethodReference64.Anno
+MethodReference64.java:29:27: compiler.err.enum.cant.be.instantiated
+MethodReference64.java:30:27: compiler.err.abstract.cant.be.instantiated: MethodReference64.I
+MethodReference64.java:31:30: compiler.err.type.found.req: ?, (compiler.misc.type.req.exact)
+MethodReference64.java:32:27: compiler.err.unexpected.type: kindname.class, kindname.value
+MethodReference64.java:34:48: compiler.err.generic.array.creation
+MethodReference64.java:38:11: compiler.err.abstract.cant.be.instantiated: MethodReference64.Anno
+MethodReference64.java:39:11: compiler.err.enum.cant.be.instantiated
+MethodReference64.java:40:11: compiler.err.abstract.cant.be.instantiated: MethodReference64.I
+MethodReference64.java:41:14: compiler.err.type.found.req: ?, (compiler.misc.type.req.exact)
+MethodReference64.java:42:11: compiler.err.unexpected.type: kindname.class, kindname.value
+MethodReference64.java:44:32: compiler.err.generic.array.creation
+12 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType65.java	Fri Feb 22 16:57:52 2013 +0000
@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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 8008723
+ * @summary Graph Inference: bad graph calculation leads to assertion error
+ * @compile TargetType65.java
+ */
+class TargetType65 {
+    interface Predicate<X> {
+        boolean accepts(X x);
+    }
+
+    static class Optional<T> {
+        public boolean isPresent() { return false; }
+        public static<E> Optional<E> empty() { return null; }
+    }
+
+    interface Supplier<X> { 
+        X make();
+    }
+
+    static class Sink<O, T> { }
+
+    static class SubSink<R> extends Sink<R, Optional<R>> {  }
+
+    static class Tester<T, O> {
+        public static <F> Tester<F, Optional<F>> makeRef() {
+            return new Tester<>(Optional.empty(), Optional::isPresent, SubSink::new);
+        }
+
+        private Tester(O emptyValue,
+                       Predicate<O> presentPredicate,
+                       Supplier<Sink<T, O>> sinkSupplier) {
+        }
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/separate/Foo.java	Fri Feb 22 16:57:52 2013 +0000
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2013, 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.
+ *
+ * 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.
+ */
+interface Foo<X extends Number> {
+    void m(X x);
+}
+
+class FooLib {
+    void m1(Foo<?> uf) { }
+    void m2(Foo<? extends Object> uf) { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/separate/Test.java	Fri Feb 22 16:57:52 2013 +0000
@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2012, 2013, 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.
+ *
+ * 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
+ * @compile Foo.java
+ * @compile Test.java
+ */
+class Test {
+    void test(FooLib fl) {
+        fl.m1(x->{});
+        fl.m2(x->{});
+    }
+}