Bug 132348 - [1.5][compiler] Eclipse reports wrong generics error
Summary: [1.5][compiler] Eclipse reports wrong generics error
Status: RESOLVED DUPLICATE of bug 106466
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Windows XP
: P3 normal (vote)
Target Milestone: ---   Edit
Assignee: JDT-Core-Inbox CLA
QA Contact:
URL:
Whiteboard:
Keywords:
Depends on:
Blocks:
 
Reported: 2006-03-17 10:36 EST by Pepe Ribas CLA
Modified: 2006-03-21 08:55 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 Pepe Ribas CLA 2006-03-17 10:36:36 EST
On Eclipse 3.2m5a 

The problems dialog shows in 3.2m5a some errors in my code which didn't appear when working with Eclipse 3.1. The piece of code reporting an error is:

...

public abstract class TrackableCollection<DAO, RET_ELEM, A extends DAO & TrackableObjectInterface<RET_ELEM, CON>, CON extends DAOTransaction> implements TrackableCollectionInterface<DAO, Collection<RET_ELEM>, CON> {

...

}

Eclipse 3.2m5a reports this error:

Cannot specify any additional bound TrackableObjectInterface<RET_ELEM,CON> when first bound  is a type parameter

It doesn't let me declare this generic: 
<...,A extends DAO & TrackableObjectInterface<RET_ELEM,CON>,...>

That was working perfectly on eclipse 3.1 as it's a Java 5.0 legal declaration, and in my case is compiled, installed and working on production enviroment since some months ago. I've tried to change declaration order this way:

...

public abstract class TrackableCollection<DAO, RET_ELEM, A extends TrackableObjectInterface<RET_ELEM, CON> & DAO, CON extends DAOTransaction> implements TrackableCollectionInterface<DAO, Collection<RET_ELEM>, CON> {

...

}

but Eclipse reports this:

The type DAO is not an interface; it cannot be specified as a bounded parameter for declaration: 
<...,A extends TrackableObjectInterface<RET_ELEM,CON> & DAO,...>

Which really seems to be a wrong declaration.
Comment 1 Olivier Thomann CLA 2006-03-17 15:41:42 EST
Would it be possible to get a complete code snippet?
Something we can compile to reproduce the problem.
Thank you.
Comment 2 Pepe Ribas CLA 2006-03-20 04:02:13 EST
Here's a code snippet to test it:

An interface:

public interface AnyInterface {

	public void doSomething();
	
}

And a class declaration which produces the error on 3.2m5a and compiles well at 3.1:

public class UsingGenericsClass<A,B extends A & AnyInterface> {
	
	public UsingGenericsClass(){
		//initialize
	}
		
}
Comment 3 Olivier Thomann CLA 2006-03-20 09:20:30 EST
Closing as a dup of bug 106466.

*** This bug has been marked as a duplicate of 106466 ***
Comment 4 Olivier Thomann CLA 2006-03-20 09:30:58 EST
Added regression test org.eclipse.jdt.core.tests.compiler.regression.GenericTypeTest#test0957
Comment 5 Pepe Ribas CLA 2006-03-21 05:17:43 EST
(In reply to comment #14)
> *** Bug 132348 has been marked as a duplicate of this bug. ***

Bug 132348 is not same case as Bug 106466 and has been marked as duplicate.

public class X {
	<T extends Runnable, U extends T & Runnable>  T foo() { return null; }
}

This is the base case for 106466 which is a wrong declaration that duplicates the Runnable bound. But Bug 132348 reported that the next declaration is legal but eclipse 3.2 reports it as illegal.

public class X<T, U extends T & Runnable> {
  //whatever...
}

Just have a look at the spec for a while, then follow my conclusions at the end. I could be mistaken, but it seems to me a right interpretation of the spec definition.

Taken from java specs:

4.4 Type Variables
A type variable (§4.4) is an unqualified identifier. Type variables are introduced by generic class declarations (§8.1.2) generic interface declarations (§9.1.2) generic method declarations (§8.4.4) and by generic constructor declarations (§8.8.4).

TypeParameter:
        TypeVariable TypeBoundopt

TypeBound:
        extends ClassOrInterfaceType AdditionalBoundListopt

AdditionalBoundList:
        AdditionalBound AdditionalBoundList
        AdditionalBound

AdditionalBound:
        & InterfaceType

Type variables have an optional bound, T & I1 ... In. The bound consists of either a type variable, or a class or interface type T possibly followed by further interface types I1 , ..., In. If no bound is given for a type variable, Object is assumed. It is a compile-time error if any of the types I1 ... In is a class type or type variable. The erasures (§4.6) of all constituent types of a bound must be pairwise different, or a compile-time error occurs. The order of types in a bound is only significant in that the erasure of a type variable is determined by the first type in its bound, and that a class type or type variable may only appear in the first position.

-------------------------------------

As the spec says, a type variable have an optional bound, U has T as an optional bound, that agrees with the spec as it says "The bound consists of either a type variable, or a class or interface type T". My type parameter is U, and has an optional bound T. T is a type parameter, allowed by the spec as seen in the previous sentence.

 And a bound can be followed only by futher interface types: "possibly followed by further interface types I1 , ..., In.". So, in this case AnyInterface is an interface so it's a legal extra bound for U, that extends T and has to implement Runnable.

None of the restrictions especified after this statement forbids this declaration so, according to the spec this is a legal declaration and Eclipse is not handling it properly.

Comment 6 Philipe Mulet CLA 2006-03-21 08:55:37 EST
This is the same bug 106466.

Your reading of the spec is wrong, like mine was 6 months ago. Note that our behavior is the same as javac, and we did fix it in 3.1.2 as well.

Basically the sentence "The bound consists of
either a type variable, or a class or interface type T possibly followed by
further interface types I1 , ..., In." is very misleading.
You need to read it as:

The bound consists of
- either a type variable, 
- or a class or interface type T possibly followed by further interface types I1 , ..., In.

This is how it is implemented, and meant by the spec, though poorly worded I agree (but we do not own the spec).

*** This bug has been marked as a duplicate of 106466 ***