Type variable as wildcard bound

Rémi Forax forax at univ-mlv.fr
Thu Nov 17 05:37:09 PST 2011


On 11/17/2011 01:43 PM, Maurizio Cimadamore wrote:
> On 15/11/11 23:23, Zhong Yu wrote:
>> Hi team, I don't understand the behavior of javac7 u2 b11 on the following code:
>>
>>     class G<N extends Number>  {}
>>
>>     <T>  void f1(G<? extends T>  k){} //error. why?
>>
>>     <T>  void f2(G<? super   T>  k){} //ok. why?
>>
>> With capture conversion applied, in f1, we have upper bound T&Number,
>> lower bound null. I don't see any problem here, even if for some T,
>> T&Number=null. Is the combination of T&Number illegal?
>>
>> In f2, we have upper bound Number, lower bound T. Since it's not true
>> that T<:Number, I don't see why this should compile.
> The failure you are seeing is caused by the following statement in JLS 
> section 5.1.10:
>
> "If/T_i /is a wildcard type argument of the form|? extends|/B_i /, 
> then/S_i /is a fresh type variable whose upper bound is/glb(B_i /,/U_i 
> [A_1 /:=/S_1 , ..., A_n /:=/S_n ]/) and whose lower bound is the null 
> type, where/glb(V_1 ,... ,V_m )/is/V_1 & ... & V_m /. _It is a 
> compile-time error if for any two classes (not interfaces)__/V_i 
> /and/V_j ,V_i /is not a subclass of/V_j /__or vice versa._"
>
> Historically, javac has always interpreted the underlined text very 
> strictly - meaning that glb(T, Number) where T is a type-variable 
> (whose bound is Object) does not exist, as neither T <: Number nor 
> Number <: T. As such, the capture conversion for G<? extends T> does 
> not exist.
>
> While Javac 1.6 didn't complain about that specific code, it still 
> ended up in calculating an erroneous glb - which then led to bad 
> programs like the following to compile without errors:
>
> class G<N extends Number> {
>    private N n;
>    G(N n) { this.n = n; }
>    N g() { return n; };
> }
>
> class Test {
>    static <T> void f1(G<? extends T> k){ String s = k.g(); }
>
>    public static void main(String[] args) {
>       Test.f1(new G<Integer>(1)); //throws CCE at runtime!!!
>    }
> }
>
> In JDK 7 we made these error manifests, so that the glb computation 
> failure is now explicit. This way no unsound programs will be accepted 
> (and, as a side-effect, we got rid of a number of javac crashes 
> related to the fact that javac needed to hanlde this erroneous 
> captured type).
>
> We will consider as to whether the above JLS paragraph needs rewording 
> and, perhaps, to be loosened, in order to allow glb(T, Number) to 
> yield T & Number.
>
> Thanks
> Maurizio

but T can represent a class, so I don't see how T & Number can be valid ?

Rémi

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20111117/85e35ba9/attachment.html 


More information about the compiler-dev mailing list