@@ -142,29 +142,31 @@ object TypeErasure {
142
142
}
143
143
}
144
144
145
- private def erasureIdx (sourceLanguage : SourceLanguage , semiEraseVCs : Boolean , isConstructor : Boolean , wildcardOK : Boolean ) =
145
+ private def erasureIdx (sourceLanguage : SourceLanguage , semiEraseVCs : Boolean , isConstructor : Boolean , isSymbol : Boolean , wildcardOK : Boolean ) =
146
146
extension (b : Boolean ) def toInt = if b then 1 else 0
147
147
wildcardOK.toInt
148
- + (isConstructor.toInt << 1 )
149
- + (semiEraseVCs.toInt << 2 )
150
- + (sourceLanguage.ordinal << 3 )
148
+ + (isSymbol.toInt << 1 )
149
+ + (isConstructor.toInt << 2 )
150
+ + (semiEraseVCs.toInt << 3 )
151
+ + (sourceLanguage.ordinal << 4 )
151
152
152
- private val erasures = new Array [TypeErasure ](1 << (SourceLanguage .bits + 3 ))
153
+ private val erasures = new Array [TypeErasure ](1 << (SourceLanguage .bits + 4 ))
153
154
154
155
for
155
156
sourceLanguage <- SourceLanguage .values
156
157
semiEraseVCs <- List (false , true )
157
158
isConstructor <- List (false , true )
159
+ isSymbol <- List (false , true )
158
160
wildcardOK <- List (false , true )
159
161
do
160
- erasures(erasureIdx(sourceLanguage, semiEraseVCs, isConstructor, wildcardOK)) =
161
- new TypeErasure (sourceLanguage, semiEraseVCs, isConstructor, wildcardOK)
162
+ erasures(erasureIdx(sourceLanguage, semiEraseVCs, isConstructor, isSymbol, wildcardOK)) =
163
+ new TypeErasure (sourceLanguage, semiEraseVCs, isConstructor, isSymbol, wildcardOK)
162
164
163
165
/** Produces an erasure function. See the documentation of the class [[TypeErasure ]]
164
166
* for a description of each parameter.
165
167
*/
166
- private def erasureFn (sourceLanguage : SourceLanguage , semiEraseVCs : Boolean , isConstructor : Boolean , wildcardOK : Boolean ): TypeErasure =
167
- erasures(erasureIdx(sourceLanguage, semiEraseVCs, isConstructor, wildcardOK))
168
+ private def erasureFn (sourceLanguage : SourceLanguage , semiEraseVCs : Boolean , isConstructor : Boolean , isSymbol : Boolean , wildcardOK : Boolean ): TypeErasure =
169
+ erasures(erasureIdx(sourceLanguage, semiEraseVCs, isConstructor, isSymbol, wildcardOK))
168
170
169
171
/** The current context with a phase no later than erasure */
170
172
def preErasureCtx (using Context ) =
@@ -175,19 +177,19 @@ object TypeErasure {
175
177
* @param tp The type to erase.
176
178
*/
177
179
def erasure (tp : Type )(using Context ): Type =
178
- erasureFn(sourceLanguage = SourceLanguage .Scala3 , semiEraseVCs = false , isConstructor = false , wildcardOK = false )(tp)(using preErasureCtx)
180
+ erasureFn(sourceLanguage = SourceLanguage .Scala3 , semiEraseVCs = false , isConstructor = false , isSymbol = false , wildcardOK = false )(tp)(using preErasureCtx)
179
181
180
182
/** The value class erasure of a Scala type, where value classes are semi-erased to
181
183
* ErasedValueType (they will be fully erased in [[ElimErasedValueType ]]).
182
184
*
183
185
* @param tp The type to erase.
184
186
*/
185
187
def valueErasure (tp : Type )(using Context ): Type =
186
- erasureFn(sourceLanguage = SourceLanguage .Scala3 , semiEraseVCs = true , isConstructor = false , wildcardOK = false )(tp)(using preErasureCtx)
188
+ erasureFn(sourceLanguage = SourceLanguage .Scala3 , semiEraseVCs = true , isConstructor = false , isSymbol = false , wildcardOK = false )(tp)(using preErasureCtx)
187
189
188
190
/** The erasure that Scala 2 would use for this type. */
189
191
def scala2Erasure (tp : Type )(using Context ): Type =
190
- erasureFn(sourceLanguage = SourceLanguage .Scala2 , semiEraseVCs = true , isConstructor = false , wildcardOK = false )(tp)(using preErasureCtx)
192
+ erasureFn(sourceLanguage = SourceLanguage .Scala2 , semiEraseVCs = true , isConstructor = false , isSymbol = false , wildcardOK = false )(tp)(using preErasureCtx)
191
193
192
194
/** Like value class erasure, but value classes erase to their underlying type erasure */
193
195
def fullErasure (tp : Type )(using Context ): Type =
@@ -197,7 +199,7 @@ object TypeErasure {
197
199
198
200
def sigName (tp : Type , sourceLanguage : SourceLanguage )(using Context ): TypeName = {
199
201
val normTp = tp.translateFromRepeated(toArray = sourceLanguage.isJava)
200
- val erase = erasureFn(sourceLanguage, semiEraseVCs = ! sourceLanguage.isJava, isConstructor = false , wildcardOK = true )
202
+ val erase = erasureFn(sourceLanguage, semiEraseVCs = ! sourceLanguage.isJava, isConstructor = false , isSymbol = false , wildcardOK = true )
201
203
erase.sigName(normTp)(using preErasureCtx)
202
204
}
203
205
@@ -227,7 +229,7 @@ object TypeErasure {
227
229
def transformInfo (sym : Symbol , tp : Type )(using Context ): Type = {
228
230
val sourceLanguage = SourceLanguage (sym)
229
231
val semiEraseVCs = ! sourceLanguage.isJava // Java sees our value classes as regular classes.
230
- val erase = erasureFn(sourceLanguage, semiEraseVCs, sym.isConstructor, wildcardOK = false )
232
+ val erase = erasureFn(sourceLanguage, semiEraseVCs, sym.isConstructor, isSymbol = true , wildcardOK = false )
231
233
232
234
def eraseParamBounds (tp : PolyType ): Type =
233
235
tp.derivedLambdaType(
@@ -446,10 +448,11 @@ import TypeErasure._
446
448
* (they will be fully erased in [[ElimErasedValueType ]]).
447
449
* If false, they are erased like normal classes.
448
450
* @param isConstructor Argument forms part of the type of a constructor
451
+ * @param isSymbol If true, the type being erased is the info of a symbol.
449
452
* @param wildcardOK Wildcards are acceptable (true when using the erasure
450
453
* for computing a signature name).
451
454
*/
452
- class TypeErasure (sourceLanguage : SourceLanguage , semiEraseVCs : Boolean , isConstructor : Boolean , wildcardOK : Boolean ) {
455
+ class TypeErasure (sourceLanguage : SourceLanguage , semiEraseVCs : Boolean , isConstructor : Boolean , isSymbol : Boolean , wildcardOK : Boolean ) {
453
456
454
457
/** The erasure |T| of a type T. This is:
455
458
*
@@ -523,7 +526,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
523
526
TypeComparer .orType(this (tp1), this (tp2), isErased = true )
524
527
case tp : MethodType =>
525
528
def paramErasure (tpToErase : Type ) =
526
- erasureFn(sourceLanguage, semiEraseVCs, isConstructor, wildcardOK)(tpToErase)
529
+ erasureFn(sourceLanguage, semiEraseVCs, isConstructor, isSymbol, wildcardOK)(tpToErase)
527
530
val (names, formals0) = if (tp.isErasedMethod) (Nil , Nil ) else (tp.paramNames, tp.paramInfos)
528
531
val formals = formals0.mapConserve(paramErasure)
529
532
eraseResult(tp.resultType) match {
@@ -567,7 +570,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
567
570
val defn .ArrayOf (elemtp) = tp
568
571
if (classify(elemtp).derivesFrom(defn.NullClass )) JavaArrayType (defn.ObjectType )
569
572
else if (isUnboundedGeneric(elemtp) && ! sourceLanguage.isJava) defn.ObjectType
570
- else JavaArrayType (erasureFn(sourceLanguage, semiEraseVCs = false , isConstructor, wildcardOK)(elemtp))
573
+ else JavaArrayType (erasureFn(sourceLanguage, semiEraseVCs = false , isConstructor, isSymbol, wildcardOK)(elemtp))
571
574
}
572
575
573
576
private def erasePair (tp : Type )(using Context ): Type = {
@@ -608,7 +611,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
608
611
val genericUnderlying = unbox.info.resultType
609
612
val underlying = tp.select(unbox).widen.resultType
610
613
611
- val erasedUnderlying = erasure (underlying)
614
+ val erasedUnderlying = this (underlying)
612
615
613
616
// Ideally, we would just use `erasedUnderlying` as the erasure of `tp`, but to
614
617
// be binary-compatible with Scala 2 we need two special cases for polymorphic
@@ -646,7 +649,7 @@ class TypeErasure(sourceLanguage: SourceLanguage, semiEraseVCs: Boolean, isConst
646
649
// correctly (see SIP-15 and [[Erasure.Boxing.adaptToType]]), so the result type of a
647
650
// constructor method should not be semi-erased.
648
651
if semiEraseVCs && isConstructor && ! tp.isInstanceOf [MethodOrPoly ] then
649
- erasureFn(sourceLanguage, semiEraseVCs = false , isConstructor, wildcardOK).eraseResult(tp)
652
+ erasureFn(sourceLanguage, semiEraseVCs = false , isConstructor, isSymbol, wildcardOK).eraseResult(tp)
650
653
else tp match
651
654
case tp : TypeRef =>
652
655
val sym = tp.symbol
0 commit comments