aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Applications.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-09-08 19:20:47 +0200
committerMartin Odersky <odersky@gmail.com>2013-09-08 19:20:47 +0200
commit1cf91fa7b14b62b6ba67971b29046631efbecd83 (patch)
tree786cdc8c23d17df96bf38d1ae2e8714df71c7579 /src/dotty/tools/dotc/typer/Applications.scala
parent115c5392b9aecc5255a6370cde4a9f7b506f47d7 (diff)
downloaddotty-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.scala32
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 =>