@@ -112,9 +112,10 @@ object TypeErasure {
112
112
/** The standard erasure of a Scala type. Value classes are erased as normal classes.
113
113
*
114
114
* @param tp The type to erase.
115
- */
116
- def erasure (tp : Type )(implicit ctx : Context ): Type =
117
- erasureFn(isJava = false , semiEraseVCs = false , isConstructor = false , wildcardOK = false )(tp)(erasureCtx)
115
+ * @param eraseOrType Whether erase OrType to its lowest uppper bound
116
+ */
117
+ def erasure (tp : Type , eraseOrType : Boolean = true )(implicit ctx : Context ): Type =
118
+ erasureFn(isJava = false , semiEraseVCs = false , isConstructor = false , wildcardOK = false )(tp, eraseOrType)(erasureCtx)
118
119
119
120
/** The value class erasure of a Scala type, where value classes are semi-erased to
120
121
* ErasedValueType (they will be fully erased in [[ElimErasedValueType ]]).
@@ -337,34 +338,34 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
337
338
* - For NoType or NoPrefix, the type itself.
338
339
* - For any other type, exception.
339
340
*/
340
- private def apply (tp : Type )(implicit ctx : Context ): Type = tp match {
341
+ private def apply (tp : Type , eraseOrType : Boolean = true )(implicit ctx : Context ): Type = tp match {
341
342
case _ : ErasedValueType =>
342
343
tp
343
344
case tp : TypeRef =>
344
345
val sym = tp.symbol
345
- if (! sym.isClass) this (tp.info)
346
+ if (! sym.isClass) this (tp.info, eraseOrType )
346
347
else if (semiEraseVCs && isDerivedValueClass(sym)) eraseDerivedValueClassRef(tp)
347
348
else if (sym == defn.ArrayClass ) apply(tp.appliedTo(TypeBounds .empty)) // i966 shows that we can hit a raw Array type.
348
349
else eraseNormalClassRef(tp)
349
350
case tp : RefinedType =>
350
351
val parent = tp.parent
351
352
if (parent isRef defn.ArrayClass ) eraseArray(tp)
352
- else this (parent)
353
+ else this (parent, eraseOrType )
353
354
case _ : TermRef | _ : ThisType =>
354
355
this (tp.widen)
355
356
case SuperType (thistpe, supertpe) =>
356
- SuperType (this (thistpe), this (supertpe))
357
+ SuperType (this (thistpe, eraseOrType ), this (supertpe, eraseOrType ))
357
358
case ExprType (rt) =>
358
359
defn.FunctionClass (0 ).typeRef
359
360
case tp : TypeProxy =>
360
- this (tp.underlying)
361
+ this (tp.underlying, eraseOrType )
361
362
case AndType (tp1, tp2) =>
362
- erasedGlb(this (tp1), this (tp2), isJava)
363
+ erasedGlb(this (tp1, eraseOrType ), this (tp2, eraseOrType ), isJava)
363
364
case OrType (tp1, tp2) =>
364
- ctx.typeComparer.orType(this (tp1), this (tp2), erased = true )
365
+ ctx.typeComparer.orType(this (tp1, eraseOrType ), this (tp2, eraseOrType ), erased = eraseOrType )
365
366
case tp : MethodType =>
366
367
def paramErasure (tpToErase : Type ) =
367
- erasureFn(tp.isJava, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
368
+ erasureFn(tp.isJava, semiEraseVCs, isConstructor, wildcardOK)(tpToErase, eraseOrType )
368
369
val formals = tp.paramTypes.mapConserve(paramErasure)
369
370
eraseResult(tp.resultType) match {
370
371
case rt : MethodType =>
@@ -373,14 +374,14 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
373
374
tp.derivedMethodType(tp.paramNames, formals, rt)
374
375
}
375
376
case tp : PolyType =>
376
- this (tp.resultType) match {
377
+ this (tp.resultType, eraseOrType ) match {
377
378
case rt : MethodType => rt
378
379
case rt => MethodType (Nil , Nil , rt)
379
380
}
380
381
case tp @ ClassInfo (pre, cls, classParents, decls, _) =>
381
382
if (cls is Package ) tp
382
383
else {
383
- def eraseTypeRef (p : TypeRef ) = this (p).asInstanceOf [TypeRef ]
384
+ def eraseTypeRef (p : TypeRef ) = this (p, eraseOrType ).asInstanceOf [TypeRef ]
384
385
val parents : List [TypeRef ] =
385
386
if ((cls eq defn.ObjectClass ) || cls.isPrimitiveValueClass) Nil
386
387
else classParents.mapConserve(eraseTypeRef) match {
0 commit comments