Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6450290
Votes 0
Synopsis Capture of nested wildcards causes type error
Category java:compiler
Reported Against
Release Fixed 7(b27)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 6450691
Submit Date 19-JUL-2006
Description
FULL PRODUCT VERSION :
java version "1.5.0_07"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.5.0_07-b03)
Java HotSpot(TM) Client VM (build 1.5.0_07-b03, mixed mode, sharing)


A DESCRIPTION OF THE PROBLEM :
In the attached code the capture of ? extends Box<?> is not treated right, allowing you to put a Box<B> in a Box<Box<A>>.
The code compiles without warnings, has no casts, but throws a ClassCastException.

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Compile (and run) the code

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
An error from the compiler
ACTUAL -
Incorrect code compiles, and throws a ClassCastException

ERROR MESSAGES/STACK TRACES THAT OCCUR :
Exception in thread "main" java.lang.ClassCastException: B
        at CaptureBug6.main(CaptureBug6.java:9)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
// this code compiles without warnings, has no casts,
// but throws a ClassCastException
public class CaptureBug6 {
	public static void main(String[] args) {
		Box<Box<A,A	>,Box<A,A>> a = new Box<Box<A,A>,Box<A,A>>(new Box<A,A>(new 
A()));
		Box<?, ?> b = a;		
		b.value.same = new Box<B,B>(new B());
		A c = a.value.same.value;
	}
}

class Box<X extends Box<?,?>, T extends X> {
	Box (T v) {
		value = v;
	}

	Box () {}
		
	T value;
	Box<X, T> same;

}

class A extends Box<A,A> {}
class B extends Box<B,B> {}


---------- END SOURCE ----------
Posted Date : 2006-07-19 08:20:15.0
Work Around
N/A
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.
Posted Date : 2008-02-26 14:07:33.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang