@@ -473,27 +473,28 @@ object Capabilities:
473473 case info: OrType => viaInfo(info.tp1)(test) && viaInfo(info.tp2)(test)
474474 case _ => false
475475
476+ def trySubpath(y: TermRef): Boolean =
477+ y.prefix.match
478+ case ypre: Capability =>
479+ this.subsumes(ypre)
480+ || this.match
481+ case x @ TermRef(xpre: Capability, _) if x.symbol == y.symbol =>
482+ // To show `{x.f} <:< {y.f}`, it is important to prove `x` and `y`
483+ // are equvalent, which means `x =:= y` in terms of subtyping,
484+ // not just `{x} =:= {y}` in terms of subcapturing.
485+ // It is possible to construct two singleton types `x` and `y`,
486+ // which subsume each other, but are not equal references.
487+ // See `tests/neg-custom-args/captures/path-prefix.scala` for example.
488+ withMode(Mode.IgnoreCaptures):
489+ TypeComparer.isSameRef(xpre, ypre)
490+ case _ =>
491+ false
492+ case _ => false
493+
476494 try (this eq y)
477495 || maxSubsumes(y, canAddHidden = !vs.isOpen)
478496 || y.match
479- case y: TermRef =>
480- y.prefix.match
481- case ypre: Capability =>
482- this.subsumes(ypre)
483- || this.match
484- case x @ TermRef(xpre: Capability, _) if x.symbol == y.symbol =>
485- // To show `{x.f} <:< {y.f}`, it is important to prove `x` and `y`
486- // are equvalent, which means `x =:= y` in terms of subtyping,
487- // not just `{x} =:= {y}` in terms of subcapturing.
488- // It is possible to construct two singleton types `x` and `y`,
489- // which subsume each other, but are not equal references.
490- // See `tests/neg-custom-args/captures/path-prefix.scala` for example.
491- withMode(Mode.IgnoreCaptures):
492- TypeComparer.isSameRef(xpre, ypre)
493- case _ =>
494- false
495- case _ => false
496- || viaInfo(y.info)(subsumingRefs(this, _))
497+ case y: TermRef => trySubpath(y) || viaInfo(y.info)(subsumingRefs(this, _))
497498 case Maybe(y1) => this.stripMaybe.subsumes(y1)
498499 case ReadOnly(y1) => this.stripReadOnly.subsumes(y1)
499500 case y: TypeRef if y.derivesFrom(defn.Caps_CapSet) =>
@@ -507,6 +508,15 @@ object Capabilities:
507508 this.subsumes(hi)
508509 case _ =>
509510 y.captureSetOfInfo.elems.forall(this.subsumes)
511+ case Reach(y1: TermRef) =>
512+ val sym = y1.symbol
513+ def isUseClassParam: Boolean =
514+ sym.owner match
515+ case classSym: ClassSymbol =>
516+ val paramSym = classSym.primaryConstructor.paramNamed(sym.name)
517+ paramSym.isUseParam
518+ case _ => false
519+ isUseClassParam && trySubpath(y1)
510520 case _ => false
511521 || this.match
512522 case Reach(x1) => x1.subsumes(y.stripReach)
@@ -858,4 +868,4 @@ object Capabilities:
858868 case tp1 => tp1
859869 end toResultInResults
860870
861- end Capabilities
871+ end Capabilities
0 commit comments