@@ -3518,20 +3518,75 @@ class MatchReducer(initctx: Context) extends TypeComparer(initctx) {
35183518 false
35193519
35203520 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+
35213573 val stableScrut : SingletonType = scrut match
35223574 case scrut : SingletonType => scrut
35233575 case _ => SkolemType (scrut)
3576+
35243577 stableScrut.member(typeMemberName) match
35253578 case denot : SingleDenotation if denot.exists =>
35263579 val info = denot.info match
35273580 case alias : AliasingBounds => alias.alias // Extract the alias
35283581 case ClassInfo (prefix, cls, _, _, _) => prefix.select(cls) // Re-select the class from the prefix
35293582 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
35353590 rec(capture, info1, variance = 0 , scrutIsWidenedAbstract)
35363591 case _ =>
35373592 false
0 commit comments