@@ -22,7 +22,7 @@ use rustc_middle::mir::{
2222 TerminatorKind ,
2323} ;
2424use rustc_middle:: ty:: TyCtxt ;
25- use rustc_span:: def_id:: DefId ;
25+ use rustc_span:: def_id:: { DefId , LocalDefId } ;
2626use rustc_span:: source_map:: SourceMap ;
2727use rustc_span:: { ExpnKind , SourceFile , Span , Symbol } ;
2828
@@ -45,18 +45,13 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
4545
4646 let def_id = mir_source. def_id ( ) . expect_local ( ) ;
4747
48- // Only instrument functions, methods, and closures (not constants since they are evaluated
49- // at compile time by Miri).
50- // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const
51- // expressions get coverage spans, we will probably have to "carve out" space for const
52- // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might
53- // be tricky if const expressions have no corresponding statements in the enclosing MIR.
54- // Closures are carved out by their initial `Assign` statement.)
55- if !tcx. def_kind ( def_id) . is_fn_like ( ) {
56- trace ! ( "InstrumentCoverage skipped for {def_id:?} (not an fn-like)" ) ;
48+ if !is_eligible_for_coverage ( tcx, def_id) {
49+ trace ! ( "InstrumentCoverage skipped for {def_id:?} (not eligible)" ) ;
5750 return ;
5851 }
5952
53+ // An otherwise-eligible function is still skipped if its start block
54+ // is known to be unreachable.
6055 match mir_body. basic_blocks [ mir:: START_BLOCK ] . terminator ( ) . kind {
6156 TerminatorKind :: Unreachable => {
6257 trace ! ( "InstrumentCoverage skipped for unreachable `START_BLOCK`" ) ;
@@ -65,10 +60,6 @@ impl<'tcx> MirPass<'tcx> for InstrumentCoverage {
6560 _ => { }
6661 }
6762
68- if tcx. codegen_fn_attrs ( def_id) . flags . contains ( CodegenFnAttrFlags :: NO_COVERAGE ) {
69- return ;
70- }
71-
7263 trace ! ( "InstrumentCoverage starting for {def_id:?}" ) ;
7364 Instrumentor :: new ( tcx, mir_body) . inject_counters ( ) ;
7465 trace ! ( "InstrumentCoverage done for {def_id:?}" ) ;
@@ -317,6 +308,26 @@ fn make_code_region(
317308 }
318309}
319310
311+ fn is_eligible_for_coverage ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> bool {
312+ // Only instrument functions, methods, and closures (not constants since they are evaluated
313+ // at compile time by Miri).
314+ // FIXME(#73156): Handle source code coverage in const eval, but note, if and when const
315+ // expressions get coverage spans, we will probably have to "carve out" space for const
316+ // expressions from coverage spans in enclosing MIR's, like we do for closures. (That might
317+ // be tricky if const expressions have no corresponding statements in the enclosing MIR.
318+ // Closures are carved out by their initial `Assign` statement.)
319+ if !tcx. def_kind ( def_id) . is_fn_like ( ) {
320+ trace ! ( "InstrumentCoverage skipped for {def_id:?} (not an fn-like)" ) ;
321+ return false ;
322+ }
323+
324+ if tcx. codegen_fn_attrs ( def_id) . flags . contains ( CodegenFnAttrFlags :: NO_COVERAGE ) {
325+ return false ;
326+ }
327+
328+ true
329+ }
330+
320331fn fn_sig_and_body (
321332 tcx : TyCtxt < ' _ > ,
322333 def_id : DefId ,
0 commit comments