mirror of
https://github.com/openjdk/jdk.git
synced 2026-05-11 05:59:52 +00:00
8009131: Overload: javac should discard methods that lead to errors in lambdas with implicit parameter types
Lambdas that have errors in their bodies should make enclosing overload resolution fail Reviewed-by: jjg
This commit is contained in:
parent
b4b6e4f82e
commit
ea55015155
@ -2340,11 +2340,34 @@ public class Attr extends JCTree.Visitor {
|
||||
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
|
||||
localEnv.info.returnResult = bodyResultInfo;
|
||||
|
||||
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
|
||||
attribTree(that.getBody(), localEnv, bodyResultInfo);
|
||||
} else {
|
||||
JCBlock body = (JCBlock)that.body;
|
||||
attribStats(body.stats, localEnv);
|
||||
Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log);
|
||||
try {
|
||||
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
|
||||
attribTree(that.getBody(), localEnv, bodyResultInfo);
|
||||
} else {
|
||||
JCBlock body = (JCBlock)that.body;
|
||||
attribStats(body.stats, localEnv);
|
||||
}
|
||||
|
||||
if (resultInfo.checkContext.deferredAttrContext().mode == AttrMode.SPECULATIVE) {
|
||||
//check for errors in lambda body
|
||||
for (JCDiagnostic deferredDiag : lambdaDeferredHandler.getDiagnostics()) {
|
||||
if (deferredDiag.getKind() == JCDiagnostic.Kind.ERROR) {
|
||||
resultInfo.checkContext
|
||||
.report(that, diags.fragment("bad.arg.types.in.lambda", TreeInfo.types(that.params)));
|
||||
//we mark the lambda as erroneous - this is crucial in the recovery step
|
||||
//as parameter-dependent type error won't be reported in that stage,
|
||||
//meaning that a lambda will be deemed erroeneous only if there is
|
||||
//a target-independent error (which will cause method diagnostic
|
||||
//to be skipped).
|
||||
result = that.type = types.createErrorType(target);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
lambdaDeferredHandler.reportDeferredDiagnostics();
|
||||
log.popDiagnosticHandler(lambdaDeferredHandler);
|
||||
}
|
||||
|
||||
result = check(that, target, VAL, resultInfo);
|
||||
|
||||
@ -731,6 +731,11 @@ compiler.misc.incompatible.arg.types.in.lambda=\
|
||||
compiler.misc.incompatible.arg.types.in.mref=\
|
||||
incompatible parameter types in method reference
|
||||
|
||||
# 0: list of type
|
||||
compiler.misc.bad.arg.types.in.lambda=\
|
||||
cannot type-check lambda expression with inferred parameter types\n\
|
||||
inferred types: {0}
|
||||
|
||||
compiler.err.new.not.allowed.in.annotation=\
|
||||
''new'' not allowed in an annotation
|
||||
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 2013, 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.
|
||||
*/
|
||||
|
||||
// key: compiler.err.cant.apply.symbol
|
||||
// key: compiler.misc.no.conforming.assignment.exists
|
||||
// key: compiler.misc.bad.arg.types.in.lambda
|
||||
|
||||
class BadArgTypesInLambda {
|
||||
interface SAM {
|
||||
void m(Integer i);
|
||||
}
|
||||
|
||||
void g(SAM s) { }
|
||||
|
||||
void test() {
|
||||
g(x->{ String s = x; });
|
||||
}
|
||||
}
|
||||
@ -1,3 +1,2 @@
|
||||
BadRecovery.java:17:9: compiler.err.cant.apply.symbol: kindname.method, m, BadRecovery.SAM1, @369, kindname.class, BadRecovery, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.incompatible.arg.types.in.lambda))
|
||||
BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null)
|
||||
2 errors
|
||||
1 error
|
||||
|
||||
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2011, Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011, 2013, 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
|
||||
@ -23,11 +23,10 @@
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8003280
|
||||
* @bug 8003280 8009131
|
||||
* @summary Add lambda tests
|
||||
* check nested case of overload resolution and lambda parameter inference
|
||||
* @author Maurizio Cimadamore
|
||||
* @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
|
||||
* @compile TargetType01.java
|
||||
*/
|
||||
|
||||
class TargetType01 {
|
||||
|
||||
@ -1,3 +0,0 @@
|
||||
TargetType01.java:46:9: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
|
||||
TargetType01.java:46:26: compiler.err.ref.ambiguous: M, kindname.method, M(TargetType01.F_I_I), TargetType01, kindname.method, M(TargetType01.F_S_S), TargetType01
|
||||
2 errors
|
||||
@ -1,5 +1,4 @@
|
||||
TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object)
|
||||
TargetType43.java:13:30: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
|
||||
TargetType43.java:14:9: compiler.err.cant.apply.symbol: kindname.method, m, java.lang.Object, @359, kindname.class, TargetType43, (compiler.misc.no.conforming.assignment.exists: (compiler.misc.not.a.functional.intf: java.lang.Object))
|
||||
TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
|
||||
4 errors
|
||||
3 errors
|
||||
|
||||
26
langtools/test/tools/javac/lambda/TargetType66.java
Normal file
26
langtools/test/tools/javac/lambda/TargetType66.java
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8009131
|
||||
* @summary Overload: javac should discard methods that lead to errors in lambdas with implicit parameter types
|
||||
* @compile/fail/ref=TargetType66.out -XDrawDiagnostics TargetType66.java
|
||||
*/
|
||||
class TargetType66 {
|
||||
interface SAM1 {
|
||||
void m(String s);
|
||||
}
|
||||
|
||||
interface SAM2 {
|
||||
void m(Integer s);
|
||||
}
|
||||
|
||||
void g(SAM1 s1) { }
|
||||
void g(SAM2 s2) { }
|
||||
|
||||
void test() {
|
||||
g(x->{ String s = x; }); //g(SAM1)
|
||||
g(x->{ Integer i = x; }); //g(SAM2)
|
||||
g(x->{ Object o = x; }); //ambiguous
|
||||
g(x->{ Character c = x; }); //error: inapplicable methods
|
||||
g(x->{ Character c = ""; }); //error: incompatible types
|
||||
}
|
||||
}
|
||||
4
langtools/test/tools/javac/lambda/TargetType66.out
Normal file
4
langtools/test/tools/javac/lambda/TargetType66.out
Normal file
@ -0,0 +1,4 @@
|
||||
TargetType66.java:22:9: compiler.err.ref.ambiguous: g, kindname.method, g(TargetType66.SAM1), TargetType66, kindname.method, g(TargetType66.SAM2), TargetType66
|
||||
TargetType66.java:23:9: compiler.err.cant.apply.symbols: kindname.method, g, @578,{(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM1), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.String))),(compiler.misc.inapplicable.method: kindname.method, TargetType66, g(TargetType66.SAM2), (compiler.misc.no.conforming.assignment.exists: (compiler.misc.bad.arg.types.in.lambda: java.lang.Integer)))}
|
||||
TargetType66.java:24:30: compiler.err.prob.found.req: (compiler.misc.inconvertible.types: java.lang.String, java.lang.Character)
|
||||
3 errors
|
||||
Loading…
x
Reference in New Issue
Block a user