JDK-6302954 : Inference fails for type variable return constraint
  • Type: Bug
  • Component: tools
  • Sub-Component: javac
  • Affected Version: 5.0,6,6u20
  • Priority: P3
  • Status: Closed
  • Resolution: Fixed
  • OS: generic,windows_2000,windows_xp
  • CPU: generic,x86
  • Submitted: 2005-07-28
  • Updated: 2011-03-08
  • 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 6 JDK 7
6u22-revFixed 7 b03Fixed
Related Reports
Duplicate :  
Duplicate :  
Relates :  
Description
https://bugs.eclipse.org/bugs/show_bug.cgi?id=98379

This program doesn't compile:

public class X {
    <T extends X> T f1() throws Exception{
    	return null;
    }
    <U extends X> U f2() throws Exception {
        return f1();
    }
}

X.java:6: type parameters of <T>T cannot be determined; no unique maximal instance exists for type variable T with upper bounds U,X
        return f1();
                 ^
1 error

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

SUGGESTED FIX Index: j2se/src/share/classes/com/sun/tools/javac/comp/Infer.java --- /tmp/geta16053 2006-10-18 23:36:54.000000000 -0700 +++ /tmp/getb16053 2006-10-18 23:36:54.000000000 -0700 @@ -140,7 +140,7 @@ bs.nonEmpty() && that.inst == null; bs = bs.tail) { // System.out.println("hibounds = " + that.hibounds);//DEBUG - if (isSubClass(bs.head, that.hibounds, types)) + if (isSubClass(bs.head, that.hibounds)) that.inst = types.fromUnknownFun.apply(bs.head); } if (that.inst == null || !types.isSubtypeUnchecked(that.inst, that.hibounds, warn)) @@ -151,19 +151,25 @@ } } //where - private boolean isSubClass(Type that, List<Type> those, Types types) { - Type that1 = that.baseType(); - boolean isSub = true; - if (that1.tag == TYPEVAR) { - for (List<Type> l = types.getBounds(((TypeVar)that1)); isSub && l.nonEmpty(); l = l.tail) { - isSub = isSubClass(l.head, those, types); + private boolean isSubClass(Type t, final List<Type> ts) { + t = t.baseType(); + if (t.tag == TYPEVAR) { + List<Type> bounds = types.getBounds((TypeVar)t); + for (Type s : ts) { + if (!types.isSameType(t, s.baseType())) { + for (Type bound : bounds) { + if (!isSubClass(bound, List.of(s.baseType()))) + return false; + } + } } } else { - for (List<Type> l = those; isSub && l.nonEmpty(); l = l.tail) { - isSub = that1.tsym.isSubClass(l.head.baseType().tsym, types); + for (Type s : ts) { + if (!t.tsym.isSubClass(s.baseType().tsym, types)) + return false; } } - return isSub; + return true; } /** Instaniate undetermined type variable to the lub of all its lower bounds. @@ -192,7 +198,7 @@ else for (List<Type> bs = that.hibounds; bs.nonEmpty() && hb == null; bs = bs.tail) { - if (isSubClass(bs.head, that.hibounds, types)) + if (isSubClass(bs.head, that.hibounds)) hb = types.fromUnknownFun.apply(bs.head); } if (hb == null ||
19-10-2006

EVALUATION A bug. The compiler should infer U.
17-10-2006