@@ -38,7 +38,7 @@ object DropBreaks:
38
38
* - the throw and the boundary are in the same method, and
39
39
* - there is no try expression inside the boundary that encloses the throw.
40
40
*/
41
- class DropBreaks extends MiniPhase , RecordStackChange :
41
+ class DropBreaks extends MiniPhase :
42
42
import DropBreaks .*
43
43
44
44
import tpd ._
@@ -158,12 +158,6 @@ class DropBreaks extends MiniPhase, RecordStackChange:
158
158
ctx.fresh.setProperty(ShadowedLabels , setSoFar ++ usesMap.keysIterator)
159
159
case _ => ctx
160
160
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
-
167
161
/** Need to suppress labeled returns if there is an intervening try
168
162
*/
169
163
override def prepareForTry (tree : Try )(using Context ): Context =
@@ -172,18 +166,13 @@ class DropBreaks extends MiniPhase, RecordStackChange:
172
166
case LabelTry (_, _) => ctx
173
167
case _ => shadowLabels
174
168
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
-
181
169
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
183
174
else ctx
184
175
185
- // other stack changing operations are handled in RecordStackChange
186
-
187
176
/** If `tree` is a BreakBoundary, transform it as follows:
188
177
* - Wrap it in a labeled block if its label has local uses
189
178
* - Drop the try/catch if its label has no other uses
@@ -203,7 +192,27 @@ class DropBreaks extends MiniPhase, RecordStackChange:
203
192
case _ =>
204
193
tree
205
194
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
+ *
207
216
* where `lbl` is a label defined in the current method and is not included in
208
217
* ShadowedLabels to
209
218
*
0 commit comments