diff options
author | Martin Odersky <odersky@gmail.com> | 2012-02-15 12:04:36 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2012-02-15 12:04:36 +0100 |
commit | cd6426a8c501eda2105196fc5a254d8f0dd77633 (patch) | |
tree | 19f5640aa4aacc3ea34c48ae4882f6170258b93c /src/compiler/scala/tools | |
parent | ea96b48d9274e90b64b66e51507460c004c01643 (diff) | |
download | scala-cd6426a8c501eda2105196fc5a254d8f0dd77633.tar.gz scala-cd6426a8c501eda2105196fc5a254d8f0dd77633.tar.bz2 scala-cd6426a8c501eda2105196fc5a254d8f0dd77633.zip |
Changed array erasure scheme to never unbox elements of inline classes.
Diffstat (limited to 'src/compiler/scala/tools')
4 files changed, 20 insertions, 24 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index b5232fff09..cc38979487 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -154,7 +154,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if (settings.Ygenjavap.isDefault) { if(settings.Ydumpclasses.isDefault) new ClassBytecodeWriter { } - else + else new ClassBytecodeWriter with DumpBytecodeWriter { } } else new ClassBytecodeWriter with JavapBytecodeWriter { } @@ -209,7 +209,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with val BeanInfoSkipAttr = definitions.getRequiredClass("scala.beans.BeanInfoSkip") val BeanDisplayNameAttr = definitions.getRequiredClass("scala.beans.BeanDisplayName") val BeanDescriptionAttr = definitions.getRequiredClass("scala.beans.BeanDescription") - + final val ExcludedForwarderFlags = { import Flags._ ( CASE | SPECIALIZED | LIFTED | PROTECTED | STATIC | BridgeAndPrivateFlags ) @@ -702,7 +702,7 @@ abstract class GenJVM extends SubComponent with GenJVMUtil with GenAndroid with if ((settings.check.value contains "genjvm")) { val normalizedTpe = atPhase(currentRun.erasurePhase)(erasure.prepareSigMap(memberTpe)) val bytecodeTpe = owner.thisType.memberInfo(sym) - if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym, normalizedTpe) =:= bytecodeTpe)) { + if (!sym.isType && !sym.isConstructor && !(erasure.erasure(sym)(normalizedTpe) =:= bytecodeTpe)) { clasz.cunit.warning(sym.pos, """|compiler bug: created generic signature for %s in %s that does not conform to its erasure |signature: %s diff --git a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala index 531a475bc6..cab440ef52 100644 --- a/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala +++ b/src/compiler/scala/tools/nsc/transform/AddInterfaces.scala @@ -11,7 +11,7 @@ import Flags._ import scala.collection.{ mutable, immutable } import collection.mutable.ListBuffer -abstract class AddInterfaces extends InfoTransform { +abstract class AddInterfaces extends InfoTransform { self: Erasure => import global._ // the global environment import definitions._ // standard classes and methods @@ -21,14 +21,6 @@ abstract class AddInterfaces extends InfoTransform { */ override def phaseNewFlags: Long = lateDEFERRED | lateINTERFACE - /** Type reference after erasure; defined in Erasure. - */ - def erasedTypeRef(sym: Symbol): Type - - /** Erasure calculation; defined in Erasure. - */ - def erasure(sym: Symbol, tpe: Type): Type - /** A lazily constructed map that associates every non-interface trait with * its implementation class. */ @@ -175,14 +167,14 @@ abstract class AddInterfaces extends InfoTransform { /** If `tp` refers to a non-interface trait, return a * reference to its implementation class. Otherwise return `tp`. */ - def mixinToImplClass(tp: Type): Type = erasure(sym, + def mixinToImplClass(tp: Type): Type = erasure(sym) { tp match { //@MATN: no normalize needed (comes after erasure) case TypeRef(pre, sym, _) if sym.needsImplClass => typeRef(pre, implClass(sym), Nil) case _ => tp } - ) + } def implType(tp: Type): Type = tp match { case ClassInfoType(parents, decls, _) => assert(phase == implClassPhase, tp) diff --git a/src/compiler/scala/tools/nsc/transform/Erasure.scala b/src/compiler/scala/tools/nsc/transform/Erasure.scala index 5e481f570d..306e00e38d 100644 --- a/src/compiler/scala/tools/nsc/transform/Erasure.scala +++ b/src/compiler/scala/tools/nsc/transform/Erasure.scala @@ -290,7 +290,7 @@ abstract class Erasure extends AddInterfaces ) ) } - else jsig(erasure(sym0, tp), existentiallyBound, toplevel, primitiveOK) + else jsig(erasure(sym0)(tp), existentiallyBound, toplevel, primitiveOK) case PolyType(tparams, restpe) => assert(tparams.nonEmpty) val poly = if (toplevel) polyParamSig(tparams) else "" @@ -310,7 +310,7 @@ abstract class Erasure extends AddInterfaces println("something's wrong: "+sym0+":"+sym0.tpe+" has a bounded wildcard type") jsig(bounds.hi, existentiallyBound, toplevel, primitiveOK) case _ => - val etp = erasure(sym0, tp) + val etp = erasure(sym0)(tp) if (etp eq tp) throw new UnknownSig else jsig(etp) } @@ -793,7 +793,7 @@ abstract class Erasure extends AddInterfaces val other = opc.overridden //println("bridge? " + member + ":" + member.tpe + member.locationString + " to " + other + ":" + other.tpe + other.locationString)//DEBUG if (atPhase(currentRun.explicitouterPhase)(!member.isDeferred)) { - val otpe = erasure(owner, other.tpe) + val otpe = erasure(owner)(other.tpe) val bridgeNeeded = atPhase(phase.next) ( !(other.tpe =:= member.tpe) && !(deconstMap(other.tpe) =:= deconstMap(member.tpe)) && @@ -838,7 +838,7 @@ abstract class Erasure extends AddInterfaces IF (typeTest) THEN bridgingCall ELSE REF(NoneModule) } else bridgingCall }); - debuglog("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(owner, member.tpe) + member.locationString + " =\n " + bridgeDef); + debuglog("generating bridge from " + other + "(" + Flags.flagsToString(bridge.flags) + ")" + ":" + otpe + other.locationString + " to " + member + ":" + erasure(owner)(member.tpe) + member.locationString + " =\n " + bridgeDef); bridgeDef } } :: bridges @@ -910,7 +910,7 @@ abstract class Erasure extends AddInterfaces gen.mkMethodCall( qual1(), fun.symbol, - List(specialErasure(fun.symbol, arg.tpe)), + List(specialErasure(fun.symbol)(arg.tpe)), Nil ), isArrayTest(qual1()) @@ -943,7 +943,7 @@ abstract class Erasure extends AddInterfaces // need to do the cast in adaptMember treeCopy.Apply( tree, - SelectFromArray(qual, name, erasure(tree.symbol, qual.tpe)).copyAttrs(fn), + SelectFromArray(qual, name, erasure(tree.symbol)(qual.tpe)).copyAttrs(fn), args) } case Apply(fn @ Select(qual, _), Nil) if interceptedMethods(fn.symbol) => @@ -1064,7 +1064,7 @@ abstract class Erasure extends AddInterfaces && ct.typeValue.typeSymbol != definitions.UnitClass => val erased = ct.typeValue match { case TypeRef(pre, clazz, args) if clazz.isInlineClass => scalaErasure.eraseNormalClassRef(pre, clazz) - case tpe => specialErasure(NoSymbol, tpe) + case tpe => specialScalaErasure(tpe) } treeCopy.Literal(tree, Constant(erased)) @@ -1084,10 +1084,13 @@ abstract class Erasure extends AddInterfaces val tree1 = preErase(tree) tree1 match { case EmptyTree | TypeTree() => - tree1 setType specialErasure(NoSymbol, tree1.tpe) + tree1 setType specialScalaErasure(tree1.tpe) + case ArrayValue(elemtpt, trees) => + treeCopy.ArrayValue( + tree1, elemtpt setType specialScalaErasure.applyInArray(elemtpt.tpe), trees map transform) setType null case DefDef(_, _, _, _, tpt, _) => val result = super.transform(tree1) setType null - tpt.tpe = specialErasure(tree1.symbol, tree1.symbol.tpe).resultType + tpt.tpe = specialErasure(tree1.symbol)(tree1.symbol.tpe).resultType result case _ => super.transform(tree1) setType null diff --git a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala index 064a3dd229..91ea7c7cd9 100644 --- a/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala +++ b/src/compiler/scala/tools/nsc/typechecker/RefChecks.scala @@ -515,7 +515,8 @@ abstract class RefChecks extends InfoTransform with reflect.internal.transform.R !other.isDeferred && other.isJavaDefined && { // #3622: erasure operates on uncurried types -- // note on passing sym in both cases: only sym.isType is relevant for uncurry.transformInfo - def uncurryAndErase(tp: Type) = erasure.erasure(sym, uncurry.transformInfo(sym, tp)) + // !!! erasure.erasure(sym, uncurry.transformInfo(sym, tp)) gives erreneous of inaccessible type - check whether that's still the case! + def uncurryAndErase(tp: Type) = erasure.erasure(sym)(uncurry.transformInfo(sym, tp)) val tp1 = uncurryAndErase(clazz.thisType.memberType(sym)) val tp2 = uncurryAndErase(clazz.thisType.memberType(other)) atPhase(currentRun.erasurePhase.next)(tp1 matches tp2) |