summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2006-04-12 16:32:54 +0000
committerMartin Odersky <odersky@gmail.com>2006-04-12 16:32:54 +0000
commite205301999b5de273f985941d8eac9cfab283343 (patch)
tree64dd8f9aa37e21abe71ceb6c74e3d9d38d733b4e
parent99a85272928ab170351fa1f36b5684ae6a6b4755 (diff)
downloadscala-e205301999b5de273f985941d8eac9cfab283343.tar.gz
scala-e205301999b5de273f985941d8eac9cfab283343.tar.bz2
scala-e205301999b5de273f985941d8eac9cfab283343.zip
Fixed bug 566
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala8
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala15
-rw-r--r--test/files/pos/bug566.scala4
3 files changed, 21 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index ef1b48aeef..d823c7081f 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 3e93ca194c..8b151063db 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 0000000000..6a2a0a3621
--- /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
+}