diff options
| author | Zalathar <Zalathar@users.noreply.github.com> | 2023-10-14 23:59:11 +1100 |
|---|---|---|
| committer | Zalathar <Zalathar@users.noreply.github.com> | 2023-10-16 21:05:46 +1100 |
| commit | 7aa1b8390bc574f50bf7fc62c8ed0f33c9494a0f (patch) | |
| tree | b98d93f5cf7db20b3f53d39b206bdbcd32baefa7 /compiler/rustc_mir_transform/src/coverage | |
| parent | 5e5a8e77695a9156e9b78e7d5d7b6b44c26c0cae (diff) | |
| download | rust-7aa1b8390bc574f50bf7fc62c8ed0f33c9494a0f.tar.gz rust-7aa1b8390bc574f50bf7fc62c8ed0f33c9494a0f.zip | |
coverage: Explain why we temporarily steal `pending_dups`
Diffstat (limited to 'compiler/rustc_mir_transform/src/coverage')
| -rw-r--r-- | compiler/rustc_mir_transform/src/coverage/spans.rs | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index b71a3101bac..1d1be8f2492 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -353,8 +353,10 @@ impl<'a> CoverageSpansGenerator<'a> { let prev = self.take_prev(); debug!(" AT END, adding last prev={prev:?}"); - let pending_dups = self.pending_dups.split_off(0); - for dup in pending_dups { + + // Take `pending_dups` so that we can drain it while calling self methods. + // It is never used as a field after this point. + for dup in std::mem::take(&mut self.pending_dups) { debug!(" ...adding at least one pending dup={:?}", dup); self.push_refined_span(dup); } @@ -474,11 +476,16 @@ impl<'a> CoverageSpansGenerator<'a> { previous iteration, or prev started a new disjoint span" ); if last_dup.span.hi() <= self.curr().span.lo() { - let pending_dups = self.pending_dups.split_off(0); - for dup in pending_dups.into_iter() { + // Temporarily steal `pending_dups` into a local, so that we can + // drain it while calling other self methods. + let mut pending_dups = std::mem::take(&mut self.pending_dups); + for dup in pending_dups.drain(..) { debug!(" ...adding at least one pending={:?}", dup); self.push_refined_span(dup); } + // The list of dups is now empty, but we can recycle its capacity. + assert!(pending_dups.is_empty() && self.pending_dups.is_empty()); + self.pending_dups = pending_dups; } else { self.pending_dups.clear(); } @@ -526,7 +533,10 @@ impl<'a> CoverageSpansGenerator<'a> { let has_pre_closure_span = prev.span.lo() < right_cutoff; let has_post_closure_span = prev.span.hi() > right_cutoff; - let mut pending_dups = self.pending_dups.split_off(0); + // Temporarily steal `pending_dups` into a local, so that we can + // mutate and/or drain it while calling other self methods. + let mut pending_dups = std::mem::take(&mut self.pending_dups); + if has_pre_closure_span { let mut pre_closure = self.prev().clone(); pre_closure.span = pre_closure.span.with_hi(left_cutoff); @@ -540,6 +550,7 @@ impl<'a> CoverageSpansGenerator<'a> { } self.push_refined_span(pre_closure); } + if has_post_closure_span { // Mutate `prev.span()` to start after the closure (and discard curr). // (**NEVER** update `prev_original_span` because it affects the assumptions @@ -550,12 +561,15 @@ impl<'a> CoverageSpansGenerator<'a> { debug!(" ...and at least one overlapping dup={:?}", dup); dup.span = dup.span.with_lo(right_cutoff); } - self.pending_dups.append(&mut pending_dups); let closure_covspan = self.take_curr(); // Prevent this curr from becoming prev. self.push_refined_span(closure_covspan); // since self.prev() was already updated } else { pending_dups.clear(); } + + // Restore the modified post-closure spans, or the empty vector's capacity. + assert!(self.pending_dups.is_empty()); + self.pending_dups = pending_dups; } /// Called if `curr.span` equals `prev_original_span` (and potentially equal to all |
