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