254 List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun); |
254 List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun); |
255 for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) { |
255 for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) { |
256 UndetVar uv = (UndetVar) l.head; |
256 UndetVar uv = (UndetVar) l.head; |
257 TypeVar tv = (TypeVar)uv.qtype; |
257 TypeVar tv = (TypeVar)uv.qtype; |
258 ListBuffer<Type> hibounds = new ListBuffer<Type>(); |
258 ListBuffer<Type> hibounds = new ListBuffer<Type>(); |
259 for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS).prependList(types.getBounds(tv))) { |
259 for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS)) { |
260 if (!t.containsSome(that.tvars) && t.tag != BOT) { |
260 if (!t.containsSome(that.tvars) && t.tag != BOT) { |
261 hibounds.append(t); |
261 hibounds.append(t); |
262 } |
262 } |
263 } |
263 } |
264 List<Type> inst = that.getConstraints(tv, ConstraintKind.EQUAL); |
264 List<Type> inst = that.getConstraints(tv, ConstraintKind.EQUAL); |
278 // System.out.println(" = " + qtype1.map(getInstFun));//DEBUG |
278 // System.out.println(" = " + qtype1.map(getInstFun));//DEBUG |
279 |
279 |
280 // check bounds |
280 // check bounds |
281 List<Type> targs = Type.map(undetvars, getInstFun); |
281 List<Type> targs = Type.map(undetvars, getInstFun); |
282 targs = types.subst(targs, that.tvars, targs); |
282 targs = types.subst(targs, that.tvars, targs); |
283 checkWithinBounds(that.tvars, targs, warn); |
|
284 return chk.checkType(warn.pos(), that.inst(targs, types), to); |
283 return chk.checkType(warn.pos(), that.inst(targs, types), to); |
285 } |
284 } |
286 |
285 |
287 /** Instantiate method type `mt' by finding instantiations of |
286 /** Instantiate method type `mt' by finding instantiations of |
288 * `tvars' so that method can be applied to `argtypes'. |
287 * `tvars' so that method can be applied to `argtypes'. |
396 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) { |
395 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) { |
397 for (Type t : restundet.toList()) { |
396 for (Type t : restundet.toList()) { |
398 UndetVar uv = (UndetVar)t; |
397 UndetVar uv = (UndetVar)t; |
399 if (uv.qtype == tv) { |
398 if (uv.qtype == tv) { |
400 switch (ck) { |
399 switch (ck) { |
401 case EXTENDS: return uv.hibounds; |
400 case EXTENDS: return uv.hibounds.appendList(types.subst(types.getBounds(tv), all_tvars, inferredTypes)); |
402 case SUPER: return uv.lobounds; |
401 case SUPER: return uv.lobounds; |
403 case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.<Type>nil(); |
402 case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.<Type>nil(); |
404 } |
403 } |
405 } |
404 } |
406 } |
405 } |
456 } |
455 } |
457 } |
456 } |
458 |
457 |
459 /** check that type parameters are within their bounds. |
458 /** check that type parameters are within their bounds. |
460 */ |
459 */ |
461 private void checkWithinBounds(List<Type> tvars, |
460 void checkWithinBounds(List<Type> tvars, |
462 List<Type> arguments, |
461 List<Type> arguments, |
463 Warner warn) |
462 Warner warn) |
464 throws InvalidInstanceException { |
463 throws InvalidInstanceException { |
465 for (List<Type> tvs = tvars, args = arguments; |
464 for (List<Type> tvs = tvars, args = arguments; |
466 tvs.nonEmpty(); |
465 tvs.nonEmpty(); |