[enhanced-enums]: Enhanced enums failure with raw types?

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Mon Sep 18 08:50:35 UTC 2017



On 16/09/17 12:27, B. Blaser wrote:
> On 15 September 2017 at 19:10, Maurizio Cimadamore
> <maurizio.cimadamore at oracle.com> wrote:
>> On 12/09/17 11:34, B. Blaser wrote:
>>> I agree with you, but this works with a warning (with the latest
>>> "enhanced enums" version - I've not tried with the JDK 9).
>>>
>>> It seems the inference occurs only on the actual argument (E = G) and
>>> then an unchecked cast is made from "EnumSet<G>" to
>>> "EnumSet<G<Object>>" when returning a value, producing a warning.
>>>
>>> Is this a bug?
>> This is a known non-confromance issue - see:
>>
>> https://bugs.openjdk.java.net/browse/JDK-8026527
>>
>> In other words, the code passes because javac does an unchecked subtyping
>> between G and G<Object> (this check would fail if standard subtyping were
>> used, as mandated by the spec).
> I'm not sure we are really in the same situation.
>
> Here, the return type constraint is simply not incorporated because G
> is raw, see [1] - Infer.instantiateMethod().
I think it is the same, but perhaps the timing with which things occur 
is slightly different; from EnumSet.allOf, we have the infreence 
variable E, with the following constraint:

E <: Enum<E>

Then, from checking actual against formal, we get this additional 
constraint:

Class<G> <: Class<E>

Now, from (18.2.3), we derive that:

G = E

And then, from (18.3.1)

G <: Enum<E>

So, to prove the above subtyping, we project the LHS to the supertype 
(which is erased, as G is raw):

Enum <: Enum<E>

And, at this point, you can only respond 'true' if you are doing an 
unchecked conversion. Otherwise (as in the JLS), the check will just fail.

Do you agree?

Maurizio


>
> A simple fix would be to remove this check but I don't know if it
> would have side-effects, as here under.
> Removing it produces the expected error:
>
> A.java:12: error: incompatible types: inference variable E has
> incompatible equality constraints G<Object>,G
>          EnumSet<G<Object>> g3 = EnumSet.allOf(G.class);
>                                               ^
>    where E is a type-variable:
>      E extends Enum<E> declared in method <E>allOf(Class<E>)
> 1 error
>
> What do you think?
>
> Bernard
>
> [1] http://hg.openjdk.java.net/amber/amber/langtools/file/7a22956a0562/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java#l201
>
>> Maurizio
> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/comp/Infer.java
> @@ -198,7 +198,7 @@
>                   //inject return constraints earlier
>                   doIncorporation(inferenceContext, warn); //propagation
>
> -                if (!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
> +//                if (!warn.hasNonSilentLint(Lint.LintCategory.UNCHECKED)) {
>                       boolean shouldPropagate =
> shouldPropagate(mt.getReturnType(), resultInfo, inferenceContext);
>
>                       InferenceContext minContext = shouldPropagate ?
> @@ -216,7 +216,7 @@
>                           deferredAttrContext.complete();
>                           return mt;
>                       }
> -                }
> +//                }
>               }
>
>               deferredAttrContext.complete();



More information about the amber-dev mailing list