Inference bug in javac: Was: enhanced enums - back from the dead?

forax at univ-mlv.fr forax at univ-mlv.fr
Sat Dec 8 12:19:03 UTC 2018


I switch to amber-dev because i think there is a bug in the inference algorithm of javac (or in the JLS ?)

----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> À: "Remi Forax" <forax at univ-mlv.fr>
> Cc: "amber-spec-experts" <amber-spec-experts at openjdk.java.net>
> Envoyé: Samedi 8 Décembre 2018 00:57:58
> Objet: Re: enhanced enums - back from the dead?

> <snip>
>> so let's retry
>>
>> public enum Foo<T extends Comparable<T>> {
>>    S<String>(""), I<Integer>(42);   // JEP 301 mentions the diamond syntax
>>    
>>    private T t;
>>    
>>    public Foo(T t) {
>>      this.t = t;
>>    }
>>    
>>    T t() {
>>      return t;
>>    }
>>    
>>    public static void main(String[] args) {
>>      Arrays.stream(values()).sorted(Comparator.comparing(Foo::t)).forEach(System.out::println);
>>    }
>> }
>>
>> My original point was, when you introduce a raw type in a Stream, you end up
>> with a warning on every methods because of the inference.
>> While if you use the correct type, with an unbounded wildcard, the compiler stop
>> you to do stupid things,
>> basically, you are trading an error to a series of warning people will be happy
>> to suppress with @SuppressWarnings.
>>
>>    Arrays.stream(values()).sorted(Comparator.comparing(Foo::t)).forEach(System.out::println);
>>    emits a series of warnings
> Yes, in this case the unchecked warning will hit. I understand that this
> is suboptimal (see at the end).
>>    Stream.of(S,
>>    I).sorted(Comparator.comparing(Foo::t)).forEach(System.out::println);
>>    emits an error
> Yes, this is no different than using classes, really.
>> BTW, it seems there is an issue somewhere in the compiler because
>>    Arrays.stream((Foo<?>[])values()).sorted(Comparator.comparing(Foo::t)).forEach(System.out::println);
>> happily compiles ??
> 
> Well, Foo and Foo<?> are interchangeable, so I guess the compiler is
> also trading Foo[] for Foo<?>[]. As per JLS 5.1.9:
> 
> "There is an unchecked conversion from the raw array type G[]k to any
> array type of the form G<T1,...,Tn>[]k. (The notation []k indicates an
> array type of k dimensions.)
> 
> Use of an unchecked conversion causes a compile-time unchecked warning
> unless all type arguments Ti (1 ≤ i ≤ n) are unbounded wildcards
> (§4.5.1), or the warning is suppressed by @SuppressWarnings (§9.6.4.5). "

What i mean is that if you run this code, it throws a CCE, because a String is not comparable to an Integer,
i believe there is a bug in javac (or the JLS) because with Foo<T extends Comparable<T>> , Foo<?>::t is Object & Comparable<?> & Serializable but then Comparator::comparing should not compile because you can not capture the '?' of Comparable to a <U extends Comparable<U>> as required by Comparator::comparing.



More information about the amber-dev mailing list