Skip to content

Commit

Permalink
Revert to previous subsumes scheme
Browse files Browse the repository at this point in the history
Add the path cases without changing the whole logic
  • Loading branch information
odersky committed Sep 24, 2024
1 parent dc4629a commit 61ca309
Showing 1 changed file with 12 additions and 70 deletions.
82 changes: 12 additions & 70 deletions compiler/src/dotty/tools/dotc/cc/CaptureRef.scala
Original file line number Diff line number Diff line change
Expand Up @@ -93,100 +93,42 @@ trait CaptureRef extends TypeProxy, ValueType:
final def invalidateCaches() =
myCaptureSetRunId = NoRunId

/** x subsumes x
* this subsumes this.f
* x subsumes y ==> x* subsumes y, x subsumes y?
* x subsumes y ==> x* subsumes y*, x? subsumes y?
* x: x1.type /\ x1 subsumes y ==> x subsumes y
* TODO: Document path cases
*/
final def subsumes(y: CaptureRef)(using Context): Boolean =
val was = subsumesOld(y)
val now = subsumesNew(y)
if was != now then
println(i"diff for $this subsumes $y, now: $now, ${this.getClass}, ${y.getClass}")
was

final def subsumesOld(y: CaptureRef)(using Context): Boolean =
(this eq y)
|| this.isRootCapability
|| y.match
case y: TermRef =>
y.prefix.match
case ypre: CaptureRef =>
this.subsumesOld(ypre)
this.subsumes(ypre)
|| this.match
case x @ TermRef(xpre: CaptureRef, _) =>
x.symbol == y.symbol && xpre =:= ypre
case _ =>
false
case _ => false
|| y.info.match
case y1: SingletonCaptureRef => this.subsumesOld(y1)
case y1: SingletonCaptureRef => this.subsumes(y1)
case _ => false
case MaybeCapability(y1) => this.stripMaybe.subsumesOld(y1)
case MaybeCapability(y1) => this.stripMaybe.subsumes(y1)
case _ => false
|| this.match
case ReachCapability(x1) => x1.subsumesOld(y.stripReach)
case ReachCapability(x1) => x1.subsumes(y.stripReach)
case x: TermRef =>
x.info match
case x1: SingletonCaptureRef => x1.subsumesOld(y)
case x1: SingletonCaptureRef => x1.subsumes(y)
case _ => false
case x: TermParamRef => subsumesExistentially(x, y)
case x: TypeRef => assumedContainsOf(x).contains(y)
case _ => false

/** x subsumes x
* this subsumes this.f
* x subsumes y ==> x* subsumes y, x subsumes y?
* x subsumes y ==> x* subsumes y*, x? subsumes y?
* x: x1.type /\ x1 subsumes y ==> x subsumes y
*/
final def subsumesNew(y: CaptureRef)(using Context): Boolean =
def compareCaptureRefs(x: Type, y: Type): Boolean =
(x eq y)
|| y.match
case y: CaptureRef => x.match
case x: CaptureRef => x.subsumesNew(y)
case _ => false
case _ => false

def compareUndelying(x: Type): Boolean = x match
case x: SingletonCaptureRef => x.subsumesNew(y)
case x: AndType => compareUndelying(x.tp1) || compareUndelying(x.tp2)
case x: OrType => compareUndelying(x.tp1) && compareUndelying(x.tp2)
case _ => false

if (this eq y) || this.isRootCapability then return true

// similar to compareNamed in TypeComparer
y match
case y: TermRef =>
this match
case x: TermRef =>
val xSym = x.symbol
val ySym = y.symbol

// check x.f and y.f
if (xSym ne NoSymbol)
&& (xSym eq ySym)
&& compareCaptureRefs(x.prefix, y.prefix)
|| (x.name eq y.name)
&& x.isPrefixDependentMemberRef
&& compareCaptureRefs(x.prefix, y.prefix)
&& x.signature == y.signature
&& !(xSym.isClass && ySym.isClass)
then return true
case _ =>

// shorten
if compareCaptureRefs(this, y.prefix) then return true
// underlying
if compareCaptureRefs(this, y.info) then return true
case MaybeCapability(y1) => return this.stripMaybe.subsumesNew(y1)
case _ =>

return this.match
case ReachCapability(x1) => x1.subsumesNew(y.stripReach)
case x: TermRef => compareUndelying(x.info)
case CapturingType(x1, _) => compareUndelying(x1)
case x: TermParamRef => subsumesExistentially(x, y)
case x: TypeRef => assumedContainsOf(x).contains(y)
case _ => false

def assumedContainsOf(x: TypeRef)(using Context): SimpleIdentitySet[CaptureRef] =
CaptureSet.assumedContains.getOrElse(x, SimpleIdentitySet.empty)

Expand Down

0 comments on commit 61ca309

Please sign in to comment.