2317 //create an environment for attribution of the lambda expression |
2317 //create an environment for attribution of the lambda expression |
2318 final Env<AttrContext> localEnv = lambdaEnv(that, env); |
2318 final Env<AttrContext> localEnv = lambdaEnv(that, env); |
2319 boolean needsRecovery = |
2319 boolean needsRecovery = |
2320 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK; |
2320 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK; |
2321 try { |
2321 try { |
2322 Type target = pt(); |
2322 Type currentTarget = pt(); |
2323 List<Type> explicitParamTypes = null; |
2323 List<Type> explicitParamTypes = null; |
2324 if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { |
2324 if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) { |
2325 //attribute lambda parameters |
2325 //attribute lambda parameters |
2326 attribStats(that.params, localEnv); |
2326 attribStats(that.params, localEnv); |
2327 explicitParamTypes = TreeInfo.types(that.params); |
2327 explicitParamTypes = TreeInfo.types(that.params); |
2328 target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext); |
|
2329 } |
2328 } |
2330 |
2329 |
2331 Type lambdaType; |
2330 Type lambdaType; |
2332 if (pt() != Type.recoveryType) { |
2331 if (pt() != Type.recoveryType) { |
2333 target = targetChecker.visit(target, that); |
2332 /* We need to adjust the target. If the target is an |
2334 lambdaType = types.findDescriptorType(target); |
2333 * intersection type, for example: SAM & I1 & I2 ... |
|
2334 * the target will be updated to SAM |
|
2335 */ |
|
2336 currentTarget = targetChecker.visit(currentTarget, that); |
|
2337 if (explicitParamTypes != null) { |
|
2338 currentTarget = infer.instantiateFunctionalInterface(that, |
|
2339 currentTarget, explicitParamTypes, resultInfo.checkContext); |
|
2340 } |
|
2341 lambdaType = types.findDescriptorType(currentTarget); |
2335 } else { |
2342 } else { |
2336 target = Type.recoveryType; |
2343 currentTarget = Type.recoveryType; |
2337 lambdaType = fallbackDescriptorType(that); |
2344 lambdaType = fallbackDescriptorType(that); |
2338 } |
2345 } |
2339 |
2346 |
2340 setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext); |
2347 setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext); |
2341 |
2348 |
2342 if (lambdaType.hasTag(FORALL)) { |
2349 if (lambdaType.hasTag(FORALL)) { |
2343 //lambda expression target desc cannot be a generic method |
2350 //lambda expression target desc cannot be a generic method |
2344 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", |
2351 resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target", |
2345 lambdaType, kindName(target.tsym), target.tsym)); |
2352 lambdaType, kindName(currentTarget.tsym), currentTarget.tsym)); |
2346 result = that.type = types.createErrorType(pt()); |
2353 result = that.type = types.createErrorType(pt()); |
2347 return; |
2354 return; |
2348 } |
2355 } |
2349 |
2356 |
2350 if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) { |
2357 if (that.paramKind == JCLambda.ParameterKind.IMPLICIT) { |
2374 //attribute lambda parameters |
2381 //attribute lambda parameters |
2375 attribStats(that.params, localEnv); |
2382 attribStats(that.params, localEnv); |
2376 |
2383 |
2377 if (arityMismatch) { |
2384 if (arityMismatch) { |
2378 resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda")); |
2385 resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda")); |
2379 result = that.type = types.createErrorType(target); |
2386 result = that.type = types.createErrorType(currentTarget); |
2380 return; |
2387 return; |
2381 } |
2388 } |
2382 } |
2389 } |
2383 |
2390 |
2384 //from this point on, no recovery is needed; if we are in assignment context |
2391 //from this point on, no recovery is needed; if we are in assignment context |
2401 } else { |
2408 } else { |
2402 JCBlock body = (JCBlock)that.body; |
2409 JCBlock body = (JCBlock)that.body; |
2403 attribStats(body.stats, localEnv); |
2410 attribStats(body.stats, localEnv); |
2404 } |
2411 } |
2405 |
2412 |
2406 result = check(that, target, VAL, resultInfo); |
2413 result = check(that, currentTarget, VAL, resultInfo); |
2407 |
2414 |
2408 boolean isSpeculativeRound = |
2415 boolean isSpeculativeRound = |
2409 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; |
2416 resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE; |
2410 |
2417 |
2411 preFlow(that); |
2418 preFlow(that); |
2412 flow.analyzeLambda(env, that, make, isSpeculativeRound); |
2419 flow.analyzeLambda(env, that, make, isSpeculativeRound); |
2413 |
2420 |
2414 checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound); |
2421 checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound); |
2415 |
2422 |
2416 if (!isSpeculativeRound) { |
2423 if (!isSpeculativeRound) { |
2417 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, target); |
2424 checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget); |
2418 } |
2425 } |
2419 result = check(that, target, VAL, resultInfo); |
2426 result = check(that, currentTarget, VAL, resultInfo); |
2420 } catch (Types.FunctionDescriptorLookupError ex) { |
2427 } catch (Types.FunctionDescriptorLookupError ex) { |
2421 JCDiagnostic cause = ex.getDiagnostic(); |
2428 JCDiagnostic cause = ex.getDiagnostic(); |
2422 resultInfo.checkContext.report(that, cause); |
2429 resultInfo.checkContext.report(that, cause); |
2423 result = that.type = types.createErrorType(pt()); |
2430 result = that.type = types.createErrorType(pt()); |
2424 return; |
2431 return; |