This compiles but should not. Running produces a CCE.
public class WildSubtyping {
static class Container<T> {
T value;
}
static class A<T> {
T aValue;
void putT(T t) {}
}
static class B<T> extends A<A<T>> {
T bValue;
@Override
void putT(A<T> a) {
bValue = a.aValue;
}
}
static void bar(Container<? extends A<A<?>>> container) {
A<Integer> a = new A<Integer>();
a.aValue = 4;
container.value.putT(a);
}
static void foo(Container<B<?>> container) {
B<String> b = new B<String>();
container.value = b;
bar(container); // Container<B<?>> is not subtype of Container<? extends A<A<?>>> !!
b.bValue.length();
}
public static void main(String[] args) {
foo(new Container<B<?>>());
}
}
Reported by Ross Tate, as encountered by the Kotlin team.