@@ -133,10 +133,37 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
133
133
}
134
134
135
135
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
+
136
155
val saved = myNecessaryConstraintsOnly
137
156
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
140
167
141
168
def testSubType (tp1 : Type , tp2 : Type ): CompareResult =
142
169
GADTused = false
@@ -183,37 +210,16 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
183
210
try op finally comparedTypeLambdas = saved
184
211
185
212
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
-
207
213
val savedApprox = approx
208
214
val savedLeftRoot = leftRoot
209
215
if (a == ApproxState .Fresh ) {
210
216
this .approx = ApproxState .None
211
- this .leftRoot = tp1dealiased
217
+ this .leftRoot = tp1
212
218
}
213
219
else this .approx = a
214
- try recur(tp1dealiased , tp2)
220
+ try recur(tp1 , tp2)
215
221
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 )
217
223
}
218
224
finally {
219
225
this .approx = savedApprox
@@ -411,14 +417,14 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
411
417
case tp2 : TypeParamRef =>
412
418
constraint.entry(tp2) match {
413
419
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)
416
422
if aliasLo || aliasHi then
417
423
constraint = constraint.updateEntry(tp2, TypeBounds (
418
424
if aliasLo then tp1 else lo,
419
425
if aliasHi then tp1 else hi))
420
426
case tp =>
421
- if tp1 != tp && info1.alias == tp then
427
+ if ( tp1 ne tp) && ( info1.alias eq tp) then
422
428
constraint = constraint.updateEntry(tp2, tp1)
423
429
}
424
430
case _ =>
@@ -1066,7 +1072,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
1066
1072
def isMatchingApply (tp1 : Type ): Boolean = tp1.widen match {
1067
1073
case tp1 @ AppliedType (tycon1, args1) =>
1068
1074
// 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
1070
1076
// constructors when this can be done without affecting type
1071
1077
// inference, doing it here would not only prevent code from compiling
1072
1078
// but could also result in the wrong thing being inferred later, for example
0 commit comments