提交 be3b9a7e 编写于 作者: M mcimadamore

8009131: Overload: javac should discard methods that lead to errors in lambdas...

8009131: Overload: javac should discard methods that lead to errors in lambdas with implicit parameter types
Summary: Lambdas that have errors in their bodies should make enclosing overload resolution fail
Reviewed-by: jjg
上级 08f5910a
...@@ -2340,11 +2340,34 @@ public class Attr extends JCTree.Visitor { ...@@ -2340,11 +2340,34 @@ public class Attr extends JCTree.Visitor {
new ResultInfo(VAL, lambdaType.getReturnType(), funcContext); new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
localEnv.info.returnResult = bodyResultInfo; localEnv.info.returnResult = bodyResultInfo;
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { Log.DeferredDiagnosticHandler lambdaDeferredHandler = new Log.DeferredDiagnosticHandler(log);
attribTree(that.getBody(), localEnv, bodyResultInfo); try {
} else { if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
JCBlock body = (JCBlock)that.body; attribTree(that.getBody(), localEnv, bodyResultInfo);
attribStats(body.stats, localEnv); } 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); result = check(that, target, VAL, resultInfo);
......
...@@ -731,6 +731,11 @@ compiler.misc.incompatible.arg.types.in.lambda=\ ...@@ -731,6 +731,11 @@ compiler.misc.incompatible.arg.types.in.lambda=\
compiler.misc.incompatible.arg.types.in.mref=\ compiler.misc.incompatible.arg.types.in.mref=\
incompatible parameter types in method reference 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=\ compiler.err.new.not.allowed.in.annotation=\
''new'' not allowed in an annotation ''new'' not allowed in an annotation
......
/*
* 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; });
}
}
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) BadRecovery.java:17:77: compiler.err.cant.resolve.location: kindname.variable, f, , , (compiler.misc.location: kindname.class, BadRecovery, null)
2 errors 1 error
/* /*
* 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. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
* *
* This code is free software; you can redistribute it and/or modify it * This code is free software; you can redistribute it and/or modify it
...@@ -23,11 +23,10 @@ ...@@ -23,11 +23,10 @@
/* /*
* @test * @test
* @bug 8003280 * @bug 8003280 8009131
* @summary Add lambda tests * @summary Add lambda tests
* check nested case of overload resolution and lambda parameter inference * check nested case of overload resolution and lambda parameter inference
* @author Maurizio Cimadamore * @compile TargetType01.java
* @compile/fail/ref=TargetType01.out -XDrawDiagnostics TargetType01.java
*/ */
class TargetType01 { class TargetType01 {
......
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
TargetType43.java:13:20: compiler.err.prob.found.req: (compiler.misc.not.a.functional.intf: java.lang.Object) 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: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) TargetType43.java:14:21: compiler.err.cant.resolve.location: kindname.class, NonExistentClass, , , (compiler.misc.location: kindname.class, TargetType43, null)
4 errors 3 errors
/*
* @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
}
}
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
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册