diff options
author | Martin Odersky <odersky@gmail.com> | 2014-01-15 19:04:07 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2014-01-15 19:04:07 +0100 |
commit | 1f604efa08bcef3604a2d6c373dc78b0730188fb (patch) | |
tree | 8e23d014e7f27e33c8cbd72ac76c4b5f9faaefd7 /src/dotty/tools/dotc/typer/Typer.scala | |
parent | 24dff883751fb5a0920f8889e6570914a0f73a26 (diff) | |
download | dotty-1f604efa08bcef3604a2d6c373dc78b0730188fb.tar.gz dotty-1f604efa08bcef3604a2d6c373dc78b0730188fb.tar.bz2 dotty-1f604efa08bcef3604a2d6c373dc78b0730188fb.zip |
Tweak to typing of function values.
We now propagte the expected function result type (if it exists) into the function body even if it not fully defined.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 20 |
1 files changed, 15 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index f565e72c9..d35e5fa93 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -613,9 +613,18 @@ class Typer extends Namer with Applications with Implicits { cpy.ValDef(param, param.mods, param.name, paramTpt, param.rhs) } - val resultTpt = - if (isFullyDefined(protoResult, ForceDegree.none)) untpd.TypeTree(protoResult) - else untpd.TypeTree() + // Define result type of closure as the expected type, thereby pushing + // down any implicit searches. We do this even if the expected type is not fully + // defined, which is a bit of a hack. But it's needed to make the following work + // (see typers.scala and printers/PlainPrinter.scala for examples). + // + // def double(x: Char): String = s"$x$x" + // "abc" flatMap double + // + val resultTpt = protoResult match { + case WildcardType(_) => untpd.TypeTree() + case _ => untpd.TypeTree(protoResult) + } typed(desugar.makeClosure(inferredParams, fnBody, resultTpt), pt) } } @@ -646,14 +655,15 @@ class Typer extends Namer with Applications with Implicits { typed(desugar.makeCaseLambda(tree.cases) withPos tree.pos, pt) case _ => val sel1 = typedExpr(tree.selector) - val selType = fullyDefinedType(sel1.tpe, "pattern selector", tree.pos) + val selType = widenForMatchSelector( + fullyDefinedType(sel1.tpe, "pattern selector", tree.pos)) /** gadtSyms = "all type parameters of enclosing methods that appear * non-variantly in the selector type" todo: should typevars * which appear with variances +1 and -1 (in different * places) be considered as well? */ - val gadtSyms: Set[Symbol] = { + val gadtSyms: Set[Symbol] = ctx.traceIndented(gadts, i"GADT syms of $selType") { val accu = new TypeAccumulator[Set[Symbol]] { def apply(tsyms: Set[Symbol], t: Type): Set[Symbol] = { val tsyms1 = t match { |