@@ -10,9 +10,7 @@ import config.SourceVersion
10
10
import config .Printers .capt
11
11
import util .Property .Key
12
12
import tpd .*
13
- import StdNames .nme
14
13
import config .Feature
15
- import collection .mutable
16
14
17
15
private val Captures : Key [CaptureSet ] = Key ()
18
16
private val BoxedType : Key [BoxedTypeCache ] = Key ()
@@ -23,11 +21,6 @@ private val BoxedType: Key[BoxedTypeCache] = Key()
23
21
*/
24
22
private val adaptUnpickledFunctionTypes = false
25
23
26
- /** Switch whether we constrain a root var that includes the source of a
27
- * root map to be an alias of that source (so that it can be mapped)
28
- */
29
- private val constrainRootsWhenMapping = true
30
-
31
24
/** The arguments of a @retains or @retainsByName annotation */
32
25
private [cc] def retainedElems (tree : Tree )(using Context ): List [Tree ] = tree match
33
26
case Apply (_, Typed (SeqLiteral (elems, _), _) :: Nil ) => elems
@@ -39,82 +32,12 @@ def allowUniversalInBoxed(using Context) =
39
32
/** An exception thrown if a @retains argument is not syntactically a CaptureRef */
40
33
class IllegalCaptureRef (tpe : Type ) extends Exception
41
34
42
- /** Capture checking state, which is stored in a context property */
43
- class CCState :
44
-
45
- val rhsClosure : mutable.HashSet [Symbol ] = new mutable.HashSet
46
-
47
- val levelOwners : mutable.HashSet [Symbol ] = new mutable.HashSet
48
-
49
- /** Associates certain symbols (the nesting level owners) with their ccNestingLevel */
50
- val nestingLevels : mutable.HashMap [Symbol , Int ] = new mutable.HashMap
51
-
52
- /** Associates nesting level owners with the local roots valid in their scopes. */
53
- val localRoots : mutable.HashMap [Symbol , Symbol ] = new mutable.HashMap
54
-
55
- /** The last pair of capture reference and capture set where
56
- * the reference could not be added to the set due to a level conflict.
57
- */
58
- var levelError : Option [(CaptureRef , CaptureSet )] = None
59
-
60
- /** Under saferExceptions: The <try block> symbol generated for a try.
61
- * Installed by Setup, removed by CheckCaptures.
62
- */
63
- val tryBlockOwner : mutable.HashMap [Try , Symbol ] = new mutable.HashMap
64
- end CCState
65
-
66
- /** Property key for capture checking state */
67
- val ccStateKey : Key [CCState ] = Key ()
68
-
69
- /** The currently valid CCState */
70
- def ccState (using Context ) = ctx.property(ccStateKey).get
71
-
72
- trait FollowAliases extends TypeMap :
73
- def mapOverFollowingAliases (t : Type ): Type = t match
74
- case t : LazyRef =>
75
- val t1 = this (t.ref)
76
- if t1 ne t.ref then t1 else t
77
- case _ =>
78
- val t1 = t.dealiasKeepAnnots
79
- if t1 ne t then
80
- val t2 = this (t1)
81
- if t2 ne t1 then return t2
82
- mapOver(t)
83
-
84
- class mapRoots (from : CaptureRoot , to : CaptureRoot )(using Context ) extends BiTypeMap , FollowAliases :
85
- thisMap =>
86
-
87
- def apply (t : Type ): Type =
88
- if t eq from then to
89
- else t match
90
- case t : CaptureRoot .Var =>
91
- val ta = t.followAlias
92
- if ta ne t then apply(ta)
93
- else from match
94
- case from : TermRef
95
- if t.upperLevel >= from.symbol.ccNestingLevel
96
- && constrainRootsWhenMapping // next two lines do the constraining
97
- && CaptureRoot .isEnclosingRoot(from, t)
98
- && CaptureRoot .isEnclosingRoot(t, from) => to
99
- case from : CaptureRoot .Var if from.followAlias eq t => to
100
- case _ => t
101
- case _ =>
102
- mapOverFollowingAliases(t)
103
-
104
- def inverse = mapRoots(to, from)
105
- end mapRoots
106
-
107
35
extension (tree : Tree )
108
36
109
37
/** Map tree with CaptureRef type to its type, throw IllegalCaptureRef otherwise */
110
- def toCaptureRef (using Context ): CaptureRef = tree match
111
- case QualifiedRoot (outer) =>
112
- ctx.owner.levelOwnerNamed(outer)
113
- .orElse(defn.captureRoot) // non-existing outer roots are reported in Setup's checkQualifiedRoots
114
- .localRoot.termRef
115
- case _ => tree.tpe match
116
- case ref : CaptureRef => ref
117
- case tpe => throw IllegalCaptureRef (tpe) // if this was compiled from cc syntax, problem should have been reported at Typer
38
+ def toCaptureRef (using Context ): CaptureRef = tree.tpe match
39
+ case ref : CaptureRef => ref
40
+ case tpe => throw IllegalCaptureRef (tpe)
118
41
119
42
/** Convert a @retains or @retainsByName annotation tree to the capture set it represents.
120
43
* For efficience, the result is cached as an Attachment on the tree.
@@ -241,7 +164,7 @@ extension (tp: Type)
241
164
* a by name parameter type, turning the latter into an impure by name parameter type.
242
165
*/
243
166
def adaptByNameArgUnderPureFuns (using Context ): Type =
244
- if adaptUnpickledFunctionTypes && Feature .pureFunsEnabledSomewhere then
167
+ if Feature .pureFunsEnabledSomewhere then
245
168
AnnotatedType (tp,
246
169
CaptureAnnotation (CaptureSet .universal, boxed = false )(defn.RetainsByNameAnnot ))
247
170
else
@@ -330,91 +253,6 @@ extension (sym: Symbol)
330
253
&& sym != defn.Caps_unsafeBox
331
254
&& sym != defn.Caps_unsafeUnbox
332
255
333
- def isLevelOwner (using Context ): Boolean = ccState.levelOwners.contains(sym)
334
-
335
- /** The owner of the current level. Qualifying owners are
336
- * - methods other than constructors and anonymous functions
337
- * - anonymous functions, provided they either define a local
338
- * root of type caps.Cap, or they are the rhs of a val definition.
339
- * - classes, if they are not staticOwners
340
- * - _root_
341
- */
342
- def levelOwner (using Context ): Symbol =
343
- if ! sym.exists || sym.isRoot || sym.isStaticOwner then defn.RootClass
344
- else if sym.isLevelOwner then sym
345
- else sym.owner.levelOwner
346
-
347
- /** The nesting level of `sym` for the purposes of `cc`,
348
- * -1 for NoSymbol
349
- */
350
- def ccNestingLevel (using Context ): Int =
351
- if sym.exists then
352
- val lowner = sym.levelOwner
353
- ccState.nestingLevels.getOrElseUpdate(lowner,
354
- if lowner.isRoot then 0 else lowner.owner.ccNestingLevel + 1 )
355
- else - 1
356
-
357
- /** Optionally, the nesting level of `sym` for the purposes of `cc`, provided
358
- * a capture checker is running.
359
- */
360
- def ccNestingLevelOpt (using Context ): Option [Int ] =
361
- if ctx.property(ccStateKey).isDefined then Some (ccNestingLevel) else None
362
-
363
- /** The parameter with type caps.Cap in the leading term parameter section,
364
- * or NoSymbol, if none exists.
365
- */
366
- def definedLocalRoot (using Context ): Symbol =
367
- sym.paramSymss.dropWhile(psyms => psyms.nonEmpty && psyms.head.isType) match
368
- case psyms :: _ => psyms.find(_.info.typeSymbol == defn.Caps_Cap ).getOrElse(NoSymbol )
369
- case _ => NoSymbol
370
-
371
- /** The local root corresponding to sym's level owner */
372
- def localRoot (using Context ): Symbol =
373
- val owner = sym.levelOwner
374
- assert(owner.exists)
375
- def newRoot = newSymbol(if owner.isClass then newLocalDummy(owner) else owner,
376
- nme.LOCAL_CAPTURE_ROOT , Synthetic , defn.Caps_Cap .typeRef, nestingLevel = owner.ccNestingLevel)
377
- def lclRoot =
378
- if owner.isTerm then owner.definedLocalRoot.orElse(newRoot)
379
- else newRoot
380
- ccState.localRoots.getOrElseUpdate(owner, lclRoot)
381
-
382
- /** The level owner enclosing `sym` which has the given name, or NoSymbol if none exists.
383
- * If name refers to a val that has a closure as rhs, we return the closure as level
384
- * owner.
385
- */
386
- def levelOwnerNamed (name : String )(using Context ): Symbol =
387
- def recur (owner : Symbol , prev : Symbol ): Symbol =
388
- if owner.name.toString == name then
389
- if owner.isLevelOwner then owner
390
- else if owner.isTerm && ! owner.isOneOf(Method | Module ) && prev.exists then prev
391
- else NoSymbol
392
- else if owner == defn.RootClass then
393
- NoSymbol
394
- else
395
- val prev1 = if owner.isAnonymousFunction && owner.isLevelOwner then owner else NoSymbol
396
- recur(owner.owner, prev1)
397
- recur(sym, NoSymbol )
398
- .showing(i " find outer $sym [ $name ] = $result" , capt)
399
-
400
- def maxNested (other : Symbol )(using Context ): Symbol =
401
- if sym.ccNestingLevel < other.ccNestingLevel then other else sym
402
- /* does not work yet, we do mix sets with different levels, for instance in cc-this.scala.
403
- else if sym.ccNestingLevel > other.ccNestingLevel then sym
404
- else
405
- assert(sym == other, i"conflicting symbols at same nesting level: $sym, $other")
406
- sym
407
- */
408
-
409
- def minNested (other : Symbol )(using Context ): Symbol =
410
- if sym.ccNestingLevel > other.ccNestingLevel then other else sym
411
-
412
- extension (tp : TermRef | ThisType )
413
- /** The nesting level of this reference as defined by capture checking */
414
- def ccNestingLevel (using Context ): Int = tp match
415
- case tp : TermRef => tp.symbol.ccNestingLevel
416
- case tp : ThisType => tp.cls.ccNestingLevel
417
-
418
256
extension (tp : AnnotatedType )
419
257
/** Is this a boxed capturing type? */
420
258
def isBoxed (using Context ): Boolean = tp.annot match
0 commit comments