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