diff options
author | Martin Odersky <odersky@gmail.com> | 2013-09-08 19:20:47 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-09-08 19:20:47 +0200 |
commit | 1cf91fa7b14b62b6ba67971b29046631efbecd83 (patch) | |
tree | 786cdc8c23d17df96bf38d1ae2e8714df71c7579 /src/dotty/tools/dotc/typer/Applications.scala | |
parent | 115c5392b9aecc5255a6370cde4a9f7b506f47d7 (diff) | |
download | dotty-1cf91fa7b14b62b6ba67971b29046631efbecd83.tar.gz dotty-1cf91fa7b14b62b6ba67971b29046631efbecd83.tar.bz2 dotty-1cf91fa7b14b62b6ba67971b29046631efbecd83.zip |
Implemented "two-hop" implicit adaptation.
That is, in a selection qual.name(args), qual can be adapted to obtain a member "name" that matches args. Important to make usage patterns like this one work:
1 + BigInt(x)
Diffstat (limited to 'src/dotty/tools/dotc/typer/Applications.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Applications.scala | 32 |
1 files changed, 26 insertions, 6 deletions
diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 8e3bb9dbb..f81fcf3cd 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -458,16 +458,36 @@ trait Applications extends Compatibility { self: Typer => typedUnApply(tree, pt) else { - def realApply(implicit ctx: Context) = { + def realApply(implicit ctx: Context): Tree = { val proto = new FunProto(tree.args, pt, this) val fun1 = typedExpr(tree.fun, proto) methPart(fun1).tpe match { case funRef: TermRef => - val app = - if (proto.argsAreTyped) new ApplyToTyped(tree, fun1, funRef, proto.typedArgs, pt) - else new ApplyToUntyped(tree, fun1, funRef, tree.args, pt) - val result = app.result - ConstFold(result) orElse result + tryEither { implicit ctx => + val app = + if (proto.argsAreTyped) new ApplyToTyped(tree, fun1, funRef, proto.typedArgs, pt) + else new ApplyToUntyped(tree, fun1, funRef, tree.args, pt) + val result = app.result + ConstFold(result) orElse result + } { failed => fun1 match { + case Select(qual, name) => + tryEither { implicit ctx => + val qual1 = adapt(qual, new SelectionProto(name, proto)) + if (qual1.tpe.isError) qual1 + else { + assert(qual1 ne qual) + typedApply( + cpy.Apply(tree, + cpy.Select(fun1, untpd.TypedSplice(qual1), name), + proto.typedArgs map untpd.TypedSplice), + pt) + } + } { _ => failed.commit() + } + case _ => + failed.commit() + } + } case _ => fun1.qualifierType match { case ErrorType => |