Fixed bug 566

git-svn-id: http://lampsvn.epfl.ch/svn-repos/scala/scala/trunk@7123 5e8d7ff9-d8ef-0310-90f0-a4852d11357a
This commit is contained in:
odersky 2006-04-12 16:32:54 +00:00
parent 0500d9f270
commit 9304130292
3 changed files with 21 additions and 6 deletions

View File

@ -15,6 +15,7 @@ trait Contexts requires Analyzer {
override def implicitss: List[List[ImplicitInfo]] = List(); override def implicitss: List[List[ImplicitInfo]] = List();
} }
NoContext.enclClass = NoContext; NoContext.enclClass = NoContext;
NoContext.enclMethod = NoContext;
val startContext = { val startContext = {
import definitions._; import definitions._;
@ -61,6 +62,7 @@ trait Contexts requires Analyzer {
var outer: Context = _; // The next outer context var outer: Context = _; // The next outer context
var enclClass: Context = _; // The next outer context whose tree is a var enclClass: Context = _; // The next outer context whose tree is a
// template or package definition // template or package definition
var enclMethod: Context = _; // The next outer context whose tree is a method
var variance: int = _; // Variance relative to enclosing class. var variance: int = _; // Variance relative to enclosing class.
private var _undetparams: List[Symbol] = List(); // Undetermined type parameters private var _undetparams: List[Symbol] = List(); // Undetermined type parameters
var depth: int = 0; 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.prefix = if (c.owner != this.owner && c.owner.isTerm) NoPrefix else this.prefix;
c.inConstructorSuffix = this.inConstructorSuffix; c.inConstructorSuffix = this.inConstructorSuffix;
} }
tree match {
case DefDef(_, _, _, _, _, _) =>
c.enclMethod = c
case _ =>
c.enclMethod = this.enclMethod
}
c.variance = this.variance; c.variance = this.variance;
c.depth = if (scope == this.scope) this.depth else this.depth + 1; c.depth = if (scope == this.scope) this.depth else this.depth + 1;
c.imports = imports; c.imports = imports;

View File

@ -786,6 +786,7 @@ trait Typers requires Analyzer {
checkNoEscaping.privates(meth, checkNoEscaping.privates(meth,
typedType(ddef.tpt))) typedType(ddef.tpt)))
checkNonCyclic(ddef, tpt1) checkNonCyclic(ddef, tpt1)
ddef.tpt.setType(tpt1.tpe)
val rhs1 = val rhs1 =
if (ddef.name == nme.CONSTRUCTOR) { if (ddef.name == nme.CONSTRUCTOR) {
if (!meth.hasFlag(SYNTHETIC) && if (!meth.hasFlag(SYNTHETIC) &&
@ -1405,14 +1406,16 @@ trait Typers requires Analyzer {
copy.Match(tree, selector1, cases1) setType ptOrLub(cases1 map (.tpe)) copy.Match(tree, selector1, cases1) setType ptOrLub(cases1 map (.tpe))
case Return(expr) => case Return(expr) =>
val enclFun = if (tree.symbol != NoSymbol) tree.symbol else context.owner.enclMethod val enclMethod = context.enclMethod;
if (!enclFun.isMethod || enclFun.isConstructor) if (enclMethod == NoContext || enclMethod.owner.isConstructor)
errorTree(tree, "return outside method definition") errorTree(tree, "return outside method definition")
else if (!context.owner.isInitialized) else if (!enclMethod.owner.isInitialized)
errorTree(tree, "method "+context.owner+" has return statement; needs result type") errorTree(tree, "method "+enclMethod.owner+" has return statement; needs result type")
else { else {
val expr1: Tree = typed(expr, enclFun.tpe.finalResultType) val DefDef(_, _, _, _, restpt, _) = enclMethod.tree
copy.Return(tree, expr1) setSymbol enclFun setType AllClass.tpe 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) => case Try(block, catches, finalizer) =>

View File

@ -0,0 +1,4 @@
object test {
def foo[a](ys: List[a]): List[a] =
return ys.head :: ys.tail
}