@@ -132,10 +132,37 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
132
132
}
133
133
134
134
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
+
135
154
val saved = myNecessaryConstraintsOnly
136
155
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
139
166
140
167
def testSubType (tp1 : Type , tp2 : Type ): CompareResult =
141
168
GADTused = false
@@ -179,37 +206,16 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
179
206
try op finally comparedTypeLambdas = saved
180
207
181
208
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
-
203
209
val savedApprox = approx
204
210
val savedLeftRoot = leftRoot
205
211
if (a == ApproxState .Fresh ) {
206
212
this .approx = ApproxState .None
207
- this .leftRoot = tp1dealiased
213
+ this .leftRoot = tp1
208
214
}
209
215
else this .approx = a
210
- try recur(tp1dealiased , tp2)
216
+ try recur(tp1 , tp2)
211
217
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 )
213
219
}
214
220
finally {
215
221
this .approx = savedApprox
@@ -407,14 +413,14 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
407
413
case tp2 : TypeParamRef =>
408
414
constraint.entry(tp2) match {
409
415
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)
412
418
if aliasLo || aliasHi then
413
419
constraint = constraint.updateEntry(tp2, TypeBounds (
414
420
if aliasLo then tp1 else lo,
415
421
if aliasHi then tp1 else hi))
416
422
case tp =>
417
- if tp1 != tp && info1.alias == tp then
423
+ if ( tp1 ne tp) && ( info1.alias eq tp) then
418
424
constraint = constraint.updateEntry(tp2, tp1)
419
425
}
420
426
case _ =>
@@ -1049,7 +1055,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1049
1055
def isMatchingApply (tp1 : Type ): Boolean = tp1.widen match {
1050
1056
case tp1 @ AppliedType (tycon1, args1) =>
1051
1057
// 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
1053
1059
// constructors when this can be done without affecting type
1054
1060
// inference, doing it here would not only prevent code from compiling
1055
1061
// but could also result in the wrong thing being inferred later, for example
0 commit comments