The implementation of GLB (Types.glb, Types.union, etc.) compares types in terms of their classes. If the classes are the same, the second type is discarded, regardless of its type arguments.
Test case:
public class MixedGlb {
interface Box<T> { T get(); }
static class Parent {}
static class Child extends Parent { void poke() {} }
interface I<X extends Box<Child>> {
X get();
}
<T extends Box<? extends Parent>> void test(I<? extends T> arg) {
arg.get().get().poke();
// expected: the type I<? extends T> is malformed, or the invocation succeeds
// actual: error, cannot find method in type Parent
}
}
In the absence of wildcards, other checks (probably?) prevent this scenario from arising. But wildcards introduce additional interesting use cases (for which the behavior is often unclear -- see JDK-7034922.
In any case, it's simply incorrect for glb to arbitrarily discard one of the types.