Type parameters inside super() calls?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Wed Feb 1 23:43:43 UTC 2023


While I agree that what javac does is against the JLS, is this a javac 
or a spec bug?

I mean, consider this hierarchy:

|class Sup<X> { Sup(X x) { ... } } class Sub<Y> extends Sup<Y> { Sub(Y 
y) { super(y); } } |

What the rules are saying is that “y” in the Sub super call should be 
evaluated in a static context. But that doesn’t make any sense - because 
Y is not even a valid type in such a static context.

And yet - this is a valid program. So, if typechecking “y” is correct, 
then, surely, typechecking “(Y)y” should also be correct? E.g. it seems 
to me that the use of “static context” here is an “approximation” for 
the behavior we really want (e.g. no access to instance fields, whether 
directly or indirectly).

Maurizio

On 01/02/2023 22:39, Alex Buckley wrote:

> Your reading of the JLS is correct. The cast expression `(T)obj` 
> occurs in a static context, so the use of T should be disallowed, and 
> javac should reject the program.
>
> These rules in 8.8.7.1 and 8.1.3 are longstanding, and have not 
> changed recently, so I'm surprised that javac lets the program 
> through. That said, JLS16 saw a reworking of 8.1.3 (driven by 
> https://openjdk.org/jeps/395#Static-members-of-inner-classes) and 
> perhaps javac got a bit turned around over static contexts.
>
> As an additional test case, make the constructor generic -- `public <U 
> extends T> TypeParam ...` -- and cast obj to U rather than T -- still 
> illegal.
>
> Alex
>
> On 2/1/2023 12:45 PM, Archie Cobbs wrote:
>> This program compiles without error:
>>
>> import java.util.concurrent.atomic.*;
>> public class TypeParamStaticContext<T> extends AtomicReference<T> {
>>      public TypeParamStaticContext(Object obj) {
>>          super((T)obj);
>>      }
>> }
>>
>> Yet according to my reading of the JLS, the appearance of T inside 
>> the super() call should be disallowed:
>>
>> §8.8.7.1 <http://8.8.7.1>:
>>
>> An explicit constructor invocation statement introduces a static 
>> context (§8.1.3 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.1.3>), 
>> which limits the use of constructs that refer to the current object. 
>> Notably, the keywords |this| and |super| are prohibited in a static 
>> context (§15.8.3 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.8.3>, 
>> §15.11.2 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.11.2>), 
>> as are unqualified references to instance variables, instance 
>> methods, and type parameters of lexically enclosing declarations 
>> (§6.5.5.1 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-6.html#jls-6.5.5.1>, 
>> §6.5.6.1 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-6.html#jls-6.5.6.1>, 
>> §15.12.3 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-15.html#jls-15.12.3>).
>>
>> §6.5.5.1 <http://6.5.5.1>:
>>
>> If a type name consists of a single /Identifier/, then the identifier 
>> must occur in the scope of exactly one declaration of a class, 
>> interface, or type parameter with this name (§6.3 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-6.html#jls-6.3>), 
>> or a compile-time error occurs.
>>
>> If the declaration denotes a type parameter of a generic class or 
>> interface C (§8.1.2 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.1.2>, 
>> §9.1.2 
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-9.html#jls-9.1.2>), 
>> then both of the following must be true, or a compile-time error occurs:
>>
>>   *
>>
>>     The type name does not occur in a static context (§8.1.3
>> <https://docs.oracle.com/javase/specs/jls/se19/html/jls-8.html#jls-8.1.3>)
>>
>>   *
>>
>>     If the type name appears in a nested class or interface declaration
>>     of C, then the immediately enclosing class or interface declaration
>>     of the type name is an inner class of C.
>>
>>
>> What am I missing?
>>
>> Thanks,
>> -Archie
>>
>> -- 
>> Archie L. Cobbs

​
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/compiler-dev/attachments/20230201/ad718979/attachment-0001.htm>


More information about the compiler-dev mailing list