Bug 106466 - [1.5][compiler] Type parameter followed by other types in bound - rejected by javac, accepted by Eclipse
Summary: [1.5][compiler] Type parameter followed by other types in bound - rejected by...
Status: VERIFIED FIXED
Alias: None
Product: JDT
Classification: Eclipse Project
Component: Core (show other bugs)
Version: 3.2   Edit
Hardware: PC Linux
: P3 normal (vote)
Target Milestone: 3.1.2   Edit
Assignee: Philipe Mulet CLA
QA Contact:
URL:
Whiteboard:
Keywords:
: 99983 104109 113070 125445 132348 (view as bug list)
Depends on:
Blocks:
 
Reported: 2005-08-09 09:35 EDT by Maxime Daniel CLA
Modified: 2006-03-21 08:57 EST (History)
5 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Maxime Daniel CLA 2005-08-09 09:35:46 EDT
The following code is accepted by Eclipse (3.2 M1 - I20050808-2000):
public class X {
	<T extends Runnable, U extends T & Runnable>  T foo() { return null; }
}
Whereas javac rejects it:
javac 1.5.0_04-ea
X.java:4: a type variable may not be followed by other bounds
        <T extends Runnable, U extends T & Runnable>  T foo() { return null; }
                                           ^
1 error
Comment 1 Philipe Mulet CLA 2005-08-12 05:16:04 EDT
The spec has no such restriction. Suspecting a bug in javac.
Comment 2 Philipe Mulet CLA 2005-10-18 06:43:55 EDT
Added GenericTypeTest#test852
Comment 3 Philipe Mulet CLA 2005-10-18 06:44:19 EDT
The JLS allows this scenario
Comment 4 Philipe Mulet CLA 2005-10-20 03:00:12 EDT
*** Bug 113070 has been marked as a duplicate of this bug. ***
Comment 5 Philipe Mulet CLA 2005-10-20 18:50:32 EDT
Reopening. The spec actually explicitly rejects it, see section 4.4.
[...]
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. 
[...]
Comment 6 Philipe Mulet CLA 2005-10-20 18:51:42 EDT
Added proper check when connecting type variables.
Fixed. Tuned test suites, and added GenericTypeTest#test857.
Comment 7 Philipe Mulet CLA 2005-10-20 18:54:51 EDT
The spec says bound looks like:
(TypeVariable) | ((Class|Interface) (& Interface)*)
Comment 8 Philipe Mulet CLA 2005-10-20 18:59:21 EDT
*** Bug 104109 has been marked as a duplicate of this bug. ***
Comment 9 Philipe Mulet CLA 2005-10-20 19:06:58 EDT
*** Bug 99983 has been marked as a duplicate of this bug. ***
Comment 10 Philipe Mulet CLA 2005-10-21 03:21:12 EDT
Backported to 3.1 maintenance stream.
Comment 11 Olivier Thomann CLA 2006-01-09 10:33:55 EST
Verified for 3.1.2 in M20060109-0800.
Comment 12 Olivier Thomann CLA 2006-01-10 10:29:54 EST
Verified for 3.2M4 in I20051215-1506
Comment 13 Philipe Mulet CLA 2006-01-27 11:42:55 EST
*** Bug 125445 has been marked as a duplicate of this bug. ***
Comment 14 Olivier Thomann CLA 2006-03-20 09:20:30 EST
*** Bug 132348 has been marked as a duplicate of this bug. ***
Comment 15 Pepe Ribas CLA 2006-03-21 05:16:40 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 16 Philipe Mulet CLA 2006-03-21 08:55:37 EST
*** Bug 132348 has been marked as a duplicate of this bug. ***
Comment 17 Philipe Mulet CLA 2006-03-21 08:57:02 EST
Re: comment 15, pls see bug  132348 for explanation.