United StatesChange Country, Oracle Worldwide Web Sites Communities I am a... I want to...
Bug ID: JDK-6302954 Inference fails for type variable return constraint
JDK-6302954 : Inference fails for type variable return constraint

Details
Type:
Bug
Submit Date:
2005-07-28
Status:
Closed
Updated Date:
2011-03-08
Project Name:
JDK
Resolved Date:
2011-03-08
Component:
tools
OS:
generic,windows_xp,windows_2000
Sub-Component:
javac
CPU:
x86,generic
Priority:
P3
Resolution:
Fixed
Affected Versions:
5.0,6,6u20
Fixed Versions:

Related Reports
Backport:
Backport:
Backport:
Duplicate:
Duplicate:
Relates:

Sub Tasks

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
EVALUATION

A bug.  The compiler should infer U.
                                     
2006-10-17
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 ||
                                     
2006-10-19
SUGGESTED FIX

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



Hardware and Software, Engineered to Work Together