mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-03 23:18:28 +00:00
8023389: Javac fails to infer type for lambda used with intersection type and wildcards
Reviewed-by: jjg, vromero
This commit is contained in:
parent
46d7a993ad
commit
06caeea3d6
@ -2319,30 +2319,37 @@ public class Attr extends JCTree.Visitor {
|
||||
boolean needsRecovery =
|
||||
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.CHECK;
|
||||
try {
|
||||
Type target = pt();
|
||||
Type currentTarget = pt();
|
||||
List<Type> explicitParamTypes = null;
|
||||
if (that.paramKind == JCLambda.ParameterKind.EXPLICIT) {
|
||||
//attribute lambda parameters
|
||||
attribStats(that.params, localEnv);
|
||||
explicitParamTypes = TreeInfo.types(that.params);
|
||||
target = infer.instantiateFunctionalInterface(that, target, explicitParamTypes, resultInfo.checkContext);
|
||||
}
|
||||
|
||||
Type lambdaType;
|
||||
if (pt() != Type.recoveryType) {
|
||||
target = targetChecker.visit(target, that);
|
||||
lambdaType = types.findDescriptorType(target);
|
||||
/* We need to adjust the target. If the target is an
|
||||
* intersection type, for example: SAM & I1 & I2 ...
|
||||
* the target will be updated to SAM
|
||||
*/
|
||||
currentTarget = targetChecker.visit(currentTarget, that);
|
||||
if (explicitParamTypes != null) {
|
||||
currentTarget = infer.instantiateFunctionalInterface(that,
|
||||
currentTarget, explicitParamTypes, resultInfo.checkContext);
|
||||
}
|
||||
lambdaType = types.findDescriptorType(currentTarget);
|
||||
} else {
|
||||
target = Type.recoveryType;
|
||||
currentTarget = Type.recoveryType;
|
||||
lambdaType = fallbackDescriptorType(that);
|
||||
}
|
||||
|
||||
setFunctionalInfo(localEnv, that, pt(), lambdaType, target, resultInfo.checkContext);
|
||||
setFunctionalInfo(localEnv, that, pt(), lambdaType, currentTarget, resultInfo.checkContext);
|
||||
|
||||
if (lambdaType.hasTag(FORALL)) {
|
||||
//lambda expression target desc cannot be a generic method
|
||||
resultInfo.checkContext.report(that, diags.fragment("invalid.generic.lambda.target",
|
||||
lambdaType, kindName(target.tsym), target.tsym));
|
||||
lambdaType, kindName(currentTarget.tsym), currentTarget.tsym));
|
||||
result = that.type = types.createErrorType(pt());
|
||||
return;
|
||||
}
|
||||
@ -2376,7 +2383,7 @@ public class Attr extends JCTree.Visitor {
|
||||
|
||||
if (arityMismatch) {
|
||||
resultInfo.checkContext.report(that, diags.fragment("incompatible.arg.types.in.lambda"));
|
||||
result = that.type = types.createErrorType(target);
|
||||
result = that.type = types.createErrorType(currentTarget);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -2403,7 +2410,7 @@ public class Attr extends JCTree.Visitor {
|
||||
attribStats(body.stats, localEnv);
|
||||
}
|
||||
|
||||
result = check(that, target, VAL, resultInfo);
|
||||
result = check(that, currentTarget, VAL, resultInfo);
|
||||
|
||||
boolean isSpeculativeRound =
|
||||
resultInfo.checkContext.deferredAttrContext().mode == DeferredAttr.AttrMode.SPECULATIVE;
|
||||
@ -2414,9 +2421,9 @@ public class Attr extends JCTree.Visitor {
|
||||
checkLambdaCompatible(that, lambdaType, resultInfo.checkContext, isSpeculativeRound);
|
||||
|
||||
if (!isSpeculativeRound) {
|
||||
checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, target);
|
||||
checkAccessibleTypes(that, localEnv, resultInfo.checkContext.inferenceContext(), lambdaType, currentTarget);
|
||||
}
|
||||
result = check(that, target, VAL, resultInfo);
|
||||
result = check(that, currentTarget, VAL, resultInfo);
|
||||
} catch (Types.FunctionDescriptorLookupError ex) {
|
||||
JCDiagnostic cause = ex.getDiagnostic();
|
||||
resultInfo.checkContext.report(that, cause);
|
||||
|
||||
46
langtools/test/tools/javac/lambda/8023389/T8023389.java
Normal file
46
langtools/test/tools/javac/lambda/8023389/T8023389.java
Normal file
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @test
|
||||
* @bug 8023389
|
||||
* @summary Javac fails to infer type for lambda used with intersection type and wildcards
|
||||
* @compile T8023389.java
|
||||
*/
|
||||
public class T8023389 {
|
||||
|
||||
static class U1 {}
|
||||
static class X1 extends U1 {}
|
||||
|
||||
interface I { }
|
||||
|
||||
interface SAM<T> {
|
||||
void m(T t);
|
||||
}
|
||||
|
||||
/* Strictly speaking only the second of the following declarations provokes the bug.
|
||||
* But the first line is also a useful test case.
|
||||
*/
|
||||
SAM<? extends U1> sam1 = (SAM<? extends U1>) (X1 x) -> { };
|
||||
SAM<? extends U1> sam2 = (SAM<? extends U1> & I) (X1 x) -> { };
|
||||
}
|
||||
Loading…
x
Reference in New Issue
Block a user