diff options
| author | bors <bors@rust-lang.org> | 2025-04-02 03:48:21 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2025-04-02 03:48:21 +0000 |
| commit | c9cd7078450abc15f6b8c969b1021934fb36c2a6 (patch) | |
| tree | 807ad6b8eb1a10c36b89e8d20122449ae830ee91 /compiler/rustc_mir_transform | |
| parent | 70dab5a27c03a5637cc1d4ba36a5139760d25e38 (diff) | |
| parent | ea51a1c055a0bbcc530ae5e6668a71b677e40bbe (diff) | |
| download | rust-c9cd7078450abc15f6b8c969b1021934fb36c2a6.tar.gz rust-c9cd7078450abc15f6b8c969b1021934fb36c2a6.zip | |
Auto merge of #139229 - Zalathar:rollup-5cs3f4d, r=Zalathar
Rollup of 14 pull requests Successful merges: - #135295 (Check empty SIMD vector in inline asm) - #138003 (Add the new `amx` target features and the `movrs` target feature) - #138823 (rustc_target: RISC-V: add base `I`-related important extensions) - #138913 (Remove even more instances of `@ts-expect-error` from search.js) - #138941 (Do not mix normalized and unnormalized caller bounds when constructing param-env for `receiver_is_dispatchable`) - #139060 (replace commit placeholder in vendor status with actual commit) - #139102 (coverage: Avoid splitting spans during span extraction/refinement) - #139191 (small opaque type/borrowck cleanup) - #139200 (Skip suggest impl or dyn when poly trait is not a real trait) - #139208 (fix dead link netbsd.md) - #139210 (chore: remove redundant backtick) - #139212 (Update mdbook to 0.4.48) - #139214 (Tell rustfmt to use the 2024 edition in ./x.py fmt) - #139225 (move autodiff from EnzymeAD/Enzyme to our rust-lang/Enzyme soft-fork) r? `@ghost` `@rustbot` modify labels: rollup
Diffstat (limited to 'compiler/rustc_mir_transform')
4 files changed, 39 insertions, 89 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/mappings.rs b/compiler/rustc_mir_transform/src/coverage/mappings.rs index d83c0d40a7e..73bd2d0705e 100644 --- a/compiler/rustc_mir_transform/src/coverage/mappings.rs +++ b/compiler/rustc_mir_transform/src/coverage/mappings.rs @@ -96,7 +96,7 @@ pub(super) fn extract_all_mapping_info_from_mir<'tcx>( } } else { // Extract coverage spans from MIR statements/terminators as normal. - extract_refined_covspans(mir_body, hir_info, graph, &mut code_mappings); + extract_refined_covspans(tcx, mir_body, hir_info, graph, &mut code_mappings); } branch_pairs.extend(extract_branch_pairs(mir_body, hir_info, graph)); diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index 8befe9c5d8d..f57a158e3e4 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -1,7 +1,9 @@ use std::collections::VecDeque; +use std::iter; use rustc_data_structures::fx::FxHashSet; use rustc_middle::mir; +use rustc_middle::ty::TyCtxt; use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span}; use tracing::{debug, debug_span, instrument}; @@ -11,8 +13,9 @@ use crate::coverage::{ExtractedHirInfo, mappings, unexpand}; mod from_mir; -pub(super) fn extract_refined_covspans( - mir_body: &mir::Body<'_>, +pub(super) fn extract_refined_covspans<'tcx>( + tcx: TyCtxt<'tcx>, + mir_body: &mir::Body<'tcx>, hir_info: &ExtractedHirInfo, graph: &CoverageGraph, code_mappings: &mut impl Extend<mappings::CodeMapping>, @@ -50,7 +53,7 @@ pub(super) fn extract_refined_covspans( // First, perform the passes that need macro information. covspans.sort_by(|a, b| graph.cmp_in_dominator_order(a.bcb, b.bcb)); remove_unwanted_expansion_spans(&mut covspans); - split_visible_macro_spans(&mut covspans); + shrink_visible_macro_spans(tcx, &mut covspans); // We no longer need the extra information in `SpanFromMir`, so convert to `Covspan`. let mut covspans = covspans.into_iter().map(SpanFromMir::into_covspan).collect::<Vec<_>>(); @@ -83,9 +86,7 @@ pub(super) fn extract_refined_covspans( // Split the covspans into separate buckets that don't overlap any holes. let buckets = divide_spans_into_buckets(covspans, &holes); - for mut covspans in buckets { - // Make sure each individual bucket is internally sorted. - covspans.sort_by(compare_covspans); + for covspans in buckets { let _span = debug_span!("processing bucket", ?covspans).entered(); let mut covspans = remove_unwanted_overlapping_spans(covspans); @@ -129,82 +130,50 @@ fn remove_unwanted_expansion_spans(covspans: &mut Vec<SpanFromMir>) { } /// When a span corresponds to a macro invocation that is visible from the -/// function body, split it into two parts. The first part covers just the -/// macro name plus `!`, and the second part covers the rest of the macro -/// invocation. This seems to give better results for code that uses macros. -fn split_visible_macro_spans(covspans: &mut Vec<SpanFromMir>) { - let mut extra_spans = vec![]; - - covspans.retain(|covspan| { - let Some(ExpnKind::Macro(MacroKind::Bang, visible_macro)) = covspan.expn_kind else { - return true; - }; - - let split_len = visible_macro.as_str().len() as u32 + 1; - let (before, after) = covspan.span.split_at(split_len); - if !covspan.span.contains(before) || !covspan.span.contains(after) { - // Something is unexpectedly wrong with the split point. - // The debug assertion in `split_at` will have already caught this, - // but in release builds it's safer to do nothing and maybe get a - // bug report for unexpected coverage, rather than risk an ICE. - return true; +/// function body, truncate it to just the macro name plus `!`. +/// This seems to give better results for code that uses macros. +fn shrink_visible_macro_spans(tcx: TyCtxt<'_>, covspans: &mut Vec<SpanFromMir>) { + let source_map = tcx.sess.source_map(); + + for covspan in covspans { + if matches!(covspan.expn_kind, Some(ExpnKind::Macro(MacroKind::Bang, _))) { + covspan.span = source_map.span_through_char(covspan.span, '!'); } - - extra_spans.push(SpanFromMir::new(before, covspan.expn_kind.clone(), covspan.bcb)); - extra_spans.push(SpanFromMir::new(after, covspan.expn_kind.clone(), covspan.bcb)); - false // Discard the original covspan that we just split. - }); - - // The newly-split spans are added at the end, so any previous sorting - // is not preserved. - covspans.extend(extra_spans); + } } /// Uses the holes to divide the given covspans into buckets, such that: -/// - No span in any hole overlaps a bucket (truncating the spans if necessary). +/// - No span in any hole overlaps a bucket (discarding spans if necessary). /// - The spans in each bucket are strictly after all spans in previous buckets, /// and strictly before all spans in subsequent buckets. /// -/// The resulting buckets are sorted relative to each other, but might not be -/// internally sorted. +/// The lists of covspans and holes must be sorted. +/// The resulting buckets are sorted relative to each other, and each bucket's +/// contents are sorted. #[instrument(level = "debug")] fn divide_spans_into_buckets(input_covspans: Vec<Covspan>, holes: &[Hole]) -> Vec<Vec<Covspan>> { debug_assert!(input_covspans.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le())); debug_assert!(holes.is_sorted_by(|a, b| compare_spans(a.span, b.span).is_le())); - // Now we're ready to start carving holes out of the initial coverage spans, - // and grouping them in buckets separated by the holes. + // Now we're ready to start grouping spans into buckets separated by holes. let mut input_covspans = VecDeque::from(input_covspans); - let mut fragments = vec![]; // For each hole: // - Identify the spans that are entirely or partly before the hole. - // - Put those spans in a corresponding bucket, truncated to the start of the hole. - // - If one of those spans also extends after the hole, put the rest of it - // in a "fragments" vector that is processed by the next hole. + // - Discard any that overlap with the hole. + // - Add the remaining identified spans to the corresponding bucket. let mut buckets = (0..holes.len()).map(|_| vec![]).collect::<Vec<_>>(); for (hole, bucket) in holes.iter().zip(&mut buckets) { - let fragments_from_prev = std::mem::take(&mut fragments); - - // Only inspect spans that precede or overlap this hole, - // leaving the rest to be inspected by later holes. - // (This relies on the spans and holes both being sorted.) - let relevant_input_covspans = - drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi()); - - for covspan in fragments_from_prev.into_iter().chain(relevant_input_covspans) { - let (before, after) = covspan.split_around_hole_span(hole.span); - bucket.extend(before); - fragments.extend(after); - } + bucket.extend( + drain_front_while(&mut input_covspans, |c| c.span.lo() < hole.span.hi()) + .filter(|c| !c.span.overlaps(hole.span)), + ); } - // After finding the spans before each hole, any remaining fragments/spans - // form their own final bucket, after the final hole. + // Any remaining spans form their own final bucket, after the final hole. // (If there were no holes, this will just be all of the initial spans.) - fragments.extend(input_covspans); - buckets.push(fragments); + buckets.push(Vec::from(input_covspans)); buckets } @@ -215,7 +184,7 @@ fn drain_front_while<'a, T>( queue: &'a mut VecDeque<T>, mut pred_fn: impl FnMut(&T) -> bool, ) -> impl Iterator<Item = T> { - std::iter::from_fn(move || if pred_fn(queue.front()?) { queue.pop_front() } else { None }) + iter::from_fn(move || queue.pop_front_if(|x| pred_fn(x))) } /// Takes one of the buckets of (sorted) spans extracted from MIR, and "refines" @@ -258,22 +227,6 @@ struct Covspan { } impl Covspan { - /// Splits this covspan into 0-2 parts: - /// - The part that is strictly before the hole span, if any. - /// - The part that is strictly after the hole span, if any. - fn split_around_hole_span(&self, hole_span: Span) -> (Option<Self>, Option<Self>) { - let before = try { - let span = self.span.trim_end(hole_span)?; - Self { span, ..*self } - }; - let after = try { - let span = self.span.trim_start(hole_span)?; - Self { span, ..*self } - }; - - (before, after) - } - /// If `self` and `other` can be merged (i.e. they have the same BCB), /// mutates `self.span` to also include `other.span` and returns true. /// diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 1faa2171c0b..804cd8ab3f7 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -120,22 +120,20 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> { // an `if condition { block }` has a span that includes the executed block, if true, // but for coverage, the code region executed, up to *and* through the SwitchInt, // actually stops before the if's block.) - TerminatorKind::Unreachable // Unreachable blocks are not connected to the MIR CFG + TerminatorKind::Unreachable | TerminatorKind::Assert { .. } | TerminatorKind::Drop { .. } | TerminatorKind::SwitchInt { .. } - // For `FalseEdge`, only the `real` branch is taken, so it is similar to a `Goto`. | TerminatorKind::FalseEdge { .. } | TerminatorKind::Goto { .. } => None, // Call `func` operand can have a more specific span when part of a chain of calls - TerminatorKind::Call { ref func, .. } - | TerminatorKind::TailCall { ref func, .. } => { + TerminatorKind::Call { ref func, .. } | TerminatorKind::TailCall { ref func, .. } => { let mut span = terminator.source_info.span; - if let mir::Operand::Constant(box constant) = func { - if constant.span.lo() > span.lo() { - span = span.with_lo(constant.span.lo()); - } + if let mir::Operand::Constant(constant) = func + && span.contains(constant.span) + { + span = constant.span; } Some(span) } @@ -147,9 +145,7 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> { | TerminatorKind::Yield { .. } | TerminatorKind::CoroutineDrop | TerminatorKind::FalseUnwind { .. } - | TerminatorKind::InlineAsm { .. } => { - Some(terminator.source_info.span) - } + | TerminatorKind::InlineAsm { .. } => Some(terminator.source_info.span), } } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index 205d388f4fb..c372b77ad25 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -12,6 +12,7 @@ #![feature(map_try_insert)] #![feature(never_type)] #![feature(try_blocks)] +#![feature(vec_deque_pop_if)] #![feature(yeet_expr)] // tidy-alphabetical-end |
