Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-6801130

JLS3 5.1.10 (capture-conversion) should be clarified

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Duplicate
    • Affects Version/s: 7
    • Fix Version/s: None
    • Component/s: specification
    • Labels:
      None
    • Subcomponent:
    • CPU:
      unknown
    • OS:
      generic

      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.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                abuckley Alex Buckley
                Reporter:
                mcimadamore Maurizio Cimadamore
              • Votes:
                0 Vote for this issue
                Watchers:
                1 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: