2242 //we will be able to attribute the whole lambda body, regardless of errors; |
2242 //we will be able to attribute the whole lambda body, regardless of errors; |
2243 //if we are in a 'check' method context, and the lambda is not compatible |
2243 //if we are in a 'check' method context, and the lambda is not compatible |
2244 //with the target-type, it will be recovered anyway in Attr.checkId |
2244 //with the target-type, it will be recovered anyway in Attr.checkId |
2245 needsRecovery = false; |
2245 needsRecovery = false; |
2246 |
2246 |
|
2247 FunctionalReturnContext funcContext = that.getBodyKind() == JCLambda.BodyKind.EXPRESSION ? |
|
2248 new ExpressionLambdaReturnContext((JCExpression)that.getBody(), resultInfo.checkContext) : |
|
2249 new FunctionalReturnContext(resultInfo.checkContext); |
|
2250 |
2247 ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ? |
2251 ResultInfo bodyResultInfo = lambdaType.getReturnType() == Type.recoveryType ? |
2248 recoveryInfo : |
2252 recoveryInfo : |
2249 new ResultInfo(VAL, lambdaType.getReturnType(), new LambdaReturnContext(resultInfo.checkContext)); |
2253 new ResultInfo(VAL, lambdaType.getReturnType(), funcContext); |
2250 localEnv.info.returnResult = bodyResultInfo; |
2254 localEnv.info.returnResult = bodyResultInfo; |
2251 |
2255 |
2252 if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { |
2256 if (that.getBodyKind() == JCLambda.BodyKind.EXPRESSION) { |
2253 attribTree(that.getBody(), localEnv, bodyResultInfo); |
2257 attribTree(that.getBody(), localEnv, bodyResultInfo); |
2254 } else { |
2258 } else { |
2325 * Lambda/method reference have a special check context that ensures |
2329 * Lambda/method reference have a special check context that ensures |
2326 * that i.e. a lambda return type is compatible with the expected |
2330 * that i.e. a lambda return type is compatible with the expected |
2327 * type according to both the inherited context and the assignment |
2331 * type according to both the inherited context and the assignment |
2328 * context. |
2332 * context. |
2329 */ |
2333 */ |
2330 class LambdaReturnContext extends Check.NestedCheckContext { |
2334 class FunctionalReturnContext extends Check.NestedCheckContext { |
2331 public LambdaReturnContext(CheckContext enclosingContext) { |
2335 |
|
2336 FunctionalReturnContext(CheckContext enclosingContext) { |
2332 super(enclosingContext); |
2337 super(enclosingContext); |
2333 } |
2338 } |
2334 |
2339 |
2335 @Override |
2340 @Override |
2336 public boolean compatible(Type found, Type req, Warner warn) { |
2341 public boolean compatible(Type found, Type req, Warner warn) { |
2339 super.compatible(found, req, warn); |
2344 super.compatible(found, req, warn); |
2340 } |
2345 } |
2341 @Override |
2346 @Override |
2342 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
2347 public void report(DiagnosticPosition pos, JCDiagnostic details) { |
2343 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); |
2348 enclosingContext.report(pos, diags.fragment("incompatible.ret.type.in.lambda", details)); |
|
2349 } |
|
2350 } |
|
2351 |
|
2352 class ExpressionLambdaReturnContext extends FunctionalReturnContext { |
|
2353 |
|
2354 JCExpression expr; |
|
2355 |
|
2356 ExpressionLambdaReturnContext(JCExpression expr, CheckContext enclosingContext) { |
|
2357 super(enclosingContext); |
|
2358 this.expr = expr; |
|
2359 } |
|
2360 |
|
2361 @Override |
|
2362 public boolean compatible(Type found, Type req, Warner warn) { |
|
2363 //a void return is compatible with an expression statement lambda |
|
2364 return TreeInfo.isExpressionStatement(expr) && req.hasTag(VOID) || |
|
2365 super.compatible(found, req, warn); |
2344 } |
2366 } |
2345 } |
2367 } |
2346 |
2368 |
2347 /** |
2369 /** |
2348 * Lambda compatibility. Check that given return types, thrown types, parameter types |
2370 * Lambda compatibility. Check that given return types, thrown types, parameter types |
2558 incompatibleReturnType = null; |
2580 incompatibleReturnType = null; |
2559 } |
2581 } |
2560 |
2582 |
2561 if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) { |
2583 if (!returnType.hasTag(VOID) && !resType.hasTag(VOID)) { |
2562 if (resType.isErroneous() || |
2584 if (resType.isErroneous() || |
2563 new LambdaReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) { |
2585 new FunctionalReturnContext(checkContext).compatible(resType, returnType, types.noWarnings)) { |
2564 incompatibleReturnType = null; |
2586 incompatibleReturnType = null; |
2565 } |
2587 } |
2566 } |
2588 } |
2567 |
2589 |
2568 if (incompatibleReturnType != null) { |
2590 if (incompatibleReturnType != null) { |