aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/Definitions.scala12
-rw-r--r--src/dotty/tools/dotc/transform/CapturedVars.scala35
2 files changed, 27 insertions, 20 deletions
diff --git a/src/dotty/tools/dotc/core/Definitions.scala b/src/dotty/tools/dotc/core/Definitions.scala
index 25c635efe..24798f8e2 100644
--- a/src/dotty/tools/dotc/core/Definitions.scala
+++ b/src/dotty/tools/dotc/core/Definitions.scala
@@ -716,18 +716,6 @@ class Definitions {
vcls
}
- /** The classes for which a Ref type exists. */
- lazy val refTypeKeys: collection.Set[TypeRef] = ScalaNumericValueTypes + BooleanTypeRef + ObjectClass.typeRef
-
- lazy val refTypeRef: Map[TypeRef, TypeRef] =
- refTypeKeys.map(rc => rc -> ctx.requiredClassRef(s"scala.runtime.${rc.name}Ref")).toMap
-
- lazy val volatileRefTypeRef: Map[TypeRef, TypeRef] =
- refTypeKeys.map(rc => rc -> ctx.requiredClassRef(s"scala.runtime.Volatile${rc.name}Ref")).toMap
-
- lazy val boxedRefTypeRefs: collection.Set[TypeRef] =
- refTypeKeys.flatMap(k => Set(refTypeRef(k), volatileRefTypeRef(k)))
-
def wrapArrayMethodName(elemtp: Type): TermName = {
val cls = elemtp.classSymbol
if (cls.isPrimitiveValueClass) nme.wrapXArray(cls.name)
diff --git a/src/dotty/tools/dotc/transform/CapturedVars.scala b/src/dotty/tools/dotc/transform/CapturedVars.scala
index bd0c7f203..9d6acb4b9 100644
--- a/src/dotty/tools/dotc/transform/CapturedVars.scala
+++ b/src/dotty/tools/dotc/transform/CapturedVars.scala
@@ -24,9 +24,30 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo
val phaseName: String = "capturedVars"
val treeTransform = new Transform(Set())
+ private class RefInfo(implicit ctx: Context) {
+ /** The classes for which a Ref type exists. */
+ val refClassKeys: collection.Set[Symbol] =
+ defn.ScalaNumericValueClasses + defn.BooleanClass + defn.ObjectClass
+
+ val refClass: Map[Symbol, Symbol] =
+ refClassKeys.map(rc => rc -> ctx.requiredClass(s"scala.runtime.${rc.name}Ref")).toMap
+
+ val volatileRefClass: Map[Symbol, Symbol] =
+ refClassKeys.map(rc => rc -> ctx.requiredClass(s"scala.runtime.Volatile${rc.name}Ref")).toMap
+
+ val boxedRefClasses: collection.Set[Symbol] =
+ refClassKeys.flatMap(k => Set(refClass(k), volatileRefClass(k)))
+ }
+
class Transform(captured: collection.Set[Symbol]) extends TreeTransform {
def phase = thisTransform
+ private var myRefInfo: RefInfo = null
+ private def refInfo(implicit ctx: Context) = {
+ if (myRefInfo == null) myRefInfo = new RefInfo()
+ myRefInfo
+ }
+
private class CollectCaptured(implicit ctx: Context) extends EnclosingMethodTraverser {
private val captured = mutable.HashSet[Symbol]()
def traverse(enclMeth: Symbol, tree: Tree)(implicit ctx: Context) = tree match {
@@ -54,19 +75,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 refTypeRef(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): TypeRef = {
- val refMap = if (isVolatile) defn.volatileRefTypeRef else defn.refTypeRef
+ def refClass(cls: Symbol, isVolatile: Boolean)(implicit ctx: Context): Symbol = {
+ val refMap = if (isVolatile) refInfo.volatileRefClass else refInfo.refClass
if (cls.isClass) {
- refMap.getOrElse(cls.typeRef, refMap(defn.ObjectClass.typeRef))
+ refMap.getOrElse(cls, refMap(defn.ObjectClass))
}
- else refMap(defn.ObjectClass.typeRef)
+ else refMap(defn.ObjectClass)
}
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 = refTypeRef(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)),
+ info = refClass(sym.info.classSymbol, sym.hasAnnotation(defn.VolatileAnnot)).typeRef,
initFlags = sym.flags &~ Mutable)
newd.removeAnnotation(defn.VolatileAnnot)
newd.installAfter(thisTransform)
@@ -112,13 +133,11 @@ 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 isBoxedRefType(lhs.symbol.maybeOwner) =>
+ case Select(_, nme.elem) if refInfo.boxedRefClasses.contains(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 _ =>