@@ -197,24 +197,6 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
197197 val elems : Refs = refs.filter(! _.isMaxCapability)
198198 recur(elems, elems.toList)
199199
200- /** The members of type Fresh.Cap(...) or Fresh.Cap(...).rd in the transitive closure
201- * of this set
202- */
203- private def freshElems (using Context ): Refs =
204- def recur (seen : Refs , acc : Refs , newElems : List [CaptureRef ]): Refs = newElems match
205- case newElem :: newElems1 =>
206- if seen.contains(newElem) then
207- recur(seen, acc, newElems1)
208- else newElem.stripReadOnly match
209- case Fresh .Cap (_) =>
210- recur(seen, acc + newElem, newElems1)
211- // case _: TypeRef | _: TypeParamRef =>
212- // recur(seen + newElem, acc, newElems1)
213- case _ =>
214- recur(seen + newElem, acc, newElem.captureSetOfInfo.elems.toList ++ newElems1)
215- case Nil => acc
216- recur(emptyRefs, emptyRefs, refs.toList)
217-
218200 private def peaks (using Context ): Refs =
219201 def recur (seen : Refs , acc : Refs , newElems : List [CaptureRef ]): Refs = newElems match
220202 case newElem :: newElems1 =>
@@ -286,7 +268,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
286268 * capability in `refs`. E g. if `R = {x, <cap hiding <y, <cap hiding z>>}` then
287269 * its hidden set is `{y, z}`.
288270 */
289- private def hidden (using Context ): Refs =
271+ private def hiddenSet (using Context ): Refs =
290272 val seen : util.EqHashSet [CaptureRef ] = new util.EqHashSet
291273
292274 def hiddenByElem (elem : CaptureRef ): Refs = elem match
@@ -299,7 +281,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
299281 if seen.add(elem) then elems ++ hiddenByElem(elem) else elems
300282
301283 recur(refs)
302- end hidden
284+ end hiddenSet
303285
304286 /** Same as !refs.hidden.isEmpty but more efficient */
305287 private def containsHidden (using Context ): Boolean =
@@ -315,11 +297,6 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
315297 recur(refs)
316298 end containsHidden
317299
318- def hiddenSet (using Context ): Refs =
319- freshElems.flatMap:
320- case Fresh .Cap (hidden) => hidden.elems
321- case ReadOnlyCapability (Fresh .Cap (hidden)) => hidden.elems.map(_.readOnly)
322-
323300 /** Subtract all elements that are covered by some element in `others` from this set. */
324301 private def deduct (others : Refs )(using Context ): Refs =
325302 refs.filter: ref =>
@@ -353,7 +330,12 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
353330 private def captures (tree : Tree )(using Context ): Refs =
354331 tree.nuType.deepCaptureSet.elems
355332
356- // ---- Error reporting TODO Once these are stabilized, move to messages -----
333+ // ---- Error reporting TODO Once these are stabilized, move to messages -----" +
334+
335+ def sharedPeaksStr (shared : Refs )(using Context ): String =
336+ shared.nth(0 ) match
337+ case fresh @ Fresh .Cap (hidden) =>
338+ if hidden.owner.exists then i " $fresh of ${hidden.owner}" else i " $fresh"
357339
358340 def overlapStr (hiddenSet : Refs , clashSet : Refs )(using Context ): String =
359341 val hiddenFootprint = hiddenSet.footprint
@@ -365,9 +347,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
365347 else
366348 val sharedPeaks = hiddenSet.peaks.sharedWith(clashSet.peaks)
367349 assert(! sharedPeaks.isEmpty, i " no overlap for $hiddenSet vs $clashSet" )
368- sharedPeaks.nth(0 ) match
369- case fresh @ Fresh .Cap (hidden) =>
370- if hidden.owner.exists then i " cap of ${hidden.owner}" else i " $fresh"
350+ sharedPeaksStr(sharedPeaks)
371351
372352 /** Report a separation failure in an application `fn(args)`
373353 * @param fn the function
@@ -429,7 +409,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
429409 */
430410 def sepUseError (tree : Tree , used : Refs , globalOverlap : Refs )(using Context ): Unit =
431411 val individualChecks = for mdefs <- previousDefs.iterator; mdef <- mdefs.iterator yield
432- val hiddenByDef = captures(mdef.tpt).hidden .footprint
412+ val hiddenByDef = captures(mdef.tpt).hiddenSet .footprint
433413 val overlap = defUseOverlap(hiddenByDef, used, tree.symbol)
434414 if ! overlap.isEmpty then
435415 def resultStr = if mdef.isInstanceOf [DefDef ] then " result" else " "
@@ -560,7 +540,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
560540 resultType.get(sym) match
561541 case Some (tp) if ! overlap.isEmpty =>
562542 val declared = tp.captureSet.elems
563- overlap.deduct(declared.footprint).deduct(declared.hidden .footprint)
543+ overlap.deduct(declared.footprint).deduct(declared.hiddenSet .footprint)
564544 case _ =>
565545 overlap
566546
@@ -784,7 +764,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
784764 // "see through them" when we look at hidden sets.
785765 then
786766 val refs = tpe.deepCaptureSet.elems
787- val toCheck = refs.hidden .footprint.deduct(refs.footprint)
767+ val toCheck = refs.hiddenSet .footprint.deduct(refs.footprint)
788768 checkConsumedRefs(toCheck, tpe, role, i " ${role.description} $tpe hides " , pos)
789769 case TypeRole .Argument (arg) =>
790770 if tpe.hasAnnotation(defn.ConsumeAnnot ) then
@@ -869,8 +849,8 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
869849 if ! tree.symbol.isOneOf(TermParamOrAccessor ) && ! isUnsafeAssumeSeparate(tree.rhs) then
870850 checkType(tree.tpt, tree.symbol)
871851 if previousDefs.nonEmpty then
872- capt.println(i " sep check def ${tree.symbol}: ${tree.tpt} with ${captures(tree.tpt).hidden .footprint}" )
873- defsShadow ++= captures(tree.tpt).hidden .deductSymRefs(tree.symbol).footprint
852+ capt.println(i " sep check def ${tree.symbol}: ${tree.tpt} with ${captures(tree.tpt).hiddenSet .footprint}" )
853+ defsShadow ++= captures(tree.tpt).hiddenSet .deductSymRefs(tree.symbol).footprint
874854 resultType(tree.symbol) = tree.tpt.nuType
875855 previousDefs.head += tree
876856
0 commit comments