Bug 312076

Summary: [1.5][compiler] Eclipse compiler behaves differently from javac
Product: [Eclipse Project] JDT Reporter: Olivier Thomann <Olivier_Thomann>
Component: CoreAssignee: Srikanth Sankaran <srikanth_sankaran>
Status: VERIFIED FIXED QA Contact:
Severity: normal    
Priority: P3 CC: hashproduct+eclipse, mpurtill, satyam.kandula
Version: 3.6   
Target Milestone: 3.7 M1   
Hardware: PC   
OS: Windows XP   
Whiteboard:
Attachments:
Description Flags
Patch under consideration
none
Same patch after synchronizing with HEAD changes. none

Description Olivier Thomann CLA 2010-05-07 10:46:23 EDT
This test case compiles fine with Eclipse, but fails to compile with javac:

public class X<T>  { 

    public abstract static class Base<S extends Base<S>> {
        public Base(Class<S> sClass) {
            Class<S> theClass = sClass;
            System.out.println(theClass);
            System.out.println(sClass);
        }
    }

    public class Arr extends Base<Arr> {
        public Arr() { 
            super(Arr.class);
            System.out.println(Arr.class);
        }
    }

    public static void main(String[] args) {
        X<Integer> x = new X<Integer>();
        X<Integer>.Arr a = x.new Arr();
        System.out.println(a);
    }
}
JDK7b91 reports:
X.java:13: constructor Base in class Base<S> cannot be applied to given types
            super(Arr.class);
            ^
  required: Class<X<T>.Arr>
  found: Class<X.Arr>
  where T,S are type-variables:
    T extends Object declared in class X
    S extends Base<S> declared in class Base
1 error


JDK6_20 reports:
X.java:13: cannot find symbol
symbol  : constructor Base(java.lang.Class<X.Arr>)
location: class X.Base<X<T>.Arr>
            super(Arr.class);
            ^
1 error

javac 1.5.0_24 reports:

X.java:13: cannot find symbol
symbol  : constructor Base(java.lang.Class<X.Arr>)
location: class X.Base<X<T>.Arr>
            super(Arr.class);
            ^
1 error
Comment 1 Olivier Thomann CLA 2010-05-07 10:46:56 EDT
Srikanth, please investigate if this should be a valid test case.
Comment 2 Srikanth Sankaran CLA 2010-07-22 00:43:12 EDT
*** Bug 320463 has been marked as a duplicate of this bug. ***
Comment 3 Srikanth Sankaran CLA 2010-07-22 01:25:47 EDT
JLS3 15.8.2 forbids the type named in the class literal expression
from being a parameterized type.

Also, given a generic outer class Outer and a generic inner class
Inner and some two concrete types X and Y, the grammar in section
18.1 (the nonterminal Primary) disallows constructs of the form

    - Outer<X>.class
    - Outer<X>.Inner.class
    - Outer.Inner<X>.class
    - Outer<X>.Inner<Y>.class

while allowing Outer.class and Outer.Inner.class, both of which evaluate
to raw typed expressions which is as it should be since class literals
exist only for the underlying raw type and all parameterized versions
share the same literal.

While the grammar itself forbids most misleading & dubious constructs,
the one case where the grammatical proscription does not kick in is the
case seen in this bug and in bug 320463 : When the expression Inner.class
(itself grammatical) is used inside the Outer, the enclosing type is
taken by eclipse to be Outer<T>, instead of being just the raw type
Outer leading to erroneous behavior.

Patch will follow shortly.
Comment 4 Srikanth Sankaran CLA 2010-07-22 01:28:49 EDT
Created attachment 174944 [details]
Patch under consideration
Comment 5 Srikanth Sankaran CLA 2010-07-22 03:12:21 EDT
All tests pass, Satyam, please review. TIA.
Comment 6 Srikanth Sankaran CLA 2010-07-25 22:35:02 EDT
Created attachment 175193 [details]
Same patch after synchronizing with HEAD changes.
Comment 7 Satyam Kandula CLA 2010-07-26 01:34:04 EDT
(In reply to comment #5)
> All tests pass, Satyam, please review. TIA.
Patch looks good. +1
Comment 8 Srikanth Sankaran CLA 2010-07-26 02:33:01 EDT
Released in HEAD for 3.7 M1
Comment 9 Olivier Thomann CLA 2010-08-04 15:51:44 EDT
Verified for 3.7M1.