aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2013-08-08 19:21:47 +0200
committerMartin Odersky <odersky@gmail.com>2013-08-08 19:24:18 +0200
commita326b06088d7eadde03bbcd56883b62fcfd21011 (patch)
treefabc34208e4cd5c6da7600cec46e45244586adc1 /src/dotty/tools/dotc
parent7f8ce8379296a399d29fdf9ec91210f44460f98f (diff)
downloaddotty-a326b06088d7eadde03bbcd56883b62fcfd21011.tar.gz
dotty-a326b06088d7eadde03bbcd56883b62fcfd21011.tar.bz2
dotty-a326b06088d7eadde03bbcd56883b62fcfd21011.zip
Typing of try and throw statements.
Also issues an error on returns form methods missing a return type.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala20
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala27
2 files changed, 44 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index fd60a100e..ab1517f9c 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -471,7 +471,25 @@ object Trees {
type ThisTree[-T >: Untyped] = Return[T]
}
- /** try block catch handler finally finalizer */
+ /** try block catch handler finally finalizer
+ *
+ * Note: if the handler is a case block CASES of the form
+ *
+ * { case1 ... caseN }
+ *
+ * the parser returns Match(EmptyTree, CASES). Desugaring and typing this yields a closure
+ * node
+ *
+ * { def $anonfun(x: Throwable) = x match CASES; Closure(Nil, $anonfun) }
+ *
+ * At some later stage when we normalize the try we can revert this to
+ *
+ * Match(EmptyTree, CASES)
+ *
+ * or else if stack is non-empty
+ *
+ * Match(EmptyTree, <case x: Throwable => $anonfun(x)>)
+ */
case class Try[-T >: Untyped] private[ast] (expr: Tree[T], handler: Tree[T], finalizer: Tree[T])
extends TermTree[T] {
type ThisTree[-T >: Untyped] = Try[T]
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 554884382..1e5d0d331 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -491,8 +491,15 @@ class Typer extends Namer with Applications with Implicits {
else cx.tree match {
case ddef: DefDef =>
val meth = ddef.symbol
- (Ident(TermRef.withSym(NoPrefix, meth.asTerm)),
- if (meth.isConstructor) defn.UnitType else ddef.tpt.tpe)
+ val from = Ident(TermRef.withSym(NoPrefix, meth.asTerm))
+ val proto =
+ if (meth.isConstructor)
+ defn.UnitType
+ else if (ddef.tpt.isEmpty)
+ errorType(s"method ${meth.show} has return statement; needs result type", tree.pos)
+ else
+ ddef.tpt.tpe
+ (from, proto)
case _ =>
enclMethInfo(cx.outer)
}
@@ -501,6 +508,22 @@ class Typer extends Namer with Applications with Implicits {
cpy.Return(tree, expr1, from) withType defn.NothingType
}
+ def typedTry(tree: untpd.Try, pt: Type)(implicit ctx: Context): Try = {
+ val expr1 = typed(tree.expr, pt)
+ val handler1 = typed(tree.handler, defn.FunctionType(defn.ThrowableType :: Nil, pt))
+ val finalizer1 = typed(tree.finalizer, defn.UnitType)
+ val handlerResultType = handler1.tpe match {
+ case defn.FunctionType(_, resultType) => resultType
+ case _ => defn.NothingType
+ }
+ cpy.Try(tree, expr1, handler1, finalizer1).withType(expr1.tpe | handlerResultType)
+ }
+
+ def typedThrow(tree: untpd.Throw)(implicit ctx: Context): Throw = {
+ val expr1 = typed(tree.expr, defn.ThrowableType)
+ cpy.Throw(tree, expr1) withType defn.NothingType
+ }
+
def typedModifiers(mods: untpd.Modifiers)(implicit ctx: Context): Modifiers = {
val annotations1 = mods.annotations mapconserve typedAnnotation
if (annotations1 eq mods.annotations) mods.asInstanceOf[Modifiers]