diff options
Diffstat (limited to 'compiler/rustc_mir_transform/src/coverage/spans.rs')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coverage/spans.rs | 92 |
1 files changed, 43 insertions, 49 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index cdc8a950640..4260a6f0c6f 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -90,23 +90,23 @@ pub(super) fn generate_coverage_spans( struct CurrCovspan { span: Span, bcb: BasicCoverageBlock, - is_closure: bool, + is_hole: bool, } impl CurrCovspan { - fn new(span: Span, bcb: BasicCoverageBlock, is_closure: bool) -> Self { - Self { span, bcb, is_closure } + fn new(span: Span, bcb: BasicCoverageBlock, is_hole: bool) -> Self { + Self { span, bcb, is_hole } } fn into_prev(self) -> PrevCovspan { - let Self { span, bcb, is_closure } = self; - PrevCovspan { span, bcb, merged_spans: vec![span], is_closure } + let Self { span, bcb, is_hole } = self; + PrevCovspan { span, bcb, merged_spans: vec![span], is_hole } } fn into_refined(self) -> RefinedCovspan { - // This is only called in cases where `curr` is a closure span that has + // This is only called in cases where `curr` is a hole span that has // been carved out of `prev`. - debug_assert!(self.is_closure); + debug_assert!(self.is_hole); self.into_prev().into_refined() } } @@ -118,12 +118,12 @@ struct PrevCovspan { /// List of all the original spans from MIR that have been merged into this /// span. Mainly used to precisely skip over gaps when truncating a span. merged_spans: Vec<Span>, - is_closure: bool, + is_hole: bool, } impl PrevCovspan { fn is_mergeable(&self, other: &CurrCovspan) -> bool { - self.bcb == other.bcb && !self.is_closure && !other.is_closure + self.bcb == other.bcb && !self.is_hole && !other.is_hole } fn merge_from(&mut self, other: &CurrCovspan) { @@ -142,8 +142,8 @@ impl PrevCovspan { } fn refined_copy(&self) -> RefinedCovspan { - let &Self { span, bcb, merged_spans: _, is_closure } = self; - RefinedCovspan { span, bcb, is_closure } + let &Self { span, bcb, merged_spans: _, is_hole } = self; + RefinedCovspan { span, bcb, is_hole } } fn into_refined(self) -> RefinedCovspan { @@ -156,12 +156,12 @@ impl PrevCovspan { struct RefinedCovspan { span: Span, bcb: BasicCoverageBlock, - is_closure: bool, + is_hole: bool, } impl RefinedCovspan { fn is_mergeable(&self, other: &Self) -> bool { - self.bcb == other.bcb && !self.is_closure && !other.is_closure + self.bcb == other.bcb && !self.is_hole && !other.is_hole } fn merge_from(&mut self, other: &Self) { @@ -176,7 +176,8 @@ impl RefinedCovspan { /// * Remove duplicate source code coverage regions /// * Merge spans that represent continuous (both in source code and control flow), non-branching /// execution -/// * Carve out (leave uncovered) any span that will be counted by another MIR (notably, closures) +/// * Carve out (leave uncovered) any "hole" spans that need to be left blank +/// (e.g. closures that will be counted by their own MIR body) struct SpansRefiner { /// The initial set of coverage spans, sorted by `Span` (`lo` and `hi`) and by relative /// dominance between the `BasicCoverageBlock`s of equal `Span`s. @@ -228,7 +229,7 @@ impl SpansRefiner { let curr = self.curr(); if prev.is_mergeable(curr) { - debug!(" same bcb (and neither is a closure), merge with prev={prev:?}"); + debug!(?prev, "curr will be merged into prev"); let curr = self.take_curr(); self.prev_mut().merge_from(&curr); } else if prev.span.hi() <= curr.span.lo() { @@ -237,15 +238,13 @@ impl SpansRefiner { ); let prev = self.take_prev().into_refined(); self.refined_spans.push(prev); - } else if prev.is_closure { + } else if prev.is_hole { // drop any equal or overlapping span (`curr`) and keep `prev` to test again in the // next iter - debug!( - " curr overlaps a closure (prev). Drop curr and keep prev for next iter. prev={prev:?}", - ); + debug!(?prev, "prev (a hole) overlaps curr, so discarding curr"); self.take_curr(); // Discards curr. - } else if curr.is_closure { - self.carve_out_span_for_closure(); + } else if curr.is_hole { + self.carve_out_span_for_hole(); } else { self.cutoff_prev_at_overlapping_curr(); } @@ -269,10 +268,9 @@ impl SpansRefiner { } }); - // Remove spans derived from closures, originally added to ensure the coverage - // regions for the current function leave room for the closure's own coverage regions - // (injected separately, from the closure's own MIR). - self.refined_spans.retain(|covspan| !covspan.is_closure); + // Discard hole spans, since their purpose was to carve out chunks from + // other spans, but we don't want the holes themselves in the final mappings. + self.refined_spans.retain(|covspan| !covspan.is_hole); self.refined_spans } @@ -315,47 +313,43 @@ impl SpansRefiner { { // Skip curr because prev has already advanced beyond the end of curr. // This can only happen if a prior iteration updated `prev` to skip past - // a region of code, such as skipping past a closure. - debug!( - " prev.span starts after curr.span, so curr will be dropped (skipping past \ - closure?); prev={prev:?}", - ); + // a region of code, such as skipping past a hole. + debug!(?prev, "prev.span starts after curr.span, so curr will be dropped"); } else { - self.some_curr = Some(CurrCovspan::new(curr.span, curr.bcb, curr.is_closure)); + self.some_curr = Some(CurrCovspan::new(curr.span, curr.bcb, curr.is_hole)); return true; } } false } - /// If `prev`s span extends left of the closure (`curr`), carve out the closure's span from - /// `prev`'s span. (The closure's coverage counters will be injected when processing the - /// closure's own MIR.) Add the portion of the span to the left of the closure; and if the span - /// extends to the right of the closure, update `prev` to that portion of the span. - fn carve_out_span_for_closure(&mut self) { + /// If `prev`s span extends left of the hole (`curr`), carve out the hole's span from + /// `prev`'s span. Add the portion of the span to the left of the hole; and if the span + /// extends to the right of the hole, update `prev` to that portion of the span. + fn carve_out_span_for_hole(&mut self) { let prev = self.prev(); let curr = self.curr(); let left_cutoff = curr.span.lo(); let right_cutoff = curr.span.hi(); - let has_pre_closure_span = prev.span.lo() < right_cutoff; - let has_post_closure_span = prev.span.hi() > right_cutoff; - - if has_pre_closure_span { - let mut pre_closure = self.prev().refined_copy(); - pre_closure.span = pre_closure.span.with_hi(left_cutoff); - debug!(" prev overlaps a closure. Adding span for pre_closure={:?}", pre_closure); - self.refined_spans.push(pre_closure); + let has_pre_hole_span = prev.span.lo() < right_cutoff; + let has_post_hole_span = prev.span.hi() > right_cutoff; + + if has_pre_hole_span { + let mut pre_hole = prev.refined_copy(); + pre_hole.span = pre_hole.span.with_hi(left_cutoff); + debug!(?pre_hole, "prev overlaps a hole; adding pre-hole span"); + self.refined_spans.push(pre_hole); } - if has_post_closure_span { - // Mutate `prev.span` to start after the closure (and discard curr). + if has_post_hole_span { + // Mutate `prev.span` to start after the hole (and discard curr). self.prev_mut().span = self.prev().span.with_lo(right_cutoff); - debug!(" Mutated prev.span to start after the closure. prev={:?}", self.prev()); + debug!(prev=?self.prev(), "mutated prev to start after the hole"); // Prevent this curr from becoming prev. - let closure_covspan = self.take_curr().into_refined(); - self.refined_spans.push(closure_covspan); // since self.prev() was already updated + let hole_covspan = self.take_curr().into_refined(); + self.refined_spans.push(hole_covspan); // since self.prev() was already updated } } |
