8041704: wrong error message when mixing lambda expression and inner class
authorpgovereau
Tue, 27 May 2014 18:57:44 +0100
changeset 24609 5139d892e270
parent 24608 71f05b7d5c10
child 24610 8b3b718970a9
8041704: wrong error message when mixing lambda expression and inner class Reviewed-by: vromero
langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out
langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java
langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out
--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Thu May 22 15:42:10 2014 -0700
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java	Tue May 27 18:57:44 2014 +0100
@@ -4678,16 +4678,30 @@
         private void initTypeIfNeeded(JCTree that) {
             if (that.type == null) {
                 if (that.hasTag(METHODDEF)) {
-                    that.type = dummyMethodType();
+                    that.type = dummyMethodType((JCMethodDecl)that);
                 } else {
                     that.type = syms.unknownType;
                 }
             }
         }
 
+        /* Construct a dummy method type. If we have a method declaration,
+         * and the declared return type is void, then use that return type
+         * instead of UNKNOWN to avoid spurious error messages in lambda
+         * bodies (see:JDK-8041704).
+         */
+        private Type dummyMethodType(JCMethodDecl md) {
+            Type restype = syms.unknownType;
+            if (md != null && md.restype.hasTag(TYPEIDENT)) {
+                JCPrimitiveTypeTree prim = (JCPrimitiveTypeTree)md.restype;
+                if (prim.typetag == VOID)
+                    restype = syms.voidType;
+            }
+            return new MethodType(List.<Type>nil(), restype,
+                                  List.<Type>nil(), syms.methodClass);
+        }
         private Type dummyMethodType() {
-            return new MethodType(List.<Type>nil(), syms.unknownType,
-                            List.<Type>nil(), syms.methodClass);
+            return dummyMethodType(null);
         }
 
         @Override
--- a/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out	Thu May 22 15:42:10 2014 -0700
+++ b/langtools/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out	Tue May 27 18:57:44 2014 +0100
@@ -1,3 +1,2 @@
-CrashLambdaExpressionWithNonAccessibleIdTest.java:15:35: compiler.err.missing.ret.stmt
 CrashLambdaExpressionWithNonAccessibleIdTest.java:14:17: compiler.err.cant.resolve.location: kindname.class, A, , , (compiler.misc.location: kindname.class, CrashLambdaExpressionWithNonAccessibleIdTest, null)
-2 errors
+1 error
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.java	Tue May 27 18:57:44 2014 +0100
@@ -0,0 +1,12 @@
+/**
+ * @test /nodynamiccopyright/
+ * @bug 8041704
+ * @summary wrong error message when mixing lambda expression and inner class
+ * @compile/fail/ref=ErrorMessageTest.out -XDrawDiagnostics ErrorMessageTest.java
+ */
+
+public class ErrorMessageTest {
+    void f(Runnable r) {
+        f(() -> { f(new MISSING() { public void run() {} }); });
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/langtools/test/tools/javac/lambda/T8041704/ErrorMessageTest.out	Tue May 27 18:57:44 2014 +0100
@@ -0,0 +1,2 @@
+ErrorMessageTest.java:10:25: compiler.err.cant.resolve.location: kindname.class, MISSING, , , (compiler.misc.location: kindname.class, ErrorMessageTest, null)
+1 error