langtools/src/share/classes/com/sun/tools/javac/comp/Attr.java
changeset 14722 aaa39655aa2e
parent 14547 86d8d242b0c4
child 14723 46aa71a5e4e0
equal deleted inserted replaced
14721:071e3587f212 14722:aaa39655aa2e
  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) {