@@ -13,6 +13,7 @@ use rustc_middle::bug;
1313use rustc_middle:: mir;
1414use rustc_middle:: mir:: coverage:: CodeRegion ;
1515use rustc_middle:: ty:: { self , TyCtxt } ;
16+ use rustc_span:: def_id:: DefIdSet ;
1617use rustc_span:: Symbol ;
1718
1819/// Generates and exports the Coverage Map.
@@ -313,8 +314,7 @@ fn save_function_record(
313314/// `-Clink-dead-code` will not generate code for unused generic functions.)
314315///
315316/// We can find the unused functions (including generic functions) by the set difference of all MIR
316- /// `DefId`s (`tcx` query `mir_keys`) minus the codegenned `DefId`s (`tcx` query
317- /// `codegened_and_inlined_items`).
317+ /// `DefId`s (`tcx` query `mir_keys`) minus the codegenned `DefId`s (`codegenned_and_inlined_items`).
318318///
319319/// These unused functions don't need to be codegenned, but we do need to add them to the function
320320/// coverage map (in a single designated CGU) so that we still emit coverage mappings for them.
@@ -350,7 +350,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
350350 } )
351351 . collect ( ) ;
352352
353- let codegenned_def_ids = tcx . codegened_and_inlined_items ( ( ) ) ;
353+ let codegenned_def_ids = codegenned_and_inlined_items ( tcx ) ;
354354
355355 // For each `DefId` that should have coverage instrumentation but wasn't
356356 // codegenned, add it to the function coverage map as an unused function.
@@ -368,6 +368,37 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
368368 }
369369}
370370
371+ /// All items participating in code generation together with (instrumented)
372+ /// items inlined into them.
373+ fn codegenned_and_inlined_items ( tcx : TyCtxt < ' _ > ) -> DefIdSet {
374+ let ( items, cgus) = tcx. collect_and_partition_mono_items ( ( ) ) ;
375+ let mut visited = DefIdSet :: default ( ) ;
376+ let mut result = items. clone ( ) ;
377+
378+ for cgu in cgus {
379+ for item in cgu. items ( ) . keys ( ) {
380+ if let mir:: mono:: MonoItem :: Fn ( ref instance) = item {
381+ let did = instance. def_id ( ) ;
382+ if !visited. insert ( did) {
383+ continue ;
384+ }
385+ let body = tcx. instance_mir ( instance. def ) ;
386+ for block in body. basic_blocks . iter ( ) {
387+ for statement in & block. statements {
388+ let mir:: StatementKind :: Coverage ( _) = statement. kind else { continue } ;
389+ let scope = statement. source_info . scope ;
390+ if let Some ( inlined) = scope. inlined_instance ( & body. source_scopes ) {
391+ result. insert ( inlined. def_id ( ) ) ;
392+ }
393+ }
394+ }
395+ }
396+ }
397+ }
398+
399+ result
400+ }
401+
371402fn declare_unused_fn < ' tcx > ( tcx : TyCtxt < ' tcx > , def_id : DefId ) -> ty:: Instance < ' tcx > {
372403 ty:: Instance :: new (
373404 def_id,
0 commit comments