@@ -50,6 +50,9 @@ class DropBreaks extends MiniPhase, RecordStackChange:
5050 override def runsAfterGroupsOf : Set [String ] = Set (ElimByName .name)
5151 // we want by-name parameters to be converted to closures
5252
53+ /** The number of boundary nodes enclosing the currently analized tree. */
54+ var enclosingBoundaries : Int = 0
55+
5356 private object LabelTry :
5457
5558 object GuardedThrow :
@@ -136,6 +139,7 @@ class DropBreaks extends MiniPhase, RecordStackChange:
136139 /** If `tree` is a BreakBoundary, associate a fresh `LabelUsage` with its label. */
137140 override def prepareForBlock (tree : Block )(using Context ): Context = tree match
138141 case BreakBoundary (label, _) =>
142+ enclosingBoundaries += 1
139143 val mapSoFar = ctx.property(LabelUsages ).getOrElse(Map .empty)
140144 val goto = newSymbol(ctx.owner, BoundaryName .fresh(), Synthetic | Label , tree.tpe)
141145 ctx.fresh.setProperty(LabelUsages ,
@@ -157,17 +161,22 @@ class DropBreaks extends MiniPhase, RecordStackChange:
157161 /** Need to suppress labeled returns if the stack can change between
158162 * source and target of the jump
159163 */
160- protected def stackChange (using Context ) = shadowLabels
164+ protected def stackChange (using Context ) =
165+ if enclosingBoundaries == 0 then ctx else shadowLabels
161166
162167 /** Need to suppress labeled returns if there is an intervening try
163168 */
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
171180
172181 // other stack changing operations are handled in RecordStackChange
173182
@@ -177,6 +186,7 @@ class DropBreaks extends MiniPhase, RecordStackChange:
177186 */
178187 override def transformBlock (tree : Block )(using Context ): Tree = tree match
179188 case BreakBoundary (label, expr) =>
189+ enclosingBoundaries -= 1
180190 val uses = ctx.property(LabelUsages ).get(label)
181191 val tree1 =
182192 if uses.otherRefs > 1 then
@@ -200,26 +210,29 @@ class DropBreaks extends MiniPhase, RecordStackChange:
200210 * and the non-local refcount is decreased, since `local` the `Label_this`
201211 * binding containing `local` is dropped.
202212 */
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
215227
216228 /** If `tree` refers to an enclosing label, increase its non local recount.
217229 * This increase is corrected in `transformInlined` if the reference turns
218230 * out to be part of a BreakThrow to a local, non-shadowed label.
219231 */
220232 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
223236 tree
224237
225238end DropBreaks
0 commit comments