Bug 82243 - [compiler][1.5] unclear type bound resolution
Summary: [compiler][1.5] unclear type bound resolution
Status: RESOLVED INVALID
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC All
: P3 minor (vote)
Target Milestone: 3.1 M5   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-01-05 10:08 EST by Tom Hofmann CLA
Modified: 2005-01-13 18:16 EST (History)
1 user (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Tom Hofmann CLA 2005-01-05 10:08:28 EST
I20040104-1600-gtk

Consider the below snippet. The eclipse compiler claims that b.getOne() should
only return an Object, which is consistent with javac. Inlining the call to
B.getTwo produces an error...

It seems that the type bound resolution depends on the calling context: inside
B.getTwo the return type of getOne is resolved to be at least a Number. Outside
of B, however, the resolvation is not made.

Also, as soon as the type parameter is bound to a concrete type (vs. just
restricted), type resolvation succeeds again, as can be seen with type C.

It looks like, while stepping up the type hierarchy, the compiler does not
sidestep from the superinterface clause "extends A<T>" to the formal type
declaration "B<T extends Number>" to collect the type bound.


------------ snip ----------

package test1;

public interface A<E>{
	E getOne();
}


abstract class B<T extends Number> implements A<T> {
	Number getTwo() {
		return getOne(); // succeeds
	}
}

abstract class C extends B<Integer> {
}

class X {
	void foo(A a, B b, C c){
		Object o= a.getOne();
		Number n1= b.getOne(); // fails
		Number n2= b.getTwo(); // succeeds, but inlining fails
		Integer i = c.getOne(); // succeeds
	}
}

------

The error message from eclipse:

"Type mismatch: cannot convert from Object to Number"

Javac:
test1/A.java:20: incompatible types
found   : java.lang.Object
required: java.lang.Number
                Number n1= b.getOne();
                                   ^
1 error
Comment 1 Philipe Mulet CLA 2005-01-13 06:59:05 EST
What exactly do you mean by "Inlining the call to B.getTwo produces an error..." ?
Comment 2 Markus Keller CLA 2005-01-13 11:09:32 EST
[I jump in because Tom is away and we looked at this together.]

If you inline the call to "b.getTwo()" (either manually, or with Refactor >
Inline), the call becomes "b.getOne()" (already done in "n1= b.getOne();" in the
line above).

"... produces an error ... " means that the compiler marks an error here:
Number n1= b.getOne();
       ^^ Type mismatch: cannot convert from Object to Number

We can't see why the statement "Number n1= b.getOne();" is marked as an error.
The upper bound of the return type of B#getOne() is Number. Therefore, the
object returned from B#getOne() must always be a Number or a subtype of Number,
and the statement "Number n1= b.getOne();" should be valid.
Comment 3 Philipe Mulet CLA 2005-01-13 18:16:38 EST
The return type of #getTwo() is Number, which definitely matches expectation for n2.

For n1, the invocation of b.getOne() is performed on raw type B.
The superclass of raw type B is raw type A, which defines a method #getOne() of
type: erasure of <E> --> Object (since it carries no bound).

Thus the invocation of #getOne() returns an Object, which isn't compatible with
Number.