diff options
author | Martin Odersky <odersky@gmail.com> | 2016-05-01 09:25:01 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-05-18 19:43:21 +0200 |
commit | d0f05ad6c756355bb6ea863e10a554f54f145907 (patch) | |
tree | 3e6ae8c3a4f47f2acec66a1f530f47cca81c0124 | |
parent | cc0f62954e814200f47f978b857abf6ab039c9f0 (diff) | |
download | dotty-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.
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 16 |
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) } } |