8153884: Expression lambda erroneously compatible with void-returning descriptor
Fix lambda compatibility check for void returning expressions Reviewed-by: vromero
This commit is contained in:
parent
eef5821303
commit
7fa26cbc1e
@ -2678,17 +2678,31 @@ public class Attr extends JCTree.Visitor {
|
||||
class ExpressionLambdaReturnContext extends FunctionalReturnContext {
|
||||
|
||||
JCExpression expr;
|
||||
boolean expStmtExpected;
|
||||
|
||||
ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
|
||||
super(enclosingContext);
|
||||
this.expr = expr;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void report(DiagnosticPosition pos, JCDiagnostic details) {
|
||||
if (expStmtExpected) {
|
||||
enclosingContext.report(pos, diags.fragment(Fragments.StatExprExpected));
|
||||
} else {
|
||||
super.report(pos, details);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean compatible(Type found, Type req, Warner warn) {
|
||||
//a void return is compatible with an expression statement lambda
|
||||
return TreeInfo.isExpressionStatement(expr) && req.hasTag(VOID) ||
|
||||
super.compatible(found, req, warn);
|
||||
if (req.hasTag(VOID)) {
|
||||
expStmtExpected = true;
|
||||
return TreeInfo.isExpressionStatement(expr);
|
||||
} else {
|
||||
return super.compatible(found, req, warn);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -779,6 +779,10 @@ compiler.misc.incompatible.ret.type.in.lambda=\
|
||||
bad return type in lambda expression\n\
|
||||
{0}
|
||||
|
||||
compiler.misc.stat.expr.expected=\
|
||||
lambda body is not compatible with a void functional interface\n\
|
||||
(consider using a block lambda body, or use a statement expression instead)
|
||||
|
||||
# 0: type
|
||||
compiler.misc.incompatible.ret.type.in.mref=\
|
||||
bad return type in method reference\n\
|
||||
|
@ -1,5 +1,5 @@
|
||||
T8012003b.java:30:12: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.cant.apply.symbol: kindname.method, g, java.lang.String, compiler.misc.no.args, kindname.class, T8012003b, (compiler.misc.arg.length.mismatch)))
|
||||
T8012003b.java:31:16: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, void))
|
||||
T8012003b.java:31:16: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||
T8012003b.java:32:22: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.conditional.target.cant.be.void))
|
||||
T8012003b.java:33:12: compiler.err.prob.found.req: (compiler.misc.invalid.mref: kindname.method, (compiler.misc.prob.found.req: (compiler.misc.inconvertible.types: java.lang.Integer, java.lang.String)))
|
||||
T8012003b.java:34:12: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.mref: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Integer))
|
||||
|
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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. Oracle designates this
|
||||
* particular file as subject to the "Classpath" exception as provided
|
||||
* by Oracle in the LICENSE file that accompanied this code.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
// key: compiler.err.prob.found.req
|
||||
// key: compiler.misc.stat.expr.expected
|
||||
|
||||
class StatExprExpected {
|
||||
void test() {
|
||||
Runnable r = () -> (foo());
|
||||
}
|
||||
|
||||
int foo() { return 1; }
|
||||
}
|
14
langtools/test/tools/javac/lambda/8153884/T8153884.java
Normal file
14
langtools/test/tools/javac/lambda/8153884/T8153884.java
Normal file
@ -0,0 +1,14 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8153884
|
||||
* @summary Expression lambda erroneously compatible with void-returning descriptor
|
||||
* @compile/fail/ref=T8153884.out -XDrawDiagnostics T8153884.java
|
||||
*/
|
||||
|
||||
class T8153884 {
|
||||
void test() {
|
||||
Runnable r = () -> (foo());
|
||||
}
|
||||
|
||||
void foo() { }
|
||||
}
|
2
langtools/test/tools/javac/lambda/8153884/T8153884.out
Normal file
2
langtools/test/tools/javac/lambda/8153884/T8153884.out
Normal file
@ -0,0 +1,2 @@
|
||||
T8153884.java:10:32: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||
1 error
|
@ -4,6 +4,6 @@ LambdaExpr10.java:23:40: compiler.err.prob.found.req: (compiler.misc.not.a.funct
|
||||
LambdaExpr10.java:24:46: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
|
||||
LambdaExpr10.java:28:29: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
|
||||
LambdaExpr10.java:29:33: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
|
||||
LambdaExpr10.java:33:35: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
|
||||
LambdaExpr10.java:34:49: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: java.lang.Object, void))
|
||||
LambdaExpr10.java:33:35: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||
LambdaExpr10.java:34:49: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||
8 errors
|
||||
|
@ -1,3 +1,3 @@
|
||||
LambdaExprNotVoid.java:14:21: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, void))
|
||||
LambdaExprNotVoid.java:15:21: compiler.err.prob.found.req: (compiler.misc.incompatible.ret.type.in.lambda: (compiler.misc.inconvertible.types: int, void))
|
||||
LambdaExprNotVoid.java:14:21: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||
LambdaExprNotVoid.java:15:21: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||
2 errors
|
||||
|
Loading…
Reference in New Issue
Block a user