@@ -28,7 +28,12 @@ fn check_fn_for_unconditional_recursion<'tcx>(
2828 def_id : DefId ,
2929) {
3030 let self_calls = find_blocks_calling_self ( tcx, & body, def_id) ;
31+
32+ // Stores a list of `Span`s for every basic block. Those are the spans of `Call` terminators
33+ // where we know that one of them will definitely be reached.
3134 let mut results = IndexVec :: from_elem_n ( vec ! [ ] , body. basic_blocks ( ) . len ( ) ) ;
35+
36+ // We start the analysis at the self calls and work backwards.
3237 let mut queue: VecDeque < _ > = self_calls. iter ( ) . collect ( ) ;
3338
3439 while let Some ( bb) = queue. pop_front ( ) {
@@ -39,6 +44,8 @@ fn check_fn_for_unconditional_recursion<'tcx>(
3944
4045 let locations = if self_calls. contains ( bb) {
4146 // `bb` *is* a self-call.
47+ // We don't look at successors here because they are irrelevant here and we don't want
48+ // to lint them (eg. `f(); f()` should only lint the first call).
4249 vec ! [ bb]
4350 } else {
4451 // If *all* successors of `bb` lead to a self-call, emit notes at all of their
@@ -69,12 +76,16 @@ fn check_fn_for_unconditional_recursion<'tcx>(
6976 }
7077 } ;
7178
79+ // If all our successors are known to lead to self-calls, then we do too.
7280 let all_are_self_calls =
7381 relevant_successors. clone ( ) . all ( |& succ| !results[ succ] . is_empty ( ) ) ;
7482
7583 if all_are_self_calls {
84+ // We'll definitely lead to a self-call. Merge all call locations of the successors
85+ // for linting them later.
7686 relevant_successors. flat_map ( |& succ| results[ succ] . iter ( ) . copied ( ) ) . collect ( )
7787 } else {
88+ // At least 1 successor does not always lead to a self-call, so we also don't.
7889 vec ! [ ]
7990 }
8091 } ;
0 commit comments