changeset 750:f5c76a5c84e3

Bug fixes: *) Lambda expression not allowed in instance creation context *) Target-type inference failure with '? extends' wildcards leads to compiler error *) Interface methods in diamond shaped inheritance trees are counted twice during SAM conversion *) Conformance error: Resolve/Infer should use Types.isConvertible instead of Types.isAssignable for actuals vs. formals check
author mcimadamore
date Thu, 11 Nov 2010 14:47:39 +0000
parents b3cc870e2c67
children 9a1ae3fc0a88
files src/share/classes/com/sun/tools/javac/code/Types.java src/share/classes/com/sun/tools/javac/comp/Attr.java src/share/classes/com/sun/tools/javac/comp/Infer.java src/share/classes/com/sun/tools/javac/comp/Resolve.java test/tools/javac/lambda/LambdaConv12.java test/tools/javac/lambda/LambdaConv13.java test/tools/javac/lambda/TargetType04.out test/tools/javac/lambda/TargetType15.java
diffstat 8 files changed, 157 insertions(+), 20 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/code/Types.java	Mon Nov 08 12:40:38 2010 +0000
+++ b/src/share/classes/com/sun/tools/javac/code/Types.java	Thu Nov 11 14:47:39 2010 +0000
@@ -297,9 +297,8 @@
         }
         return buf.toList();
     }
-
-    //where
-    private ConversionResult isConvertible(final Type t, final Type s, final Warner warn) {
+    
+    public ConversionResult isConvertible(final Type t, final Type s, final Warner warn) {
         if (isFunctionType(t) &&
                 (s.tsym.kind == Kinds.TYP)) {
             return new ConversionResult(true) {
@@ -316,12 +315,10 @@
                     boolean isReturnOk = t.getReturnType().tag == NONE || (t.getReturnType() == syms.voidType ?
                         (isSameType(mtype.getReturnType(), boxedClass(syms.voidType).type) ||
                             isSameType(mtype.getReturnType(), syms.voidType)) :
-                        (isConvertibleNoCheck(t.getReturnType(), mtype.getReturnType(), warn) ||
-                        containsType(mtype.getReturnType(), boxedTypeOrType(t.getReturnType()))));
-
-                    boolean argsOk = t.getParameterTypes().size() == mtype.getParameterTypes().size() && (
-                        isSameTypes(mtype.getParameterTypes(), t.getParameterTypes()) ||
-                        containsType(mtype.getParameterTypes(), t.getParameterTypes()));
+                        containsType(boxedTypeOrType(mtype.getReturnType()), boxedTypeOrType(t.getReturnType())));
+
+                    boolean argsOk = t.getParameterTypes().size() == mtype.getParameterTypes().size() &&
+                        containsType(mtype.getParameterTypes(), t.getParameterTypes());
 
                     boolean thrownOk = t.getThrownTypes() == Type.noTypes ||
                             chk.unhandled(t.getThrownTypes(), mtype.getThrownTypes()).isEmpty();
@@ -437,7 +434,7 @@
         }
         
         ListBuffer<Symbol> abstracts = ListBuffer.lb();
-        int count = findSAM(t, t, abstracts);
+        int count = findSAM(t, t, abstracts, ListBuffer.<Type>lb());
         if (abstracts.size() == 0) {
             //t must define a suitable non-generic method
             return new SAMResult(site, t, "no.target.method.for.lambda.conv");
@@ -449,9 +446,10 @@
         }
     }    
     //where
-    private int findSAM(Type site, Type t, ListBuffer<Symbol> buf) {
+    private int findSAM(Type site, Type t, ListBuffer<Symbol> buf, ListBuffer<Type> seenTypes) {
         int count = 0;
-        if (t == Type.noType) return count;
+        if (t == Type.noType || seenTypes.contains(t)) return count;
+        seenTypes.append(t);
         for (Scope.Entry e = t.tsym.members().elems ; e != null ; e = e.sibling) {
             if (e.sym != null && 
                     e.sym.kind == Kinds.MTH &&
@@ -468,9 +466,9 @@
                 count++;
             }
         }
-        count += findSAM(site, supertype(t), buf);
+        count += findSAM(site, supertype(t), buf, seenTypes);
         for (Type i : interfaces(t)) {
-            count += findSAM(site, i, buf);
+            count += findSAM(site, i, buf, seenTypes);
         }
         return count;
     }
@@ -719,6 +717,8 @@
         return isSubtypeUnchecked(t2, t) ?
             t2 : createErrorType(t);
     }
+
+
     // </editor-fold>
 
     // <editor-fold defaultstate="collapsed" desc="isSubtype">
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Mon Nov 08 12:40:38 2010 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Nov 11 14:47:39 2010 +0000
@@ -2158,6 +2158,14 @@
                 }
             }
             return false;
+        } else if (env.tree.getTag() == JCTree.NEWCLASS) {
+            JCNewClass newClazz = (JCNewClass)env.tree;
+            for (JCTree arg : newClazz.args) {
+                if (arg == lambdaOrReference) {
+                    return true;
+                }
+            }
+            return false;
         } else {
             return pt.tag == CLASS;
         }
