changeset 1588:c9a4b3c92810

Add temporary workaround to support intersection-type targets on lambdas method references. Type-checking code will now use the _first_ interface bound of an intersection type as the target type for lambdas/method refs. This allows code using patterns such as: (Predicate<String> & Serializable)x->false To compile and behave exactly like before: additional interface bounds are simply ignored.
author mcimadamore
date Fri, 02 Nov 2012 11:45:58 +0000
parents 7ffcc63f2b3d
children 39145a667f8a
files src/share/classes/com/sun/tools/javac/comp/Attr.java test/tools/javac/lambda/Intersection01.java test/tools/javac/lambda/Intersection01.out
diffstat 3 files changed, 61 insertions(+), 2 deletions(-) [+]
line wrap: on
line diff
--- a/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu Nov 01 09:11:51 2012 +0000
+++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java	Fri Nov 02 11:45:58 2012 +0000
@@ -2187,7 +2187,7 @@
                 explicitParamTypes = TreeInfo.types(that.params);
             }
 
-            Type target = infer.instantiateFunctionalInterface(that, pt(), explicitParamTypes, resultInfo.checkContext);
+            Type target = infer.instantiateFunctionalInterface(that, adjustTarget(pt()), explicitParamTypes, resultInfo.checkContext);
             Type lambdaType = (target == Type.recoveryType) ?
                     fallbackDescriptorType(that) :
                     types.findDescriptorType(target);
@@ -2271,6 +2271,21 @@
         }
     }
     
+    //TODO - this needs to be removed when translation code will handle intersection types
+    private Type adjustTarget(Type t) {
+        if (t != Type.recoveryType && t.isCompound()) {
+            for (Type b : ((IntersectionClassType)t).getComponents()) {
+                if (b.isInterface()) {
+                    return b;
+                }
+            }
+            Assert.error("Cannot get here!");
+            return null;
+        } else {
+            return t;
+        }
+    }
+    
     Type fallbackDescriptorType(JCExpression tree) {
         switch (tree.getTag()) {
             case LAMBDA:
@@ -2421,7 +2436,7 @@
                 typeargtypes = attribTypes(that.typeargs, localEnv);
             }
 
-            Type target = infer.instantiateFunctionalInterface(that, pt(), null, resultInfo.checkContext);
+            Type target = infer.instantiateFunctionalInterface(that, adjustTarget(pt()), null, resultInfo.checkContext);
             Type desc = (target == Type.recoveryType) ?
                     fallbackDescriptorType(that) :
                     types.findDescriptorType(target);
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/Intersection01.java	Fri Nov 02 11:45:58 2012 +0000
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2012, 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 check that additional interface bounds are thrown away during Attr (temporrary workaround!)
+ * @compile/fail/ref=Intersection01.out -XDrawDiagnostics Intersection01.java
+ */
+class Intersection01 {
+    
+    interface SAM {
+        void m();
+    }
+
+    Object o1 = (java.io.Serializable & SAM)()->{};
+    Object o2 = (SAM & java.io.Serializable)()->{};
+    Object o3 = (java.io.Serializable & SAM)Intersection01::m;
+    Object o4 = (SAM & java.io.Serializable)Intersection01::m;
+
+    static void m() { }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/test/tools/javac/lambda/Intersection01.out	Fri Nov 02 11:45:58 2012 +0000
@@ -0,0 +1,3 @@
+Intersection01.java:35:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+Intersection01.java:37:45: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf.1: (compiler.misc.no.abstracts: kindname.interface, java.io.Serializable))
+2 errors