Java Solaris Communities Sun Store Join SDN My Profile Why Join?
 
Bug Database
Bug Detail
Quick Lists
Top 25 Bugs
Top 25 RFE's
Recently Closed Bugs
Printable Page Printable Page


Bug Database
Bug ID: 6611449
Votes 0
Synopsis Internal Error thrown during generic method/constructor invocation
Category java:compiler
Reported Against
Release Fixed 7(b25)
State 10-Fix Delivered, bug
Priority: 4-Low
Related Bugs 6478540
Submit Date 01-OCT-2007
Description
Description:
   
The following code fails during compilation with  "internal error".
<code>

public class TypeInferenceTest<S>{

    public  TypeInferenceTest() {

    this(1,1); //Throws internal error; cannot instanatiate ...
    //<Number>this(1,1); //Cannot find  customer 
    //  <Integer>this(1); //Cannot find  customer 
    // this(1); //Cannot find  customer 
    }
    public <T extends S> TypeInferenceTest(T a, T b) {
        //.....
    }
    public <T extends S> TypeInferenceTest(T a) {
       //....
    }

    <T extends S> void met1(T a,T b){
       met2 (1,1);//Throws internal error; cannot instanatiate ...
       new TypeInferenceTest<Number> ().met2 (1,1); //Compiles fine -- Type Inference works
//       met2(1); // Cannot find  customer 
    }
    <T extends S> void met2(T a,T b){
        //..
    }

    <T extends S> void met2(T a){
       //...
    }

}



</code>

Compilation result is :
<output>

TypeInferenceTest.java:5: internal error; cannot instantiate <T>TypeInferenceTest(T,T) at TypeInferenceTest<S> to ()
    this(1,1); //Throws internal error; cannot instanatiate ...
        ^
TypeInferenceTest.java:18: internal error; cannot instantiate <T>met2(T,T) at TypeInferenceTest<S> to (int,int)
       Integer i = met2 (1,1);//Throws internal error; cannot instanatiate ...
                        ^
2 errors


</output>

Tried in :
<version>
java version "1.7.0-internal"
Java(TM) SE Runtime Environment (build 1.7.0-internal-jprtadm_26_Sep_2007_03_43-b00)
Java HotSpot(TM) Server VM (build 11.0-b06, mixed mode)

uname -a
SunOS bonsai 5.11 snv_49 i86pc i386 i86pc
Posted Date : 2007-10-01 10:12:18.0
Work Around
N/A
Evaluation
The use of "throws internal error" is mildly confusing; it "reports" an internal error. Either way, internal errors are not good.



gzilla[6611449]% /w/local/jdk/1.7.0/bin/javac TypeInferenceTest.java
TypeInferenceTest.java:6: internal error; cannot instantiate <T>TypeInferenceTest(T,T) at TypeInferenceTest<S> to ()
    this(1,1); //Throws internal error; cannot instanatiate ...
        ^
TypeInferenceTest.java:19: internal error; cannot instantiate <T>met2(T,T) at TypeInferenceTest<S> to (int,int)
       met2 (1,1);//Throws internal error; cannot instanatiate ...
            ^
2 errors
gzilla[6611449]%
Posted Date : 2008-01-30 19:00:19.0

The internal error is due to the fact that javac selects a method/constructor that is not applicable because of the declared bound of the type variable T extending S. Unfortunatelly, this incompatibility is detected only at a later point during the resolution process so that javac is forced to trigger an internal error (because it realizes that something wrong happened during resolution).

In particular, the interplay between boxing and type inference makes the resolution process to select an inapplicable method. Given a method declaration M1 and a list of actual argument types A1, A2 ... An, the resolution process is internally composed into two main steps:

1) An instantiation of M1 is found so that the formal parameters of M1 match against A1, A2 ... An.
2) If 1) fails repeat step 1) by substituting each primitive type (if any) in A1, A2 ... An with their corresponding boxed types.

As an example, suppose that M1 = <T extends String> void m(T t1,T t2) and that A1,A2 = {int,int}. Step 1) should fail, since no instance of T exists so that T==int. On the other hand, step 2 fails too, since T is inferred to be Integer which is not compliant wrt the declared bound of T (Integer <: String does NOT hold).

The actual behavior of javac differs from the one described above since javac makes step 1 succeed by basically inferring T itself for the type variable T. Such an inferred type is good for javac as it satisfies the declared bound of T (T <: T!), but then, at a later point, when javac checks that the selected method is effectively applicable (this is done by basically repeating step 2 - so enabling autoboxing), it suddenly realizes that the selected method is not compliant wrt the declared bound S of T. 

The solution to this problem is to fix javac so that step 1) fails as expected - this is equivalent to say that any type inference constraint referring a primitive type should be rewritten so that the primitive type is substituted by its boxing type, as described in JLS 15.12.2.7

"
...
Otherwise, if the constraint has the form A <<F
    * If A is a primitive type, then A is converted to a reference type U via boxing conversion and this algorithm is applied recursively to the constraint U << F.
...
"
Posted Date : 2008-02-14 17:15:00.0
Comments
  
  Include a link with my name & email   


PLEASE NOTE: JDK6 is formerly known as Project Mustang