diff options
-rw-r--r-- | src/dotty/tools/dotc/core/TypeErasure.scala | 13 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ClassOf.scala | 39 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/Erasure.scala | 6 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/ExtensionMethods.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TypeTestsCasts.scala | 2 |
5 files changed, 34 insertions, 28 deletions
diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala index 92e32d4b1..abe5418d4 100644 --- a/src/dotty/tools/dotc/core/TypeErasure.scala +++ b/src/dotty/tools/dotc/core/TypeErasure.scala @@ -110,7 +110,14 @@ object TypeErasure { private def erasureCtx(implicit ctx: Context) = if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase).addMode(Mode.FutureDefsOK) else ctx - def erasure(tp: Type, semiEraseVCs: Boolean = true)(implicit ctx: Context): Type = + /** The standard erasure of a Scala type. + * + * @param tp The type to erase. + * @param semiEraseVCs If true, value classes are semi-erased to ErasedValueType + * (they will be fully erased in [[ElimErasedValueType]]). + * If false, they are erased like normal classes. + */ + def erasure(tp: Type, semiEraseVCs: Boolean = false)(implicit ctx: Context): Type = erasureFn(isJava = false, semiEraseVCs, isConstructor = false, wildcardOK = false)(tp)(erasureCtx) def sigName(tp: Type, isJava: Boolean)(implicit ctx: Context): TypeName = { @@ -134,7 +141,7 @@ object TypeErasure { case tp: ThisType => tp case tp => - erasure(tp) + erasure(tp, semiEraseVCs = true) } /** The symbol's erased info. This is the type's erasure, except for the following symbols: @@ -389,7 +396,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type = { val cls = tref.symbol.asClass val underlying = underlyingOfValueClass(cls) - ErasedValueType(cls, erasure(underlying)) + ErasedValueType(cls, erasure(underlying, semiEraseVCs = true)) } diff --git a/src/dotty/tools/dotc/transform/ClassOf.scala b/src/dotty/tools/dotc/transform/ClassOf.scala index 948e0117b..4d6bf2dc9 100644 --- a/src/dotty/tools/dotc/transform/ClassOf.scala +++ b/src/dotty/tools/dotc/transform/ClassOf.scala @@ -9,10 +9,12 @@ import core.Symbols.TermSymbol import core.TypeErasure import TreeTransforms.{MiniPhaseTransform, TransformerInfo, TreeTransform} -/** Performs rewritings as follows for `classOf` calls: - * classOf[CustomValueClass] ~> CustomValueClass class - * classOf[ValueClass] ~> ValueClass class, where ValueClass is Boolean, Byte, Short, etc. - * classOf[AnyOtherClass] ~> erasure(AnyOtherClass) +/** Rewrite `classOf` calls as follow: + * + * For every primitive class C whose boxed class is called B: + * classOf[C] -> B.TYPE + * For every non-primitive class D: + * classOf[D] -> Literal(Constant(erasure(D))) */ class ClassOf extends MiniPhaseTransform { import tpd._ @@ -32,22 +34,19 @@ class ClassOf extends MiniPhaseTransform { val tp = tree.args.head.tpe val defn = ctx.definitions val claz = tp.classSymbol - if (ValueClasses.isDerivedValueClass(claz)) { - Literal(Constant(ref(claz).tpe)) - } else { - def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe) - claz match { - case defn.BooleanClass => TYPE(defn.BoxedBooleanModule) - case defn.ByteClass => TYPE(defn.BoxedByteModule) - case defn.ShortClass => TYPE(defn.BoxedShortModule) - case defn.CharClass => TYPE(defn.BoxedCharModule) - case defn.IntClass => TYPE(defn.BoxedIntModule) - case defn.LongClass => TYPE(defn.BoxedLongModule) - case defn.FloatClass => TYPE(defn.BoxedFloatModule) - case defn.DoubleClass => TYPE(defn.BoxedDoubleModule) - case defn.UnitClass => TYPE(defn.BoxedVoidModule) - case _ => Literal(Constant(TypeErasure.erasure(tp))) - } + + def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe) + claz match { + case defn.BooleanClass => TYPE(defn.BoxedBooleanModule) + case defn.ByteClass => TYPE(defn.BoxedByteModule) + case defn.ShortClass => TYPE(defn.BoxedShortModule) + case defn.CharClass => TYPE(defn.BoxedCharModule) + case defn.IntClass => TYPE(defn.BoxedIntModule) + case defn.LongClass => TYPE(defn.BoxedLongModule) + case defn.FloatClass => TYPE(defn.BoxedFloatModule) + case defn.DoubleClass => TYPE(defn.BoxedDoubleModule) + case defn.UnitClass => TYPE(defn.BoxedVoidModule) + case _ => Literal(Constant(TypeErasure.erasure(tp))) } } else tree } diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala index 962297517..ad261c16b 100644 --- a/src/dotty/tools/dotc/transform/Erasure.scala +++ b/src/dotty/tools/dotc/transform/Erasure.scala @@ -268,7 +268,7 @@ object Erasure extends TypeTestsCasts{ class Typer extends typer.ReTyper with NoChecking { import Boxing._ - def erasedType(tree: untpd.Tree, semiEraseVCs: Boolean = true)(implicit ctx: Context): Type = + def erasedType(tree: untpd.Tree, semiEraseVCs: Boolean)(implicit ctx: Context): Type = tree.typeOpt match { case tp: TermRef if tree.isTerm => erasedRef(tp) case tp => erasure(tp, semiEraseVCs) @@ -296,7 +296,7 @@ object Erasure extends TypeTestsCasts{ /** This override is only needed to semi-erase type ascriptions */ override def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = { val Typed(expr, tpt) = tree - val tpt1 = promote(tpt) + val tpt1 = promote(tpt, semiEraseVCs = true) val expr1 = typed(expr, tpt1.tpe) assignType(untpd.cpy.Typed(tree)(expr1, tpt1), tpt1) } @@ -460,7 +460,7 @@ object Erasure extends TypeTestsCasts{ if (pt.isValueType) pt else { if (tree.typeOpt.derivesFrom(ctx.definitions.UnitClass)) tree.typeOpt - else erasure(tree.typeOpt) + else erasure(tree.typeOpt, semiEraseVCs = true) } } diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala index 36a1b9b30..503016d8b 100644 --- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala +++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala @@ -65,7 +65,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful } } - val underlying = erasure(underlyingOfValueClass(valueClass)) + val underlying = erasure(underlyingOfValueClass(valueClass), semiEraseVCs = true) val evt = ErasedValueType(valueClass, underlying) val u2evtSym = ctx.newSymbol(moduleSym, nme.U2EVT, Synthetic | Method, MethodType(List(nme.x_0), List(underlying), evt)) diff --git a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala index 1be0ef39b..4ce64da33 100644 --- a/src/dotty/tools/dotc/transform/TypeTestsCasts.scala +++ b/src/dotty/tools/dotc/transform/TypeTestsCasts.scala @@ -96,7 +96,7 @@ trait TypeTestsCasts { } else derivedTree(qual, defn.Any_asInstanceOf, argType) } - def erasedArg = erasure(tree.args.head.tpe, semiEraseVCs = false) + def erasedArg = erasure(tree.args.head.tpe) if (sym eq defn.Any_isInstanceOf) transformIsInstanceOf(qual, erasedArg) else if (sym eq defn.Any_asInstanceOf) |