From 9304130292da9bb34ac3fac9a58257d43a1ecde0 Mon Sep 17 00:00:00 2001 From: odersky Date: Wed, 12 Apr 2006 16:32:54 +0000 Subject: [PATCH] Fixed bug 566 git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@7123 5e8d7ff9-d8ef-0310-90f0-a4852d11357a --- .../scala/tools/nsc/typechecker/Contexts.scala | 8 ++++++++ .../scala/tools/nsc/typechecker/Typers.scala | 15 +++++++++------ test/files/pos/bug566.scala | 4 ++++ 3 files changed, 21 insertions(+), 6 deletions(-) create mode 100644 test/files/pos/bug566.scala diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 64de20f72..690195b78 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -15,6 +15,7 @@ trait Contexts requires Analyzer { override def implicitss: List[List[ImplicitInfo]] = List(); } NoContext.enclClass = NoContext; + NoContext.enclMethod = NoContext; val startContext = { import definitions._; @@ -61,6 +62,7 @@ trait Contexts requires Analyzer { var outer: Context = _; // The next outer context var enclClass: Context = _; // The next outer context whose tree is a // template or package definition + var enclMethod: Context = _; // The next outer context whose tree is a method var variance: int = _; // Variance relative to enclosing class. private var _undetparams: List[Symbol] = List(); // Undetermined type parameters var depth: int = 0; @@ -98,6 +100,12 @@ trait Contexts requires Analyzer { c.prefix = if (c.owner != this.owner && c.owner.isTerm) NoPrefix else this.prefix; c.inConstructorSuffix = this.inConstructorSuffix; } + tree match { + case DefDef(_, _, _, _, _, _) => + c.enclMethod = c + case _ => + c.enclMethod = this.enclMethod + } c.variance = this.variance; c.depth = if (scope == this.scope) this.depth else this.depth + 1; c.imports = imports; diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 672c7c141..1ff1ce946 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -786,6 +786,7 @@ trait Typers requires Analyzer { checkNoEscaping.privates(meth, typedType(ddef.tpt))) checkNonCyclic(ddef, tpt1) + ddef.tpt.setType(tpt1.tpe) val rhs1 = if (ddef.name == nme.CONSTRUCTOR) { if (!meth.hasFlag(SYNTHETIC) && @@ -1405,14 +1406,16 @@ trait Typers requires Analyzer { copy.Match(tree, selector1, cases1) setType ptOrLub(cases1 map (.tpe)) case Return(expr) => - val enclFun = if (tree.symbol != NoSymbol) tree.symbol else context.owner.enclMethod - if (!enclFun.isMethod || enclFun.isConstructor) + val enclMethod = context.enclMethod; + if (enclMethod == NoContext || enclMethod.owner.isConstructor) errorTree(tree, "return outside method definition") - else if (!context.owner.isInitialized) - errorTree(tree, "method "+context.owner+" has return statement; needs result type") + else if (!enclMethod.owner.isInitialized) + errorTree(tree, "method "+enclMethod.owner+" has return statement; needs result type") else { - val expr1: Tree = typed(expr, enclFun.tpe.finalResultType) - copy.Return(tree, expr1) setSymbol enclFun setType AllClass.tpe + val DefDef(_, _, _, _, restpt, _) = enclMethod.tree + assert(restpt.tpe != null, restpt) + val expr1: Tree = typed(expr, restpt.tpe) + copy.Return(tree, expr1) setSymbol enclMethod.owner setType AllClass.tpe } case Try(block, catches, finalizer) => diff --git a/test/files/pos/bug566.scala b/test/files/pos/bug566.scala new file mode 100644 index 000000000..6a2a0a362 --- /dev/null +++ b/test/files/pos/bug566.scala @@ -0,0 +1,4 @@ +object test { + def foo[a](ys: List[a]): List[a] = + return ys.head :: ys.tail +}