JDK-5021635 : Incorrect default inferred type parameter when type params interdependent
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0
  • Priority: P5
  • Status: Closed
  • Resolution: Fixed
  • OS: solaris_8,windows_xp
  • CPU: generic,x86
  • Submitted: 2004-03-26
  • Updated: 2010-07-09
  • Resolved: 2011-03-08
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 7
7 b03Fixed
Description
I'm trying to understand the compiler behavior in this case:

  class M<T> {}
  class Main {
    static <T extends M<U>, U> void f1() {
    }
    void g(M m1) {
        f1();
    }
  }

when I compile this I get

H.java:6: incompatible types; inferred type argument(s) M<U>,java.lang.Object do not conform to bounds of type variable(s) T,U
found   : <T,U>void
required: void
        f1();
          ^

This doesn't make sense.  Why didn't it infer M<Object>,Object?  What is this 'U' that appears in the argument to M in the error message?  Is there a type substitution missing somewhere in the compiler?

Strangely, it still fails if I change the order of the formal type parameters, but with a different message altogether.

I think the compiler has to be able to handle this kind of code in order to be able to handle calls involving raw types (in the new overload resolution algorithm, raw types underconstrain the type parameters).

Comments
SUGGESTED FIX Webrev of changes: http://sa.sfbay/projects/langtools/bugid_summary.pl?bugid=5021635 See also attachment 5021635.tar.gz.
01-11-2006

SUGGESTED FIX Index: j2se/src/share/classes/com/sun/tools/javac/comp/Infer.java --- /tmp/geta3925 2006-10-31 23:02:19.000000000 -0800 +++ /tmp/getb3925 2006-10-31 23:02:19.000000000 -0800 @@ -244,6 +244,7 @@ // check bounds List<Type> targs = Type.map(undetvars, getInstFun); + targs = types.subst(targs, that.tvars, targs); checkWithinBounds(that.tvars, targs, warn); return getInstFun.apply(qtype1);
01-11-2006

EVALUATION Indeed. The type inferred for the type variables could still refer to the type variables.
01-11-2006

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: dragon mustang
07-09-2004

EVALUATION It looks like there is indeed a substitution missing, maybe because of the order that things get applied. I'll investigate. ###@###.### 2004-03-29
29-03-2004