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