src/share/classes/com/sun/tools/javac/comp/Infer.java

changeset 396
dda7e13f09fb
parent 299
22872b24d38c
child 547
04cf82179fa7
equal deleted inserted replaced
395:5a72ba18c471 396:dda7e13f09fb
27 27
28 import com.sun.tools.javac.util.*; 28 import com.sun.tools.javac.util.*;
29 import com.sun.tools.javac.util.List; 29 import com.sun.tools.javac.util.List;
30 import com.sun.tools.javac.code.*; 30 import com.sun.tools.javac.code.*;
31 import com.sun.tools.javac.code.Type.*; 31 import com.sun.tools.javac.code.Type.*;
32 import com.sun.tools.javac.code.Type.ForAll.ConstraintKind;
32 import com.sun.tools.javac.code.Symbol.*; 33 import com.sun.tools.javac.code.Symbol.*;
33 import com.sun.tools.javac.util.JCDiagnostic; 34 import com.sun.tools.javac.util.JCDiagnostic;
34 35
35 import static com.sun.tools.javac.code.TypeTags.*; 36 import static com.sun.tools.javac.code.TypeTags.*;
36 37
48 /** A value for prototypes that admit any type, including polymorphic ones. */ 49 /** A value for prototypes that admit any type, including polymorphic ones. */
49 public static final Type anyPoly = new Type(NONE, null); 50 public static final Type anyPoly = new Type(NONE, null);
50 51
51 Symtab syms; 52 Symtab syms;
52 Types types; 53 Types types;
54 Check chk;
53 Resolve rs; 55 Resolve rs;
54 JCDiagnostic.Factory diags; 56 JCDiagnostic.Factory diags;
55 57
56 public static Infer instance(Context context) { 58 public static Infer instance(Context context) {
57 Infer instance = context.get(inferKey); 59 Infer instance = context.get(inferKey);
63 protected Infer(Context context) { 65 protected Infer(Context context) {
64 context.put(inferKey, this); 66 context.put(inferKey, this);
65 syms = Symtab.instance(context); 67 syms = Symtab.instance(context);
66 types = Types.instance(context); 68 types = Types.instance(context);
67 rs = Resolve.instance(context); 69 rs = Resolve.instance(context);
70 chk = Check.instance(context);
68 diags = JCDiagnostic.Factory.instance(context); 71 diags = JCDiagnostic.Factory.instance(context);
69 ambiguousNoInstanceException = 72 ambiguousNoInstanceException =
70 new NoInstanceException(true, diags); 73 new NoInstanceException(true, diags);
71 unambiguousNoInstanceException = 74 unambiguousNoInstanceException =
72 new NoInstanceException(false, diags); 75 new NoInstanceException(false, diags);
248 public Type instantiateExpr(ForAll that, 251 public Type instantiateExpr(ForAll that,
249 Type to, 252 Type to,
250 Warner warn) throws InferenceException { 253 Warner warn) throws InferenceException {
251 List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun); 254 List<Type> undetvars = Type.map(that.tvars, fromTypeVarFun);
252 for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) { 255 for (List<Type> l = undetvars; l.nonEmpty(); l = l.tail) {
253 UndetVar v = (UndetVar) l.head; 256 UndetVar uv = (UndetVar) l.head;
257 TypeVar tv = (TypeVar)uv.qtype;
254 ListBuffer<Type> hibounds = new ListBuffer<Type>(); 258 ListBuffer<Type> hibounds = new ListBuffer<Type>();
255 for (List<Type> l1 = types.getBounds((TypeVar) v.qtype); l1.nonEmpty(); l1 = l1.tail) { 259 for (Type t : that.getConstraints(tv, ConstraintKind.EXTENDS).prependList(types.getBounds(tv))) {
256 if (!l1.head.containsSome(that.tvars)) { 260 if (!t.containsSome(that.tvars) && t.tag != BOT) {
257 hibounds.append(l1.head); 261 hibounds.append(t);
258 } 262 }
259 } 263 }
260 v.hibounds = hibounds.toList(); 264 List<Type> inst = that.getConstraints(tv, ConstraintKind.EQUAL);
265 if (inst.nonEmpty() && inst.head.tag != BOT) {
266 uv.inst = inst.head;
267 }
268 uv.hibounds = hibounds.toList();
261 } 269 }
262 Type qtype1 = types.subst(that.qtype, that.tvars, undetvars); 270 Type qtype1 = types.subst(that.qtype, that.tvars, undetvars);
263 if (!types.isSubtype(qtype1, to)) { 271 if (!types.isSubtype(qtype1, to)) {
264 throw unambiguousNoInstanceException 272 throw unambiguousNoInstanceException
265 .setMessage("no.conforming.instance.exists", 273 .setMessage("no.conforming.instance.exists",
271 279
272 // check bounds 280 // check bounds
273 List<Type> targs = Type.map(undetvars, getInstFun); 281 List<Type> targs = Type.map(undetvars, getInstFun);
274 targs = types.subst(targs, that.tvars, targs); 282 targs = types.subst(targs, that.tvars, targs);
275 checkWithinBounds(that.tvars, targs, warn); 283 checkWithinBounds(that.tvars, targs, warn);
276 return that.inst(targs, types); 284 return chk.checkType(warn.pos(), that.inst(targs, types), to);
277 } 285 }
278 286
279 /** Instantiate method type `mt' by finding instantiations of 287 /** Instantiate method type `mt' by finding instantiations of
280 * `tvars' so that method can be applied to `argtypes'. 288 * `tvars' so that method can be applied to `argtypes'.
281 */ 289 */
347 minimizeInst((UndetVar) t, warn); 355 minimizeInst((UndetVar) t, warn);
348 356
349 /** Type variables instantiated to bottom */ 357 /** Type variables instantiated to bottom */
350 ListBuffer<Type> restvars = new ListBuffer<Type>(); 358 ListBuffer<Type> restvars = new ListBuffer<Type>();
351 359
360 /** Undet vars instantiated to bottom */
361 final ListBuffer<Type> restundet = new ListBuffer<Type>();
362
352 /** Instantiated types or TypeVars if under-constrained */ 363 /** Instantiated types or TypeVars if under-constrained */
353 ListBuffer<Type> insttypes = new ListBuffer<Type>(); 364 ListBuffer<Type> insttypes = new ListBuffer<Type>();
354 365
355 /** Instantiated types or UndetVars if under-constrained */ 366 /** Instantiated types or UndetVars if under-constrained */
356 ListBuffer<Type> undettypes = new ListBuffer<Type>(); 367 ListBuffer<Type> undettypes = new ListBuffer<Type>();
357 368
358 for (Type t : undetvars) { 369 for (Type t : undetvars) {
359 UndetVar uv = (UndetVar)t; 370 UndetVar uv = (UndetVar)t;
360 if (uv.inst.tag == BOT) { 371 if (uv.inst.tag == BOT) {
361 restvars.append(uv.qtype); 372 restvars.append(uv.qtype);
373 restundet.append(uv);
362 insttypes.append(uv.qtype); 374 insttypes.append(uv.qtype);
363 undettypes.append(uv); 375 undettypes.append(uv);
364 uv.inst = null; 376 uv.inst = null;
365 } else { 377 } else {
366 insttypes.append(uv.inst); 378 insttypes.append(uv.inst);
377 final List<Type> inferredTypes = insttypes.toList(); 389 final List<Type> inferredTypes = insttypes.toList();
378 final List<Type> all_tvars = tvars; //this is the wrong tvars 390 final List<Type> all_tvars = tvars; //this is the wrong tvars
379 final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass); 391 final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass);
380 mt2.restype = new ForAll(restvars.toList(), mt.restype) { 392 mt2.restype = new ForAll(restvars.toList(), mt.restype) {
381 @Override 393 @Override
394 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
395 for (Type t : restundet.toList()) {
396 UndetVar uv = (UndetVar)t;
397 if (uv.qtype == tv) {
398 switch (ck) {
399 case EXTENDS: return uv.hibounds;
400 case SUPER: return uv.lobounds;
401 case EQUAL: return uv.inst != null ? List.of(uv.inst) : List.<Type>nil();
402 }
403 }
404 }
405 return List.nil();
406 }
407
408 @Override
382 public Type inst(List<Type> inferred, Types types) throws NoInstanceException { 409 public Type inst(List<Type> inferred, Types types) throws NoInstanceException {
383 List<Type> formals = types.subst(mt2.argtypes, tvars, inferred); 410 List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
384 if (!rs.argumentsAcceptable(capturedArgs, formals, 411 if (!rs.argumentsAcceptable(capturedArgs, formals,
385 allowBoxing, useVarargs, warn)) { 412 allowBoxing, useVarargs, warn)) {
386 // inferred method is not applicable 413 // inferred method is not applicable
387 throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes); 414 throw invalidInstanceException.setMessage("inferred.do.not.conform.to.params", formals, argtypes);
388 } 415 }
389 // check that inferred bounds conform to their bounds 416 // check that inferred bounds conform to their bounds
390 checkWithinBounds(all_tvars, 417 checkWithinBounds(all_tvars,
391 types.subst(inferredTypes, tvars, inferred), warn); 418 types.subst(inferredTypes, tvars, inferred), warn);
392 return super.inst(inferred, types); 419 return super.inst(inferred, types);
393 }}; 420 }};
394 return mt2; 421 return mt2;
395 } 422 }
396 else if (!rs.argumentsAcceptable(capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) { 423 else if (!rs.argumentsAcceptable(capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn)) {
397 // inferred method is not applicable 424 // inferred method is not applicable

mercurial