-
Bug
-
Resolution: Unresolved
-
P4
-
7
-
Fix Understood
4.4 (Type Variables) constrains the structure of a variable bound (a class or type variable can only appear in the first position) and provides some limitations on the possible combinations of types (the variable cannot subtype two parameterizations of an interface; no two erasures can be the same (redudant?)). But there exist stronger restrictions on a class or interface type whose "bound" (its extends/implements clauses) is the same as a particular intersection. For example, the return types of two override-equivalent member methods of a class must be directly related.
It is unclear whether this inconsistency is intentional. Other parts of the spec seem to assume that the guarantees made for class and interface members apply to variable bounds: 4.9 (Intersection Types) maps intersection types to (supposedly well-formed?) class declarations in order to determine members; 15.12.2.5 (Choosing the Most Specific Method) selects a method that has "the most specific return type". There are probably other cases.
If any additional restrictions are added, they should go in 4.4, not 4.9. It's nonsensical to mandate a compile-time error based on the format of an intersection type when programs never contain intersection types. If there are well-formedness conditions on intersections, it is the specification's job to guarantee, possibly via *other* compile-time checks, that these conditions are met when it produces intersections. (The existing "a compile-time error occurs" in 4.9 does not belong there.)
Here's a test case documenting current compiler behavior:
public class Intersection {
interface I1 { I1 m(); }
interface I2 { I2 m(); }
interface I3 extends I1, I2 {} // error in javac6, javac7, ecj36
<T extends I1 & I2> T mi() { return null; } // error in javac6*, javac7
interface J1 { void m(Iterable<String> arg); }
interface J2 { void m(Iterable<Integer> arg); }
interface J3 extends J1, J2 {} // error in javac7
<T extends J1 & J2> T mj() { return null; } // error in javac7
// * Error in javac6 only if the interface declarations are moved outside of this class
}
It is unclear whether this inconsistency is intentional. Other parts of the spec seem to assume that the guarantees made for class and interface members apply to variable bounds: 4.9 (Intersection Types) maps intersection types to (supposedly well-formed?) class declarations in order to determine members; 15.12.2.5 (Choosing the Most Specific Method) selects a method that has "the most specific return type". There are probably other cases.
If any additional restrictions are added, they should go in 4.4, not 4.9. It's nonsensical to mandate a compile-time error based on the format of an intersection type when programs never contain intersection types. If there are well-formedness conditions on intersections, it is the specification's job to guarantee, possibly via *other* compile-time checks, that these conditions are met when it produces intersections. (The existing "a compile-time error occurs" in 4.9 does not belong there.)
Here's a test case documenting current compiler behavior:
public class Intersection {
interface I1 { I1 m(); }
interface I2 { I2 m(); }
interface I3 extends I1, I2 {} // error in javac6, javac7, ecj36
<T extends I1 & I2> T mi() { return null; } // error in javac6*, javac7
interface J1 { void m(Iterable<String> arg); }
interface J2 { void m(Iterable<Integer> arg); }
interface J3 extends J1, J2 {} // error in javac7
<T extends J1 & J2> T mj() { return null; } // error in javac7
// * Error in javac6 only if the interface declarations are moved outside of this class
}
- relates to
-
JDK-7034913 15.12.2.5: Resolution of call to abstract methods is nondeterministic
- Closed
-
JDK-7120669 4.9: Clarify well-formedness for intersection types & bounded type variables
- Open
-
JDK-7030781 problem with multiple interface inheritance using bounded type parameters
- Closed