@@ -469,10 +469,9 @@ trait Implicits {
469
469
def isPlausiblyCompatible (tp : Type , pt : Type ) = checkCompatibility(fast = true , tp, pt)
470
470
def normSubType (tp : Type , pt : Type ) = checkCompatibility(fast = false , tp, pt)
471
471
472
- /** Does type `dtor` dominate type `dted`?
473
- * This is the case if the stripped cores `dtor1` and `dted1` of both types are
474
- * the same wrt `=:=`, or if they overlap and the complexity of `dtor1` is higher
475
- * than the complexity of `dted1`.
472
+ /** Does stripped core type `dtor` dominate the stripped core type `dted`?
473
+ * This is the case if both types are the same wrt `=:=`, or if they overlap
474
+ * and the complexity of `dtor` is higher than the complexity of `dted`.
476
475
* The _stripped core_ of a type is the type where
477
476
* - all refinements and annotations are dropped,
478
477
* - all universal and existential quantification is eliminated
@@ -488,27 +487,33 @@ trait Implicits {
488
487
case h :: t => sumComplexity(acc + complexity(h), t)
489
488
case _ : Nil .type => acc
490
489
}
490
+
491
491
def complexity (tp : Type ): Int = tp.dealias match {
492
492
case NoPrefix => 0
493
- case SingleType (pre , sym) => if (sym.hasPackageFlag) 0 else complexity(tp.dealiasWiden)
493
+ case SingleType (_ , sym) => if (sym.hasPackageFlag) 0 else complexity(tp.dealiasWiden)
494
494
case ThisType (sym) => if (sym.hasPackageFlag) 0 else 1
495
- case TypeRef (pre, sym , args) => 1 + complexity(pre) + sumComplexity(0 , args)
495
+ case TypeRef (pre, _ , args) => 1 + complexity(pre) + sumComplexity(0 , args)
496
496
case RefinedType (parents, _) => 1 + sumComplexity(0 , parents)
497
497
case _ => 1
498
498
}
499
+
499
500
def overlaps (tp1 : Type , tp2 : Type ): Boolean = (tp1, tp2) match {
500
501
case (RefinedType (parents, _), _) => parents exists (overlaps(_, tp2))
501
502
case (_, RefinedType (parents, _)) => parents exists (overlaps(tp1, _))
502
503
case _ => tp1.typeSymbol == tp2.typeSymbol
503
504
}
504
- val dtor1 = stripped(core(dtor))
505
- val dted1 = stripped(core(dted))
506
- overlaps(dtor1, dted1) && (dtor1 =:= dted1 || complexity(dtor1) > complexity(dted1))
505
+
506
+ overlaps(dtor, dted) && {
507
+ complexity(dtor) compareTo complexity(dted) match {
508
+ case 0 => dtor =:= dted
509
+ case cmp => cmp > 0
510
+ }
511
+ }
507
512
}
508
513
509
514
private def core (tp : Type ): Type = tp.dealiasWiden match {
510
- case RefinedType (parents, defs) => intersectionType(parents map core, tp.typeSymbol.owner)
511
- case AnnotatedType (annots , tp) => core(tp)
515
+ case RefinedType (parents, _) => intersectionType(parents map core, tp.typeSymbol.owner)
516
+ case AnnotatedType (_ , tp) => core(tp)
512
517
case ExistentialType (tparams, result) => core(result).subst(tparams, tparams map (t => core(t.info.upperBound)))
513
518
case PolyType (tparams, result) => core(result).subst(tparams, tparams map (t => core(t.info.upperBound)))
514
519
case TypeRef (pre, sym, args) =>
@@ -543,7 +548,8 @@ trait Implicits {
543
548
case _ => loop(tl, hdSym(acc))
544
549
}
545
550
}
546
- loop(List (tp), Set ())
551
+
552
+ loop(List (tp), Set .empty)
547
553
}
548
554
549
555
/** The expected type with all undetermined type parameters replaced with wildcards. */
@@ -571,31 +577,27 @@ trait Implicits {
571
577
// upon receiving `c.abort` the typechecker will decide that the corresponding implicit search has failed
572
578
// which will fail the entire stack of implicit searches, producing a nice error message provided by the programmer
573
579
val existsDominatedImplicit : Boolean =
574
- if (tree == EmptyTree ) false
580
+ if (tree == EmptyTree ) false
575
581
else {
576
- lazy val spt = stripped(core(pt))
577
- lazy val sptSyms = allSymbols(spt)
578
- // Are all the symbols of the stripped core of pt contained in the stripped core of tp?
579
- def coversPt (tp : Type ): Boolean = {
580
- val stp = stripped(core(tp))
581
- (stp =:= spt) || (sptSyms == allSymbols(stp))
582
+ lazy val ptStripped = stripped(core(pt))
583
+ lazy val ptStrippedSyms = allSymbols(ptStripped)
584
+
585
+ // Are all the symbols of the stripped core of dominating pt contained in the stripped core of tp?
586
+ def coversDominatingPt (tp : Type ): Boolean = {
587
+ val tpStripped = stripped(core(tp))
588
+ dominates(ptStripped, tpStripped) && ptStrippedSyms == allSymbols(tpStripped)
582
589
}
583
590
584
591
@ tailrec
585
- def loop (ois : List [OpenImplicit ], belowByName : Boolean ): Boolean = {
586
- ois match {
587
- case Nil => false
588
- case (hd@ OpenImplicit (info1, tp, tree1)) :: tl =>
589
- (if (! info1.sym.isMacro && tree1.symbol == tree.symbol) {
590
- if (belowByName && (tp =:= pt)) Some (false ) // if there is a byname argument between tp and pt we can tie the knot
591
- else if (dominates(pt, tp) && coversPt(tp)) Some (true )
592
- else None
593
- } else None ) match {
594
- case Some (res) => res
595
- case None => loop(tl, hd.isByName || belowByName)
596
- }
597
- }
592
+ def loop (ois : List [OpenImplicit ], belowByName : Boolean ): Boolean = ois match {
593
+ case Nil => false
594
+ case (hd @ OpenImplicit (info1, tp, tree1)) :: tl =>
595
+ val possiblyDominated = ! info1.sym.isMacro && tree1.symbol == tree.symbol
596
+ if (possiblyDominated && belowByName && tp =:= pt) false
597
+ else if (possiblyDominated && coversDominatingPt(tp)) true
598
+ else loop(tl, hd.isByName || belowByName)
598
599
}
600
+
599
601
loop(context.openImplicits, this .isByNamePt)
600
602
}
601
603
0 commit comments