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

changeset 895
9286a5d1fae3
parent 845
5a43b245aed1
child 1006
a2d422d480cb
equal deleted inserted replaced
894:23b64ad3eec8 895:9286a5d1fae3
463 if (!restvars.isEmpty()) { 463 if (!restvars.isEmpty()) {
464 // if there are uninstantiated variables, 464 // if there are uninstantiated variables,
465 // quantify result type with them 465 // quantify result type with them
466 final List<Type> inferredTypes = insttypes.toList(); 466 final List<Type> inferredTypes = insttypes.toList();
467 final List<Type> all_tvars = tvars; //this is the wrong tvars 467 final List<Type> all_tvars = tvars; //this is the wrong tvars
468 final MethodType mt2 = new MethodType(mt.argtypes, null, mt.thrown, syms.methodClass); 468 return new UninferredMethodType(mt, restvars.toList()) {
469 mt2.restype = new ForAll(restvars.toList(), mt.restype) {
470 @Override 469 @Override
471 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) { 470 List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
472 for (Type t : restundet.toList()) { 471 for (Type t : restundet.toList()) {
473 UndetVar uv = (UndetVar)t; 472 UndetVar uv = (UndetVar)t;
474 if (uv.qtype == tv) { 473 if (uv.qtype == tv) {
475 switch (ck) { 474 switch (ck) {
476 case EXTENDS: return uv.hibounds.appendList(types.subst(types.getBounds(tv), all_tvars, inferredTypes)); 475 case EXTENDS: return uv.hibounds.appendList(types.subst(types.getBounds(tv), all_tvars, inferredTypes));
479 } 478 }
480 } 479 }
481 } 480 }
482 return List.nil(); 481 return List.nil();
483 } 482 }
484
485 @Override 483 @Override
486 public Type inst(List<Type> inferred, Types types) throws NoInstanceException { 484 void check(List<Type> inferred, Types types) throws NoInstanceException {
487 List<Type> formals = types.subst(mt2.argtypes, tvars, inferred);
488 // check that actuals conform to inferred formals 485 // check that actuals conform to inferred formals
489 checkArgumentsAcceptable(env, capturedArgs, formals, allowBoxing, useVarargs, warn); 486 checkArgumentsAcceptable(env, capturedArgs, getParameterTypes(), allowBoxing, useVarargs, warn);
490 // check that inferred bounds conform to their bounds 487 // check that inferred bounds conform to their bounds
491 checkWithinBounds(all_tvars, 488 checkWithinBounds(all_tvars,
492 types.subst(inferredTypes, tvars, inferred), warn); 489 types.subst(inferredTypes, tvars, inferred), warn);
493 if (useVarargs) { 490 if (useVarargs) {
494 chk.checkVararg(env.tree.pos(), formals, msym); 491 chk.checkVararg(env.tree.pos(), getParameterTypes(), msym);
495 } 492 }
496 return super.inst(inferred, types);
497 }}; 493 }};
498 return mt2;
499 } 494 }
500 else { 495 else {
501 // check that actuals conform to inferred formals 496 // check that actuals conform to inferred formals
502 checkArgumentsAcceptable(env, capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn); 497 checkArgumentsAcceptable(env, capturedArgs, mt.getParameterTypes(), allowBoxing, useVarargs, warn);
503 // return instantiated version of method type 498 // return instantiated version of method type
504 return mt; 499 return mt;
505 } 500 }
506 } 501 }
507 //where 502 //where
508 503
504 /**
505 * A delegated type representing a partially uninferred method type.
506 * The return type of a partially uninferred method type is a ForAll
507 * type - when the return type is instantiated (see Infer.instantiateExpr)
508 * the underlying method type is also updated.
509 */
510 static abstract class UninferredMethodType extends DelegatedType {
511
512 final List<Type> tvars;
513
514 public UninferredMethodType(MethodType mtype, List<Type> tvars) {
515 super(METHOD, new MethodType(mtype.argtypes, null, mtype.thrown, mtype.tsym));
516 this.tvars = tvars;
517 asMethodType().restype = new UninferredReturnType(tvars, mtype.restype);
518 }
519
520 @Override
521 public MethodType asMethodType() {
522 return qtype.asMethodType();
523 }
524
525 @Override
526 public Type map(Mapping f) {
527 return qtype.map(f);
528 }
529
530 void instantiateReturnType(Type restype, List<Type> inferred, Types types) throws NoInstanceException {
531 //update method type with newly inferred type-arguments
532 qtype = new MethodType(types.subst(getParameterTypes(), tvars, inferred),
533 restype,
534 types.subst(UninferredMethodType.this.getThrownTypes(), tvars, inferred),
535 UninferredMethodType.this.qtype.tsym);
536 check(inferred, types);
537 }
538
539 abstract void check(List<Type> inferred, Types types) throws NoInstanceException;
540
541 abstract List<Type> getConstraints(TypeVar tv, ConstraintKind ck);
542
543 class UninferredReturnType extends ForAll {
544 public UninferredReturnType(List<Type> tvars, Type restype) {
545 super(tvars, restype);
546 }
547 @Override
548 public Type inst(List<Type> actuals, Types types) {
549 Type newRestype = super.inst(actuals, types);
550 instantiateReturnType(newRestype, actuals, types);
551 return newRestype;
552 }
553 @Override
554 public List<Type> getConstraints(TypeVar tv, ConstraintKind ck) {
555 return UninferredMethodType.this.getConstraints(tv, ck);
556 }
557 }
558 }
559
509 private void checkArgumentsAcceptable(Env<AttrContext> env, List<Type> actuals, List<Type> formals, 560 private void checkArgumentsAcceptable(Env<AttrContext> env, List<Type> actuals, List<Type> formals,
510 boolean allowBoxing, boolean useVarargs, Warner warn) { 561 boolean allowBoxing, boolean useVarargs, Warner warn) {
511 try { 562 try {
512 rs.checkRawArgumentsAcceptable(env, actuals, formals, 563 rs.checkRawArgumentsAcceptable(env, actuals, formals,
513 allowBoxing, useVarargs, warn); 564 allowBoxing, useVarargs, warn);
516 // inferred method is not applicable 567 // inferred method is not applicable
517 throw invalidInstanceException.setMessage(ex.getDiagnostic()); 568 throw invalidInstanceException.setMessage(ex.getDiagnostic());
518 } 569 }
519 } 570 }
520 571
521 /** Try to instantiate argument type `that' to given type `to'. 572 /** Try to instantiate argument type `that' to given type `to'.
522 * If this fails, try to insantiate `that' to `to' where 573 * If this fails, try to insantiate `that' to `to' where
523 * every occurrence of a type variable in `tvars' is replaced 574 * every occurrence of a type variable in `tvars' is replaced
524 * by an unknown type. 575 * by an unknown type.
525 */ 576 */
526 private Type instantiateArg(ForAll that, 577 private Type instantiateArg(ForAll that,
527 Type to, 578 Type to,
528 List<Type> tvars, 579 List<Type> tvars,
529 Warner warn) throws InferenceException { 580 Warner warn) throws InferenceException {
530 List<Type> targs; 581 List<Type> targs;
531 try { 582 try {
532 return instantiateExpr(that, to, warn); 583 return instantiateExpr(that, to, warn);
533 } catch (NoInstanceException ex) { 584 } catch (NoInstanceException ex) {
534 Type to1 = to; 585 Type to1 = to;
535 for (List<Type> l = tvars; l.nonEmpty(); l = l.tail) 586 for (List<Type> l = tvars; l.nonEmpty(); l = l.tail)
536 to1 = types.subst(to1, List.of(l.head), List.of(syms.unknownType)); 587 to1 = types.subst(to1, List.of(l.head), List.of(syms.unknownType));
537 return instantiateExpr(that, to1, warn); 588 return instantiateExpr(that, to1, warn);
538 } 589 }
539 } 590 }
540 591
541 /** check that type parameters are within their bounds. 592 /** check that type parameters are within their bounds.
542 */ 593 */
543 void checkWithinBounds(List<Type> tvars, 594 void checkWithinBounds(List<Type> tvars,
544 List<Type> arguments, 595 List<Type> arguments,
614 // infer as java.lang.Void for now 665 // infer as java.lang.Void for now
615 t = types.boxedClass(syms.voidType).type; 666 t = types.boxedClass(syms.voidType).type;
616 return t; 667 return t;
617 } 668 }
618 }; 669 };
619 } 670 }

mercurial