recursive types capture: avoid capture comparison during glb computation (IDEA-57379; IDEA-139167; IDEA-139157)

This commit is contained in:
Anna Kozlova
2015-12-07 10:35:33 +01:00
parent c9285488b7
commit f55279387c
10 changed files with 83 additions and 27 deletions
@@ -52,9 +52,9 @@ class Test {
}*/
abstract class D<T extends Throwable & Runnable> {
<error descr="'foo(T, D<? extends Runnable>)' clashes with 'foo(T, D<? extends Throwable>)'; both methods have same erasure">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Runnable> y)</error>;
<error descr="'foo(T, D<? extends Runnable>)' is already defined in 'Test.D'">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Runnable> y)</error>;
abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Throwable> y);
<error descr="'foo(T, D<? extends Throwable>)' is already defined in 'Test.D'">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Throwable> y)</error>;
}
@@ -62,8 +62,8 @@ class Test {
interface IB {}
void testExtendsOrder() {
class E<T extends IA & IB> {
<error descr="'foo(E<? extends IA>)' clashes with 'foo(E<? extends IB>)'; both methods have same erasure">void foo(E<? extends IA> x)</error> {}
void foo(E<? extends IB> x) {}
<error descr="'foo(E<? extends IA>)' is already defined in 'E'">void foo(E<? extends IA> x)</error> {}
<error descr="'foo(E<? extends IB>)' is already defined in 'E'">void foo(E<? extends IB> x)</error> {}
}
}
@@ -52,9 +52,9 @@ class Test {
}*/
abstract class D<T extends Throwable & Runnable> {
<error descr="'foo(T, D<? extends Runnable>)' clashes with 'foo(T, D<? extends Throwable>)'; both methods have same erasure">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Runnable> y)</error>;
<error descr="'foo(T, D<? extends Runnable>)' is already defined in 'Test.D'">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Runnable> y)</error>;
abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Throwable> y);
<error descr="'foo(T, D<? extends Throwable>)' is already defined in 'Test.D'">abstract <T extends Serializable & Comparable<?>> void foo(T x, D<? extends Throwable> y)</error>;
}
@@ -62,8 +62,8 @@ class Test {
interface IB {}
void testExtendsOrder() {
class E<T extends IA & IB> {
<error descr="'foo(E<? extends IA>)' clashes with 'foo(E<? extends IB>)'; both methods have same erasure">void foo(E<? extends IA> x)</error> {}
void foo(E<? extends IB> x) {}
<error descr="'foo(E<? extends IA>)' is already defined in 'E'">void foo(E<? extends IA> x)</error> {}
<error descr="'foo(E<? extends IB>)' is already defined in 'E'">void foo(E<? extends IB> x)</error> {}
}
}
@@ -0,0 +1,12 @@
class A<T extends Iterable<?>>{
T get() {return null;}
T x;
void foo(A<? extends Iterable<String> > a){
String s = bar(a.get());
String s1 = bar(a.x);
}
<Tb> Tb bar(Iterable<Tb> a){
return null;
}
}
@@ -0,0 +1,10 @@
import java.util.*;
interface A<T extends A<? extends A<T>>> { }
class C {
void foo(List<A<? extends A<?>>> x){
List<A<?>> y = x;
}
}
@@ -0,0 +1,13 @@
import java.util.List;
interface A<T extends List<String>> {
T m();
}
abstract class C {
abstract <S> A<? extends S> foo();
void bar() {
this.<List<?>>foo().m().get(0).toLowerCase();
}
}