aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/typer/Applications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-12-05 09:52:28 +0100
committerMartin Odersky <odersky@gmail.com>2016-12-17 18:34:27 +0100
commit0336785a2280a4a1e51e739e9aac3d5015f7c16f (patch)
treec8304e129def0b658a25aa47d58a1a354201ee15 /compiler/src/dotty/tools/dotc/typer/Applications.scala
parentd5ff7e052f4c321e3089e0543617f81416e4aed4 (diff)
downloaddotty-0336785a2280a4a1e51e739e9aac3d5015f7c16f.tar.gz
dotty-0336785a2280a4a1e51e739e9aac3d5015f7c16f.tar.bz2
dotty-0336785a2280a4a1e51e739e9aac3d5015f7c16f.zip
Take nesting into account when ranking implicits
This will need a spec change. It's necessary in order not to confuse synthetic implicits with each other or with explicit ones in the environment.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Applications.scala20
1 files changed, 16 insertions, 4 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Applications.scala b/compiler/src/dotty/tools/dotc/typer/Applications.scala
index 469d657a9..1cb656ca3 100644
--- a/compiler/src/dotty/tools/dotc/typer/Applications.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Applications.scala
@@ -975,9 +975,21 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
}
/** In a set of overloaded applicable alternatives, is `alt1` at least as good as
- * `alt2`? `alt1` and `alt2` are non-overloaded references.
+ * `alt2`? Also used for implicits disambiguation.
+ *
+ * @param alt1, alt2 Non-overloaded references indicating the two choices
+ * @param level1, level2 If alternatives come from a comparison of two contextual
+ * implicit candidates, the nesting levels of the candidates.
+ * In all other cases the nesting levels are both 0.
+ *
+ * An alternative A1 is "as good as" an alternative A2 if it wins or draws in a tournament
+ * that awards one point for each of the following
+ *
+ * - A1 is nested more deeply than A2
+ * - The nesting levels of A1 and A2 are the same, and A1's owner derives from A2's owner
+ * - A1's type is more specific than A2's type.
*/
- def isAsGood(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Boolean = track("isAsGood") { ctx.traceIndented(i"isAsGood($alt1, $alt2)", overload) {
+ def isAsGood(alt1: TermRef, alt2: TermRef, nesting1: Int = 0, nesting2: Int = 0)(implicit ctx: Context): Boolean = track("isAsGood") { ctx.traceIndented(i"isAsGood($alt1, $alt2)", overload) {
assert(alt1 ne alt2)
@@ -1092,9 +1104,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
val tp1 = stripImplicit(alt1.widen)
val tp2 = stripImplicit(alt2.widen)
- def winsOwner1 = isDerived(owner1, owner2)
+ def winsOwner1 = nesting1 > nesting2 || isDerived(owner1, owner2)
def winsType1 = isAsSpecific(alt1, tp1, alt2, tp2)
- def winsOwner2 = isDerived(owner2, owner1)
+ def winsOwner2 = nesting2 > nesting1 || isDerived(owner2, owner1)
def winsType2 = isAsSpecific(alt2, tp2, alt1, tp1)
overload.println(i"isAsGood($alt1, $alt2)? $tp1 $tp2 $winsOwner1 $winsType1 $winsOwner2 $winsType2")