diff options
author | Martin Odersky <odersky@gmail.com> | 2013-11-06 18:39:00 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2013-11-06 18:39:00 +0100 |
commit | e401bac707d6d56d551db5556a7f58861ea3ae16 (patch) | |
tree | bdb6f5f25a9f339914858ff87143064a694eb9fc /src/dotty/tools/dotc/typer/Typer.scala | |
parent | c1abb572fa3adaeef3f66c79ac8946d15c7aeca7 (diff) | |
download | dotty-e401bac707d6d56d551db5556a7f58861ea3ae16.tar.gz dotty-e401bac707d6d56d551db5556a7f58861ea3ae16.tar.bz2 dotty-e401bac707d6d56d551db5556a7f58861ea3ae16.zip |
Fixing several type checking problems.
1. Being more precise what gets forced when.
2. stopping repeated evaluation when inserting an implicit methods to make arguments match.
Previously the argument got re-evaluated which could lead to misleading errors (e..g missing parameter type
if argument was a closure), and could also lead to exponential checking blowup. We now re-use the old argument
but in its unadapted form. We do this with a tight coupling between an Application node and a FunProto node -
typedArg in the application node forwards to new caching functionality in the FunProto node. It would probably
be better overall to merge the two abstractions. FunProto = Application?
3. Various fixes to pattern matching.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r-- | src/dotty/tools/dotc/typer/Typer.scala | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index efb89cc4c..e9c6b0d08 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -460,7 +460,7 @@ class Typer extends Namer with Applications with Implicits { val result = cpy.Block(tree, stats1, expr1).withType(blockType(stats1, expr1.tpe)) val leaks = CheckTrees.escapingRefs(result) if (leaks.isEmpty) result - else if (forceFullyDefined(pt)) { + else if (isFullyDefined(pt, ForceDegree.all)) { val expr2 = typed(untpd.Typed(untpd.TypedSplice(expr1), untpd.TypeTree(pt))) untpd.Block(stats1, expr2) withType expr2.tpe } else @@ -496,8 +496,14 @@ class Typer extends Namer with Applications with Implicits { if (!param.tpt.isEmpty) param else { val paramType = - if (forceFullyDefined(formal)) formal - else errorType("missing parameter type", param.pos) + if (isFullyDefined(formal, ForceDegree.noBottom)) formal + else { + val ofFun = + if (nme.syntheticParamNames(args.length + 1) contains param.name) + s" for expanded function ${tree.show}" + else "" + errorType(s"missing parameter type for parameter ${param.name}$ofFun, expected = ${pt.show}", param.pos) + } cpy.ValDef(param, param.mods, param.name, untpd.TypeTree(paramType), param.rhs) } typed(desugar.makeClosure(inferredParams, body), pt) @@ -617,7 +623,7 @@ class Typer extends Namer with Applications with Implicits { def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = track("typedTypeTree") { val (original1, ownType) = tree.original match { case untpd.EmptyTree => - assert(isFullyDefined(pt)) + assert(isFullyDefined(pt, ForceDegree.none)) (EmptyTree, pt) case original: ValDef => val meth = symbolOfTree(original) @@ -1073,7 +1079,7 @@ class Typer extends Namer with Applications with Implicits { if defn.isFunctionType(wtp) && !defn.isFunctionType(pt) => pt match { case SAMType(meth) - if wtp <:< meth.info.toFunctionType && isFullyDefined(pt) => + if wtp <:< meth.info.toFunctionType && isFullyDefined(pt, ForceDegree.noBottom) => return cpy.Closure(tree, Nil, id, TypeTree(pt)).withType(pt) case _ => } |