diff --git a/src/share/classes/com/sun/tools/javac/comp/Attr.java b/src/share/classes/com/sun/tools/javac/comp/Attr.java index ad0d5003144612c82e5bb6564bc9a148818cb41a..4c49601e2a4c33283041fe4df07187fdd24c08c9 100644 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java @@ -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 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); diff --git a/test/tools/javac/lambda/8023389/T8023389.java b/test/tools/javac/lambda/8023389/T8023389.java new file mode 100644 index 0000000000000000000000000000000000000000..25eb0c8a06645f57031bb4e7032976c711377c5f --- /dev/null +++ b/test/tools/javac/lambda/8023389/T8023389.java @@ -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 { + 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 sam1 = (SAM) (X1 x) -> { }; + SAM sam2 = (SAM & I) (X1 x) -> { }; +}