# HG changeset patch # User vromero # Date 1382446489 -3600 # Node ID 963c57175e40b210dbd90e1aff54fa230448577e # Parent f003f09144ff75634906986ff8ebaac2994da0f8 8025290: javac implicit versus explicit lambda compilation error Reviewed-by: jjg, dlsmith diff -r f003f09144ff -r 963c57175e40 src/share/classes/com/sun/tools/javac/comp/Attr.java --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Oct 22 10:08:49 2013 +0200 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Oct 22 13:54:49 2013 +0100 @@ -250,6 +250,14 @@ Type owntype = found; if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { if (allowPoly && inferenceContext.free(found)) { + if ((ownkind & ~resultInfo.pkind) == 0) { + owntype = resultInfo.check(tree, inferenceContext.asFree(owntype)); + } else { + log.error(tree.pos(), "unexpected.type", + kindNames(resultInfo.pkind), + kindName(ownkind)); + owntype = types.createErrorType(owntype); + } inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { @Override public void typesInferred(InferenceContext inferenceContext) { @@ -511,6 +519,15 @@ protected ResultInfo dup(CheckContext newContext) { return new ResultInfo(pkind, pt, newContext); } + + @Override + public String toString() { + if (pt != null) { + return pt.toString(); + } else { + return ""; + } + } } class RecoveryInfo extends ResultInfo { diff -r f003f09144ff -r 963c57175e40 src/share/classes/com/sun/tools/javac/comp/Check.java --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Oct 22 10:08:49 2013 +0200 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Oct 22 13:54:49 2013 +0100 @@ -528,7 +528,7 @@ inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() { @Override public void typesInferred(InferenceContext inferenceContext) { - checkType(pos, found, inferenceContext.asInstType(req), checkContext); + checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext); } }); } diff -r f003f09144ff -r 963c57175e40 src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Oct 22 10:08:49 2013 +0200 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Oct 22 13:54:49 2013 +0100 @@ -1768,9 +1768,11 @@ public Type apply(Type t) { if (t.hasTag(TYPEVAR)) { TypeVar tv = (TypeVar)t; - return tv.isCaptured() ? - new CapturedUndetVar((CapturedType)tv, types) : - new UndetVar(tv, types); + if (tv.isCaptured()) { + return new CapturedUndetVar((CapturedType)tv, types); + } else { + return new UndetVar(tv, types); + } } else { return t.map(this); } diff -r f003f09144ff -r 963c57175e40 src/share/classes/com/sun/tools/javac/util/JavacMessages.java --- a/src/share/classes/com/sun/tools/javac/util/JavacMessages.java Tue Oct 22 10:08:49 2013 +0200 +++ b/src/share/classes/com/sun/tools/javac/util/JavacMessages.java Tue Oct 22 13:54:49 2013 +0100 @@ -1,5 +1,5 @@ /* - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2005, 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 @@ -184,19 +184,19 @@ String key, Object... args) { String msg = null; - for (List l = bundles; l.nonEmpty() && msg == null; l = l.tail) { - ResourceBundle rb = l.head; - try { - msg = rb.getString(key); - } - catch (MissingResourceException e) { - // ignore, try other bundles in list - } - } - if (msg == null) { - msg = "compiler message file broken: key=" + key + - " arguments={0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}"; - } - return MessageFormat.format(msg, args); + for (List l = bundles; l.nonEmpty() && msg == null; l = l.tail) { + ResourceBundle rb = l.head; + try { + msg = rb.getString(key); + } + catch (MissingResourceException e) { + // ignore, try other bundles in list + } + } + if (msg == null) { + msg = "compiler message file broken: key=" + key + + " arguments={0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}"; + } + return MessageFormat.format(msg, args); } } diff -r f003f09144ff -r 963c57175e40 test/tools/javac/lambda/T8025290/ExplicitVSImplicitLambdaTest.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/test/tools/javac/lambda/T8025290/ExplicitVSImplicitLambdaTest.java Tue Oct 22 13:54:49 2013 +0100 @@ -0,0 +1,73 @@ +/* + * 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 8025290 + * @summary javac implicit versus explicit lambda compilation error + * @compile ExplicitVSImplicitLambdaTest.java + */ + +import java.util.function.*; + +public class ExplicitVSImplicitLambdaTest { + private void test() + { + /* in the explicit case "e" is inferred to String so we can use a String + * only method. + */ + MyComparator.mycomparing1((String e) -> e.concat("")); + MyComparator.mycomparing2((String e) -> e.concat("")); + MyComparator.mycomparing3((String e) -> e.concat("")); + MyComparator.mycomparing4((String e) -> e.concat("")); + + /* in the implicit case "e" is inferred to Object so toString() is OK. + */ + MyComparator.mycomparing1((e) -> e.toString()); + MyComparator.mycomparing2((e) -> e.toString()); + MyComparator.mycomparing3((e) -> e.toString()); + MyComparator.mycomparing4((e) -> e.toString()); + } +} + +interface MyComparator { + public static > MyComparator mycomparing1( + Function keyExtractor) { + return null; + } + + public static > MyComparator mycomparing2( + Function keyExtractor) { + return null; + } + + public static > MyComparator mycomparing3( + Function keyExtractor) { + return null; + } + + public static > MyComparator mycomparing4( + Function keyExtractor) { + return null; + } +}