@@ -165,12 +165,11 @@ object SepCheck:
165
165
extension (refs : Refs )
166
166
167
167
/** The footprint of a set of references `refs` the smallest set `F` such that
168
- * 1. if includeMax is false then no maximal capability is in `F`
169
- * 2. all capabilities in `refs` satisfying (1) are in `F`
170
- * 3. if `f in F` then the footprint of `f`'s info is also in `F`.
168
+ * 1. all capabilities in `refs` satisfying (1) are in `F`
169
+ * 2. if `f in F` then the footprint of `f`'s info is also in `F`.
171
170
*/
172
- private def footprint (includeMax : Boolean = false )( using Context ): Refs =
173
- def retain (ref : Capability ) = includeMax || ! ref.isTerminalCapability
171
+ private def footprint (using Context ): Refs =
172
+ def retain (ref : Capability ) = ! ref.isTerminalCapability
174
173
def recur (elems : Refs , newElems : List [Capability ]): Refs = newElems match
175
174
case newElem :: newElems1 =>
176
175
val superElems = newElem.captureSetOfInfo.elems.filter: superElem =>
@@ -326,15 +325,14 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
326
325
i " $other"
327
326
328
327
def overlapStr (hiddenSet : Refs , clashSet : Refs )(using Context ): String =
329
- val hiddenFootprint = hiddenSet.footprint()
330
- val clashFootprint = clashSet.footprint()
328
+ val hiddenFootprint = hiddenSet.footprint
329
+ val clashFootprint = clashSet.footprint
331
330
// The overlap of footprints, or, of this empty the set of shared peaks.
332
331
// We prefer footprint overlap since it tends to be more informative.
333
332
val overlap = hiddenFootprint.overlapWith(clashFootprint)
334
333
if ! overlap.isEmpty then i " ${CaptureSet (overlap)}"
335
334
else
336
- val sharedPeaks = hiddenSet.footprint(includeMax = true ).sharedWith:
337
- clashSet.footprint(includeMax = true )
335
+ val sharedPeaks = hiddenSet.peaks.sharedWith(clashSet.peaks)
338
336
assert(! sharedPeaks.isEmpty, i " no overlap for $hiddenSet vs $clashSet" )
339
337
sharedPeaksStr(sharedPeaks)
340
338
@@ -386,9 +384,9 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
386
384
|Some of these overlap with the captures of the ${clashArgStr.trim}$clashTypeStr.
387
385
|
388
386
| Hidden set of current argument : ${CaptureSet (hiddenSet)}
389
- | Hidden footprint of current argument : ${CaptureSet (hiddenSet.footprint() )}
387
+ | Hidden footprint of current argument : ${CaptureSet (hiddenSet.footprint)}
390
388
| Capture set of $clashArgStr : ${CaptureSet (clashSet)}
391
- | Footprint set of $clashArgStr : ${CaptureSet (clashSet.footprint() )}
389
+ | Footprint set of $clashArgStr : ${CaptureSet (clashSet.footprint)}
392
390
| The two sets overlap at : ${overlapStr(hiddenSet, clashSet)}""" ,
393
391
polyArg.srcPos)
394
392
@@ -679,7 +677,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
679
677
val captured = genPart.deepCaptureSet.elems
680
678
val hiddenSet = captured.hiddenSet.pruned
681
679
val clashSet = otherPart.deepCaptureSet.elems
682
- val deepClashSet = (clashSet.footprint() ++ clashSet.hiddenSet).pruned
680
+ val deepClashSet = (clashSet.footprint ++ clashSet.hiddenSet).pruned
683
681
report.error(
684
682
em """ Separation failure in ${role.description} $tpe.
685
683
|One part, $genPart, hides capabilities ${CaptureSet (hiddenSet)}.
@@ -782,11 +780,11 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
782
780
// "see through them" when we look at hidden sets.
783
781
then
784
782
val refs = tpe.deepCaptureSet.elems
785
- val toCheck = refs.hiddenSet.footprint() .deduct(refs.footprint() )
783
+ val toCheck = refs.hiddenSet.footprint.deduct(refs.footprint)
786
784
checkConsumedRefs(toCheck, tpe, role, i " ${role.description} $tpe hides " , pos)
787
785
case TypeRole .Argument (arg) =>
788
786
if tpe.hasAnnotation(defn.ConsumeAnnot ) then
789
- val capts = captures(arg).footprint()
787
+ val capts = captures(arg).footprint
790
788
checkConsumedRefs(capts, tpe, role, i " argument to @consume parameter with type ${arg.nuType} refers to " , pos)
791
789
case _ =>
792
790
@@ -881,7 +879,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
881
879
def checkValOrDefDef (tree : ValOrDefDef )(using Context ): Unit =
882
880
if ! tree.symbol.isOneOf(TermParamOrAccessor ) && ! isUnsafeAssumeSeparate(tree.rhs) then
883
881
checkType(tree.tpt, tree.symbol)
884
- capt.println(i " sep check def ${tree.symbol}: ${tree.tpt} with ${captures(tree.tpt).hiddenSet.footprint() }" )
882
+ capt.println(i " sep check def ${tree.symbol}: ${tree.tpt} with ${captures(tree.tpt).hiddenSet.footprint}" )
885
883
pushDef(tree, captures(tree.tpt).hiddenSet.deductSymRefs(tree.symbol))
886
884
887
885
def inSection [T ](op : => T )(using Context ): T =
@@ -894,6 +892,13 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
894
892
895
893
def traverseSection [T ](tree : Tree )(using Context ) = inSection(traverseChildren(tree))
896
894
895
+ /** Should separatiion checking be disabled for the body of this method?
896
+ */
897
+ def skippable (sym : Symbol )(using Context ): Boolean =
898
+ sym.isInlineMethod
899
+ // We currently skip inline method bodies since these seem to generan
900
+ // spurious recheck completions. Test case is i20237.scala
901
+
897
902
/** Traverse `tree` and perform separation checks everywhere */
898
903
def traverse (tree : Tree )(using Context ): Unit =
899
904
if ! isUnsafeAssumeSeparate(tree) then trace(i " checking separate $tree" ):
@@ -902,7 +907,7 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
902
907
case tree @ Select (qual, _) if tree.symbol.is(Method ) && tree.symbol.isConsumeParam =>
903
908
traverseChildren(tree)
904
909
checkConsumedRefs(
905
- captures(qual).footprint() , qual.nuType,
910
+ captures(qual).footprint, qual.nuType,
906
911
TypeRole .Qualifier (qual, tree.symbol),
907
912
i " call prefix of @consume ${tree.symbol} refers to " , qual.srcPos)
908
913
case tree : GenericApply =>
@@ -916,15 +921,14 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
916
921
traverseChildren(tree)
917
922
checkValOrDefDef(tree)
918
923
case tree : DefDef =>
919
- if tree.symbol.isInlineMethod then
920
- // We currently skip inline method since these seem to generate
921
- // spurious recheck completions. Test case is i20237.scala
922
- capt.println(i " skipping sep check of inline def ${tree.symbol}" )
923
- else inSection :
924
- consumed.segment:
925
- for params <- tree.paramss; case param : ValDef <- params do
926
- pushDef(param, emptyRefs)
927
- traverseChildren(tree)
924
+ if skippable(tree.symbol) then
925
+ capt.println(i " skipping sep check of ${tree.symbol}" )
926
+ else
927
+ inSection :
928
+ consumed.segment:
929
+ for params <- tree.paramss; case param : ValDef <- params do
930
+ pushDef(param, emptyRefs)
931
+ traverseChildren(tree)
928
932
checkValOrDefDef(tree)
929
933
case If (cond, thenp, elsep) =>
930
934
traverse(cond)
0 commit comments