diff options
author | Martin Odersky <odersky@gmail.com> | 2016-01-19 12:41:53 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2016-02-19 14:00:55 +0100 |
commit | 9dd07aad2ae6941a23c256245340771b3b5c2ab1 (patch) | |
tree | 399772b3bf21354a4debb5a258f8281597899030 /src/dotty/tools/dotc/typer/Applications.scala | |
parent | 6ee8569e6bf14412dc924fe1379a544f263397ed (diff) | |
download | dotty-9dd07aad2ae6941a23c256245340771b3b5c2ab1.tar.gz dotty-9dd07aad2ae6941a23c256245340771b3b5c2ab1.tar.bz2 dotty-9dd07aad2ae6941a23c256245340771b3b5c2ab1.zip |
Take defult parameters into account for overloading resolution.
The current Scala spec only considers methods without default parameters
for overloading resolution (unless only a single one remains anyway after
filtering by shape). This is needlessly restrictive. But dropping this
restriction (as dotty does) can lead to ambiguity errors, which is why
run/t8197 did not compile anymore.
We fix the problem by a last try rule: If after asSpecific tests there are
still several alternatives, and only one of them is without default arguments,
pick that one.
I tried an alternative rule which would make the distinction on default params
earlier but that one fails for the overloaded tree copier functions in Trees.scala
(the method with default parameters is also the one which is more specific).
Diffstat (limited to 'src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 25 |
1 files changed, 14 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 86980f337..217b75f61 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -262,13 +262,13 @@ trait Applications extends Compatibility { self: Typer => val receiver: Tree = methPart(normalizedFun) match { case Select(receiver, _) => receiver case mr => mr.tpe.normalizedPrefix match { - case mr: TermRef => - ref(mr) - case mr: TypeRef if this.isInstanceOf[TestApplication[_]] => - // In this case it is safe to skolemize now; we will produce a stable prefix for the actual call. - ref(mr.narrow) - case _ => - EmptyTree + case mr: TermRef => ref(mr) + case mr => + if (this.isInstanceOf[TestApplication[_]]) + // In this case it is safe to skolemize now; we will produce a stable prefix for the actual call. + ref(mr.narrow) + else + EmptyTree } } val getterPrefix = @@ -1105,10 +1105,13 @@ trait Applications extends Compatibility { self: Typer => // the arguments (which are constants) to be adapted to Byte. If we had picked // `candidates` instead, no solution would have been found. case alts => -// overload.println(i"ambiguous $alts%, %") - val deepPt = pt.deepenProto - if (deepPt ne pt) resolveOverloaded(alts, deepPt, targs) - else alts + val noDefaults = alts.filter(!_.symbol.hasDefaultParams) + if (noDefaults.length == 1) noDefaults // return unique alternative without default parameters if it exists + else { + val deepPt = pt.deepenProto + if (deepPt ne pt) resolveOverloaded(alts, deepPt, targs) + else alts + } } } |