@@ -196,8 +196,6 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx
196196 | TerminatorKind :: CoroutineDrop
197197 | TerminatorKind :: UnwindResume
198198 | TerminatorKind :: Return
199- // FIXME(explicit_tail_calls) Is this right??
200- | TerminatorKind :: TailCall { .. }
201199 | TerminatorKind :: Unreachable
202200 | TerminatorKind :: Yield { .. } => ControlFlow :: Break ( NonRecursive ) ,
203201
@@ -218,12 +216,28 @@ impl<'mir, 'tcx, C: TerminatorClassifier<'tcx>> TriColorVisitor<BasicBlocks<'tcx
218216 | TerminatorKind :: FalseUnwind { .. }
219217 | TerminatorKind :: Goto { .. }
220218 | TerminatorKind :: SwitchInt { .. } => ControlFlow :: Continue ( ( ) ) ,
219+
220+ // Note that tail call terminator technically returns to the caller,
221+ // but for purposes of this lint it makes sense to count it as possibly recursive,
222+ // since it's still a call.
223+ //
224+ // If this'll be repurposed for something else, this might need to be changed.
225+ TerminatorKind :: TailCall { .. } => ControlFlow :: Continue ( ( ) ) ,
221226 }
222227 }
223228
224229 fn node_settled ( & mut self , bb : BasicBlock ) -> ControlFlow < Self :: BreakVal > {
225230 // When we examine a node for the last time, remember it if it is a recursive call.
226231 let terminator = self . body [ bb] . terminator ( ) ;
232+
233+ // FIXME(explicit_tail_calls): highlight tail calls as "recursive call site"
234+ //
235+ // We don't want to lint functions that recurse only through tail calls
236+ // (such as `fn g() { become () }`), so just adding `| TailCall { ... }`
237+ // here won't work.
238+ //
239+ // But at the same time we would like to highlight both calls in a function like
240+ // `fn f() { if false { become f() } else { f() } }`, so we need to figure something out.
227241 if self . classifier . is_recursive_terminator ( self . tcx , self . body , terminator) {
228242 self . reachable_recursive_calls . push ( terminator. source_info . span ) ;
229243 }
0 commit comments