@@ -66,7 +66,20 @@ trait Applications { self: Typer =>
66
66
tree
67
67
}
68
68
69
- def isCompatible (tp : Type , pt : Type ): Boolean = ???
69
+ def normalize (tp : Type )(implicit ctx : Context ) = tp.widen match {
70
+ case pt : PolyType => ctx.track(pt).resultType
71
+ case mt : MethodType if ! mt.isDependent =>
72
+ if (mt.isImplicit) mt.resultType
73
+ else defn.FunctionType (mt.paramTypes, mt.resultType)
74
+ case et : ExprType => et.resultType
75
+ case _ => tp
76
+ }
77
+
78
+ def isCompatible (tp : Type , pt : Type )(implicit ctx : Context ): Boolean = (
79
+ tp <:< pt
80
+ || pt.typeSymbol == defn.ByNameParamClass && tp <:< pt.typeArgs.head
81
+ || viewExists(tp, pt)
82
+ )
70
83
71
84
/**
72
85
* @param Arg the type of arguments, could be tpd.Tree, untpd.Tree, or Type
@@ -365,7 +378,7 @@ trait Applications { self: Typer =>
365
378
/** Subclass of Application for applicability tests with trees as arguments. */
366
379
class ApplicableToTrees (methRef : TermRef , args : List [tpd.Tree ], resultType : Type )(implicit ctx : Context )
367
380
extends TestApplication (methRef, methRef, args, resultType) with TreeApplication [Type ] {
368
- def argType (arg : tpd.Tree ): Type = arg.tpe
381
+ def argType (arg : tpd.Tree ): Type = normalize( arg.tpe)
369
382
def treeToArg (arg : tpd.Tree ): tpd.Tree = arg
370
383
}
371
384
@@ -492,7 +505,8 @@ trait Applications { self: Typer =>
492
505
new ApplicableToTypes (methRef, args, resultType)(ctx.fresh.withNewTyperState).success
493
506
494
507
/** Is `tp` a subtype of `pt`? */
495
- def isSubType (tp : Type , pt : Type )(implicit ctx : Context ) = (tp <:< pt)(ctx.fresh.withNewTyperState)
508
+ def testCompatible (tp : Type , pt : Type )(implicit ctx : Context ) =
509
+ isCompatible(tp, pt)(ctx.fresh.withNewTyperState)
496
510
497
511
/** In a set of overloaded applicable alternatives, is `alt1` at least as good as
498
512
* `alt2`? `alt1` and `alt2` are nonoverloaded references.
@@ -507,17 +521,17 @@ trait Applications { self: Typer =>
507
521
508
522
/** Is alternative `alt1` with type `tp1` as specific as alternative
509
523
* `alt2` with type `tp2` ? This is the case if `tp2` can be applied to
510
- * `tp1` or `tp2` is a supertype of `tp1`.
524
+ * `tp1` (without intervention of implicits) or `tp2' is a supertype of `tp1`.
511
525
*/
512
526
def isAsSpecific (alt1 : TermRef , tp1 : Type , alt2 : TermRef , tp2 : Type ): Boolean = tp1 match {
513
527
case tp1 : PolyType =>
514
528
def bounds (tparamRefs : List [TypeRef ]) = tp1.paramBounds map (_.substParams(tp1, tparamRefs))
515
529
val tparams = ctx.newTypeParams(alt1.symbol.owner, tp1.paramNames, EmptyFlags , bounds)
516
530
isAsSpecific(alt1, tp1.instantiate(tparams map (_.symRef)), alt2, tp2)
517
531
case tp1 : MethodType =>
518
- isApplicableToTypes(alt2, tp1.paramTypes)
532
+ isApplicableToTypes(alt2, tp1.paramTypes)(ctx)
519
533
case _ =>
520
- isSubType (tp1, tp2)
534
+ testCompatible (tp1, tp2)(ctx )
521
535
}
522
536
523
537
val owner1 = alt1.symbol.owner
@@ -547,6 +561,25 @@ trait Applications { self: Typer =>
547
561
else /* 1/9 */ winsType1 || /* 2/27 */ ! winsType2
548
562
}
549
563
564
+ def narrowMostSpecific (alts : List [TermRef ])(implicit ctx : Context ): List [TermRef ] = (alts : @ unchecked) match {
565
+ case alt :: alts1 =>
566
+ def winner (bestSoFar : TermRef , alts : List [TermRef ]): TermRef = alts match {
567
+ case alt :: alts1 =>
568
+ winner(if (isAsGood(alt, bestSoFar)) alt else bestSoFar, alts1)
569
+ case nil =>
570
+ bestSoFar
571
+ }
572
+ val best = winner(alt, alts1)
573
+ def asGood (alts : List [TermRef ]): List [TermRef ] = alts match {
574
+ case alt :: alts1 =>
575
+ if ((alt eq best) || ! isAsGood(alt, best)) asGood(alts1)
576
+ else alt :: asGood(alts1)
577
+ case nil =>
578
+ Nil
579
+ }
580
+ best :: asGood(alts1)
581
+ }
582
+
550
583
/** Resolve overloaded alternative `alts`, given expected type `pt`. */
551
584
def resolveOverloaded (alts : List [TermRef ], pt : Type )(implicit ctx : Context ): List [TermRef ] = {
552
585
@@ -574,25 +607,6 @@ trait Applications { self: Typer =>
574
607
def narrowByTypes (alts : List [TermRef ], argTypes : List [Type ], resultType : Type ): List [TermRef ] =
575
608
alts filter (isApplicableToTypes(_, argTypes, resultType))
576
609
577
- def narrowMostSpecific (alts : List [TermRef ]): List [TermRef ] = (alts : @ unchecked) match {
578
- case alt :: alts1 =>
579
- def winner (bestSoFar : TermRef , alts : List [TermRef ]): TermRef = alts match {
580
- case alt :: alts1 =>
581
- winner(if (isAsGood(alt, bestSoFar)) alt else bestSoFar, alts1)
582
- case nil =>
583
- bestSoFar
584
- }
585
- val best = winner(alt, alts1)
586
- def asGood (alts : List [TermRef ]): List [TermRef ] = alts match {
587
- case alt :: alts1 =>
588
- if ((alt eq best) || ! isAsGood(alt, best)) asGood(alts1)
589
- else alt :: asGood(alts1)
590
- case nil =>
591
- Nil
592
- }
593
- best :: asGood(alts1)
594
- }
595
-
596
610
val candidates = pt match {
597
611
case pt @ FunProtoType (args, resultType) =>
598
612
val numArgs = args.length
@@ -636,10 +650,10 @@ trait Applications { self: Typer =>
636
650
narrowByTypes(alts, args, resultType)
637
651
638
652
case tp =>
639
- alts filter (isSubType (_, tp))
653
+ alts filter (testCompatible (_, tp))
640
654
}
641
655
642
656
if (isDetermined(candidates)) candidates
643
- else narrowMostSpecific(candidates)
657
+ else narrowMostSpecific(candidates)(ctx.fresh.withImplicitsDisabled)
644
658
}
645
659
}
0 commit comments