@@ -50,6 +50,9 @@ class DropBreaks extends MiniPhase, RecordStackChange:
50
50
override def runsAfterGroupsOf : Set [String ] = Set (ElimByName .name)
51
51
// we want by-name parameters to be converted to closures
52
52
53
+ /** The number of boundary nodes enclosing the currently analized tree. */
54
+ var enclosingBoundaries : Int = 0
55
+
53
56
private object LabelTry :
54
57
55
58
object GuardedThrow :
@@ -136,6 +139,7 @@ class DropBreaks extends MiniPhase, RecordStackChange:
136
139
/** If `tree` is a BreakBoundary, associate a fresh `LabelUsage` with its label. */
137
140
override def prepareForBlock (tree : Block )(using Context ): Context = tree match
138
141
case BreakBoundary (label, _) =>
142
+ enclosingBoundaries += 1
139
143
val mapSoFar = ctx.property(LabelUsages ).getOrElse(Map .empty)
140
144
val goto = newSymbol(ctx.owner, BoundaryName .fresh(), Synthetic | Label , tree.tpe)
141
145
ctx.fresh.setProperty(LabelUsages ,
@@ -157,17 +161,22 @@ class DropBreaks extends MiniPhase, RecordStackChange:
157
161
/** Need to suppress labeled returns if the stack can change between
158
162
* source and target of the jump
159
163
*/
160
- protected def stackChange (using Context ) = shadowLabels
164
+ protected def stackChange (using Context ) =
165
+ if enclosingBoundaries == 0 then ctx else shadowLabels
161
166
162
167
/** Need to suppress labeled returns if there is an intervening try
163
168
*/
164
- override def prepareForTry (tree : Try )(using Context ): Context = tree match
165
- case LabelTry (_, _) => ctx
166
- case _ => shadowLabels
167
-
168
- override def prepareForApply (tree : Apply )(using Context ): Context = tree match
169
- case Break (_, _) => ctx
170
- case _ => stackChange
169
+ override def prepareForTry (tree : Try )(using Context ): Context =
170
+ if enclosingBoundaries == 0 then ctx
171
+ else tree match
172
+ case LabelTry (_, _) => ctx
173
+ case _ => shadowLabels
174
+
175
+ override def prepareForApply (tree : Apply )(using Context ): Context =
176
+ if enclosingBoundaries == 0 then ctx
177
+ else tree match
178
+ case Break (_, _) => ctx
179
+ case _ => stackChange
171
180
172
181
// other stack changing operations are handled in RecordStackChange
173
182
@@ -177,6 +186,7 @@ class DropBreaks extends MiniPhase, RecordStackChange:
177
186
*/
178
187
override def transformBlock (tree : Block )(using Context ): Tree = tree match
179
188
case BreakBoundary (label, expr) =>
189
+ enclosingBoundaries -= 1
180
190
val uses = ctx.property(LabelUsages ).get(label)
181
191
val tree1 =
182
192
if uses.otherRefs > 1 then
@@ -200,26 +210,29 @@ class DropBreaks extends MiniPhase, RecordStackChange:
200
210
* and the non-local refcount is decreased, since `local` the `Label_this`
201
211
* binding containing `local` is dropped.
202
212
*/
203
- override def transformApply (tree : Apply )(using Context ): Tree = tree match
204
- case Break (lbl, arg) =>
205
- labelUsage(lbl) match
206
- case Some (uses : LabelUsage )
207
- if uses.enclMeth == ctx.owner.enclosingMethod
208
- && ! ctx.property(ShadowedLabels ).getOrElse(Set .empty).contains(lbl)
209
- =>
210
- uses.otherRefs -= 1
211
- uses.returnRefs += 1
212
- Return (arg, ref(uses.goto)).withSpan(arg.span)
213
- case _ => tree
214
- case _ => tree
213
+ override def transformApply (tree : Apply )(using Context ): Tree =
214
+ if enclosingBoundaries == 0 then tree
215
+ else tree match
216
+ case Break (lbl, arg) =>
217
+ labelUsage(lbl) match
218
+ case Some (uses : LabelUsage )
219
+ if uses.enclMeth == ctx.owner.enclosingMethod
220
+ && ! ctx.property(ShadowedLabels ).getOrElse(Set .empty).contains(lbl)
221
+ =>
222
+ uses.otherRefs -= 1
223
+ uses.returnRefs += 1
224
+ Return (arg, ref(uses.goto)).withSpan(arg.span)
225
+ case _ => tree
226
+ case _ => tree
215
227
216
228
/** If `tree` refers to an enclosing label, increase its non local recount.
217
229
* This increase is corrected in `transformInlined` if the reference turns
218
230
* out to be part of a BreakThrow to a local, non-shadowed label.
219
231
*/
220
232
override def transformIdent (tree : Ident )(using Context ): Tree =
221
- for uses <- labelUsage(tree.symbol) do
222
- uses.otherRefs += 1
233
+ if enclosingBoundaries != 0 then
234
+ for uses <- labelUsage(tree.symbol) do
235
+ uses.otherRefs += 1
223
236
tree
224
237
225
238
end DropBreaks
0 commit comments