@@ -543,6 +543,7 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
543
543
res
544
544
545
545
case tp1 @ CapturingType (parent1, refs1) =>
546
+ if (approx.lowIgnoreCaptures) then return recur(parent1, tp2)
546
547
def compareCapturing =
547
548
if tp2.isAny then true
548
549
else if subCaptures(refs1, tp2.captureSet, frozenConstraint).isOK && sameBoxed(tp1, tp2, refs1)
@@ -936,7 +937,10 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
936
937
|| tp1.widen.underlyingClassRef(refinementOK = true ).exists)
937
938
then
938
939
def checkBase =
939
- isSubType(base, tp2, if tp1.isRef(cls2) then approx else approx.addLow)
940
+ var a = approx
941
+ if (! tp1.isRef(cls2)) then a = a.addLow
942
+ if (cls2 eq defn.Caps_CapSet ) then a = a.addLowIgnoreCaptures // TODO is this the correct place to add this?
943
+ isSubType(base, tp2, a)
940
944
&& recordGadtUsageIf { MatchType .thatReducesUsingGadt(tp1) }
941
945
if tp1.widenDealias.isInstanceOf [AndType ] || base.isInstanceOf [OrType ] then
942
946
// If tp1 is a intersection, it could be that one of the original
@@ -3325,30 +3329,35 @@ object TypeComparer {
3325
3329
* - `None` : They are still the same types
3326
3330
* - `LoApprox`: The left type is approximated (i.e widened)"
3327
3331
* - `HiApprox`: The right type is approximated (i.e narrowed)"
3332
+ * - `LoIgnoreCaptures`: (Capture checking): The captures of the left type are ignored in the comparison
3328
3333
*/
3329
3334
object ApproxState :
3330
3335
opaque type Repr = Int
3331
3336
3332
3337
val None : Repr = 0
3333
3338
private val LoApprox = 1
3334
3339
private val HiApprox = 2
3340
+ private val LoIgnoreCaptures = 4
3335
3341
3336
3342
/** A special approximation state to indicate that this is the first time we
3337
3343
* compare (approximations of) this pair of types. It's converted to `None`
3338
3344
* in `isSubType`, but also leads to `leftRoot` being set there.
3339
3345
*/
3340
- val Fresh : Repr = 4
3346
+ val Fresh : Repr = 8
3341
3347
3342
3348
object Repr :
3343
3349
extension (approx : Repr )
3344
3350
def low : Boolean = (approx & LoApprox ) != 0
3345
3351
def high : Boolean = (approx & HiApprox ) != 0
3352
+ def lowIgnoreCaptures : Boolean = (approx & LoIgnoreCaptures ) != 0
3346
3353
def addLow : Repr = approx | LoApprox
3347
3354
def addHigh : Repr = approx | HiApprox
3355
+ def addLowIgnoreCaptures : Repr = approx | LoIgnoreCaptures
3348
3356
def show : String =
3349
3357
val lo = if low then " (left is approximated)" else " "
3350
3358
val hi = if high then " (right is approximated)" else " "
3351
- lo ++ hi
3359
+ val locapt = if lowIgnoreCaptures then " (left captures are ignored)" else " "
3360
+ lo ++ hi ++ locapt
3352
3361
end ApproxState
3353
3362
type ApproxState = ApproxState .Repr
3354
3363
0 commit comments