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

inference: Inferred types not substituted in bounds of unconstrained type variables

    Details

    • Type: Bug
    • Status: Closed
    • Priority: P4
    • Resolution: Fixed
    • Affects Version/s: 5.0
    • Fix Version/s: 7
    • Component/s: specification
    • Labels:
      None
    • Subcomponent:
    • Resolved In Build:
      rc
    • CPU:
      generic
    • OS:
      generic
    • Verification:
      Verified

      Description

      See https://bugs.eclipse.org/bugs/show_bug.cgi?id=121369

      Apparently, the specification requires a compiler must infer
      List<T>, not List<Object> for U in a call to Foo.foo() in this
      example:

      class Foo {
        static <T, U extends java.util.List<T>> void foo() {
          return;
        }
      }
      A further issue with uninferred type variables:

      Can you explain how javac is accepting the following code if not doing what I am suggesting below?
        public <E, S extends java.util.Collection<E>> S test1(S param){ return null; }
        public void test2() { test1(new Vector<String>()); }

      15.12.2.7 determines that: S = Vector<String>.
      Then 15.12.2.8 kicks in to infer unconstrained E.
        * S >> R' means: Object >> Vector<String>
        * Bi[T1 = B(T1) ... Tn = B(Tn)] >> Ti means: Collection<E> >> S

      Stepping back for an instant; what are we doing here? S already got inferred, so why would it try to infer it over again? Where is the fact that S = Vector<String> appearing then?

      I think the spec should rather say
        Bi[T1 = B(T1) ... Tn = B(Tn)] >> B(Ti) (note 'B(Ti)' instead of 'Ti')
      but then the algorithm described in 15.12.2.7 wouldn't yield anything as:
        Collection<E> >> Vector<String>
      doesn't yield any data (as no formal argument on right side).

      This is why I would suggest injecting:
        Vector<String> << Collection<E>
      If you don't do this, how can you infer E to be String instead of Object?
      (E=Object would invalidate the bound contract for S, as Vector<String> is not <: Collection<Object>.)

      If you change the line:
        test1(new Vector<String>());
      into:
        String s = (String) test1(new Vector<String>());
      you can see that javac did infer S to be Vector<String> as per error message tells.

      To be clear my spec suggestion is that instead of 15.12.2.8 only saying:
        * additional constraints Bi[T1 = B(T1) ... Tn = B(Tn)] >> Ti,
          where Bi is the declared bound of Ti,
      It would also hint from bounds of already inferred type variables, since
      these may contain references to underconstrained variables.
        * additional constraints B(Ti) << Bi[T1 = B(T1) ... Tn = B(Tn)],
          where Bi is the declared bound of Ti,

        Attachments

          Issue Links

            Activity

              People

              • Assignee:
                abuckley Alex Buckley
                Reporter:
                ahe Peter Ahe
              • Votes:
                0 Vote for this issue
                Watchers:
                0 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved:
                  Imported:
                  Indexed: