@@ -353,10 +353,11 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
353
353
354
354
// To be eligible for "unused function" mappings, a definition must:
355
355
// - Be function-like
356
- // - Not participate directly in codegen
356
+ // - Not participate directly in codegen (or have lost all its coverage statements)
357
357
// - Not have any coverage statements inlined into codegenned functions
358
358
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) )
360
361
&& !usage. used_via_inlining . contains ( & def_id)
361
362
} ;
362
363
@@ -379,6 +380,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
379
380
struct UsageSets < ' tcx > {
380
381
all_mono_items : & ' tcx DefIdSet ,
381
382
used_via_inlining : FxHashSet < DefId > ,
383
+ missing_own_coverage : FxHashSet < DefId > ,
382
384
}
383
385
384
386
/// 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> {
408
410
409
411
// Functions whose coverage statments were found inlined into other functions.
410
412
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 ;
411
419
412
- for ( _def_id, body) in def_and_mir_for_all_mono_fns {
413
420
// Inspect every coverage statement in the function's MIR.
414
421
for stmt in body
415
422
. basic_blocks
@@ -420,11 +427,18 @@ fn prepare_usage_sets<'tcx>(tcx: TyCtxt<'tcx>) -> UsageSets<'tcx> {
420
427
if let Some ( inlined) = stmt. source_info . scope . inlined_instance ( & body. source_scopes ) {
421
428
// This coverage statement was inlined from another function.
422
429
used_via_inlining. insert ( inlined. def_id ( ) ) ;
430
+ } else {
431
+ // Non-inlined coverage statements belong to the enclosing function.
432
+ saw_own_coverage = true ;
423
433
}
424
434
}
435
+
436
+ if !saw_own_coverage && body. function_coverage_info . is_some ( ) {
437
+ missing_own_coverage. insert ( def_id) ;
438
+ }
425
439
}
426
440
427
- UsageSets { all_mono_items, used_via_inlining }
441
+ UsageSets { all_mono_items, used_via_inlining, missing_own_coverage }
428
442
}
429
443
430
444
fn add_unused_function_coverage < ' tcx > (
0 commit comments