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 {
|
class ExpressionLambdaReturnContext extends FunctionalReturnContext {
|
||||||
|
|
||||||
JCExpression expr;
|
JCExpression expr;
|
||||||
|
boolean expStmtExpected;
|
||||||
|
|
||||||
ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
|
ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
|
||||||
super(enclosingContext);
|
super(enclosingContext);
|
||||||
this.expr = expr;
|
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
|
@Override
|
||||||
public boolean compatible(Type found, Type req, Warner warn) {
|
public boolean compatible(Type found, Type req, Warner warn) {
|
||||||
//a void return is compatible with an expression statement lambda
|
//a void return is compatible with an expression statement lambda
|
||||||
return TreeInfo.isExpressionStatement(expr) && req.hasTag(VOID) ||
|
if (req.hasTag(VOID)) {
|
||||||
super.compatible(found, req, warn);
|
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\
|
bad return type in lambda expression\n\
|
||||||
{0}
|
{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
|
# 0: type
|
||||||
compiler.misc.incompatible.ret.type.in.mref=\
|
compiler.misc.incompatible.ret.type.in.mref=\
|
||||||
bad return type in method reference\n\
|
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: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: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: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))
|
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: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: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: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:33:35: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||||
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:34:49: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||||
8 errors
|
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:14:21: compiler.err.prob.found.req: (compiler.misc.stat.expr.expected)
|
||||||
LambdaExprNotVoid.java:15: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.stat.expr.expected)
|
||||||
2 errors
|
2 errors
|
||||||
|
Loading…
x
Reference in New Issue
Block a user