Tue, 22 Oct 2013 13:54:49 +0100
8025290: javac implicit versus explicit lambda compilation error
Reviewed-by: jjg, dlsmith
1.1 --- a/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Oct 22 10:08:49 2013 +0200 1.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Attr.java Tue Oct 22 13:54:49 2013 +0100 1.3 @@ -250,6 +250,14 @@ 1.4 Type owntype = found; 1.5 if (!owntype.hasTag(ERROR) && !resultInfo.pt.hasTag(METHOD) && !resultInfo.pt.hasTag(FORALL)) { 1.6 if (allowPoly && inferenceContext.free(found)) { 1.7 + if ((ownkind & ~resultInfo.pkind) == 0) { 1.8 + owntype = resultInfo.check(tree, inferenceContext.asFree(owntype)); 1.9 + } else { 1.10 + log.error(tree.pos(), "unexpected.type", 1.11 + kindNames(resultInfo.pkind), 1.12 + kindName(ownkind)); 1.13 + owntype = types.createErrorType(owntype); 1.14 + } 1.15 inferenceContext.addFreeTypeListener(List.of(found, resultInfo.pt), new FreeTypeListener() { 1.16 @Override 1.17 public void typesInferred(InferenceContext inferenceContext) { 1.18 @@ -511,6 +519,15 @@ 1.19 protected ResultInfo dup(CheckContext newContext) { 1.20 return new ResultInfo(pkind, pt, newContext); 1.21 } 1.22 + 1.23 + @Override 1.24 + public String toString() { 1.25 + if (pt != null) { 1.26 + return pt.toString(); 1.27 + } else { 1.28 + return ""; 1.29 + } 1.30 + } 1.31 } 1.32 1.33 class RecoveryInfo extends ResultInfo {
2.1 --- a/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Oct 22 10:08:49 2013 +0200 2.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Check.java Tue Oct 22 13:54:49 2013 +0100 2.3 @@ -528,7 +528,7 @@ 2.4 inferenceContext.addFreeTypeListener(List.of(req), new FreeTypeListener() { 2.5 @Override 2.6 public void typesInferred(InferenceContext inferenceContext) { 2.7 - checkType(pos, found, inferenceContext.asInstType(req), checkContext); 2.8 + checkType(pos, inferenceContext.asInstType(found), inferenceContext.asInstType(req), checkContext); 2.9 } 2.10 }); 2.11 }
3.1 --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Oct 22 10:08:49 2013 +0200 3.2 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Oct 22 13:54:49 2013 +0100 3.3 @@ -1768,9 +1768,11 @@ 3.4 public Type apply(Type t) { 3.5 if (t.hasTag(TYPEVAR)) { 3.6 TypeVar tv = (TypeVar)t; 3.7 - return tv.isCaptured() ? 3.8 - new CapturedUndetVar((CapturedType)tv, types) : 3.9 - new UndetVar(tv, types); 3.10 + if (tv.isCaptured()) { 3.11 + return new CapturedUndetVar((CapturedType)tv, types); 3.12 + } else { 3.13 + return new UndetVar(tv, types); 3.14 + } 3.15 } else { 3.16 return t.map(this); 3.17 }
4.1 --- a/src/share/classes/com/sun/tools/javac/util/JavacMessages.java Tue Oct 22 10:08:49 2013 +0200 4.2 +++ b/src/share/classes/com/sun/tools/javac/util/JavacMessages.java Tue Oct 22 13:54:49 2013 +0100 4.3 @@ -1,5 +1,5 @@ 4.4 /* 4.5 - * Copyright (c) 2005, 2011, Oracle and/or its affiliates. All rights reserved. 4.6 + * Copyright (c) 2005, 2013, Oracle and/or its affiliates. All rights reserved. 4.7 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4.8 * 4.9 * This code is free software; you can redistribute it and/or modify it 4.10 @@ -184,19 +184,19 @@ 4.11 String key, 4.12 Object... args) { 4.13 String msg = null; 4.14 - for (List<ResourceBundle> l = bundles; l.nonEmpty() && msg == null; l = l.tail) { 4.15 - ResourceBundle rb = l.head; 4.16 - try { 4.17 - msg = rb.getString(key); 4.18 - } 4.19 - catch (MissingResourceException e) { 4.20 - // ignore, try other bundles in list 4.21 - } 4.22 - } 4.23 - if (msg == null) { 4.24 - msg = "compiler message file broken: key=" + key + 4.25 - " arguments={0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}"; 4.26 - } 4.27 - return MessageFormat.format(msg, args); 4.28 + for (List<ResourceBundle> l = bundles; l.nonEmpty() && msg == null; l = l.tail) { 4.29 + ResourceBundle rb = l.head; 4.30 + try { 4.31 + msg = rb.getString(key); 4.32 + } 4.33 + catch (MissingResourceException e) { 4.34 + // ignore, try other bundles in list 4.35 + } 4.36 + } 4.37 + if (msg == null) { 4.38 + msg = "compiler message file broken: key=" + key + 4.39 + " arguments={0}, {1}, {2}, {3}, {4}, {5}, {6}, {7}"; 4.40 + } 4.41 + return MessageFormat.format(msg, args); 4.42 } 4.43 }
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 5.2 +++ b/test/tools/javac/lambda/T8025290/ExplicitVSImplicitLambdaTest.java Tue Oct 22 13:54:49 2013 +0100 5.3 @@ -0,0 +1,73 @@ 5.4 +/* 5.5 + * Copyright (c) 2013, Oracle and/or its affiliates. All rights reserved. 5.6 + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 5.7 + * 5.8 + * This code is free software; you can redistribute it and/or modify it 5.9 + * under the terms of the GNU General Public License version 2 only, as 5.10 + * published by the Free Software Foundation. 5.11 + * 5.12 + * This code is distributed in the hope that it will be useful, but WITHOUT 5.13 + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 5.14 + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 5.15 + * version 2 for more details (a copy is included in the LICENSE file that 5.16 + * accompanied this code). 5.17 + * 5.18 + * You should have received a copy of the GNU General Public License version 5.19 + * 2 along with this work; if not, write to the Free Software Foundation, 5.20 + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 5.21 + * 5.22 + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 5.23 + * or visit www.oracle.com if you need additional information or have any 5.24 + * questions. 5.25 + */ 5.26 + 5.27 +/* 5.28 + * @test 5.29 + * @bug 8025290 5.30 + * @summary javac implicit versus explicit lambda compilation error 5.31 + * @compile ExplicitVSImplicitLambdaTest.java 5.32 + */ 5.33 + 5.34 +import java.util.function.*; 5.35 + 5.36 +public class ExplicitVSImplicitLambdaTest { 5.37 + private void test() 5.38 + { 5.39 + /* in the explicit case "e" is inferred to String so we can use a String 5.40 + * only method. 5.41 + */ 5.42 + MyComparator.mycomparing1((String e) -> e.concat("")); 5.43 + MyComparator.mycomparing2((String e) -> e.concat("")); 5.44 + MyComparator.mycomparing3((String e) -> e.concat("")); 5.45 + MyComparator.mycomparing4((String e) -> e.concat("")); 5.46 + 5.47 + /* in the implicit case "e" is inferred to Object so toString() is OK. 5.48 + */ 5.49 + MyComparator.mycomparing1((e) -> e.toString()); 5.50 + MyComparator.mycomparing2((e) -> e.toString()); 5.51 + MyComparator.mycomparing3((e) -> e.toString()); 5.52 + MyComparator.mycomparing4((e) -> e.toString()); 5.53 + } 5.54 +} 5.55 + 5.56 +interface MyComparator<T> { 5.57 + public static <T, U extends Comparable<? super U>> MyComparator<T> mycomparing1( 5.58 + Function<? super T, ? extends U> keyExtractor) { 5.59 + return null; 5.60 + } 5.61 + 5.62 + public static <T, U extends Comparable<? super U>> MyComparator<T> mycomparing2( 5.63 + Function<? super T, ? super U> keyExtractor) { 5.64 + return null; 5.65 + } 5.66 + 5.67 + public static <T, U extends Comparable<? super U>> MyComparator<T> mycomparing3( 5.68 + Function<? extends T, ? extends U> keyExtractor) { 5.69 + return null; 5.70 + } 5.71 + 5.72 + public static <T, U extends Comparable<? super U>> MyComparator<T> mycomparing4( 5.73 + Function<? extends T, ? super U> keyExtractor) { 5.74 + return null; 5.75 + } 5.76 +}