@@ -132,10 +132,37 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
132132 }
133133
134134 def necessarySubType (tp1 : Type , tp2 : Type ): Boolean =
135+ inline def followAlias [T ](inline tp : Type )(inline default : T )(inline f : (TypeProxy , Symbol ) => T ): T =
136+ tp match
137+ case tp : (AppliedType | TypeRef ) => f(tp, tp.typeSymbol)
138+ case _ => default
139+
140+ @ tailrec def aliasedSymbols (tp : Type , result : Set [Symbol ] = Set .empty): Set [Symbol ] =
141+ followAlias(tp)(result) { (tp, sym) =>
142+ if sym.isAliasType then aliasedSymbols(tp.superType, result + sym)
143+ else if sym.exists && (sym ne AnyClass ) then result + sym
144+ else result
145+ }
146+
147+ @ tailrec def dealias (tp : Type , syms : Set [Symbol ]): Type =
148+ followAlias(tp)(NoType ) { (tp, sym) =>
149+ if syms contains sym then tp
150+ else if sym.isAliasType then dealias(tp.superType, syms)
151+ else NoType
152+ }
153+
135154 val saved = myNecessaryConstraintsOnly
136155 myNecessaryConstraintsOnly = true
137- try topLevelSubType(tp1, tp2)
138- finally myNecessaryConstraintsOnly = saved
156+
157+ try
158+ val tryDealias = (tp2 ne tp1) && (tp2 ne WildcardType ) && followAlias(tp1)(false ) { (_, sym) => sym.isAliasType }
159+ if tryDealias then
160+ topLevelSubType(dealias(tp1, aliasedSymbols(tp2)) orElse tp1, tp2)
161+ else
162+ topLevelSubType(tp1, tp2)
163+ finally
164+ myNecessaryConstraintsOnly = saved
165+ end necessarySubType
139166
140167 def testSubType (tp1 : Type , tp2 : Type ): CompareResult =
141168 GADTused = false
@@ -179,37 +206,16 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
179206 try op finally comparedTypeLambdas = saved
180207
181208 protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
182- inline def followAlias [T ](inline tp : Type )(inline default : T )(inline f : (TypeProxy , Symbol ) => T ): T =
183- tp.stripAnnots.stripTypeVar match
184- case tp : (AppliedType | TypeRef ) => f(tp, tp.typeSymbol)
185- case _ => default
186-
187- @ tailrec def dealias (tp : Type , syms : Set [Symbol ]): Type =
188- followAlias(tp)(NoType ) { (tp, sym) =>
189- if syms contains sym then tp
190- else if sym.isAliasType then dealias(tp.superType, syms)
191- else NoType
192- }
193-
194- @ tailrec def aliasedSymbols (tp : Type , result : Set [Symbol ] = Set .empty): Set [Symbol ] =
195- followAlias(tp)(Set .empty) { (tp, sym) =>
196- if sym.isAliasType then aliasedSymbols(tp.superType, result + sym)
197- else if sym.exists && (sym ne AnyClass ) then result + sym
198- else Set .empty
199- }
200-
201- val tp1dealiased = dealias(tp1, aliasedSymbols(tp2)) orElse tp1
202-
203209 val savedApprox = approx
204210 val savedLeftRoot = leftRoot
205211 if (a == ApproxState .Fresh ) {
206212 this .approx = ApproxState .None
207- this .leftRoot = tp1dealiased
213+ this .leftRoot = tp1
208214 }
209215 else this .approx = a
210- try recur(tp1dealiased , tp2)
216+ try recur(tp1 , tp2)
211217 catch {
212- case ex : Throwable => handleRecursive(" subtype" , i " $tp1dealiased <:< $tp2" , ex, weight = 2 )
218+ case ex : Throwable => handleRecursive(" subtype" , i " $tp1 <:< $tp2" , ex, weight = 2 )
213219 }
214220 finally {
215221 this .approx = savedApprox
@@ -407,14 +413,14 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
407413 case tp2 : TypeParamRef =>
408414 constraint.entry(tp2) match {
409415 case TypeBounds (lo, hi) =>
410- val aliasLo = tp1 != lo && info1.alias == lo
411- val aliasHi = tp1 != hi && info1.alias == hi
416+ val aliasLo = ( tp1 ne lo) && ( info1.alias eq lo)
417+ val aliasHi = ( tp1 ne hi) && ( info1.alias eq hi)
412418 if aliasLo || aliasHi then
413419 constraint = constraint.updateEntry(tp2, TypeBounds (
414420 if aliasLo then tp1 else lo,
415421 if aliasHi then tp1 else hi))
416422 case tp =>
417- if tp1 != tp && info1.alias == tp then
423+ if ( tp1 ne tp) && ( info1.alias eq tp) then
418424 constraint = constraint.updateEntry(tp2, tp1)
419425 }
420426 case _ =>
@@ -1049,7 +1055,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
10491055 def isMatchingApply (tp1 : Type ): Boolean = tp1.widen match {
10501056 case tp1 @ AppliedType (tycon1, args1) =>
10511057 // We intentionally do not automatically dealias `tycon1` or `tycon2` here.
1052- // `isSubType ` already takes care of dealiasing type
1058+ // `necessarySubType ` already takes care of dealiasing type
10531059 // constructors when this can be done without affecting type
10541060 // inference, doing it here would not only prevent code from compiling
10551061 // but could also result in the wrong thing being inferred later, for example
0 commit comments