@@ -38,7 +38,7 @@ object DropBreaks:
3838 * - the throw and the boundary are in the same method, and
3939 * - there is no try expression inside the boundary that encloses the throw.
4040 */
41- class DropBreaks extends MiniPhase , RecordStackChange :
41+ class DropBreaks extends MiniPhase :
4242 import DropBreaks .*
4343
4444 import tpd ._
@@ -158,12 +158,6 @@ class DropBreaks extends MiniPhase, RecordStackChange:
158158 ctx.fresh.setProperty(ShadowedLabels , setSoFar ++ usesMap.keysIterator)
159159 case _ => ctx
160160
161- /** Need to suppress labeled returns if the stack can change between
162- * source and target of the jump
163- */
164- protected def stackChange (using Context ) =
165- ctx // if enclosingBoundaries == 0 then ctx else shadowLabels
166-
167161 /** Need to suppress labeled returns if there is an intervening try
168162 */
169163 override def prepareForTry (tree : Try )(using Context ): Context =
@@ -172,18 +166,13 @@ class DropBreaks extends MiniPhase, RecordStackChange:
172166 case LabelTry (_, _) => ctx
173167 case _ => shadowLabels
174168
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
180-
181169 override def prepareForValDef (tree : ValDef )(using Context ): Context =
182- if tree.symbol.is(Lazy ) && tree.symbol.owner == ctx.owner.enclosingMethod then shadowLabels
170+ if enclosingBoundaries != 0
171+ && tree.symbol.is(Lazy )
172+ && tree.symbol.owner == ctx.owner.enclosingMethod
173+ then shadowLabels // RHS be converted to a lambda
183174 else ctx
184175
185- // other stack changing operations are handled in RecordStackChange
186-
187176 /** If `tree` is a BreakBoundary, transform it as follows:
188177 * - Wrap it in a labeled block if its label has local uses
189178 * - Drop the try/catch if its label has no other uses
@@ -203,7 +192,27 @@ class DropBreaks extends MiniPhase, RecordStackChange:
203192 case _ =>
204193 tree
205194
206- /** Rewrite a break with argument `arg` and label `lbl`
195+ private def isBreak (sym : Symbol )(using Context ): Boolean =
196+ sym.name == nme.apply && sym.owner == defn.breakModule.moduleClass
197+
198+ private def transformBreak (tree : Tree , arg : Tree , lbl : Symbol )(using Context ): Tree =
199+ report.log(i " transform break $tree/ $arg/ $lbl" )
200+ labelUsage(lbl) match
201+ case Some (uses : LabelUsage )
202+ if uses.enclMeth == ctx.owner.enclosingMethod
203+ && ! ctx.property(ShadowedLabels ).getOrElse(Set .empty).contains(lbl)
204+ =>
205+ uses.otherRefs -= 1
206+ uses.returnRefs += 1
207+ Return (arg, ref(uses.goto)).withSpan(arg.span)
208+ case _ =>
209+ tree
210+
211+
212+ /** Rewrite a break call
213+ *
214+ * break.apply[...](value)(using lbl)
215+ *
207216 * where `lbl` is a label defined in the current method and is not included in
208217 * ShadowedLabels to
209218 *
0 commit comments