aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Typer.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-08-18 13:40:29 +0200
committerMartin Odersky <odersky@gmail.com>2014-08-18 13:40:29 +0200
commit2cdc79d433d80168ab3bc98918bc27e239891d6c (patch)
treef118fb62d5632e9789a5feb7bbaa2e734cb7586d /src/dotty/tools/dotc/typer/Typer.scala
parentea616bf0b9f5c62d1f5a7b5b16b98cfac3c9ca1d (diff)
downloaddotty-2cdc79d433d80168ab3bc98918bc27e239891d6c.tar.gz
dotty-2cdc79d433d80168ab3bc98918bc27e239891d6c.tar.bz2
dotty-2cdc79d433d80168ab3bc98918bc27e239891d6c.zip
Fixed re-tpying of Return nodes.
Need to honor `from` if it exists, instead of searching for enclosing method. Code motion might move the code under a different method.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Typer.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala31
1 files changed, 17 insertions, 14 deletions
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 7d8eb7f98..5c2b44877 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -628,21 +628,24 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def typedReturn(tree: untpd.Return)(implicit ctx: Context): Return = track("typedReturn") {
- def enclMethInfo(cx: Context): (Tree, Type) = {
- val owner = cx.owner
- if (cx == NoContext || owner.isType) {
- ctx.error("return outside method definition", tree.pos)
- (EmptyTree, WildcardType)
+ def returnProto(owner: Symbol) =
+ if (owner.isConstructor) defn.UnitType else owner.info.finalResultType
+ def enclMethInfo(cx: Context): (Tree, Type) =
+ if (tree.from.isEmpty) {
+ val owner = cx.owner
+ if (cx == NoContext || owner.isType) {
+ ctx.error("return outside method definition", tree.pos)
+ (EmptyTree, WildcardType)
+ } else if (owner.isSourceMethod)
+ if (owner.isCompleted) {
+ val from = Ident(TermRef(NoPrefix, owner.asTerm))
+ val proto = returnProto(owner)
+ (from, proto)
+ } else (EmptyTree, errorType(d"$owner has return statement; needs result type", tree.pos))
+ else enclMethInfo(cx.outer)
}
- else if (owner.isSourceMethod)
- if (owner.isCompleted) {
- val from = Ident(TermRef(NoPrefix, owner.asTerm))
- val proto = if (owner.isConstructor) defn.UnitType else owner.info.finalResultType
- (from, proto)
- }
- else (EmptyTree, errorType(d"$owner has return statement; needs result type", tree.pos))
- else enclMethInfo(cx.outer)
- }
+ else
+ (tree.from.asInstanceOf[tpd.Tree], returnProto(tree.from.symbol))
val (from, proto) = enclMethInfo(ctx)
val expr1 = typedExpr(tree.expr orElse untpd.unitLiteral.withPos(tree.pos), proto)
assignType(cpy.Return(tree)(expr1, from))