--- a/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Thu Nov 29 09:41:48 2012 +0000
+++ b/langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java Fri Nov 30 15:14:12 2012 +0000
@@ -2244,9 +2244,13 @@
//with the target-type, it will be recovered anyway in Attr.checkId
needsRecovery = false;
+ FunctionalReturnContext funcContext = that.getBodyKind() == JCLambda.BodyKind.EXPRESSION ?
+ new ExpressionLambdaReturnContext((JCExpression)that.getBody(), resultInfo.checkContext) :
+ new FunctionalReturnContext(resultInfo.checkContext);
+
ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ?
recoveryInfo :
- new ResultInfo(VAL, lambdaType.getReturnType(), new LambdaReturnContext(resultInfo.checkContext));
+ new ResultInfo(VAL, lambdaType.getReturnType(), funcContext);
localEnv.info.returnResult = bodyResultInfo;
if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) {
@@ -2327,8 +2331,9 @@
* type according to both the inherited context and the assignment
* context.
*/
- class LambdaReturnContext extends Check.NestedCheckContext {
- public LambdaReturnContext(CheckContext enclosingContext) {
+ class FunctionalReturnContext extends Check.NestedCheckContext {
+
+ FunctionalReturnContext(CheckContext enclosingContext) {
super(enclosingContext);
}
@@ -2344,6 +2349,23 @@
}
}
+ class ExpressionLambdaReturnContext extends FunctionalReturnContext {
+
+ JCExpression expr;
+
+ ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) {
+ super(enclosingContext);
+ this.expr = expr;
+ }
+
+ @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);
+ }
+ }
+
/**
* Lambda compatibility. Check that given return types, thrown types, parameter types
* are compatible with the expected functional interface descriptor. This means that:
@@ -2560,7 +2582,7 @@
if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) {
if (resType.isErroneous() ||
- new LambdaReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) {
+ new FunctionalReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) {
incompatibleReturnType = null;
}
}