@@ -3518,20 +3518,75 @@ class MatchReducer(initctx: Context) extends TypeComparer(initctx) {
3518
3518
false
3519
3519
3520
3520
case MatchTypeCasePattern .TypeMemberExtractor (typeMemberName, capture) =>
3521
+ /** Try to remove references to `skolem` from a type in accordance with the spec.
3522
+ *
3523
+ * If any reference to `skolem` remains in the result type,
3524
+ * `refersToSkolem` is set to true.
3525
+ */
3526
+ class DropSkolemMap (skolem : SkolemType ) extends TypeMap :
3527
+ var refersToSkolem = false
3528
+ def apply (tp : Type ): Type =
3529
+ tp match
3530
+ case `skolem` =>
3531
+ refersToSkolem = true
3532
+ tp
3533
+ case tp : NamedType =>
3534
+ var savedRefersToSkolem = refersToSkolem
3535
+ refersToSkolem = false
3536
+ try
3537
+ val pre1 = apply(tp.prefix)
3538
+ if refersToSkolem then
3539
+ tp match
3540
+ case tp : TermRef => tp.info.widenExpr.dealias match
3541
+ case info : SingletonType =>
3542
+ refersToSkolem = false
3543
+ apply(info)
3544
+ case _ =>
3545
+ tp.derivedSelect(pre1)
3546
+ case tp : TypeRef => tp.info match
3547
+ case info : AliasingBounds =>
3548
+ refersToSkolem = false
3549
+ apply(info.alias)
3550
+ case _ =>
3551
+ tp.derivedSelect(pre1)
3552
+ else
3553
+ tp.derivedSelect(pre1)
3554
+ finally
3555
+ refersToSkolem |= savedRefersToSkolem
3556
+ case tp : LazyRef =>
3557
+ // By default, TypeMap maps LazyRefs lazily. We need to
3558
+ // force it for `refersToSkolem` to be correctly set.
3559
+ apply(tp.ref)
3560
+ case _ =>
3561
+ mapOver(tp)
3562
+ end DropSkolemMap
3563
+ /** Try to remove references to `skolem` from `u` in accordance with the spec.
3564
+ *
3565
+ * If any reference to `skolem` remains in the result type, return
3566
+ * NoType instead.
3567
+ */
3568
+ def dropSkolem (u : Type , skolem : SkolemType ): Type =
3569
+ val dmap = DropSkolemMap (skolem)
3570
+ val res = dmap(u)
3571
+ if dmap.refersToSkolem then NoType else res
3572
+
3521
3573
val stableScrut : SingletonType = scrut match
3522
3574
case scrut : SingletonType => scrut
3523
3575
case _ => SkolemType (scrut)
3576
+
3524
3577
stableScrut.member(typeMemberName) match
3525
3578
case denot : SingleDenotation if denot.exists =>
3526
3579
val info = denot.info match
3527
3580
case alias : AliasingBounds => alias.alias // Extract the alias
3528
3581
case ClassInfo (prefix, cls, _, _, _) => prefix.select(cls) // Re-select the class from the prefix
3529
3582
case info => info // Notably, RealTypeBounds, which will eventually give a MatchResult.NoInstances
3530
- val infoRefersToSkolem = stableScrut.isInstanceOf [SkolemType ] && stableScrut.occursIn(info)
3531
- val info1 = info match
3532
- case info : TypeBounds => info // Will already trigger a MatchResult.NoInstances
3533
- case _ if infoRefersToSkolem => RealTypeBounds (info, info) // Explicitly trigger a MatchResult.NoInstances
3534
- case _ => info // We have a match
3583
+ val info1 = stableScrut match
3584
+ case skolem : SkolemType =>
3585
+ dropSkolem(info, skolem).orElse:
3586
+ info match
3587
+ case info : TypeBounds => info // Will already trigger a MatchResult.NoInstances
3588
+ case _ => RealTypeBounds (info, info) // Explicitly trigger a MatchResult.NoInstances
3589
+ case _ => info
3535
3590
rec(capture, info1, variance = 0 , scrutIsWidenedAbstract)
3536
3591
case _ =>
3537
3592
false
0 commit comments