@@ -48,134 +48,6 @@ class IllegalCaptureRef(tpe: Type)(using Context) extends Exception(tpe.show)
48
48
/** A base trait for data producing addenda to error messages */
49
49
trait ErrorNote
50
50
51
- /** Capture checking state, which is known to other capture checking components */
52
- class CCState :
53
-
54
- /** Error reprting notes produces since the last call to `test` */
55
- var notes : List [ErrorNote ] = Nil
56
-
57
- def addNote (note : ErrorNote ): Unit =
58
- if ! notes.exists(_.getClass == note.getClass) then
59
- notes = note :: notes
60
-
61
- def test (op : => CompareResult ): CompareResult =
62
- val saved = notes
63
- notes = Nil
64
- try op match
65
- case res : CompareFailure => res.withNotes(notes)
66
- case res => res
67
- finally notes = saved
68
-
69
- def testOK (op : => Boolean ): CompareResult =
70
- test(if op then CompareResult .OK else CompareResult .Fail (Nil ))
71
-
72
- /** Warnings relating to upper approximations of capture sets with
73
- * existentially bound variables.
74
- */
75
- val approxWarnings : mutable.ListBuffer [Message ] = mutable.ListBuffer ()
76
-
77
- private var curLevel : Level = outermostLevel
78
- private val symLevel : mutable.Map [Symbol , Int ] = mutable.Map ()
79
-
80
- private var openExistentialScopes : List [MethodType ] = Nil
81
-
82
- private var capIsRoot : Boolean = false
83
-
84
- /** If true, apply a BiTypeMap also to elements added to the set in the future
85
- * (and use its inverse when back-progating).
86
- */
87
- private var mapFutureElems = true
88
-
89
- var iterCount = 1
90
-
91
- object CCState :
92
-
93
- opaque type Level = Int
94
-
95
- val undefinedLevel : Level = - 1
96
-
97
- val outermostLevel : Level = 0
98
-
99
- /** The level of the current environment. Levels start at 0 and increase for
100
- * each nested function or class. -1 means the level is undefined.
101
- */
102
- def currentLevel (using Context ): Level = ccState.curLevel
103
-
104
- /** Perform `op` in the next inner level
105
- * @pre We are currently in capture checking or setup
106
- */
107
- inline def inNestedLevel [T ](inline op : T )(using Context ): T =
108
- val ccs = ccState
109
- val saved = ccs.curLevel
110
- ccs.curLevel = ccs.curLevel.nextInner
111
- try op finally ccs.curLevel = saved
112
-
113
- /** Perform `op` in the next inner level unless `p` holds.
114
- * @pre We are currently in capture checking or setup
115
- */
116
- inline def inNestedLevelUnless [T ](inline p : Boolean )(inline op : T )(using Context ): T =
117
- val ccs = ccState
118
- val saved = ccs.curLevel
119
- if ! p then ccs.curLevel = ccs.curLevel.nextInner
120
- try op finally ccs.curLevel = saved
121
-
122
- /** If we are currently in capture checking or setup, and `mt` is a method
123
- * type that is not a prefix of a curried method, perform `op` assuming
124
- * a fresh enclosing existential scope `mt`, otherwise perform `op` directly.
125
- */
126
- inline def inNewExistentialScope [T ](mt : MethodType )(op : => T )(using Context ): T =
127
- if isCaptureCheckingOrSetup then
128
- val ccs = ccState
129
- val saved = ccs.openExistentialScopes
130
- if mt.marksExistentialScope then ccs.openExistentialScopes = mt :: ccs.openExistentialScopes
131
- try op finally ccs.openExistentialScopes = saved
132
- else
133
- op
134
-
135
- /** Run `op` under the assumption that `cap` can subsume all other capabilties
136
- * except Result capabilities. Every use of this method should be scrutinized
137
- * for whether it introduces an unsoundness hole.
138
- */
139
- inline def withCapAsRoot [T ](op : => T )(using Context ): T =
140
- if isCaptureCheckingOrSetup then
141
- val ccs = ccState
142
- val saved = ccs.capIsRoot
143
- ccs.capIsRoot = true
144
- try op finally ccs.capIsRoot = saved
145
- else op
146
-
147
- /** Don't map future elements in this `op` */
148
- inline def withoutMappedFutureElems [T ](op : => T )(using Context ): T =
149
- val ccs = ccState
150
- val saved = ccs.mapFutureElems
151
- ccs.mapFutureElems = false
152
- try op finally ccs.mapFutureElems = saved
153
-
154
- /** Is `caps.cap` a root capability that is allowed to subsume other capabilities? */
155
- def capIsRoot (using Context ): Boolean = ccState.capIsRoot
156
-
157
- /** When mapping a capture set with a BiTypeMap, should we create a BiMapped set
158
- * so that future elements can also be mapped, and elements added to the BiMapped
159
- * are back-propagated? Turned off when creating capture set variables for the
160
- * first time, since we then do not want to change the binder to the original type
161
- * without capture sets when back propagating. Error case where this shows:
162
- * pos-customargs/captures/lists.scala, method m2c.
163
- */
164
- def mapFutureElems (using Context ) = ccState.mapFutureElems
165
-
166
- /** The currently opened existential scopes */
167
- def openExistentialScopes (using Context ): List [MethodType ] = ccState.openExistentialScopes
168
-
169
- extension (x : Level )
170
- def isDefined : Boolean = x >= 0
171
- def <= (y : Level ) = (x : Int ) <= y
172
- def nextInner : Level = if isDefined then x + 1 else x
173
-
174
- extension (sym : Symbol )(using Context )
175
- def ccLevel : Level = ccState.symLevel.getOrElse(sym, - 1 )
176
- def recordLevel () = ccState.symLevel(sym) = currentLevel
177
- end CCState
178
-
179
51
/** The currently valid CCState */
180
52
def ccState (using Context ): CCState =
181
53
Phases .checkCapturesPhase.asInstanceOf [CheckCaptures ].ccState1
@@ -631,8 +503,8 @@ extension (tp: Type)
631
503
632
504
def level (using Context ): Level =
633
505
tp match
634
- case tp : TermRef => tp.symbol.ccLevel
635
- case tp : ThisType => tp.cls.ccLevel .nextInner
506
+ case tp : TermRef => ccState.symLevel( tp.symbol)
507
+ case tp : ThisType => ccState.symLevel( tp.cls) .nextInner
636
508
case _ => undefinedLevel
637
509
638
510
extension (tp : MethodType )
0 commit comments