diff --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java index a0e0b3cc60e075b099ccb9d5e7f14b912b923d08..928c3dacb42290b4a3a46122f80a25a4e477a02a 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -4671,16 +4671,30 @@ public class Attr extends JCTree.Visitor { 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.nil(), restype, + List.nil(), syms.methodClass); + } private Type dummyMethodType() { - return new MethodType(List.nil(), syms.unknownType, - List.nil(), syms.methodClass); + return dummyMethodType(null); } @Override diff --git a/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out b/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out index d253b9c660b192d504cacbdda73010cb01323eef..3b2266c0b218b624723616f1de2364c9efc57ef1 100644 --- a/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out +++ b/test/tools/javac/T8030816/CrashLambdaExpressionWithNonAccessibleIdTest.out @@ -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 diff --git a/test/tools/javac/lambda/T8041704/ErrorMessageTest.java b/test/tools/javac/lambda/T8041704/ErrorMessageTest.java new file mode 100644 index 0000000000000000000000000000000000000000..5bd38c79d5916d64b126a8a428dda85ffc0f3420 --- /dev/null +++ b/test/tools/javac/lambda/T8041704/ErrorMessageTest.java @@ -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() {} }); }); + } +} diff --git a/test/tools/javac/lambda/T8041704/ErrorMessageTest.out b/test/tools/javac/lambda/T8041704/ErrorMessageTest.out new file mode 100644 index 0000000000000000000000000000000000000000..bdd25993c86604faae916702899365ea1ff92655 --- /dev/null +++ b/test/tools/javac/lambda/T8041704/ErrorMessageTest.out @@ -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