aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Applications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-03 20:41:32 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-03 20:43:49 +0200
commit2020938a77590f8c461041707716eca228f647d2 (patch)
tree137eb62b6ae9eaf70ee781ca1b756744673dd7cd /src/dotty/tools/dotc/typer/Applications.scala
parent0c97f086f80c4d29e1cc894df4c7dc4cc5be3a6a (diff)
downloaddotty-2020938a77590f8c461041707716eca228f647d2.tar.gz
dotty-2020938a77590f8c461041707716eca228f647d2.tar.bz2
dotty-2020938a77590f8c461041707716eca228f647d2.zip
Code to handle overloaded unapply/unapplySeq methods
These were not handled before.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala
index 242985b57..b506e7e33 100644
--- a/src/dotty/tools/dotc/typer/Applications.scala
+++ b/src/dotty/tools/dotc/typer/Applications.scala
@@ -555,18 +555,32 @@ trait Applications extends Compatibility { self: Typer =>
/** A typed qual.unappy or qual.unappySeq tree, if this typechecks.
* Otherwise fallBack with (maltyped) qual.unapply as argument
+ * Note: requires special handling for overloaded occurrences of
+ * unapply or unapplySeq. We first try to find a non-overloaded
+ * method which matches any type. If that fails, we try to find an
+ * overloaded variant which matches one of the argument types.
+ * In fact, overloaded unapply's are problematic because a non-
+ * overloaded unapply does *not* need to be applicable to its argument
+ * whereas overloaded variants need to have a conforming variant.
*/
def trySelectUnapply(qual: untpd.Tree)(fallBack: Tree => Tree): Tree = {
- val unappProto = new UnapplyFunProto(this)
- tryEither {
- implicit ctx => typedExpr(untpd.Select(qual, nme.unapply), unappProto)
- } {
- (sel, _) =>
- tryEither {
- implicit ctx => typedExpr(untpd.Select(qual, nme.unapplySeq), unappProto) // for backwards compatibility; will be dropped
- } {
- (_, _) => fallBack(sel)
- }
+ val genericProto = new UnapplyFunProto(WildcardType, this)
+ def specificProto = new UnapplyFunProto(pt, this)
+ // try first for non-overloaded, then for overloaded ocurrences
+ def tryWithName(name: TermName)(fallBack: Tree => Tree)(implicit ctx: Context): Tree =
+ tryEither {
+ implicit ctx => typedExpr(untpd.Select(qual, name), genericProto)
+ } {
+ (sel, _) =>
+ tryEither {
+ implicit ctx => typedExpr(untpd.Select(qual, name), specificProto)
+ } {
+ (_, _) => fallBack(sel)
+ }
+ }
+ // try first for unapply, then for unapplySeq
+ tryWithName(nme.unapply) {
+ sel => tryWithName(nme.unapplySeq)(_ => fallBack(sel)) // for backwards compatibility; will be dropped
}
}