unchecked conversion with self-referencing type parameter
Rafkind, Jon
jon.rafkind at hp.com
Thu Jan 30 15:29:44 PST 2014
On 01/30/2014 12:20 PM, Rafkind, Jon wrote:
> In the following code javac warns that unchecked conversion was needed,
> but my own type inference engine doesn't find a case where unchecked
> conversion is possible.
>
> public class C<X>{
> public <T extends C<T>> void foo(Class<T> c){
> }
>
> public void test(){
> Class<C> c = null;
> foo(c);
> // foo(C.class); // originally my test case was this, but its
> the same as using 'c'
> }
> }
>
> Substitute 'a1' for T.
>
> Bounds: a1 <: C<a1>
> Constraints: c -> Class<a1>
>
> reduce 'c -> Class<a1>'
> 1. c -> Class<a1>
> 2. Class<C> -> Class<a1>
> // at this point I think unchecked conversion is needed as loose
> constraints are the only place in the reduction process that mention
> unchecked conversion
> // but case 1 doesn't apply (Class<a1> is not proper), and case 4
> doesn't apply because G = Class<a1>, S is already a form of G = Class<C>.
> 3. Class<C> <: Class<a1>
> 4. C <= a1
> 5. C = a1
>
> add bound C = a1, infer the constraint 'C <: C<a1>' during incorporation.
>
> reduce 'C <: C<a1>'
> 1. C <: C<a1>
> fail, because C<a1> is a parameterized type but there is no super type
> of C that is a parameterized type of C
>
I think the mistake I made is during incorporation, the new bound should
have been 'C <: C<C>' which succeeds with unchecked conversion for the
subtype constraint. If the rule 'a = U and S <: T' matches before 'a = S
and a <: T' this is possible. The rules for incorporation (18.3) need to
be changed slightly to allow for this outcome, however.
1. The process doesn't explicitly say only one rule should match, just
that 'for any pair of bounds matching one of the rules'. I can see the
meaning go either way, but I originally took this to mean match as many
rules as possible.
2. Supposing only one rule should match it is not clear that the 'a = U
...' rules should match before the 'a = S' rules. So the ordering of the
rules should put 'a = U' at the top. Probably the process should be
explicit about matching in the order they are given as well.
Alternatively, S and T could be types that must contain inference
variables while U must be a proper type. I understood 'S and T are
inference variables or types' to mean they can be any kind of type.
More information about the lambda-spec-observers
mailing list