mirror of
https://github.com/openjdk/jdk.git
synced 2026-03-20 04:43:32 +00:00
8144767: Fix handling of capture variables in most-specific test
Reviewed-by: vromero
This commit is contained in:
parent
b2d09f5c6c
commit
5cffc0a3ab
@ -1155,12 +1155,18 @@ public class Resolve {
|
||||
|
||||
/** Parameters {@code t} and {@code s} are unrelated functional interface types. */
|
||||
private boolean functionalInterfaceMostSpecific(Type t, Type s, JCTree tree) {
|
||||
Type tDesc = types.findDescriptorType(t);
|
||||
Type tDesc = types.findDescriptorType(types.capture(t));
|
||||
Type tDescNoCapture = types.findDescriptorType(t);
|
||||
Type sDesc = types.findDescriptorType(s);
|
||||
|
||||
// compare type parameters -- can't use Types.hasSameBounds because bounds may have ivars
|
||||
final List<Type> tTypeParams = tDesc.getTypeArguments();
|
||||
final List<Type> tTypeParamsNoCapture = tDescNoCapture.getTypeArguments();
|
||||
final List<Type> sTypeParams = sDesc.getTypeArguments();
|
||||
|
||||
// compare type parameters
|
||||
if (tDesc.hasTag(FORALL) && !types.hasSameBounds((ForAll) tDesc, (ForAll) tDescNoCapture)) {
|
||||
return false;
|
||||
}
|
||||
// can't use Types.hasSameBounds on sDesc because bounds may have ivars
|
||||
List<Type> tIter = tTypeParams;
|
||||
List<Type> sIter = sTypeParams;
|
||||
while (tIter.nonEmpty() && sIter.nonEmpty()) {
|
||||
@ -1181,20 +1187,26 @@ public class Resolve {
|
||||
|
||||
// compare parameters
|
||||
List<Type> tParams = tDesc.getParameterTypes();
|
||||
List<Type> tParamsNoCapture = tDescNoCapture.getParameterTypes();
|
||||
List<Type> sParams = sDesc.getParameterTypes();
|
||||
while (tParams.nonEmpty() && sParams.nonEmpty()) {
|
||||
while (tParams.nonEmpty() && tParamsNoCapture.nonEmpty() && sParams.nonEmpty()) {
|
||||
Type tParam = tParams.head;
|
||||
Type tParamNoCapture = types.subst(tParamsNoCapture.head, tTypeParamsNoCapture, tTypeParams);
|
||||
Type sParam = types.subst(sParams.head, sTypeParams, tTypeParams);
|
||||
if (tParam.containsAny(tTypeParams) && inferenceContext().free(sParam)) {
|
||||
return false;
|
||||
}
|
||||
if (!types.isSameType(tParam, inferenceContext().asUndetVar(sParam))) {
|
||||
if (!types.isSubtype(inferenceContext().asUndetVar(sParam), tParam)) {
|
||||
return false;
|
||||
}
|
||||
if (!types.isSameType(tParamNoCapture, inferenceContext().asUndetVar(sParam))) {
|
||||
return false;
|
||||
}
|
||||
tParams = tParams.tail;
|
||||
tParamsNoCapture = tParamsNoCapture.tail;
|
||||
sParams = sParams.tail;
|
||||
}
|
||||
if (!tParams.isEmpty() || !sParams.isEmpty()) {
|
||||
if (!tParams.isEmpty() || !tParamsNoCapture.isEmpty() || !sParams.isEmpty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
@ -12,8 +12,6 @@ class MostSpecific28 {
|
||||
static void m1(Pred<? super Integer> f) {}
|
||||
static void m1(Fun<Number, Boolean> f) {}
|
||||
|
||||
static String foo(Object in) { return "a"; }
|
||||
|
||||
void test() {
|
||||
m1((Number n) -> true);
|
||||
}
|
||||
|
||||
@ -1,2 +1,2 @@
|
||||
MostSpecific28.java:18:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific28.Pred<? super java.lang.Integer>), MostSpecific28, kindname.method, m1(MostSpecific28.Fun<java.lang.Number,java.lang.Boolean>), MostSpecific28
|
||||
MostSpecific28.java:16:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific28.Pred<? super java.lang.Integer>), MostSpecific28, kindname.method, m1(MostSpecific28.Fun<java.lang.Number,java.lang.Boolean>), MostSpecific28
|
||||
1 error
|
||||
|
||||
42
langtools/test/tools/javac/lambda/MostSpecific29.java
Normal file
42
langtools/test/tools/javac/lambda/MostSpecific29.java
Normal file
@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2016, 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 8144767
|
||||
* @summary Correct most-specific test when wildcards appear in functional interface type
|
||||
* @compile MostSpecific29.java
|
||||
*/
|
||||
class MostSpecific29 {
|
||||
|
||||
interface Pred<T> { boolean test(T arg); }
|
||||
interface Fun<T,R> { R apply(T arg); }
|
||||
|
||||
static void m1(Pred<? super Integer> f) {}
|
||||
static void m1(Fun<Integer, Boolean> f) {}
|
||||
|
||||
void test() {
|
||||
m1((Integer n) -> true);
|
||||
}
|
||||
|
||||
}
|
||||
19
langtools/test/tools/javac/lambda/MostSpecific30.java
Normal file
19
langtools/test/tools/javac/lambda/MostSpecific30.java
Normal file
@ -0,0 +1,19 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8144767
|
||||
* @summary Correct most-specific test when wildcards appear in functional interface type
|
||||
* @compile/fail/ref=MostSpecific30.out -XDrawDiagnostics MostSpecific30.java
|
||||
*/
|
||||
class MostSpecific30 {
|
||||
|
||||
interface Pred<T> { boolean test(T arg); }
|
||||
interface Fun<T,R> { R apply(T arg); }
|
||||
|
||||
static void m1(Pred<? extends Integer> f) {}
|
||||
static void m1(Fun<Integer, Boolean> f) {}
|
||||
|
||||
void test() {
|
||||
m1((Integer n) -> true);
|
||||
}
|
||||
|
||||
}
|
||||
2
langtools/test/tools/javac/lambda/MostSpecific30.out
Normal file
2
langtools/test/tools/javac/lambda/MostSpecific30.out
Normal file
@ -0,0 +1,2 @@
|
||||
MostSpecific30.java:16:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific30.Pred<? extends java.lang.Integer>), MostSpecific30, kindname.method, m1(MostSpecific30.Fun<java.lang.Integer,java.lang.Boolean>), MostSpecific30
|
||||
1 error
|
||||
21
langtools/test/tools/javac/lambda/MostSpecific31.java
Normal file
21
langtools/test/tools/javac/lambda/MostSpecific31.java
Normal file
@ -0,0 +1,21 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8144767
|
||||
* @summary Correct most-specific test when wildcards appear in functional interface type
|
||||
* @compile/fail/ref=MostSpecific31.out -XDrawDiagnostics MostSpecific31.java
|
||||
*/
|
||||
class MostSpecific31 {
|
||||
|
||||
interface Pred<T> { boolean test(T arg); }
|
||||
interface Fun<T,R> { R apply(T arg); }
|
||||
|
||||
static void m1(Pred<? super Number> f) {}
|
||||
static void m1(Fun<Integer, Boolean> f) {}
|
||||
|
||||
static boolean foo(Object arg) { return false; }
|
||||
|
||||
void test() {
|
||||
m1(MostSpecific31::foo);
|
||||
}
|
||||
|
||||
}
|
||||
2
langtools/test/tools/javac/lambda/MostSpecific31.out
Normal file
2
langtools/test/tools/javac/lambda/MostSpecific31.out
Normal file
@ -0,0 +1,2 @@
|
||||
MostSpecific31.java:18:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific31.Pred<? super java.lang.Number>), MostSpecific31, kindname.method, m1(MostSpecific31.Fun<java.lang.Integer,java.lang.Boolean>), MostSpecific31
|
||||
1 error
|
||||
22
langtools/test/tools/javac/lambda/MostSpecific32.java
Normal file
22
langtools/test/tools/javac/lambda/MostSpecific32.java
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* @test /nodynamiccopyright/
|
||||
* @bug 8144767
|
||||
* @summary Correct most-specific test when wildcards appear in functional interface type
|
||||
* @compile/fail/ref=MostSpecific32.out -XDrawDiagnostics MostSpecific32.java
|
||||
*/
|
||||
class MostSpecific32 {
|
||||
|
||||
interface A<T> {}
|
||||
interface B<T> extends A<T> {}
|
||||
|
||||
interface F1<S> { A<S> apply(); }
|
||||
interface F2<S> { B<S> apply(); }
|
||||
|
||||
static void m1(F1<? extends Number> f1) {}
|
||||
static void m1(F2<? extends Number> f2) {}
|
||||
|
||||
void test() {
|
||||
m1(() -> null); // B<CAP ext Number> </: A<Number>
|
||||
}
|
||||
|
||||
}
|
||||
2
langtools/test/tools/javac/lambda/MostSpecific32.out
Normal file
2
langtools/test/tools/javac/lambda/MostSpecific32.out
Normal file
@ -0,0 +1,2 @@
|
||||
MostSpecific32.java:19:9: compiler.err.ref.ambiguous: m1, kindname.method, m1(MostSpecific32.F1<? extends java.lang.Number>), MostSpecific32, kindname.method, m1(MostSpecific32.F2<? extends java.lang.Number>), MostSpecific32
|
||||
1 error
|
||||
Loading…
x
Reference in New Issue
Block a user