Bug 98228 - [1.5][compiler] regression - incorrect handling of generics
Summary: [1.5][compiler] regression - incorrect handling of generics
Status: CLOSED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.1   Edit
Hardware: PC Linux
: P3 blocker (vote)
Target Milestone: 3.1 RC2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-03 00:14 EDT by Eric Goff CLA
Modified: 2005-06-10 11:21 EDT (History)
0 users

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Eric Goff CLA 2005-06-03 00:14:48 EDT
This set of files compiled fine in M6 and M7 and the jdk 1.5.0 from Sun,
but does not compile in RC1.

Controller.java
package foo;

public interface Controller<T extends Model,U extends View<T,?>> {
    public U getView() ;
    public T getTarget() ;
}


Model.java
package foo;
public interface Model  {
}

MouseEventReceiver.java
package foo;

import java.awt.Component ;
public interface MouseEventReceiver {
     public interface Model extends foo.Model {
    }
    public interface View<T extends Model,U extends Component> extends
foo.View<T,U> {
    }
    public interface Ctrl<T extends Model,U extends View<T,?>> extends
Controller<T,U> {
    }
}

View.java
package foo;
public interface View<T extends Model, U> {
	public T getModel();
	public U getContent();
}

test.java
package foo;

import java.awt.Component;

public class test {
	public static void main(String [] args) {
		MouseEventReceiver.Ctrl<?,?> ctrl = null ;
		foobar(ctrl.getView().getContent()) ;
	}
	public static void foobar(Component c) {
		
	}
}

I get:
The method foobar(Component) in the type test is not applicable for the 
 arguments (?)

It is not correctly determining that ? is bound to Component.
Comment 1 Philipe Mulet CLA 2005-06-08 06:22:48 EDT
Reduced testcase:

package foo;

public class Test {
	
	public static void main(String[] args) {
		
		Controller<?> ctrl = null;
		foobar(ctrl.getView().getContent()); 
	} 
	
	static void foobar(Test t) {
	}
}
interface Controller<T extends View<?>> {
    public T getView() ;
}
interface View<U extends Test> {
	public U getContent();
}
Comment 2 Philipe Mulet CLA 2005-06-08 10:57:52 EDT
Reason for change is tightened capture conversion. 

When 'ctrl' gets capture conversion applied, what is the fresh type variable
(say S) upper bound ?
Is it:
(1) strictly View<?> 
(2) or rather View<capture-of ?>  ?  (which I am guessing)

If (1) is true, then the program should be rejected I think, as the type of
ctrl.getView() would yield 'capture-of ?', then next call for #getContent() will
issue '?' (from View<?>). Then this type hasn't been captured, and doesn't know
enough to be a proper 'Test' as mandated by #foobar(...)  invocation.

If (2) is true, then it seems to indicate that capture conversion would have to
recurse when computing the bounds of the fresh type variables.
However, then I am wondering about infinite regressions when capturing some type
Y<?> where class Y<T extends Y<?>> {}; if capturing is allocating
a fresh variable each time it encounters Y<?>; could be closed by reusing same
capture; but then it would change semantics and handle
class Y<T extends Y<?>> {};  as if it had been defined: class Y<T extends Y<T>> {};
Comment 3 Philipe Mulet CLA 2005-06-08 11:00:09 EDT
I can make this scenario work, by adding back type variable bounds in wildcard
direct supertypes. But as demonstrated by following program, it reveals non
substituted variables:

public class X<E> {
	
	public static void main(String[] args) {
		
		Controller<?> ctrl = null;
		foobar(ctrl.getView().getContent()); 
	} 
	
	static void foobar(X<String> x) {
	}
}
interface Controller<T extends View<?>> {
    public T getView() ;
}
interface View<U extends X<U>> {
	public U getContent();
}

javac:
X.java:6: foobar(X<java.lang.String>) in X<E> cannot be applied to (X<U>)
                foobar(ctrl.getView().getContent());
                ^
1 error

(U shouldn't appear outside its context !?)
Comment 4 Philipe Mulet CLA 2005-06-08 11:33:03 EDT
Tuned wildcard supertypes to meet old behavior and javac.
May reconsider this behavior in the light of spec revision.
Comment 5 Philipe Mulet CLA 2005-06-08 11:55:28 EDT
Added GenericTypeTest#test726-728.
Fixed
Comment 6 Olivier Thomann CLA 2005-06-09 09:32:07 EDT
Verified in N20050609-0010 + JDT/Core HEAD.
Comment 7 David Audel CLA 2005-06-10 11:21:38 EDT
Verified for 3.1 RC2 using build I20050610-0010