Skip to content

Commit 5e4fed2

Browse files
committed
Extends "covers" between capability to classified capabilities
Classifiers are ignored in covers.
1 parent 403165e commit 5e4fed2

File tree

2 files changed

+21
-37
lines changed

2 files changed

+21
-37
lines changed

compiler/src/dotty/tools/dotc/cc/Capability.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -769,6 +769,7 @@ object Capabilities:
769769
* x covers x
770770
* x covers y ==> x covers y.f
771771
* x covers y ==> x* covers y*, x? covers y?
772+
* x covers y ==> x.only[C] covers y, x covers y.only[C]
772773
* TODO what other clauses from subsumes do we need to port here?
773774
*/
774775
final def covers(y: Capability)(using Context): Boolean =
@@ -784,10 +785,13 @@ object Capabilities:
784785
this match
785786
case Maybe(x1) => x1.covers(y1)
786787
case _ => false
787-
case y: FreshCap =>
788-
y.hiddenSet.superCaps.exists(this.covers(_))
788+
case Restricted(y1, _) =>
789+
this.covers(y1)
789790
case _ =>
790791
false
792+
|| this.match
793+
case Restricted(x1, _) => x1.covers(y)
794+
case _ => false
791795

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

compiler/src/dotty/tools/dotc/cc/SepCheck.scala

Lines changed: 15 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -214,36 +214,16 @@ object SepCheck:
214214
private def directFootprint(using Context): Refs =
215215
computeFootprint(followHidden = false)
216216

217-
/** The hidden footprint of a set of capabilities `refs` is the closure
217+
/** The complete footprint of a set of capabilities `refs` is the closure
218218
* of `refs` under `_.captureSetOfInfo` and `_.hiddenElems`, dropping any shared terminal
219219
* capabilities.
220220
*/
221-
private def hiddenFootprint(using Context): Refs =
221+
private def completeFootprint(using Context): Refs =
222222
computeFootprint(followHidden = true)
223223

224-
/** Same as hiddenFootprint.peaks under new scheme. Was maximal elements before */
225-
private def transPeaks(using Context): Refs =
226-
def recur(seen: Refs, acc: Refs, newElems: List[Capability]): Refs = trace(i"peaks $acc, $newElems = "):
227-
newElems match
228-
case newElem :: newElems1 =>
229-
if seen.contains(newElem) then
230-
recur(seen, acc, newElems1)
231-
else newElem.stripRestricted.stripReadOnly match
232-
case elem: FreshCap if !elem.isKnownClassifiedAs(defn.Caps_SharedCapability) =>
233-
if elem.hiddenSet.deps.isEmpty then recur(seen + newElem, acc + newElem, newElems1)
234-
else
235-
val superCaps =
236-
if newElem.isReadOnly then elem.hiddenSet.superCaps.map(_.readOnly)
237-
else elem.hiddenSet.superCaps
238-
recur(seen + newElem, acc, superCaps ++ newElems)
239-
case _ =>
240-
if newElem.isTerminalCapability
241-
//|| newElem.isInstanceOf[TypeRef | TypeParamRef]
242-
then recur(seen + newElem, acc, newElems1)
243-
else recur(seen + newElem, acc, newElem.captureSetOfInfo.dropEmpties().elems.toList ++ newElems1)
244-
case Nil => acc
245-
if ccConfig.newScheme then hiddenFootprint.peaks
246-
else recur(emptyRefs, emptyRefs, refs.toList)
224+
/** Same as completeFootprint.peaks under new scheme. Was maximal elements before */
225+
private def allPeaks(using Context): Refs =
226+
completeFootprint.peaks
247227

