File tree 1 file changed +10
-5
lines changed
compiler/src/dotty/tools/dotc/transform
1 file changed +10
-5
lines changed Original file line number Diff line number Diff line change @@ -175,18 +175,23 @@ class TailRec extends MiniPhase {
175
175
).transform(rhsSemiTransformed)
176
176
}
177
177
178
- // Is a simple this a simple recursive tail call, possibly with swapped or modified pure arguments
178
+ /** Is the RHS a direct recursive tailcall, possibly with swapped arguments or modified pure arguments.
179
+ * ```
180
+ * def f(<params>): T = f(<args>)
181
+ * ```
182
+ * where `<args>` are pure arguments or references to parameters in `<params>`.
183
+ */
179
184
def isInfiniteRecCall (tree : Tree ): Boolean = {
180
- def statOk (stat : Tree ): Boolean = stat match {
181
- case stat : ValDef if stat.name.is(TailTempName ) || ! stat.symbol.is(Mutable ) => statOk (stat.rhs)
182
- case Assign (lhs : Ident , rhs) if lhs.symbol.name.is(TailLocalName ) => statOk (rhs)
185
+ def tailArgOrPureExpr (stat : Tree ): Boolean = stat match {
186
+ case stat : ValDef if stat.name.is(TailTempName ) || ! stat.symbol.is(Mutable ) => tailArgOrPureExpr (stat.rhs)
187
+ case Assign (lhs : Ident , rhs) if lhs.symbol.name.is(TailLocalName ) => tailArgOrPureExpr (rhs)
183
188
case stat : Ident if stat.symbol.name.is(TailLocalName ) => true
184
189
case _ => tpd.isPureExpr(stat)
185
190
}
186
191
tree match {
187
192
case Typed (expr, _) => isInfiniteRecCall(expr)
188
193
case Return (Literal (Constant (())), label) => label.symbol == transformer.continueLabel
189
- case Block (stats, expr) => stats.forall(statOk ) && isInfiniteRecCall(expr)
194
+ case Block (stats, expr) => stats.forall(tailArgOrPureExpr ) && isInfiniteRecCall(expr)
190
195
case _ => false
191
196
}
192
197
}
You can’t perform that action at this time.
0 commit comments