@@ -109,6 +109,28 @@ object TypeErasure {
109
109
}
110
110
loop(tp1.baseClasses, defn.ObjectClass ).typeRef
111
111
}
112
+
113
+ def erasedGlb (tp1 : Type , tp2 : Type , isJava : Boolean )(implicit ctx : Context ): Type = tp1 match {
114
+ case defn.ArrayType (elem1) =>
115
+ tp2 match {
116
+ case defn.ArrayType (elem2) => defn.ArrayType (erasedGlb(elem1, elem2, isJava))
117
+ case _ => defn.ObjectType
118
+ }
119
+ case _ =>
120
+ tp2 match {
121
+ case defn.ArrayType (_) => defn.ObjectType
122
+ case _ =>
123
+ val tsym1 = tp1.typeSymbol
124
+ val tsym2 = tp2.typeSymbol
125
+ if (! tsym2.exists) tp1
126
+ else if (! tsym1.exists) tp2
127
+ else if (! isJava && tsym1.derivesFrom(tsym2)) tp1
128
+ else if (! isJava && tsym2.derivesFrom(tsym1)) tp2
129
+ else if (tp1.typeSymbol.isRealClass) tp1
130
+ else if (tp2.typeSymbol.isRealClass) tp2
131
+ else tp1
132
+ }
133
+ }
112
134
}
113
135
import TypeErasure ._
114
136
@@ -127,15 +149,15 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
127
149
* - otherwise, if T <: Object, scala.Array+[|T|]
128
150
* - otherwise, if T is a type paramter coming from Java, scala.Array+[Object].
129
151
* - otherwise, Object
130
- * - For all other type proxies: The erasure of the underlying type.
131
- * - For a typeref scala.Any, scala.AnyVal, scala.Singleon or scala.NotNull: java.lang.Object.
132
- * - For a typeref scala.Unit, scala.runtime.BoxedUnit.
133
- * - For a typeref whose symbol is owned by Array: The typeref itself
134
- * - For a typeref P.C where C refers to a toplevel class, P.C.
135
- * - For a typeref P.C where C refers to a nested class, |P|.C.
152
+ * - For a term ref p.x, the type <noprefix> # x.
153
+ * - For a typeref scala.Any, scala.AnyVal, scala.Singleon or scala.NotNull: |java.lang.Object|
154
+ * - For a typeref scala.Unit, |scala.runtime.BoxedUnit|.
155
+ * - For a typeref whose symbol is owned by Array: The typeref itself, with prefix = <noprefix>
156
+ * - For a typeref P.C where C refers to a class, <noprefix> # C.
136
157
* - For a typeref P.C where C refers to an alias type, the erasure of C's alias.
137
158
* - For a typeref P.C where C refers to an abstract type, the erasure of C's upper bound.
138
- * - For T1 & T2, the merge of |T1| and |T2| (see mergeAnd)
159
+ * - For all other type proxies: The erasure of the underlying type.
160
+ * - For T1 & T2, the erased glb of |T1| and |T2| (see erasedGlb)
139
161
* - For T1 | T2, the first base class in the linearization of T which is also a base class of T2
140
162
* - For => T, ()T
141
163
* - For a method type (Fs)scala.Unit, (|Fs|)scala.Unit.
@@ -164,14 +186,12 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
164
186
case tp : TermRef =>
165
187
assert(tp.symbol.exists, tp)
166
188
TermRef (NoPrefix , tp.symbol.asTerm)
167
- case _ : ThisType =>
168
- tp
169
189
case ExprType (rt) =>
170
190
MethodType (Nil , Nil , this (rt))
171
191
case tp : TypeProxy =>
172
192
this (tp.underlying)
173
193
case AndType (tp1, tp2) =>
174
- mergeAnd (this (tp1), this (tp2))
194
+ erasedGlb (this (tp1), this (tp2), isJava )
175
195
case OrType (tp1, tp2) =>
176
196
ctx.typeComparer.orType(this (tp1), this (tp2), erased = true )
177
197
case tp : MethodType =>
@@ -196,7 +216,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
196
216
if ((cls eq defn.ObjectClass ) || cls.isPrimitiveValueClass) Nil
197
217
else if (cls eq defn.ArrayClass ) defn.ObjectClass .typeRef :: Nil
198
218
else removeLaterObjects(classParents.mapConserve(eraseTypeRef))
199
- tp.derivedClassInfo(this (pre), parents, decls, this (tp.selfType))
219
+ tp.derivedClassInfo(NoPrefix , parents, decls, this (tp.selfType))
220
+ // can't replace selftype by NoType because this would lose the sourceModule link
200
221
}
201
222
case NoType | NoPrefix | ErrorType =>
202
223
tp
@@ -215,9 +236,8 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
215
236
unsupported(" eraseDerivedValueClass" )
216
237
217
238
private def eraseNormalClassRef (tref : TypeRef )(implicit ctx : Context ): Type = {
218
- val sym = tref.symbol
219
- if (sym.owner is Package ) normalizeClass(sym.asClass).typeRef
220
- else tref.derivedSelect(this (tref.prefix))
239
+ val cls = tref.symbol.asClass
240
+ (if (cls.owner is Package ) normalizeClass(cls) else cls).typeRef
221
241
}
222
242
223
243
private def eraseResult (tp : Type )(implicit ctx : Context ): Type = tp match {
@@ -247,28 +267,6 @@ class TypeErasure(isJava: Boolean, isSemi: Boolean, isConstructor: Boolean, wild
247
267
case nil => nil
248
268
}
249
269
250
- private def mergeAnd (tp1 : Type , tp2 : Type )(implicit ctx : Context ): Type = tp1 match {
251
- case defn.ArrayType (elem1) =>
252
- tp2 match {
253
- case defn.ArrayType (elem2) => defn.ArrayType (mergeAnd(elem1, elem2))
254
- case _ => defn.ObjectType
255
- }
256
- case _ =>
257
- tp2 match {
258
- case defn.ArrayType (_) => defn.ObjectType
259
- case _ =>
260
- val tsym1 = tp1.typeSymbol
261
- val tsym2 = tp2.typeSymbol
262
- if (! tsym2.exists) tp1
263
- else if (! tsym1.exists) tp2
264
- else if (! isJava && tsym1.derivesFrom(tsym2)) tp1
265
- else if (! isJava && tsym2.derivesFrom(tsym1)) tp2
266
- else if (tp1.typeSymbol.isRealClass) tp1
267
- else if (tp2.typeSymbol.isRealClass) tp2
268
- else tp1
269
- }
270
- }
271
-
272
270
/** The name of the type as it is used in `Signature`s.
273
271
* Need to ensure correspondence with erasure!
274
272
*/
0 commit comments