JDK-6801130 : JLS3 5.1.10 (capture-conversion) should be clarified
  • Type: Bug
  • Component: specification
  • Sub-Component: language
  • Affected Version: 7
  • Priority: P4
  • Status: Closed
  • Resolution: Duplicate
  • OS: generic
  • CPU: unknown
  • Submitted: 2009-02-04
  • Updated: 2014-05-21
  • Resolved: 2014-04-10
Related Reports
Duplicate :  
Relates :  
Description
Consider the following class hierarchy:

class A{ public void a(){}}
class B extends A{ public void b(){}}
interface I{ void i();}
class E extends B implements I{ public void i(){};}

class C<W extends B & I, T extends W>{
    public T fieldT;   }


Question: What is the capture of C<? extends I, ? extends E> ?

It's C<#1. #2>, where both #1 and #2 are captured-type variables. According to JLS3 5.1.10, we have that:

upper-bound(#1) = glb(I, B&I) = B&I
upper-bound(#2) = glb(E, #1) = E & #1 (in eval of 6594284 I stated that this glb was incorrect)

Are #1, #2 conform to declared bounds?

a) #1 <: B&I, ok (since #1 <: upper-bound(#1) = B&I <: B&I)
b) #2 <: I, ok (since #2 <: upper-bound(#2) = E&I <: I)

At first it seems like everything is correct - however reading 5.1.10 it's not crystal clear to understand what the desired behavior should look like:

"If Ti is a wildcard type argument of the form ? extends Bi, then Si is a fresh type variable whose upper bound is glb(Bi, Ui[A1 := S1, ..., An := Sn]) and whose lower bound is the null type, where glb(V1,... ,Vm) is V1 & ... & Vm. It is a compile-time error if for any two classes (not interfaces) Vi and Vj,Vi is not a subclass of Vj or vice versa"

I think the problem is all in the sentence *if for any two classes (not interfaces)* ; here we have to compute a glb between a classtype (namely E) and a captured-type-variable (namely #1) - which rules should we apply? This is not clear as #1 is neither a class nor an interface.

Note: enforcing that either #1 <: E or E <: #1 will result in flagging the above capture-conversion as erroneous as neither of the two subtyping assumptions hold:

Is either #CAP1  <: E or E <: #CAP1 ?

a) #1  <: E iff
ub(#1) = B&I <: E --> false

b) E <: #1 false

Note that we don't have (as you say) that #1 = B&I, we have that #1's upper bound is B&I which is different.
The above subtyping test would hold only if you assume the following rule:

S <: T iff S <: ub(T)

which is unsafe (e.g. Integer <: T, where T is a type-variable whose bound is Object).

I don't see how the subtyping between E and #1 could be justified in term of the JLS.

Comments
EVALUATION We may have to ban bounds that imply a subtype relationship between involves different kinds of types. It is not obvious that the resulting subtype tests between ground types (e.g. class types) and the types representing upper/lower bounds of synthesized type variables arising from capture conversion.
18-08-2010