EVALUATION
This is a javac bug. What is the type of the expression
b.value.same
where the type of B is Box<?,?> ?
Let's do one step at time. We should compute the type of b.value first, but in order to do this, we should first capture the type of b. This lead to the type Box<X,Y>, where the upperbound ub(X) = Box<?,?> and where ub(Y) = X, where both X and Y are captured type-variables.
Since the declared type of b.value is T, it turns out that the actual type of b.value is Y. So our problem is now to determine the type of the field 'same' of Box, where the site symbol is Y.
It's important to notice that when the site symbol is a type variable, javac assumes the site symbol to be the upper bound of the type variable. In this case, this means that javac looks for the field 'some' within the type ub(Y) = X.
Here's the problem, since the site symbol is still a type variable, capture conversion of the site symbol has no effect here and javac ends up in looking for 'same' again into the type ub(X) = B<?,?> and not into the type capture(ub(X)) == capture(B<?,?>) as it should be.
This lead to javac uncorrectly assume that the site symbol is indeed of type B<?,?>, so when the field 'same' is accessed, this field is of type B<?,?> (the same type as the site). This makes the assignment b.value.some = new Box<B,B>() to be wrongly marked as correct, since what the compiler is actually checking is:
Box<B,B> <: Box<?,?> (which is clearly accepted by the compiler) and not
Box<B,B> <: capture(Box<?,?>) as it should be.
The solution to this problem is to recursively walk the site symbol's upper bound until we found some type that is not itself a type variable and then apply capture conversion to that non-type variable type. In this case, when accessing 'some' in Y, javac should retrieve ub(Y) = X and then ub(X) = Box<?,?>, since X is itself a (captured) type-variable.
|