@@ -669,25 +669,36 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
669669 }
670670
671671 def typedReturn (tree : untpd.Return )(implicit ctx : Context ): Return = track(" typedReturn" ) {
672- def returnProto (owner : Symbol ) =
673- if (owner.isConstructor) defn.UnitType else owner.info.finalResultType
674- def enclMethInfo (cx : Context ): (Tree , Type ) =
675- if (tree.from.isEmpty) {
676- val owner = cx.owner
677- if (cx == NoContext || owner.isType) {
678- ctx.error(" return outside method definition" , tree.pos)
679- (EmptyTree , WildcardType )
680- } else if (owner.isSourceMethod)
681- if (owner.isCompleted) {
682- val from = Ident (TermRef (NoPrefix , owner.asTerm))
683- val proto = returnProto(owner)
684- (from, proto)
685- } else (EmptyTree , errorType(d " $owner has return statement; needs result type " , tree.pos))
686- else enclMethInfo(cx.outer)
672+ def returnProto (owner : Symbol , locals : Scope ): Type =
673+ if (owner.isConstructor) defn.UnitType
674+ else owner.info match {
675+ case info : PolyType =>
676+ val tparams = locals.toList.takeWhile(_ is TypeParam )
677+ assert(info.paramNames.length == tparams.length,
678+ i " return mismatch from $owner, tparams = $tparams, locals = ${locals.toList}%, % " )
679+ info.instantiate(tparams.map(_.typeRef)).finalResultType
680+ case info =>
681+ info.finalResultType
687682 }
688- else
689- (tree.from.asInstanceOf [tpd.Tree ], returnProto(tree.from.symbol))
690- val (from, proto) = enclMethInfo(ctx)
683+ def enclMethInfo (cx : Context ): (Tree , Type ) = {
684+ val owner = cx.owner
685+ if (cx == NoContext || owner.isType) {
686+ ctx.error(" return outside method definition" , tree.pos)
687+ (EmptyTree , WildcardType )
688+ }
689+ else if (owner != cx.outer.owner && owner.isSourceMethod) {
690+ if (owner.isCompleted) {
691+ val from = Ident (TermRef (NoPrefix , owner.asTerm))
692+ val proto = returnProto(owner, cx.scope)
693+ (from, proto)
694+ }
695+ else (EmptyTree , errorType(d " $owner has return statement; needs result type " , tree.pos))
696+ }
697+ else enclMethInfo(cx.outer)
698+ }
699+ val (from, proto) =
700+ if (tree.from.isEmpty) enclMethInfo(ctx)
701+ else (tree.from.asInstanceOf [tpd.Tree ], WildcardType )
691702 val expr1 = typedExpr(tree.expr orElse untpd.unitLiteral.withPos(tree.pos), proto)
692703 assignType(cpy.Return (tree)(expr1, from))
693704 }
0 commit comments