@@ -44,19 +44,19 @@ object Implicits {
44
44
/** Return those references in `refs` that are compatible with type `pt`. */
45
45
protected def filterMatching (pt : Type )(implicit ctx : Context ): List [TermRef ] = track(" filterMatching" ) {
46
46
47
- def refMatches (ref : TermRef )(implicit ctx : Context ) = {
47
+ def refMatches (ref : TermRef )(implicit ctx : Context ) = /* ctx.traceIndented(i"refMatches $ref $pt") */ {
48
48
49
49
def discardForView (tpw : Type , argType : Type ): Boolean = tpw match {
50
50
case mt : MethodType =>
51
51
mt.isImplicit ||
52
52
mt.paramTypes.length != 1 ||
53
- ! (argType <:< mt.paramTypes.head)(ctx.fresh.setExploreTyperState)
53
+ ! (argType relaxed_ <:< mt.paramTypes.head)(ctx.fresh.setExploreTyperState)
54
54
case poly : PolyType =>
55
55
poly.resultType match {
56
56
case mt : MethodType =>
57
57
mt.isImplicit ||
58
58
mt.paramTypes.length != 1 ||
59
- ! (argType <:< wildApprox(mt.paramTypes.head)(ctx.fresh.setExploreTyperState))
59
+ ! (argType relaxed_ <:< wildApprox(mt.paramTypes.head)(ctx.fresh.setExploreTyperState))
60
60
case rtp =>
61
61
discardForView(wildApprox(rtp), argType)
62
62
}
@@ -532,6 +532,25 @@ trait Implicits { self: Typer =>
532
532
case nil => acc
533
533
}
534
534
535
+ /** If the (result types of) the expected type, and both alternatives
536
+ * are all numeric value types, return the alternative which has
537
+ * the smaller numeric subtype as result type, if it exists.
538
+ * (This alternative is then discarded).
539
+ */
540
+ def numericValueTieBreak (alt1 : SearchSuccess , alt2 : SearchSuccess ): SearchResult = {
541
+ def isNumeric (tp : Type ) = tp.typeSymbol.isNumericValueClass
542
+ def isProperSubType (tp1 : Type , tp2 : Type ) =
543
+ tp1.isValueSubType(tp2) && ! tp2.isValueSubType(tp1)
544
+ val rpt = pt.resultType
545
+ val rt1 = alt1.ref.widen.resultType
546
+ val rt2 = alt2.ref.widen.resultType
547
+ if (isNumeric(rpt) && isNumeric(rt1) && isNumeric(rt2))
548
+ if (isProperSubType(rt1, rt2)) alt1
549
+ else if (isProperSubType(rt2, rt1)) alt2
550
+ else NoImplicitMatches
551
+ else NoImplicitMatches
552
+ }
553
+
535
554
/** Convert a (possibly empty) list of search successes into a single search result */
536
555
def condense (hits : List [SearchSuccess ]): SearchResult = hits match {
537
556
case best :: alts =>
@@ -541,7 +560,10 @@ trait Implicits { self: Typer =>
541
560
println(i"ambiguous refs: ${hits map (_.ref) map (_.show) mkString ", "}")
542
561
isAsGood(best.ref, alt.ref, explain = true)(ctx.fresh.withExploreTyperState)
543
562
*/
544
- new AmbiguousImplicits (best.ref, alt.ref, pt, argument)
563
+ numericValueTieBreak(best, alt) match {
564
+ case eliminated : SearchSuccess => condense(hits.filter(_ ne eliminated))
565
+ case _ => new AmbiguousImplicits (best.ref, alt.ref, pt, argument)
566
+ }
545
567
case None =>
546
568
ctx.runInfo.useCount(best.ref) += 1
547
569
best
0 commit comments