diff options
author | Martin Odersky <odersky@gmail.com> | 2015-11-07 12:58:33 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-11-09 15:45:37 +0100 |
commit | 8978ae6dfabae562fb5dcf4c7f66983d4d865892 (patch) | |
tree | 999cd971a10b46ec307c550a5af464329495c6c9 /src/dotty/tools/dotc/transform/CapturedVars.scala | |
parent | f2b61ce055fccf96e305ef43fca8abef8a912f33 (diff) | |
download | dotty-8978ae6dfabae562fb5dcf4c7f66983d4d865892.tar.gz dotty-8978ae6dfabae562fb5dcf4c7f66983d4d865892.tar.bz2 dotty-8978ae6dfabae562fb5dcf4c7f66983d4d865892.zip |
First versions of Definitions based on TypeRefs not Symbols.
Symbols are not stable between runs, so if some symbol referred
to from Definitions gets recompiled, there are then two Symbols
that are both visible, one referenced from Definitions, the other
the one that got compiled.
Thos led to a crash when e.g. compiling scala.Short, because the
newly compiled symbol was not recognized as a primitive value
class.
The present commit tries to make systematic changes without regard
to simplicity or aesthetics. This will be polished in future commits.
// ### comments signal areas that need further attention.
Diffstat (limited to 'src/dotty/tools/dotc/transform/CapturedVars.scala')
-rw-r--r-- | src/dotty/tools/dotc/transform/CapturedVars.scala | 15 |
1 files changed, 10 insertions, 5 deletions
diff --git a/src/dotty/tools/dotc/transform/CapturedVars.scala b/src/dotty/tools/dotc/transform/CapturedVars.scala index 0f1a60282..bd0c7f203 100644 --- a/src/dotty/tools/dotc/transform/CapturedVars.scala +++ b/src/dotty/tools/dotc/transform/CapturedVars.scala @@ -54,16 +54,19 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo /** The {Volatile|}{Int|Double|...|Object}Ref class corresponding to the class `cls`, * depending on whether the reference should be @volatile */ - def refCls(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): Symbol = { - val refMap = if (isVolatile) defn.volatileRefClass else defn.refClass - refMap.getOrElse(cls, refMap(defn.ObjectClass)) + def refTypeRef(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): TypeRef = { + val refMap = if (isVolatile) defn.volatileRefTypeRef else defn.refTypeRef + if (cls.isClass) { + refMap.getOrElse(cls.typeRef, refMap(defn.ObjectClass.typeRef)) + } + else refMap(defn.ObjectClass.typeRef) } override def prepareForValDef(vdef: ValDef)(implicit ctx: Context) = { val sym = vdef.symbol if (captured contains sym) { val newd = sym.denot(ctx.withPhase(thisTransform)).copySymDenotation( - info = refCls(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)).typeRef, + info = refTypeRef(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)), initFlags = sym.flags &~ Mutable) newd.removeAnnotation(defn.VolatileAnnot) newd.installAfter(thisTransform) @@ -109,11 +112,13 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo * drop the cast. */ override def transformAssign(tree: Assign)(implicit ctx: Context, info: TransformerInfo): Tree = { + def isBoxedRefType(sym: Symbol) = + sym.isClass && defn.boxedRefTypeRefs.exists(_.symbol == sym) def recur(lhs: Tree): Tree = lhs match { case TypeApply(Select(qual, nme.asInstanceOf_), _) => val Select(_, nme.elem) = qual recur(qual) - case Select(_, nme.elem) if defn.boxedRefClasses.contains(lhs.symbol.maybeOwner) => + case Select(_, nme.elem) if isBoxedRefType(lhs.symbol.maybeOwner) => val tempDef = transformFollowing(SyntheticValDef(ctx.freshName("ev$").toTermName, tree.rhs)) transformFollowing(Block(tempDef :: Nil, cpy.Assign(tree)(lhs, ref(tempDef.symbol)))) case _ => |