From 3a1d34eebfb06ec3d66a46509b368256318510d1 Mon Sep 17 00:00:00 2001 From: Adriaan Moors Date: Thu, 8 Jul 2010 15:59:15 +0000 Subject: closes #3486. fixed by having mixin do the cloning at the beginning of erasure and then updating the symbol's info to transform it to be valid in current phase review by odersky --- src/compiler/scala/tools/nsc/symtab/Symbols.scala | 1 + src/compiler/scala/tools/nsc/transform/Mixin.scala | 19 +++++++++++++++++-- 2 files changed, 18 insertions(+), 2 deletions(-) (limited to 'src/compiler') diff --git a/src/compiler/scala/tools/nsc/symtab/Symbols.scala b/src/compiler/scala/tools/nsc/symtab/Symbols.scala index 1908b4ded9..e386508bdd 100644 --- a/src/compiler/scala/tools/nsc/symtab/Symbols.scala +++ b/src/compiler/scala/tools/nsc/symtab/Symbols.scala @@ -776,6 +776,7 @@ trait Symbols extends reflect.generic.Symbols { self: SymbolTable => assert(phaseId(infos.validFrom) <= phase.id) if (phaseId(infos.validFrom) == phase.id) infos = infos.prev infos = TypeHistory(currentPeriod, info, infos) + validTo = if (info.isComplete) currentPeriod else NoPeriod this } diff --git a/src/compiler/scala/tools/nsc/transform/Mixin.scala b/src/compiler/scala/tools/nsc/transform/Mixin.scala index c228ee0e46..d1b3142c8a 100644 --- a/src/compiler/scala/tools/nsc/transform/Mixin.scala +++ b/src/compiler/scala/tools/nsc/transform/Mixin.scala @@ -231,12 +231,27 @@ abstract class Mixin extends InfoTransform with ast.TreeDSL { for (member <- impl.info.decls.toList) { if (isForwarded(member)) { val imember = member.overriddenSymbol(iface) - //Console.println("mixin member "+member+":"+member.tpe+member.locationString+" "+imember+" "+imember.overridingSymbol(clazz)+" to "+clazz+" with scope "+clazz.info.decls)//DEBUG + // atPhase(currentRun.erasurePhase){ + // println(""+(clazz, iface, clazz.typeParams, iface.typeParams, imember, clazz.thisType.baseType(iface), clazz.thisType.baseType(iface).memberInfo(imember), imember.info substSym(iface.typeParams, clazz.typeParams) )) + // } + // Console.println("mixin member "+member+":"+member.tpe+member.locationString+" "+imember+" "+imember.overridingSymbol(clazz)+" to "+clazz+" with scope "+clazz.info.decls)//DEBUG if (imember.overridingSymbol(clazz) == NoSymbol && clazz.info.findMember(member.name, 0, lateDEFERRED, false).alternatives.contains(imember)) { + val newSym = atPhase(currentRun.erasurePhase){ + val res = imember.cloneSymbol(clazz) + // since we used the member (imember) from the interface that represents the trait that's being mixed in, + // have to instantiate the interface type params (that may occur in imember's info) as they are seen from the class + // we can't use the member that we get from the implementation class, as it's a clone that was made after erasure, + // and thus it does not know its info at the beginning of erasure anymore + // optimize: no need if iface has no typeparams + if(iface.typeParams nonEmpty) res.setInfo(clazz.thisType.baseType(iface).memberInfo(imember)) + res + } // clone before erasure got rid of type info we'll need to generate a javaSig + // now we'll have the type info at (the beginning of) erasure in our history, + newSym.updateInfo(imember.info.cloneInfo(newSym)) // and now newSym has the info that's been transformed to fit this period (no need for asSeenFrom as phase.erasedTypes) val member1 = addMember( clazz, - member.cloneSymbol(clazz) setPos clazz.pos resetFlag (DEFERRED | lateDEFERRED)) + newSym setPos clazz.pos resetFlag (DEFERRED | lateDEFERRED)) member1.asInstanceOf[TermSymbol] setAlias member; } } -- cgit v1.2.3