Skip to content

Commit 6dbb991

Browse files
committed
Merge pull request #680 from smarter/simplify/erasure
TypeErasure#erasure: do not semi-erase types by default
2 parents 67aef97 + d4d2ada commit 6dbb991

File tree

5 files changed

+34
-28
lines changed

5 files changed

+34
-28
lines changed

src/dotty/tools/dotc/core/TypeErasure.scala

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,14 @@ object TypeErasure {
110110
private def erasureCtx(implicit ctx: Context) =
111111
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase).addMode(Mode.FutureDefsOK) else ctx
112112

113-
def erasure(tp: Type, semiEraseVCs: Boolean = true)(implicit ctx: Context): Type =
113+
/** The standard erasure of a Scala type.
114+
*
115+
* @param tp The type to erase.
116+
* @param semiEraseVCs If true, value classes are semi-erased to ErasedValueType
117+
* (they will be fully erased in [[ElimErasedValueType]]).
118+
* If false, they are erased like normal classes.
119+
*/
120+
def erasure(tp: Type, semiEraseVCs: Boolean = false)(implicit ctx: Context): Type =
114121
erasureFn(isJava = false, semiEraseVCs, isConstructor = false, wildcardOK = false)(tp)(erasureCtx)
115122

116123
def sigName(tp: Type, isJava: Boolean)(implicit ctx: Context): TypeName = {
@@ -134,7 +141,7 @@ object TypeErasure {
134141
case tp: ThisType =>
135142
tp
136143
case tp =>
137-
erasure(tp)
144+
erasure(tp, semiEraseVCs = true)
138145
}
139146

140147
/** 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
389396
private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
390397
val cls = tref.symbol.asClass
391398
val underlying = underlyingOfValueClass(cls)
392-
ErasedValueType(cls, erasure(underlying))
399+
ErasedValueType(cls, erasure(underlying, semiEraseVCs = true))
393400
}
394401

395402

src/dotty/tools/dotc/transform/ClassOf.scala

Lines changed: 19 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,12 @@ import core.Symbols.TermSymbol
99
import core.TypeErasure
1010
import TreeTransforms.{MiniPhaseTransform, TransformerInfo, TreeTransform}
1111

12-
/** Performs rewritings as follows for `classOf` calls:
13-
* classOf[CustomValueClass] ~> CustomValueClass class
14-
* classOf[ValueClass] ~> ValueClass class, where ValueClass is Boolean, Byte, Short, etc.
15-
* classOf[AnyOtherClass] ~> erasure(AnyOtherClass)
12+
/** Rewrite `classOf` calls as follow:
13+
*
14+
* For every primitive class C whose boxed class is called B:
15+
* classOf[C] -> B.TYPE
16+
* For every non-primitive class D:
17+
* classOf[D] -> Literal(Constant(erasure(D)))
1618
*/
1719
class ClassOf extends MiniPhaseTransform {
1820
import tpd._
@@ -32,22 +34,19 @@ class ClassOf extends MiniPhaseTransform {
3234
val tp = tree.args.head.tpe
3335
val defn = ctx.definitions
3436
val claz = tp.classSymbol
35-
if (ValueClasses.isDerivedValueClass(claz)) {
36-
Literal(Constant(ref(claz).tpe))
37-
} else {
38-
def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe)
39-
claz match {
40-
case defn.BooleanClass => TYPE(defn.BoxedBooleanModule)
41-
case defn.ByteClass => TYPE(defn.BoxedByteModule)
42-
case defn.ShortClass => TYPE(defn.BoxedShortModule)
43-
case defn.CharClass => TYPE(defn.BoxedCharModule)
44-
case defn.IntClass => TYPE(defn.BoxedIntModule)
45-
case defn.LongClass => TYPE(defn.BoxedLongModule)
46-
case defn.FloatClass => TYPE(defn.BoxedFloatModule)
47-
case defn.DoubleClass => TYPE(defn.BoxedDoubleModule)
48-
case defn.UnitClass => TYPE(defn.BoxedVoidModule)
49-
case _ => Literal(Constant(TypeErasure.erasure(tp)))
50-
}
37+
38+
def TYPE(module: TermSymbol) = ref(module).select(nme.TYPE_).ensureConforms(tree.tpe)
39+
claz match {
40+
case defn.BooleanClass => TYPE(defn.BoxedBooleanModule)
41+
case defn.ByteClass => TYPE(defn.BoxedByteModule)
42+
case defn.ShortClass => TYPE(defn.BoxedShortModule)
43+
case defn.CharClass => TYPE(defn.BoxedCharModule)
44+
case defn.IntClass => TYPE(defn.BoxedIntModule)
45+
case defn.LongClass => TYPE(defn.BoxedLongModule)
46+
case defn.FloatClass => TYPE(defn.BoxedFloatModule)
47+
case defn.DoubleClass => TYPE(defn.BoxedDoubleModule)
48+
case defn.UnitClass => TYPE(defn.BoxedVoidModule)
49+
case _ => Literal(Constant(TypeErasure.erasure(tp)))
5150
}
5251
} else tree
5352
}

src/dotty/tools/dotc/transform/Erasure.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -268,7 +268,7 @@ object Erasure extends TypeTestsCasts{
268268
class Typer extends typer.ReTyper with NoChecking {
269269
import Boxing._
270270

271-
def erasedType(tree: untpd.Tree, semiEraseVCs: Boolean = true)(implicit ctx: Context): Type =
271+
def erasedType(tree: untpd.Tree, semiEraseVCs: Boolean)(implicit ctx: Context): Type =
272272
tree.typeOpt match {
273273
case tp: TermRef if tree.isTerm => erasedRef(tp)
274274
case tp => erasure(tp, semiEraseVCs)
@@ -296,7 +296,7 @@ object Erasure extends TypeTestsCasts{
296296
/** This override is only needed to semi-erase type ascriptions */
297297
override def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = {
298298
val Typed(expr, tpt) = tree
299-
val tpt1 = promote(tpt)
299+
val tpt1 = promote(tpt, semiEraseVCs = true)
300300
val expr1 = typed(expr, tpt1.tpe)
301301
assignType(untpd.cpy.Typed(tree)(expr1, tpt1), tpt1)
302302
}
@@ -460,7 +460,7 @@ object Erasure extends TypeTestsCasts{
460460
if (pt.isValueType) pt else {
461461
if (tree.typeOpt.derivesFrom(ctx.definitions.UnitClass))
462462
tree.typeOpt
463-
else erasure(tree.typeOpt)
463+
else erasure(tree.typeOpt, semiEraseVCs = true)
464464
}
465465
}
466466

src/dotty/tools/dotc/transform/ExtensionMethods.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
6565
}
6666
}
6767

68-
val underlying = erasure(underlyingOfValueClass(valueClass))
68+
val underlying = erasure(underlyingOfValueClass(valueClass), semiEraseVCs = true)
6969
val evt = ErasedValueType(valueClass, underlying)
7070
val u2evtSym = ctx.newSymbol(moduleSym, nme.U2EVT, Synthetic | Method,
7171
MethodType(List(nme.x_0), List(underlying), evt))

src/dotty/tools/dotc/transform/TypeTestsCasts.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ trait TypeTestsCasts {
9696
} else
9797
derivedTree(qual, defn.Any_asInstanceOf, argType)
9898
}
99-
def erasedArg = erasure(tree.args.head.tpe, semiEraseVCs = false)
99+
def erasedArg = erasure(tree.args.head.tpe)
100100
if (sym eq defn.Any_isInstanceOf)
101101
transformIsInstanceOf(qual, erasedArg)
102102
else if (sym eq defn.Any_asInstanceOf)

0 commit comments

Comments
 (0)