@@ -353,8 +353,10 @@ impl<'a> CoverageSpansGenerator<'a> {
353353
354354 let prev = self . take_prev ( ) ;
355355 debug ! ( " AT END, adding last prev={prev:?}" ) ;
356- let pending_dups = self . pending_dups . split_off ( 0 ) ;
357- for dup in pending_dups {
356+
357+ // Take `pending_dups` so that we can drain it while calling self methods.
358+ // It is never used as a field after this point.
359+ for dup in std:: mem:: take ( & mut self . pending_dups ) {
358360 debug ! ( " ...adding at least one pending dup={:?}" , dup) ;
359361 self . push_refined_span ( dup) ;
360362 }
@@ -471,11 +473,16 @@ impl<'a> CoverageSpansGenerator<'a> {
471473 previous iteration, or prev started a new disjoint span"
472474 ) ;
473475 if dup. span . hi ( ) <= self . curr ( ) . span . lo ( ) {
474- let pending_dups = self . pending_dups . split_off ( 0 ) ;
475- for dup in pending_dups. into_iter ( ) {
476+ // Temporarily steal `pending_dups` into a local, so that we can
477+ // drain it while calling other self methods.
478+ let mut pending_dups = std:: mem:: take ( & mut self . pending_dups ) ;
479+ for dup in pending_dups. drain ( ..) {
476480 debug ! ( " ...adding at least one pending={:?}" , dup) ;
477481 self . push_refined_span ( dup) ;
478482 }
483+ // The list of dups is now empty, but we can recycle its capacity.
484+ assert ! ( pending_dups. is_empty( ) && self . pending_dups. is_empty( ) ) ;
485+ self . pending_dups = pending_dups;
479486 } else {
480487 self . pending_dups . clear ( ) ;
481488 }
@@ -524,7 +531,10 @@ impl<'a> CoverageSpansGenerator<'a> {
524531 let has_pre_closure_span = prev. span . lo ( ) < right_cutoff;
525532 let has_post_closure_span = prev. span . hi ( ) > right_cutoff;
526533
527- let mut pending_dups = self . pending_dups . split_off ( 0 ) ;
534+ // Temporarily steal `pending_dups` into a local, so that we can
535+ // mutate and/or drain it while calling other self methods.
536+ let mut pending_dups = std:: mem:: take ( & mut self . pending_dups ) ;
537+
528538 if has_pre_closure_span {
529539 let mut pre_closure = self . prev ( ) . clone ( ) ;
530540 pre_closure. span = pre_closure. span . with_hi ( left_cutoff) ;
@@ -538,6 +548,7 @@ impl<'a> CoverageSpansGenerator<'a> {
538548 }
539549 self . push_refined_span ( pre_closure) ;
540550 }
551+
541552 if has_post_closure_span {
542553 // Mutate `prev.span()` to start after the closure (and discard curr).
543554 // (**NEVER** update `prev_original_span` because it affects the assumptions
@@ -548,12 +559,15 @@ impl<'a> CoverageSpansGenerator<'a> {
548559 debug ! ( " ...and at least one overlapping dup={:?}" , dup) ;
549560 dup. span = dup. span . with_lo ( right_cutoff) ;
550561 }
551- self . pending_dups . append ( & mut pending_dups) ;
552562 let closure_covspan = self . take_curr ( ) ; // Prevent this curr from becoming prev.
553563 self . push_refined_span ( closure_covspan) ; // since self.prev() was already updated
554564 } else {
555565 pending_dups. clear ( ) ;
556566 }
567+
568+ // Restore the modified post-closure spans, or the empty vector's capacity.
569+ assert ! ( self . pending_dups. is_empty( ) ) ;
570+ self . pending_dups = pending_dups;
557571 }
558572
559573 /// Called if `curr.span` equals `prev_original_span` (and potentially equal to all
0 commit comments