@@ -353,10 +353,11 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
353353
354354 // To be eligible for "unused function" mappings, a definition must:
355355 // - Be function-like
356- // - Not participate directly in codegen
356+ // - Not participate directly in codegen (or have lost all its coverage statements)
357357 // - Not have any coverage statements inlined into codegenned functions
358358 tcx. def_kind ( def_id) . is_fn_like ( )
359- && !usage. all_mono_items . contains ( & def_id)
359+ && ( !usage. all_mono_items . contains ( & def_id)
360+ || usage. missing_own_coverage . contains ( & def_id) )
360361 && !usage. used_via_inlining . contains ( & def_id)
361362 } ;
362363
@@ -379,6 +380,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
379380struct UsageSets < ' tcx > {
380381 all_mono_items : & ' tcx DefIdSet ,
381382 used_via_inlining : FxHashSet < DefId > ,
383+ missing_own_coverage : FxHashSet < DefId > ,
382384}
383385
384386/// Prepare sets of definitions that are relevant to deciding whether something
@@ -408,8 +410,13 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
408410
409411 // Functions whose coverage statments were found inlined into other functions.
410412 let mut used_via_inlining = FxHashSet :: default ( ) ;
413+ // Functions that were instrumented, but had all of their coverage statements
414+ // removed by later MIR transforms (e.g. UnreachablePropagation).
415+ let mut missing_own_coverage = FxHashSet :: default ( ) ;
416+
417+ for ( def_id, body) in def_and_mir_for_all_mono_fns {
418+ let mut saw_own_coverage = false ;
411419
412- for ( _def_id, body) in def_and_mir_for_all_mono_fns {
413420 // Inspect every coverage statement in the function's MIR.
414421 for stmt in body
415422 . basic_blocks
@@ -420,11 +427,18 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
420427 if let Some ( inlined) = stmt. source_info . scope . inlined_instance ( & body. source_scopes ) {
421428 // This coverage statement was inlined from another function.
422429 used_via_inlining. insert ( inlined. def_id ( ) ) ;
430+ } else {
431+ // Non-inlined coverage statements belong to the enclosing function.
432+ saw_own_coverage = true ;
423433 }
424434 }
435+
436+ if !saw_own_coverage && body. function_coverage_info . is_some ( ) {
437+ missing_own_coverage. insert ( def_id) ;
438+ }
425439 }
426440
427- UsageSets { all_mono_items, used_via_inlining }
441+ UsageSets { all_mono_items, used_via_inlining, missing_own_coverage }
428442}
429443
430444fn add_unused_function_coverage < ' tcx > (
0 commit comments