@@ -31,7 +31,7 @@ object TypeErasure {
3131 */
3232 def isErasedType (tp : Type )(implicit ctx : Context ): Boolean = tp match {
3333 case tp : TypeRef =>
34- tp.symbol.isClass
34+ tp.symbol.isClass && tp.symbol != defn. AnyClass
3535 case _ : TermRef =>
3636 true
3737 case JavaArrayType (elem) =>
@@ -87,15 +87,36 @@ object TypeErasure {
8787 private val javaSigFn = erasureFn(isJava = true , isSemi = false , isConstructor = false , wildcardOK = true )
8888 private val semiErasureFn = erasureFn(isJava = false , isSemi = true , isConstructor = false , wildcardOK = false )
8989
90- def erasure (tp : Type )(implicit ctx : Context ): Type = scalaErasureFn(tp)
91- def semiErasure (tp : Type )(implicit ctx : Context ): Type = semiErasureFn(tp)
90+ /** The current context with a phase no later than erasure */
91+ private def erasureCtx (implicit ctx : Context ) =
92+ if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase) else ctx
93+
94+ def erasure (tp : Type )(implicit ctx : Context ): Type = scalaErasureFn(tp)(erasureCtx)
95+ def semiErasure (tp : Type )(implicit ctx : Context ): Type = semiErasureFn(tp)(erasureCtx)
9296 def sigName (tp : Type , isJava : Boolean )(implicit ctx : Context ): TypeName = {
9397 val normTp =
9498 if (tp.isRepeatedParam) tp.translateParameterized(defn.RepeatedParamClass , defn.SeqClass )
9599 else tp
96- (if (isJava) javaSigFn else scalaSigFn).sigName(normTp)
100+ (if (isJava) javaSigFn else scalaSigFn).sigName(normTp)(erasureCtx)
101+ }
102+
103+ /** The erasure of a top-level reference. Differs from normal erasure in that
104+ * TermRefs are kept instead of being widened away.
105+ */
106+ def erasedRef (tp : Type )(implicit ctx : Context ): Type = tp match {
107+ case tp : TermRef =>
108+ assert(tp.symbol.exists, tp)
109+ TermRef (erasedRef(tp.prefix), tp.symbol.asTerm)
110+ case tp =>
111+ erasure(tp)
97112 }
98113
114+ /** The erasure of a function result type. Differs from normal erasure in that
115+ * Unit is kept instead of being mapped to BoxedUnit.
116+ */
117+ def eraseResult (tp : Type )(implicit ctx : Context ): Type =
118+ scalaErasureFn.eraseResult(tp)(erasureCtx)
119+
99120 /** The symbol's erased info. This is the type's erasure, except for the following symbols:
100121 *
101122 * - For $asInstanceOf : [T]T
@@ -113,8 +134,8 @@ object TypeErasure {
113134
114135 if ((sym eq defn.Any_asInstanceOf ) || (sym eq defn.Any_isInstanceOf )) eraseParamBounds(sym.info.asInstanceOf [PolyType ])
115136 else if (sym.isAbstractType) TypeAlias (WildcardType )
116- else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp))
117- else erase(tp)
137+ else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx) )
138+ else erase(tp)(erasureCtx)
118139 }
119140
120141 def isUnboundedGeneric (tp : Type )(implicit ctx : Context ) = ! (
@@ -147,7 +168,7 @@ object TypeErasure {
147168 def loop (bcs : List [ClassSymbol ], bestSoFar : ClassSymbol ): ClassSymbol = bcs match {
148169 case bc :: bcs1 =>
149170 if (cls2.derivesFrom(bc))
150- if (! bc.is(Trait )) bc
171+ if (! bc.is(Trait ) && bc != defn. AnyClass ) bc
151172 else loop(bcs1, if (bestSoFar.derivesFrom(bc)) bestSoFar else bc)
152173 else
153174 loop(bcs1, bestSoFar)
@@ -225,7 +246,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
225246 * - For NoType or NoPrefix, the type itself.
226247 * - For any other type, exception.
227248 */
228- def apply (tp : Type )(implicit ctx : Context ): Type = tp match {
249+ private def apply (tp : Type )(implicit ctx : Context ): Type = tp match {
229250 case tp : TypeRef =>
230251 val sym = tp.symbol
231252 if (! sym.isClass) this (tp.info)
@@ -236,8 +257,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
236257 if (parent isRef defn.ArrayClass ) eraseArray(tp)
237258 else this (parent)
238259 case tp : TermRef =>
239- assert(tp.symbol.exists, tp)
240- TermRef (NoPrefix , tp.symbol.asTerm)
260+ this (tp.widen)
241261 case ThisType (_) | SuperType (_, _) =>
242262 tp
243263 case ExprType (rt) =>
@@ -269,7 +289,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
269289 val parents : List [TypeRef ] =
270290 if ((cls eq defn.ObjectClass ) || cls.isPrimitiveValueClass) Nil
271291 else removeLaterObjects(classParents.mapConserve(eraseTypeRef))
272- tp.derivedClassInfo(NoPrefix , parents, decls, this (tp.selfType))
292+ val erasedDecls = decls.filteredScope(d => ! d.isType || d.isClass)
293+ tp.derivedClassInfo(NoPrefix , parents, erasedDecls, erasedRef(tp.selfType))
273294 // can't replace selftype by NoType because this would lose the sourceModule link
274295 }
275296 case NoType | NoPrefix | ErrorType | JavaArrayType (_) =>
@@ -278,7 +299,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
278299 tp
279300 }
280301
281- def eraseArray (tp : RefinedType )(implicit ctx : Context ) = {
302+ private def eraseArray (tp : RefinedType )(implicit ctx : Context ) = {
282303 val defn .ArrayType (elemtp) = tp
283304 if (elemtp derivesFrom defn.NullClass ) JavaArrayType (defn.ObjectType )
284305 else if (isUnboundedGeneric(elemtp))
@@ -327,7 +348,7 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
327348 /** The name of the type as it is used in `Signature`s.
328349 * Need to ensure correspondence with erasure!
329350 */
330- def sigName (tp : Type )(implicit ctx : Context ): TypeName = tp match {
351+ private def sigName (tp : Type )(implicit ctx : Context ): TypeName = tp match {
331352 case tp : TypeRef =>
332353 val sym = tp.symbol
333354 if (! sym.isClass) sigName(tp.info)
@@ -337,8 +358,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
337358 sigName(this (tp))
338359 case JavaArrayType (elem) =>
339360 sigName(elem) ++ " []"
340- case tp : TypeBounds =>
341- sigName(tp.hi )
361+ case tp : TermRef =>
362+ sigName(tp.widen )
342363 case ExprType (rt) =>
343364 sigName(defn.FunctionType (Nil , rt))
344365 case tp : TypeProxy =>
0 commit comments