Change:
The immediate symptoms of were fixed by , but some users reported that their builds now encounter another coverage-related ICE:
label +T-compiler +A-code-coverage
This ICE does not occur on current stable/beta, but does occur on nightly. label +regression-from-stable-to-nightly
(This will be fixed by , which is awaiting review.)
WG-prioritization assigning priority (). label -I-prioritize +P-high

Discussion:
let bx = self; <ins> match coverage.kind { // Marker statements have no effect during codegen, // so return early and don't create `func_coverage`. CoverageKind::SpanMarker => return, // Match exhaustively to ensure that newly-added kinds are classified correctly. CoverageKind::CounterIncrement { .. } | CoverageKind::ExpressionUsed { .. } => {} } </ins> let Some(function_coverage_info) = bx.tcx.instance_mir(instance.def).function_coverage_info.as_deref() else {

let Coverage { kind } = coverage; match *kind { <del> // Span markers are only meaningful during MIR instrumentation, // and have no effect during codegen. CoverageKind::SpanMarker => {} </del> <ins> CoverageKind::SpanMarker => unreachable!( "unexpected marker statement {kind:?} should have caused an early return" ), </ins> CoverageKind::CounterIncrement { id } => { func_coverage.mark_counter_id_seen(id); // We need to explicitly drop the `RefMut` before calling into `instrprof_increment`,

fn inject_counters(&'a mut self) { //////////////////////////////////////////////////// // Compute coverage spans from the `CoverageGraph`. <del> let coverage_spans = CoverageSpans::generate_coverage_spans( </del> <ins> let Some(coverage_spans) = CoverageSpans::generate_coverage_spans( </ins> self.mir_body, self.fn_sig_span, self.body_span, &self.basic_coverage_blocks, <del> ); </del> <ins> ) else { // No relevant spans were found in MIR, so skip instrumenting this function. return; }; </ins> //////////////////////////////////////////////////// // Create an optimized mix of `Counter`s and `Expression`s for the `CoverageGraph`. Ensure

} impl CoverageSpans { <ins> /// Extracts coverage-relevant spans from MIR, and associates them with /// their corresponding BCBs. /// /// Returns `None` if no coverage-relevant spans could be extracted. </ins> pub(super) fn generate_coverage_spans( mir_body: &mir::Body<'_>, fn_sig_span: Span, body_span: Span, basic_coverage_blocks: &CoverageGraph, <del> ) -> Self { </del> <ins> ) -> Option<Self> { </ins> let coverage_spans = CoverageSpansGenerator::generate_coverage_spans( mir_body, fn_sig_span,

basic_coverage_blocks, ); <ins> if coverage_spans.is_empty() { return None; } </ins> // Group the coverage spans by BCB, with the BCBs in sorted order. let mut bcb_to_spans = IndexVec::from_elem_n(Vec::new(), basic_coverage_blocks.num_nodes()); for CoverageSpan { bcb, span, .. } in coverage_spans { bcb_to_spans[bcb].push(span); } <del> Self { bcb_to_spans } </del> <ins> Some(Self { bcb_to_spans }) </ins> } pub(super) fn bcb_has_coverage_spans(&self, bcb: BasicCoverageBlock) -> bool {

<ins> Function name: no_spans_if_not::main Raw bytes (9): 0x[01, 01, 00, 01, 01, 0b, 01, 02, 02] Number of files: 1 - file 0 => global file 1 Number of expressions: 0 Number of file 0 mappings: 1 - Code(Counter(0)) at (prev + 11, 1) to (start + 2, 2) </ins>

<ins> LL|       |// edition: 2021 LL|       | LL|       |// If the span extractor can't find any relevant spans for a function, LL|       |// but the function contains coverage span-marker statements (e.g. inserted LL|       |// for `if !`), coverage codegen may think that it is instrumented and LL|       |// consequently complain that it has no spans. LL|       |// LL|       |// Regression test for <https://github.com/rust-lang/rust/issues/118850>, LL|       |// "A used function should have had coverage mapping data but did not". LL|       | LL|      1|fn main() { LL|      1|    affected_function(); LL|      1|} LL|       | LL|       |macro_rules! macro_that_defines_a_function { LL|       |    (fn $name:ident () $body:tt) => { LL|       |        fn $name () $body LL|       |    } LL|       |} LL|       | LL|       |macro_that_defines_a_function! { LL|       |    fn affected_function() { LL|       |        if !false { LL|       |            () LL|       |        } else { LL|       |            () LL|       |        } LL|       |    } LL|       |} </ins>

<ins> // edition: 2021 // If the span extractor can't find any relevant spans for a function, // but the function contains coverage span-marker statements (e.g. inserted // for `if !`), coverage codegen may think that it is instrumented and // consequently complain that it has no spans. // // Regression test for <https://github.com/rust-lang/rust/issues/118850>, // "A used function should have had coverage mapping data but did not". fn main() { affected_function(); } macro_rules! macro_that_defines_a_function { (fn $name:ident () $body:tt) => { fn $name () $body } } macro_that_defines_a_function! { fn affected_function() { if !false { () } else { () } } } </ins>