Anonymous class instance creation expression with diamond compatibility constraint is reduced to anonymous class type?

Remi Forax forax at univ-mlv.fr
Mon Mar 13 07:05:29 UTC 2017


Hi Maurizio,

----- Mail original -----
> De: "Maurizio Cimadamore" <maurizio.cimadamore at oracle.com>
> À: "B. Blaser" <bsrbnd at gmail.com>
> Cc: compiler-dev at openjdk.java.net
> Envoyé: Samedi 11 Mars 2017 22:49:34
> Objet: Re: Anonymous class instance creation expression with diamond compatibility constraint is reduced to anonymous
> class type?

> On 11/03/17 15:05, B. Blaser wrote:
>> Hi,
>>
>> On 10 March 2017 at 22:46, Maurizio Cimadamore
>> <maurizio.cimadamore at oracle.com> wrote:
>>> Hi Georgiy - thanks for the report. Just so that I understand - is this a
>>> regression or is it a new test and that's the behavior you are seeing with
>>> the latest build? I'm asking because I don't recall recent changes in this
>>> area.
>>>
>>> That said, I think your analysis looks correct - the spec draft calls for
>>> the anonymous inner class non-denotable type to be 'normalized'.
>>>
>>> Maurizio
>> The problem seems to be present since build 82, 136, 152 and rev
>> a21e5b9dc5c3 (1.5 month ago).
> Uhm - I looked at  a21e5b9dc5c3, and all I found is this:
> 
> http://hg.openjdk.java.net/jdk9/dev/langtools/rev/a21e5b9dc5c3
> 
> Which seems unlikely to cause inference issues?
>>
>> Next is a patch that corrects this specific case upon rev a21e5b9dc5c3
>> (needs to be well tested).
>> It 'normalizes' T when checking for same type (Types.isSameType(),
>> Types.SameTypeVisitor.visitClassType() and
>> Types.SameTypeVisitor.visitUndetVar()).
> I believe the issue should be addressed in a more direct way - as per
> Georgiy's evaluation, the spec draft says that the type of
> 
> new Foo<>() { ... }
> 
> is simply Foo, not an anonymous type. So normalization should never be
> needed during type-checking.

You can not do that !

new Object() {  } is typed as the anonymous inner class, not Object,
the goal of the inference, at least for the average guy, is to fill the blank,
the resulting type has to be either the anonymous inner class or we should remove this feature.

> 
> Maurizio

Rémi

>>
>> Bernard
>>
>> diff --git a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>> b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>> --- a/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>> +++ b/src/jdk.compiler/share/classes/com/sun/tools/javac/code/Types.java
>> @@ -1022,6 +1022,20 @@
>>                   isSameTypeStrict.visit(t, s) :
>>                   isSameTypeLoose.visit(t, s);
>>       }
>> +    private Type normalize(Type t) {
>> +        if (t.tsym.name.isEmpty()) {
>> +            // Anonymous class
>> +            ClassType norm = (ClassType) t.tsym.type;
>> +            if (norm == null)
>> +                return null;
>> +            else if (norm.interfaces_field != null &&
>> norm.interfaces_field.nonEmpty())
>> +                return norm.interfaces_field.head;
>> +            else
>> +                return norm.supertype_field;
>> +        }
>> +        else
>> +            return t;
>> +    }
>>       // where
>>           abstract class SameTypeVisitor extends TypeRelation {
>>
>> @@ -1070,7 +1084,7 @@
>>
>>               @Override
>>               public Boolean visitClassType(ClassType t, Type s) {
>> -                if (t == s)
>> +                if (normalize(t) == normalize(s))
>>                       return true;
>>
>>                   if (s.isPartial())
>> @@ -1152,7 +1166,7 @@
>>                       return true;
>>                   }
>>
>> -                t.addBound(InferenceBound.EQ, s, Types.this);
>> +                t.addBound(InferenceBound.EQ, normalize(s), Types.this);
>>
>>                   return true;
>>               }
>>
>>> On 10/03/17 20:02, Georgiy Rakov wrote:
>>>> class MyType<T> {}
>>>>
>>>> class MyList<T> {
>>>>      MyList<T> copyThis() { return null; }
>>>> }
>>>>
>>>> class Foo<T> {
>>>>      Foo(MyType<String> a){ }
>>>> }
>>>>
>>>> public class Test26  {
>>>>      public static void main(String argv[]) {
>>>>          MyList<Foo> l1 = new MyList<>();
>>>>          m2(l1, m1(
>>>>                     new Foo<>(new MyType()){ }
>>>>                   ).copyThis());
>>>>      }
>>>>      public static <T> MyList<T> m2(MyList<T> l1, MyList<T> l2) { return
>>>> null; }
>>>>      public static <U> MyList<U> m1(U item) { return null; }
>>>> }


More information about the compiler-dev mailing list