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

5.1.10: Define glb for non-class types

    Details

      Description

      JLS 5.1.10 ensures that intersection types produced by glb have only one "best" class:

      "glb(V1, ..., Vm) is defined as 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."

      The well-formedness rule is important: if two unrelated classes were part of an intersection, we would not know how to determine the intersection's members (this is an unsupported form of multiple inheritance).

      However, this rule doesn't consider other types:
      - Array types should be treated just like class types
      - Intersection types should be decomposed when creating the list V1, ..., Vm
      - Treatment of type variables is unclear...

      A related problem with glb is that it does not claim to eliminate redundant elements, and it is unclear whether glb of a single type is that type or the (singleton) "intersection of" that type. Different behavior of compilers might result in different membership (depending also on how membership of an intersection is defined).

      Some points about type variables:

      - An unbounded or Object-bounded type variable might be treated like an interface, since it only extends Object. Or perhaps not, since i) there are subtle differences between the members of an empty class that extends Object and an empty interface, and ii) the instantiation of the type variable might be a class (does this matter?)

      - A class-bounded type variable must be treated like a class.

      - An interface-bounded type variable could probably be treated like an interface; but see above about unbounded type variables -- (i) does not apply, but (ii) does.

      - A type variable with some other upper bound needs to have this test somehow performed on its upper bound, recursively.

      - A capture variable with a lower bound presents an interesting problem: two lower-bounded capture variables might have the same lower bound. In that case, a naive glb would consider this an error, but a smarter glb would use the lower bound as the glb of the two types! (Just like the lub of two unrelated type variables is the lub of their upper bounds.) (JDK-8033718 implements this glb logic.)

      Example:
      <T> void doGLB(List<? super T> l1, List<? super T> l2) {}
      void test(List<? super String> l) { doGLB(l, l); }

      - Note in all of this that 5.1.10 may ask to glb capture variables that _don't have bounds yet_. This makes things tricky when we start trying to look at type variable bounds.

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                dlsmith Dan Smith
                Reporter:
                dlsmith Dan Smith
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated: