aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/core/TypeErasure.scala13
-rw-r--r--src/dotty/tools/dotc/transform/ClassOf.scala39
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala6
-rw-r--r--src/dotty/tools/dotc/transform/ExtensionMethods.scala2
-rw-r--r--src/dotty/tools/dotc/transform/TypeTestsCasts.scala2
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)