@@ -64,15 +64,15 @@ fn process<'tcx>(
6464    typing_env :  ty:: TypingEnv < ' tcx > , 
6565    caller :  ty:: Instance < ' tcx > , 
6666    target :  LocalDefId , 
67-     seen :  & mut  FxHashSet < ty:: Instance < ' tcx > > , 
67+     seen :  & mut  FxHashMap < ty:: Instance < ' tcx > ,   bool > , 
6868    involved :  & mut  FxHashSet < LocalDefId > , 
6969    recursion_limiter :  & mut  FxHashMap < DefId ,  usize > , 
7070    recursion_limit :  Limit , 
7171)  -> bool  { 
7272    trace ! ( %caller) ; 
73-     let  mut  cycle_found  = false ; 
73+     let  mut  reaches_root  = false ; 
7474
75-     for  & ( callee ,  args)  in  tcx. mir_inliner_callees ( caller. def )  { 
75+     for  & ( callee_def_id ,  args)  in  tcx. mir_inliner_callees ( caller. def )  { 
7676        let  Ok ( args)  = caller. try_instantiate_mir_and_normalize_erasing_regions ( 
7777            tcx, 
7878            typing_env, 
@@ -81,14 +81,17 @@ fn process<'tcx>(
8181            trace ! ( ?caller,  ?typing_env,  ?args,  "cannot normalize, skipping" ) ; 
8282            continue ; 
8383        } ; 
84-         let  Ok ( Some ( callee) )  = ty:: Instance :: try_resolve ( tcx,  typing_env,  callee,  args)  else  { 
85-             trace ! ( ?callee,  "cannot resolve, skipping" ) ; 
84+         let  Ok ( Some ( callee) )  = ty:: Instance :: try_resolve ( tcx,  typing_env,  callee_def_id,  args) 
85+         else  { 
86+             trace ! ( ?callee_def_id,  "cannot resolve, skipping" ) ; 
8687            continue ; 
8788        } ; 
8889
8990        // Found a path. 
9091        if  callee. def_id ( )  == target. to_def_id ( )  { 
91-             cycle_found = true ; 
92+             reaches_root = true ; 
93+             seen. insert ( callee,  true ) ; 
94+             continue ; 
9295        } 
9396
9497        if  tcx. is_constructor ( callee. def_id ( ) )  { 
@@ -101,10 +104,17 @@ fn process<'tcx>(
101104            continue ; 
102105        } 
103106
104-         if  seen. insert ( callee)  { 
107+         let  callee_reaches_root = if  let  Some ( & c)  = seen. get ( & callee)  { 
108+             // Even if we have seen this callee before, and thus don't need 
109+             // to recurse into it, we still need to propagate whether it reaches 
110+             // the root so that we can mark all the involved callers, in case we 
111+             // end up reaching that same recursive callee through some *other* cycle. 
112+             c
113+         }  else  { 
114+             seen. insert ( callee,  false ) ; 
105115            let  recursion = recursion_limiter. entry ( callee. def_id ( ) ) . or_default ( ) ; 
106116            trace ! ( ?callee,  recursion = * recursion) ; 
107-             let  found_recursion  = if  recursion_limit. value_within_limit ( * recursion)  { 
117+             let  callee_reaches_root  = if  recursion_limit. value_within_limit ( * recursion)  { 
108118                * recursion += 1 ; 
109119                ensure_sufficient_stack ( || { 
110120                    process ( 
@@ -122,17 +132,19 @@ fn process<'tcx>(
122132                // Pessimistically assume that there could be recursion. 
123133                true 
124134            } ; 
125-             if  found_recursion { 
126-                 if  let  Some ( callee)  = callee. def_id ( ) . as_local ( )  { 
127-                     // Calling `optimized_mir` of a non-local definition cannot cycle. 
128-                     involved. insert ( callee) ; 
129-                 } 
130-                 cycle_found = true ; 
135+             seen. insert ( callee,  callee_reaches_root) ; 
136+             callee_reaches_root
137+         } ; 
138+         if  callee_reaches_root { 
139+             if  let  Some ( callee_def_id)  = callee. def_id ( ) . as_local ( )  { 
140+                 // Calling `optimized_mir` of a non-local definition cannot cycle. 
141+                 involved. insert ( callee_def_id) ; 
131142            } 
143+             reaches_root = true ; 
132144        } 
133145    } 
134146
135-     cycle_found 
147+     reaches_root 
136148} 
137149
138150#[ instrument( level = "debug" ,  skip( tcx) ,  ret) ]  
@@ -166,7 +178,7 @@ pub(crate) fn mir_callgraph_cyclic<'tcx>(
166178        typing_env, 
167179        root_instance, 
168180        root, 
169-         & mut  FxHashSet :: default ( ) , 
181+         & mut  FxHashMap :: default ( ) , 
170182        & mut  involved, 
171183        & mut  FxHashMap :: default ( ) , 
172184        recursion_limit, 
0 commit comments