@@ -66,21 +66,28 @@ class SepChecker(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
66
66
67
67
recur(refs)
68
68
end hidden
69
+
70
+ /** Deduct the footprint of `sym` and `sym*` from `refs` */
71
+ private def deductSym (sym : Symbol )(using Context ) =
72
+ val ref = sym.termRef
73
+ if ref.isTrackableRef then refs -- CaptureSet (ref, ref.reach).elems.footprint
74
+ else refs
75
+
76
+ /** Deduct the footprint of all captures of `deps` from `refs` */
77
+ private def deductCapturesOf (deps : List [Tree ])(using Context ): Refs =
78
+ deps.foldLeft(refs): (refs, dep) =>
79
+ refs -- captures(dep).footprint
69
80
end extension
70
81
71
82
/** The captures of an argument or prefix widened to the formal parameter, if
72
83
* the latter contains a cap.
73
84
*/
74
85
private def formalCaptures (arg : Tree )(using Context ): Refs =
75
- val argType = arg.formalType.orElse(arg.nuType)
76
- (if argType.hasUseAnnot then argType.deepCaptureSet else argType.captureSet)
77
- .elems
86
+ arg.formalType.orElse(arg.nuType).deepCaptureSet.elems
78
87
79
88
/** The captures of a node */
80
89
private def captures (tree : Tree )(using Context ): Refs =
81
- val tpe = tree.nuType
82
- (if tree.formalType.hasUseAnnot then tpe.deepCaptureSet else tpe.captureSet)
83
- .elems
90
+ tree.nuType.deepCaptureSet.elems
84
91
85
92
private def sepApplyError (fn : Tree , args : List [Tree ], argIdx : Int ,
86
93
overlap : Refs , hiddenInArg : Refs , footprints : List [(Refs , Int )],
@@ -144,7 +151,7 @@ class SepChecker(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
144
151
145
152
def sepUseError (tree : Tree , used : Refs , globalOverlap : Refs )(using Context ): Unit =
146
153
val individualChecks = for mdefs <- previousDefs.iterator; mdef <- mdefs.iterator yield
147
- val hiddenByDef = captures(mdef.tpt).hidden
154
+ val hiddenByDef = captures(mdef.tpt).hidden.footprint
148
155
val overlap = defUseOverlap(hiddenByDef, used, tree.symbol)
149
156
if ! overlap.isEmpty then
150
157
def resultStr = if mdef.isInstanceOf [DefDef ] then " result" else " "
@@ -172,20 +179,16 @@ class SepChecker(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
172
179
val footprints = mutable.ListBuffer [(Refs , Int )]((footprint, 0 ))
173
180
val indexedArgs = args.zipWithIndex
174
181
175
- def subtractDeps (elems : Refs , arg : Tree ): Refs =
176
- deps(arg).foldLeft(elems): (elems, dep) =>
177
- elems -- captures(dep).footprint
178
-
179
182
for (arg, idx) <- indexedArgs do
180
183
if ! arg.needsSepCheck then
181
- footprint = footprint ++ subtractDeps( captures(arg).footprint, arg)
184
+ footprint = footprint ++ captures(arg).footprint.deductCapturesOf(deps( arg) )
182
185
footprints += ((footprint, idx + 1 ))
183
186
for (arg, idx) <- indexedArgs do
184
187
if arg.needsSepCheck then
185
188
val ac = formalCaptures(arg)
186
189
val hiddenInArg = ac.hidden.footprint
187
190
// println(i"check sep $arg: $ac, footprint so far = $footprint, hidden = $hiddenInArg")
188
- val overlap = subtractDeps( hiddenInArg.overlapWith(footprint), arg)
191
+ val overlap = hiddenInArg.overlapWith(footprint).deductCapturesOf(deps( arg) )
189
192
if ! overlap.isEmpty then
190
193
sepApplyError(fn, args, idx, overlap, hiddenInArg, footprints.toList, deps)
191
194
footprint ++= captures(arg).footprint
@@ -267,7 +270,8 @@ class SepChecker(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
267
270
case tree : ValOrDefDef =>
268
271
traverseChildren(tree)
269
272
if previousDefs.nonEmpty && ! tree.symbol.isOneOf(TermParamOrAccessor ) then
270
- defsShadow ++= captures(tree.tpt).hidden.footprint
273
+ capt.println(i " sep check def ${tree.symbol}: ${tree.tpt} with ${captures(tree.tpt).hidden.footprint}" )
274
+ defsShadow ++= captures(tree.tpt).hidden.footprint.deductSym(tree.symbol)
271
275
resultType(tree.symbol) = tree.tpt.nuType
272
276
previousDefs.head += tree
273
277
case _ =>
0 commit comments