248228
/** The shared elements between the peak sets `refs` and `other`.
249229
* These are the core capabilities and fresh capabilities that appear
@@ -403,7 +383,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
403383
val overlap = hiddenFootprint.overlapWith(clashFootprint)
404384
if !overlap.isEmpty then i"${CaptureSet(overlap)}"
405385
else
406-
val sharedPeaks = hiddenSet.transPeaks.sharedPeaks(clashSet.transPeaks)
386+
val sharedPeaks = hiddenSet.allPeaks.sharedPeaks(clashSet.allPeaks)
407387
assert(!sharedPeaks.isEmpty, i"no overlap for $hiddenSet vs $clashSet")
408388
sharedPeaksStr(sharedPeaks)
409389

@@ -540,7 +520,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
540520
val (qual, fnCaptures) = methPart(fn) match
541521
case Select(qual, _) => (qual, qual.nuType.captureSet)
542522
case _ => (fn, CaptureSet.empty)
543-
var currentPeaks = PeaksPair(fnCaptures.elems.transPeaks, emptyRefs)
523+
var currentPeaks = PeaksPair(fnCaptures.elems.allPeaks, emptyRefs)
544524
val partsWithPeaks = mutable.ListBuffer[(Tree, PeaksPair)]() += (qual -> currentPeaks)
545525

546526
capt.println(
@@ -554,8 +534,8 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
554534

555535
for arg <- args do
556536
val argPeaks = PeaksPair(
557-
spanCaptures(arg).transPeaks,
558-
if arg.needsSepCheck then formalCaptures(arg).transHiddenSet.transPeaks else emptyRefs)
537+
spanCaptures(arg).allPeaks,
538+
if arg.needsSepCheck then formalCaptures(arg).transHiddenSet.allPeaks else emptyRefs)
559539
val argDeps = deps(arg)
560540

561541
def clashingPart(argPeaks: Refs, selector: PeaksPair => Refs): Tree =
@@ -607,9 +587,9 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
607587
val used = tree.markedFree.elems
608588
if !used.isEmpty then
609589
capt.println(i"check use $tree: $used")
610-
val usedPeaks = used.transPeaks
611-
val overlap = defsShadow.transPeaks.sharedPeaks(usedPeaks)
612-
if !defsShadow.transPeaks.sharedPeaks(usedPeaks).isEmpty then
590+
val usedPeaks = used.allPeaks
591+
val overlap = defsShadow.allPeaks.sharedPeaks(usedPeaks)
592+
if !defsShadow.allPeaks.sharedPeaks(usedPeaks).isEmpty then
613593
val sym = tree.symbol
614594

615595
def findClashing(prevDefs: List[DefInfo]): Option[DefInfo] = prevDefs match
@@ -757,7 +737,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
757737
val captured = part.deepCaptureSet.elems.pruned
758738
val hidden = captured.transHiddenSet.pruned
759739
val actual = captured ++ hidden
760-
val partPeaks = PeaksPair(actual.transPeaks, hidden.transPeaks)
740+
val partPeaks = PeaksPair(actual.allPeaks, hidden.allPeaks)
761741
/*
762742
println(i"""check parts $parts
763743
|current = ${currentPeaks.actual}/${currentPeaks.hidden}
@@ -933,7 +913,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
933913
val resultType = mtpe.finalResultType
934914
val resultCaptures =
935915
(resultArgCaptures(resultType) ++ resultType.deepCaptureSet.elems).filter(!isLocalRef(_))
936-
val resultPeaks = resultCaptures.transPeaks
916+
val resultPeaks = resultCaptures.allPeaks
937917
capt.println(i"deps for $app = ${deps.toList}")
938918
(deps, resultPeaks)
939919

@@ -959,7 +939,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
959939

960940
def pushDef(tree: ValOrDefDef, hiddenByDef: Refs)(using Context): Unit =
961941
defsShadow ++= hiddenByDef
962-
previousDefs = DefInfo(tree, tree.symbol, hiddenByDef, hiddenByDef.transPeaks) :: previousDefs
942+
previousDefs = DefInfo(tree, tree.symbol, hiddenByDef, hiddenByDef.allPeaks) :: previousDefs
963943

964944
/** Check (result-) type of `tree` for separation conditions using `checkType`.
965945
* Excluded are parameters and definitions that have an =unsafeAssumeSeparate

0 commit comments

Comments
 (0)