@@ -171,6 +171,31 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
171171 else if GADTused then CompareResult .OKwithGADTUsed
172172 else CompareResult .OK
173173
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+
174199 /** The current approximation state. See `ApproxState`. */
175200 private var approx : ApproxState = ApproxState .Fresh
176201 protected def approxState : ApproxState = approx
@@ -210,18 +235,24 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
210235 try op finally comparedTypeLambdas = saved
211236
212237 protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
238+ val outermostCall = leftRoot eq null
213239 val savedApprox = approx
214240 val savedLeftRoot = leftRoot
215241 if (a == ApproxState .Fresh ) {
216242 this .approx = ApproxState .None
217243 this .leftRoot = tp1
218244 }
219245 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
221251 catch {
222252 case ex : Throwable => handleRecursive(" subtype" , i " $tp1 <:< $tp2" , ex, weight = 2 )
223253 }
224254 finally {
255+ if outermostCall then this .realiases = List .empty
225256 this .approx = savedApprox
226257 this .leftRoot = savedLeftRoot
227258 }
@@ -297,13 +328,15 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
297328 val info2 = tp2.info
298329 info2 match
299330 case info2 : TypeAlias =>
331+ aliasedConstraint(tp1, tp2, info2.alias)
300332 if recur(tp1, info2.alias) then return true
301333 if tp2.asInstanceOf [TypeRef ].canDropAlias then return false
302334 case _ =>
303335 tp1 match
304336 case tp1 : NamedType =>
305337 tp1.info match {
306338 case info1 : TypeAlias =>
339+ aliasedConstraint(tp2, tp1, info1.alias)
307340 if recur(info1.alias, tp2) then return true
308341 if tp1.asInstanceOf [TypeRef ].canDropAlias then return false
309342 case _ =>
@@ -413,26 +446,9 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
413446 case tp1 : NamedType =>
414447 tp1.info match {
415448 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
436452 case _ =>
437453 if (tp1 eq NothingType ) || isBottom(tp1) then return true
438454 }
0 commit comments