Possible compiler bug

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Oct 22 11:25:48 UTC 2019


This is what is specified in the JLS 4. (raw types):

https://docs.oracle.com/javase/specs/jls/se13/html/jls-4.html#jls-4.8

More specifically, the combinations of these two bullets:

"
The superclasses (respectively, superinterfaces) of a raw type are the 
erasures of the superclasses (superinterfaces) of any of the 
parameterizations of the generic type.

The type of a constructor (§8.8), instance method (§8.4, §9.4), or 
non-static field (§8.3) of a raw type C that is not inherited from its 
superclasses or superinterfaces is the raw type that corresponds to the 
erasure of its type in the generic declaration corresponding to C.
"

Lead to the behavior you observed.

I agree that the behavior is surprising, and this has been pointed out 
in the past. The existing rules are designed to prevent issues when a 
member of the superclass refer to some of the type variable (if the 
subclass is raw, the type parameters might be missing!). In cases such 
as yours, this rule works against you - in the sense that there's no 
reason to erase the type of 'map' since it doesn't refer to any type 
variable of Base. But that said, we looked at this issue several times 
in the past and come away with a feeling that determining in which case 
the compiler should erase vs. should _not_ erase is trickier than it 
seems in the general case.

Maurizio


On 22/10/2019 12:19, Stefan Reich wrote:
> I was confused because the map's type parameters have nothing to do 
> with either the base, derived or enclosing classes.
>
> Be that as it may, your fix works. Thanks!
>
> On Tue, 22 Oct 2019 at 13:18, Stefan Reich 
> <stefan.reich.maker.of.eye at googlemail.com 
> <mailto:stefan.reich.maker.of.eye at googlemail.com>> wrote:
>
>     Hmm... so you're saying all the fields in a base class lose their
>     type parameters when I inherit from the raw base class? That's
>     quite surprising actually.
>
>     On Tue, 22 Oct 2019 at 13:16, Maurizio Cimadamore
>     <maurizio.cimadamore at oracle.com
>     <mailto:maurizio.cimadamore at oracle.com>> wrote:
>
>         The problem is that Derived.Inner extends Base.Inner - which
>         is a raw type.
>
>         Because of that, Derived.Inner does not inherit 'map' with
>         type Map<Integer, Referenced> as you expect, but instead it
>         inherits it raw (Map). Hence the error.
>
>         To fix, you need to replace the extends clause of
>         Derived.Inner to say  "extends Base<Derived.Inner>.Inner"
>
>         Maurizio
>
>         On 22/10/2019 12:11, Stefan Reich wrote:
>>         Hi, ok, the class relationships in this example are bit
>>         convoluted (I have them for a reason in the original source
>>         code), but I still don't see why it would fail to compile.
>>         import java.util.Map;
>>
>>         class Referenced {
>>         }
>>
>>         class Base<A extends Base.Inner> {
>>
>>              class Inner {
>>                  Map<Integer, Referenced>map;
>>
>>                  void bla() {
>>                      Referenced r =map.get(0);
>>                  }
>>              }
>>         }
>>
>>         class Derivedextends Base<Derived.Inner> {
>>              class Innerextends Base.Inner {
>>                  void bla() {
>>                      Referenced r =map.get(0);
>>                  }
>>              }
>>         }
>>         The error message is:
>>
>>         Referenced.java:20: error: incompatible types: Object cannot
>>         be converted to Referenced
>>                     Referenced r = map.get(0);
>>
>>         Why does the map suddenly lose its type parameters?
>>
>>         Many greetings,
>>         Stefan
>>
>>         -- 
>>         Stefan Reich
>>         BotCompany.de // Java-based operating systems
>
>
>
>     -- 
>     Stefan Reich
>     BotCompany.de // Java-based operating systems
>
>
>
> -- 
> Stefan Reich
> BotCompany.de // Java-based operating systems
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20191022/25285399/attachment-0001.html>


More information about the compiler-dev mailing list