--- a/src/share/classes/com/sun/tools/javac/comp/Infer.java	Mon Nov 08 12:40:38 2010 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java	Thu Nov 11 14:47:39 2010 +0000
@@ -401,7 +401,7 @@
                 boolean works = false;
                 JCDiagnostic problem = null;
                 if (allowBoxing) {
-                    Types.ConversionResult res = types.isAssignable(actual, undetFormal, warn);
+                    Types.ConversionResult res = types.isConvertible(actual, undetFormal, warn);
                     works = res.check(env);
                     problem = res.getDiagnostic(diags);
                 } else {
@@ -452,7 +452,7 @@
                     } else {
                         capturedArgs.append(actual = types.capture(actual));
                     }
-                    Types.ConversionResult res = types.isAssignable(actual, elemUndet, warn);
+                    Types.ConversionResult res = types.isConvertible(actual, elemUndet, warn);
                     boolean works = res.check(env);
                     JCDiagnostic problem = res.getDiagnostic(diags);
                     if (!works) {
--- a/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Mon Nov 08 12:40:38 2010 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Resolve.java	Thu Nov 11 14:47:39 2010 +0000
@@ -448,7 +448,7 @@
             boolean works = false;
             JCDiagnostic problem = null;
             if (allowBoxing) {
-                Types.ConversionResult res = types.isAssignable(actual, formals.head, warn);
+                Types.ConversionResult res = types.isConvertible(actual, formals.head, warn);
                 works = res.check(env);
                 problem = res.getDiagnostic(diags);
             } else {
@@ -475,7 +475,7 @@
     	        Type actual = argtypes.head.tag == FORALL ?
     	            infer.instantiateArg(env, (ForAll)argtypes.head, elt, warn) :
                     argtypes.head;
-                Types.ConversionResult res = types.isAssignable(actual, elt, warn);
+                Types.ConversionResult res = types.isConvertible(actual, elt, warn);
     	        if (!res.check(env)) {
                     JCDiagnostic problem = res.getDiagnostic(diags);
                     String errKey = problem == null ?
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaConv12.java	Thu Nov 11 14:47:39 2010 +0000
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2010, 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
+ * @summary instance creation expression should allow lambda expressions as constrcutor arguments
+ * @author  Maurizio Cimadamore
+ * @compile LambdaConv12.java
+ */
+
+class LambdaConv12 {
+
+    LambdaConv12(SAM s) {}
+
+    static abstract class SAM {
+        public abstract void m();
+    }
+
+    void test() {
+        new LambdaConv12(#{});
+        new LambdaConv12(#{}) {};
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/LambdaConv13.java	Thu Nov 11 14:47:39 2010 +0000
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2010, 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
+ * @summary interface methods in diamond shaped inheritance trees shouldn't be counted twice
+ * @author  Maurizio Cimadamore
+ * @compile LambdaConv13.java
+ */
+
+class LambdaConv13 {
+
+    interface I {
+        void m();
+    }
+
+    interface A extends I {}
+    interface B extends I {}
+    interface C extends A, B {}
+    interface D extends A, I {}
+    interface E extends B, I {}
+
+    C c = #{};
+    D d = #{};
+    D e = #{};
+}
--- a/test/tools/javac/lambda/TargetType04.out	Mon Nov 08 12:40:38 2010 +0000
+++ b/test/tools/javac/lambda/TargetType04.out	Thu Nov 11 14:47:39 2010 +0000
@@ -1,3 +1,3 @@
-TargetType04.java:37:44: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Double, java.lang.Integer
-TargetType04.java:38:44: compiler.err.prob.found.req: (compiler.misc.incompatible.types), java.lang.Integer, java.lang.Double
+TargetType04.java:37:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: ?, #?(?), TargetType04.S<java.lang.Double,java.lang.Integer>)), compiler.misc.type.lambda, TargetType04.S<java.lang.Double,java.lang.Integer>
+TargetType04.java:38:29: compiler.err.prob.found.req: (compiler.misc.incompatible.types.1: (compiler.misc.infer.no.conforming.instance.exists: ?, #?(?), TargetType04.S<java.lang.Integer,java.lang.Double>)), compiler.misc.type.lambda, TargetType04.S<java.lang.Integer,java.lang.Double>
 2 errors
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/TargetType15.java	Thu Nov 11 14:47:39 2010 +0000
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2010, 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
+ * @summary bad target-type inference lead to compiler crash
+ * @author  Maurizio Cimadamore
+ * @compile TargetType15.java
+ */
+
+class TargetType15 {
+
+    interface SAM<T> {
+        T foo(T a, T b);
+    }
+
+    SAM<? extends String> f_1 = #{ a, b -> a };
+    //SAM<? super String> f_2 = #{ a, b -> a }; //disabled as this is problematic
+    SAM<?> f_3 = #{ a, b -> a };
+}