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

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Sat Mar 11 21:49:34 UTC 2017



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.

Maurizio
>
> 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