aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-10-24 17:39:10 +0200
committerMartin Odersky <odersky@gmail.com>2013-10-24 17:44:52 +0200
commitafa83000f39f0b10824cb11b84ab0e8b66a91241 (patch)
tree22e459af8f2cbbe095e021ba38fbb37b22b2f361
parentdbd9569755f40263a783d0301b3fb07849605d17 (diff)
downloaddotty-afa83000f39f0b10824cb11b84ab0e8b66a91241.tar.gz
dotty-afa83000f39f0b10824cb11b84ab0e8b66a91241.tar.bz2
dotty-afa83000f39f0b10824cb11b84ab0e8b66a91241.zip
Parsing and desugaring fixes for blocks.
Previously, { () } was expanded to { (); EmptyTree }, because the empty tuple is not a term tree. Now EmptyTree is inserted only after a definition. Furthermore, blocks ending in EmptyTree are now replaced by blocks that end in a unit literal.
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala8
-rw-r--r--src/dotty/tools/dotc/parsing/Parsers.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala7
3 files changed, 13 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index 31154b2ef..fb80509fd 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -255,6 +255,14 @@ object desugar {
case tree: PatDef => patDef(tree)
}
+ def block(tree: Block)(implicit ctx: Context): Block = tree.expr match {
+ case EmptyTree =>
+ cpy.Block(tree, tree.stats,
+ unitLiteral withPos (if (tree.stats.isEmpty) tree.pos else tree.pos.endPos))
+ case _ =>
+ tree
+ }
+
/** In case there is exactly one variable x_1 in pattern
* val/var p = e ==> val/var x_1 = (e: @unchecked) match (case p => (x_1))
*
diff --git a/src/dotty/tools/dotc/parsing/Parsers.scala b/src/dotty/tools/dotc/parsing/Parsers.scala
index 57356f305..500ea4810 100644
--- a/src/dotty/tools/dotc/parsing/Parsers.scala
+++ b/src/dotty/tools/dotc/parsing/Parsers.scala
@@ -1130,7 +1130,7 @@ object Parsers {
*/
def block(): Tree = {
val stats = blockStatSeq()
- if (stats.nonEmpty && stats.last.isTerm) Block(stats.init, stats.last)
+ if (stats.nonEmpty && !stats.last.isDef) Block(stats.init, stats.last)
else Block(stats, EmptyTree)
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 5b79c62f3..bb3e1052a 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -461,8 +461,9 @@ class Typer extends Namer with Applications with Implicits {
else if (forceFullyDefined(pt)) {
val expr2 = typed(untpd.Typed(untpd.TypedSplice(expr1), untpd.TypeTree(pt)))
untpd.Block(stats1, expr2) withType expr2.tpe
- } else errorTree(result,
- i"local definition of ${leaks.head.name} escapes as part of block's type ${result.tpe}")
+ } else
+ errorTree(result,
+ i"local definition of ${leaks.head.name} escapes as part of block's type ${result.tpe}")
}
def typedIf(tree: untpd.If, pt: Type)(implicit ctx: Context) = track("typedIf") {
@@ -825,7 +826,7 @@ class Typer extends Namer with Applications with Implicits {
case tree: untpd.Typed => typedTyped(tree, pt)
case tree: untpd.NamedArg => typedNamedArg(tree, pt)
case tree: untpd.Assign => typedAssign(tree, pt)
- case tree: untpd.Block => typedBlock(tree, pt)
+ case tree: untpd.Block => typedBlock(desugar.block(tree), pt)
case tree: untpd.If => typedIf(tree, pt)
case tree: untpd.Function => typedFunction(tree, pt)
case tree: untpd.Closure => typedClosure(tree, pt)