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

4.10.4: Fix dependency on unspecified "infinite types" in lub



      A useful feature of lub (JLS 4.10.4) is its ability to handle multiple parameterizations of the same generic class by introducing a wildcard that encompasses both parameterizations.

          lub(List<S>, List<T>) = List<? extends lub(S,T)>

      Unfortunately, in general this recursion does not terminate. For example:

          interface A extends Comparable<A> {}
          interface B extends Comparable<B> {}

          lub(A,B) = Comparable<? extends Comparable<? extends Comparable<...>>>

      This problem is acknowledged by JLS, with the unhelpful note that "a compiler for the Java programming language must recognize such situations and represent them appropriately using cyclic data structures". This note fails to recognize that simply _encoding_ these types is not sufficient for accurately _reasoning_ about them.

      One solution could be to explore the theoretical implications of these types and fully specify them. They seem similar to equi-recursive types, although JLS claims they are different. To scratch the surface, we would need a definition of subtyping that is able to handle a test like

              Iterable<? extends List<? extends Iterable<...>>> <: Iterable<? extends Iterable<...>>

      However, acknowledging that it is rare for the precision of this infinite wildcard bound to be of practical use, we could simply define the _lub_ to produce a slightly weaker bound after one or two loops:

              lub(A,B) = Comparable<? extends Comparable<?>>

      This is the strategy javac has been silently using since Java 5 (with an outstanding bug to come back and "fix" it: see JDK-4993221).


          Issue Links



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


                • Created: