aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-05-01 09:25:01 +0200
committerMartin Odersky <odersky@gmail.com>2016-05-18 19:43:21 +0200
commitd0f05ad6c756355bb6ea863e10a554f54f145907 (patch)
tree3e6ae8c3a4f47f2acec66a1f530f47cca81c0124 /src
parentcc0f62954e814200f47f978b857abf6ab039c9f0 (diff)
downloaddotty-d0f05ad6c756355bb6ea863e10a554f54f145907.tar.gz
dotty-d0f05ad6c756355bb6ea863e10a554f54f145907.tar.bz2
dotty-d0f05ad6c756355bb6ea863e10a554f54f145907.zip
ResolveOverloaded should handle alternatives that are the same TermRef
This happens once we do not merge methods with the same signature coming from the same class.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala16
1 files changed, 10 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 390ecaee9..4f7a1c220 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -867,8 +867,6 @@ trait Applications extends Compatibility { self: Typer =>
*/
def isAsGood(alt1: TermRef, alt2: TermRef)(implicit ctx: Context): Boolean = track("isAsGood") { ctx.traceIndented(i"isAsGood($alt1, $alt2)", overload) {
- assert(alt1 ne alt2)
-
/** Is class or module class `sym1` derived from class or module class `sym2`?
* Module classes also inherit the relationship from their companions.
*/
@@ -975,14 +973,20 @@ trait Applications extends Compatibility { self: Typer =>
bestSoFar
}
val best = winner(alt, alts1)
- def asGood(alts: List[TermRef]): List[TermRef] = alts match {
+ // A tricky corner case is where we have two methods that have the same signature
+ // when seen from a particulatr prefix. In that case the TermRefs of two
+ // alternatives are identical. Hence, we have to make sure (using `altSeen`) that we
+ // eliminate only one alternative that's identical to `best`.
+ // A test case is in neg/i1240.scala
+ def asGood(alts: List[TermRef], altSeen: Boolean): List[TermRef] = alts match {
case alt :: alts1 =>
- if ((alt eq best) || !isAsGood(alt, best)) asGood(alts1)
- else alt :: asGood(alts1)
+ if (!altSeen && (alt eq best)) asGood(alts1, altSeen = true)
+ else if (!isAsGood(alt, best)) asGood(alts1, altSeen)
+ else alt :: asGood(alts1, altSeen)
case nil =>
Nil
}
- best :: asGood(alts)
+ best :: asGood(alts, altSeen = false)
}
}