diff -r 5a72ba18c471 -r dda7e13f09fb src/share/classes/com/sun/tools/javac/comp/Infer.java --- a/src/share/classes/com/sun/tools/javac/comp/Infer.java Mon Aug 31 19:43:06 2009 -0700 +++ b/src/share/classes/com/sun/tools/javac/comp/Infer.java Tue Sep 01 14:53:39 2009 +0100 @@ -29,6 +29,7 @@ import com.sun.tools.javac.util.List; import com.sun.tools.javac.code.*; import com.sun.tools.javac.code.Type.*; +import com.sun.tools.javac.code.Type.ForAll.ConstraintKind; import com.sun.tools.javac.code.Symbol.*; import com.sun.tools.javac.util.JCDiagnostic; @@ -50,6 +51,7 @@ Symtab syms; Types types; + Check chk; Resolve rs; JCDiagnostic.Factory diags; @@ -65,6 +67,7 @@ syms = Symtab.instance(context); types = Types.instance(context); rs = Resolve.instance(context); + chk = Check.instance(context); diags = JCDiagnostic.Factory.instance(context); ambiguousNoInstanceException = new NoInstanceException(true, diags); @@ -250,14 +253,19 @@ Warner warn) throws InferenceException { List undetvars = Type.map(that.tvars, fromTypeVarFun); for (List l = undetvars; l.nonEmpty(); l = l.tail) { - UndetVar v = (UndetVar) l.head; + UndetVar uv = (UndetVar) l.head; + TypeVar tv = (TypeVar)uv.qtype; ListBuffer hibounds = new ListBuffer(); - for (List l1 = types.getBounds((TypeVar) v.qtype); l1.nonEmpty(); l1 = l1.tail) { - if (!l1.head.containsSome(that.tvars)) { - hibounds.append(l1.head); + for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS).prependList(types.getBounds(tv))) { + if (!t.containsSome(that.tvars) && t.tag != BOT) { + hibounds.append(t); } } - v.hibounds = hibounds.toList(); + List inst = that.getConstraints(tv, ConstraintKind.EQUAL); + if (inst.nonEmpty() && inst.head.tag != BOT) { + uv.inst = inst.head; + } + uv.hibounds = hibounds.toList(); } Type qtype1 = types.subst(that.qtype, that.tvars, undetvars); if (!types.isSubtype(qtype1, to)) { @@ -273,7 +281,7 @@ List targs = Type.map(undetvars, getInstFun); targs = types.subst(targs, that.tvars, targs); checkWithinBounds(that.tvars, targs, warn); - return that.inst(targs, types); + return chk.checkType(warn.pos(), that.inst(targs, types), to); } /** Instantiate method type `mt' by finding instantiations of @@ -349,6 +357,9 @@ /** Type variables instantiated to bottom */ ListBuffer restvars = new ListBuffer(); + /** Undet vars instantiated to bottom */ + final ListBuffer restundet = new ListBuffer(); + /** Instantiated types or TypeVars if under-constrained */ ListBuffer insttypes = new ListBuffer(); @@ -359,6 +370,7 @@ UndetVar uv = (UndetVar)t; if (uv.inst.tag == BOT) { restvars.append(uv.qtype); + restundet.append(uv); insttypes.append(uv.qtype); undettypes.append(uv); uv.inst = null; @@ -379,17 +391,32 @@ final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass); mt2.restype = new ForAll(restvars.toList(), mt.restype) { @Override + public List getConstraints(TypeVar tv, ConstraintKind ck) { + for (Type t : restundet.toList()) { + UndetVar uv = (UndetVar)t; + if (uv.qtype == tv) { + switch (ck) { + case EXTENDS: return uv.hibounds; + case SUPER: return uv.lobounds; + case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.nil(); + } + } + } + return List.nil(); + } + + @Override public Type inst(List inferred, Types types) throws NoInstanceException { List formals = types.subst(mt2.argtypes, tvars, inferred); - if (!rs.argumentsAcceptable(capturedArgs, formals, + if (!rs.argumentsAcceptable(capturedArgs, formals, allowBoxing, useVarargs, warn)) { // inferred method is not applicable throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes); - } - // check that inferred bounds conform to their bounds - checkWithinBounds(all_tvars, + } + // check that inferred bounds conform to their bounds + checkWithinBounds(all_tvars, types.subst(inferredTypes, tvars, inferred), warn); - return super.inst(inferred, types); + return super.inst(inferred, types); }}; return mt2; }