Compiler binds base class incorrectly (shortcoming of base class circularity spec)

Maurizio Cimadamore maurizio.cimadamore at oracle.com
Tue Feb 8 03:47:24 PST 2011


I see... the following reduced test case is even more explicit:

class A<T> {
   static class X {
     static class Q {  }
   }
}

class B extends A<B.Y.Q> { //compiler error here
   static class Y extends X { } // X here should be inherited from A
}

class X {}


The problem is that B's supertype is somewhat circular: its 
type-argument (B.Y.Q) depends on a member type of B itself (and members 
of B are undetermined until supertypes are fully resolved). This means 
that when we see 'B.Y.Q' we don't see (yet) that X comes from A - so 
that Q is inherited in B.Y. As a result, X is resolved to the wrong class.

I guess you are suggesting that supertypes' type-arguments in 
extends/implements clauses cannot rely on (inherited?) members of the 
class declaration currently being checked.

Another interesting case arises when we exploit A's type-parameter in 
some useful way:

class A<T> {
   class X<T> {
     class Q {  }
   }
}

class B extends A<B.Y.Q> {
   class Y extends X<String> { } // B inherits X<B.Y.Q>...
}

class X<U> {}

In the above case, even if the compiler was smart enough to detect that 
Y's supertype is indeed A.X, there should still be an error, since 
X<String> != X<B.Y.Q>.

Maurizio

On 08/02/11 08:57, Neal Gafter wrote:
> Javac (any version) compiles the following code without error, but 
> when Main is run it prints "X.Q" instead of "A<T>.X.Q" as required by 
> the language specification.  I think this is really a shortcoming of 
> the specification for circular class declarations, but demonstrating 
> my point is easier if I just start by reporting it as a compiler bug.
>
> *class A<T> {
>   static class X {
>     static class Q {
>       public static void main() {
>         System.out.println("A<T>.X.Q");
>       }
>     }
>   }
> }
>
> class B extends A<B.Y.Q> {
>   static class Y extends X { } // X here is inherited from A
> }
>
> class X {
>   static class Q {
>     public static void main() {
>       System.out.println("X.Q");
>     }
>   }
> }
>
> class Main {
>   public static void main(String[] args) {
>     B.Y.Q.main();
>   }
> }
> *

-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/compiler-dev/attachments/20110208/cfb9a9f6/attachment.html 


More information about the compiler-dev mailing list