diff options
author | Martin Odersky <odersky@gmail.com> | 2014-08-03 20:41:32 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-08-03 20:43:49 +0200 |
commit | 2020938a77590f8c461041707716eca228f647d2 (patch) | |
tree | 137eb62b6ae9eaf70ee781ca1b756744673dd7cd /src/dotty/tools | |
parent | 0c97f086f80c4d29e1cc894df4c7dc4cc5be3a6a (diff) | |
download | dotty-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')
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 34 | ||||
-rw-r--r-- | src/dotty/tools/dotc/typer/ProtoTypes.scala | 4 |
2 files changed, 26 insertions, 12 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 } } diff --git a/src/dotty/tools/dotc/typer/ProtoTypes.scala b/src/dotty/tools/dotc/typer/ProtoTypes.scala index 19d8d6895..0aa0aa538 100644 --- a/src/dotty/tools/dotc/typer/ProtoTypes.scala +++ b/src/dotty/tools/dotc/typer/ProtoTypes.scala @@ -257,8 +257,8 @@ object ProtoTypes { unique(new CachedViewProto(argType, resultType)) } - class UnapplyFunProto(typer: Typer)(implicit ctx: Context) extends FunProto( - untpd.TypedSplice(dummyTreeOfType(WildcardType)) :: Nil, WildcardType, typer) + class UnapplyFunProto(argType: Type, typer: Typer)(implicit ctx: Context) extends FunProto( + untpd.TypedSplice(dummyTreeOfType(argType)) :: Nil, WildcardType, typer) /** A prototype for expressions [] that are type-parameterized: * |