@@ -2575,47 +2575,61 @@ unsafe impl<T: Send> Send for Drain<'_, T> {}
25752575#[ stable( feature = "drain" , since = "1.6.0" ) ]
25762576impl < T > Drop for Drain < ' _ , T > {
25772577 fn drop ( & mut self ) {
2578- self . for_each ( drop ) ;
2578+ struct DropGuard < ' r , ' a , T > ( & ' r mut Drain < ' a , T > ) ;
25792579
2580- let source_deque = unsafe { self . deque . as_mut ( ) } ;
2580+ impl < ' r , ' a , T > Drop for DropGuard < ' r , ' a , T > {
2581+ fn drop ( & mut self ) {
2582+ self . 0 . for_each ( drop) ;
25812583
2582- // T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head
2583- //
2584- // T t h H
2585- // [. . . o o x x o o . . .]
2586- //
2587- let orig_tail = source_deque. tail ;
2588- let drain_tail = source_deque. head ;
2589- let drain_head = self . after_tail ;
2590- let orig_head = self . after_head ;
2584+ let source_deque = unsafe { self . 0 . deque . as_mut ( ) } ;
25912585
2592- let tail_len = count ( orig_tail, drain_tail, source_deque. cap ( ) ) ;
2593- let head_len = count ( drain_head, orig_head, source_deque. cap ( ) ) ;
2586+ // T = source_deque_tail; H = source_deque_head; t = drain_tail; h = drain_head
2587+ //
2588+ // T t h H
2589+ // [. . . o o x x o o . . .]
2590+ //
2591+ let orig_tail = source_deque. tail ;
2592+ let drain_tail = source_deque. head ;
2593+ let drain_head = self . 0 . after_tail ;
2594+ let orig_head = self . 0 . after_head ;
25942595
2595- // Restore the original head value
2596- source_deque . head = orig_head;
2596+ let tail_len = count ( orig_tail , drain_tail , source_deque . cap ( ) ) ;
2597+ let head_len = count ( drain_head , orig_head, source_deque . cap ( ) ) ;
25972598
2598- match ( tail_len, head_len) {
2599- ( 0 , 0 ) => {
2600- source_deque. head = 0 ;
2601- source_deque. tail = 0 ;
2602- }
2603- ( 0 , _) => {
2604- source_deque. tail = drain_head;
2605- }
2606- ( _, 0 ) => {
2607- source_deque. head = drain_tail;
2608- }
2609- _ => unsafe {
2610- if tail_len <= head_len {
2611- source_deque. tail = source_deque. wrap_sub ( drain_head, tail_len) ;
2612- source_deque. wrap_copy ( source_deque. tail , orig_tail, tail_len) ;
2613- } else {
2614- source_deque. head = source_deque. wrap_add ( drain_tail, head_len) ;
2615- source_deque. wrap_copy ( drain_tail, drain_head, head_len) ;
2599+ // Restore the original head value
2600+ source_deque. head = orig_head;
2601+
2602+ match ( tail_len, head_len) {
2603+ ( 0 , 0 ) => {
2604+ source_deque. head = 0 ;
2605+ source_deque. tail = 0 ;
2606+ }
2607+ ( 0 , _) => {
2608+ source_deque. tail = drain_head;
2609+ }
2610+ ( _, 0 ) => {
2611+ source_deque. head = drain_tail;
2612+ }
2613+ _ => unsafe {
2614+ if tail_len <= head_len {
2615+ source_deque. tail = source_deque. wrap_sub ( drain_head, tail_len) ;
2616+ source_deque. wrap_copy ( source_deque. tail , orig_tail, tail_len) ;
2617+ } else {
2618+ source_deque. head = source_deque. wrap_add ( drain_tail, head_len) ;
2619+ source_deque. wrap_copy ( drain_tail, drain_head, head_len) ;
2620+ }
2621+ } ,
26162622 }
2617- } ,
2623+ }
26182624 }
2625+
2626+ while let Some ( item) = self . next ( ) {
2627+ let guard = DropGuard ( self ) ;
2628+ drop ( item) ;
2629+ mem:: forget ( guard) ;
2630+ }
2631+
2632+ DropGuard ( self ) ;
26192633 }
26202634}
26212635
0 commit comments