@@ -171,6 +171,31 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
171
171
else if GADTused then CompareResult .OKwithGADTUsed
172
172
else CompareResult .OK
173
173
174
+ /** original aliases of types used to instantiate type parameters
175
+ * collected in `recur` and to be restored after sub type check */
176
+ private var realiases : List [(TypeParamRef , NamedType , Type )] = List .empty
177
+
178
+ private def realiasConstraints () =
179
+ this .realiases foreach { (param, alias, dealiased) =>
180
+ constraint.entry(param) match
181
+ case TypeBounds (lo, hi) =>
182
+ val aliasLo = (alias ne lo) && (dealiased eq lo)
183
+ val aliasHi = (alias ne hi) && (dealiased eq hi)
184
+ if aliasLo || aliasHi then
185
+ constraint = constraint.updateEntry(param, TypeBounds (
186
+ if aliasLo then alias else lo,
187
+ if aliasHi then alias else hi))
188
+ case tp =>
189
+ if (alias ne tp) && (dealiased eq tp) then
190
+ constraint = constraint.updateEntry(param, alias)
191
+ }
192
+
193
+ private inline def aliasedConstraint (param : Type , alias : NamedType , dealiased : Type ) =
194
+ if alias.symbol.isStatic then
195
+ param.stripTypeVar match
196
+ case param : TypeParamRef => this .realiases ::= (param, alias, dealiased)
197
+ case _ =>
198
+
174
199
/** The current approximation state. See `ApproxState`. */
175
200
private var approx : ApproxState = ApproxState .Fresh
176
201
protected def approxState : ApproxState = approx
@@ -210,18 +235,24 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
210
235
try op finally comparedTypeLambdas = saved
211
236
212
237
protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
238
+ val outermostCall = leftRoot eq null
213
239
val savedApprox = approx
214
240
val savedLeftRoot = leftRoot
215
241
if (a == ApproxState .Fresh ) {
216
242
this .approx = ApproxState .None
217
243
this .leftRoot = tp1
218
244
}
219
245
else this .approx = a
220
- try recur(tp1, tp2)
246
+ if outermostCall then this .realiases = List .empty
247
+ try
248
+ val res = recur(tp1, tp2)
249
+ if outermostCall then realiasConstraints()
250
+ res
221
251
catch {
222
252
case ex : Throwable => handleRecursive(" subtype" , i " $tp1 <:< $tp2" , ex, weight = 2 )
223
253
}
224
254
finally {
255
+ if outermostCall then this .realiases = List .empty
225
256
this .approx = savedApprox
226
257
this .leftRoot = savedLeftRoot
227
258
}
@@ -297,13 +328,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
297
328
val info2 = tp2.info
298
329
info2 match
299
330
case info2 : TypeAlias =>
331
+ aliasedConstraint(tp1, tp2, info2.alias)
300
332
if recur(tp1, info2.alias) then return true
301
333
if tp2.asInstanceOf [TypeRef ].canDropAlias then return false
302
334
case _ =>
303
335
tp1 match
304
336
case tp1 : NamedType =>
305
337
tp1.info match {
306
338
case info1 : TypeAlias =>
339
+ aliasedConstraint(tp2, tp1, info1.alias)
307
340
if recur(info1.alias, tp2) then return true
308
341
if tp1.asInstanceOf [TypeRef ].canDropAlias then return false
309
342
case _ =>
@@ -413,26 +446,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
413
446
case tp1 : NamedType =>
414
447
tp1.info match {
415
448
case info1 : TypeAlias =>
416
- def realiasConstraint () = tp2 match {
417
- case tp2 : TypeParamRef =>
418
- constraint.entry(tp2) match {
419
- case TypeBounds (lo, hi) =>
420
- val aliasLo = (tp1 ne lo) && (info1.alias eq lo)
421
- val aliasHi = (tp1 ne hi) && (info1.alias eq hi)
422
- if aliasLo || aliasHi then
423
- constraint = constraint.updateEntry(tp2, TypeBounds (
424
- if aliasLo then tp1 else lo,
425
- if aliasHi then tp1 else hi))
426
- case tp =>
427
- if (tp1 ne tp) && (info1.alias eq tp) then
428
- constraint = constraint.updateEntry(tp2, tp1)
429
- }
430
- case _ =>
431
- }
432
- val res = recur(info1.alias, tp2)
433
- if (tp1.symbol.isStatic) realiasConstraint()
434
- if (res) return true
435
- if (tp1.prefix.isStable) return tryLiftedToThis1
449
+ aliasedConstraint(tp2, tp1, info1.alias)
450
+ if recur(info1.alias, tp2) then return true
451
+ if tp1.prefix.isStable then return tryLiftedToThis1
436
452
case _ =>
437
453
if (tp1 eq NothingType ) || isBottom(tp1) then return true
438
454
}
0 commit comments