@@ -133,10 +133,37 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
133133 }
134134
135135 def necessarySubType (tp1 : Type , tp2 : Type ): Boolean =
136+ inline def followAlias [T ](inline tp : Type )(inline default : T )(inline f : (TypeProxy , Symbol ) => T ): T =
137+ tp match
138+ case tp : (AppliedType | TypeRef ) => f(tp, tp.typeSymbol)
139+ case _ => default
140+
141+ @ tailrec def aliasedSymbols (tp : Type , result : Set [Symbol ] = Set .empty): Set [Symbol ] =
142+ followAlias(tp)(result) { (tp, sym) =>
143+ if sym.isAliasType then aliasedSymbols(tp.superType, result + sym)
144+ else if sym.exists && (sym ne AnyClass ) then result + sym
145+ else result
146+ }
147+
148+ @ tailrec def dealias (tp : Type , syms : Set [Symbol ]): Type =
149+ followAlias(tp)(NoType ) { (tp, sym) =>
150+ if syms contains sym then tp
151+ else if sym.isAliasType then dealias(tp.superType, syms)
152+ else NoType
153+ }
154+
136155 val saved = myNecessaryConstraintsOnly
137156 myNecessaryConstraintsOnly = true
138- try topLevelSubType(tp1, tp2)
139- finally myNecessaryConstraintsOnly = saved
157+
158+ try
159+ val tryDealias = (tp2 ne tp1) && (tp2 ne WildcardType ) && followAlias(tp1)(false ) { (_, sym) => sym.isAliasType }
160+ if tryDealias then
161+ topLevelSubType(dealias(tp1, aliasedSymbols(tp2)) orElse tp1, tp2)
162+ else
163+ topLevelSubType(tp1, tp2)
164+ finally
165+ myNecessaryConstraintsOnly = saved
166+ end necessarySubType
140167
141168 def testSubType (tp1 : Type , tp2 : Type ): CompareResult =
142169 GADTused = false
@@ -183,37 +210,16 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
183210 try op finally comparedTypeLambdas = saved
184211
185212 protected def isSubType (tp1 : Type , tp2 : Type , a : ApproxState ): Boolean = {
186- inline def followAlias [T ](inline tp : Type )(inline default : T )(inline f : (TypeProxy , Symbol ) => T ): T =
187- tp.stripAnnots.stripTypeVar match
188- case tp : (AppliedType | TypeRef ) => f(tp, tp.typeSymbol)
189- case _ => default
190-
191- @ tailrec def dealias (tp : Type , syms : Set [Symbol ]): Type =
192- followAlias(tp)(NoType ) { (tp, sym) =>
193- if syms contains sym then tp
194- else if sym.isAliasType then dealias(tp.superType, syms)
195- else NoType
196- }
197-
198- @ tailrec def aliasedSymbols (tp : Type , result : Set [Symbol ] = Set .empty): Set [Symbol ] =
199- followAlias(tp)(result) { (tp, sym) =>
200- if sym.isAliasType then aliasedSymbols(tp.superType, result + sym)
201- else if sym.exists && (sym ne AnyClass ) then result + sym
202- else result
203- }
204-
205- val tp1dealiased = dealias(tp1, aliasedSymbols(tp2)) orElse tp1
206-
207213 val savedApprox = approx
208214 val savedLeftRoot = leftRoot
209215 if (a == ApproxState .Fresh ) {
210216 this .approx = ApproxState .None
211- this .leftRoot = tp1dealiased
217+ this .leftRoot = tp1
212218 }
213219 else this .approx = a
214- try recur(tp1dealiased , tp2)
220+ try recur(tp1 , tp2)
215221 catch {
216- case ex : Throwable => handleRecursive(" subtype" , i " $tp1dealiased <:< $tp2" , ex, weight = 2 )
222+ case ex : Throwable => handleRecursive(" subtype" , i " $tp1 <:< $tp2" , ex, weight = 2 )
217223 }
218224 finally {
219225 this .approx = savedApprox
@@ -411,14 +417,14 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
411417 case tp2 : TypeParamRef =>
412418 constraint.entry(tp2) match {
413419 case TypeBounds (lo, hi) =>
414- val aliasLo = tp1 != lo && info1.alias == lo
415- val aliasHi = tp1 != hi && info1.alias == hi
420+ val aliasLo = ( tp1 ne lo) && ( info1.alias eq lo)
421+ val aliasHi = ( tp1 ne hi) && ( info1.alias eq hi)
416422 if aliasLo || aliasHi then
417423 constraint = constraint.updateEntry(tp2, TypeBounds (
418424 if aliasLo then tp1 else lo,
419425 if aliasHi then tp1 else hi))
420426 case tp =>
421- if tp1 != tp && info1.alias == tp then
427+ if ( tp1 ne tp) && ( info1.alias eq tp) then
422428 constraint = constraint.updateEntry(tp2, tp1)
423429 }
424430 case _ =>
@@ -1066,7 +1072,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
10661072 def isMatchingApply (tp1 : Type ): Boolean = tp1.widen match {
10671073 case tp1 @ AppliedType (tycon1, args1) =>
10681074 // We intentionally do not automatically dealias `tycon1` or `tycon2` here.
1069- // `isSubType ` already takes care of dealiasing type
1075+ // `necessarySubType ` already takes care of dealiasing type
10701076 // constructors when this can be done without affecting type
10711077 // inference, doing it here would not only prevent code from compiling
10721078 // but could also result in the wrong thing being inferred later, for example
0 commit comments