@@ -206,10 +206,8 @@ pub struct ValueIterMut<'a, T> {
206206/// An drain iterator of all values associated with a single header name.
207207#[ derive( Debug ) ]
208208pub struct ValueDrain < ' a , T > {
209- raw_links : RawLinks < T > ,
210- extra_values : * mut Vec < ExtraValue < T > > ,
211209 first : Option < T > ,
212- next : Option < usize > ,
210+ next : Option < :: std :: vec :: IntoIter < T > > ,
213211 lt : PhantomData < & ' a mut HeaderMap < T > > ,
214212}
215213
@@ -1193,13 +1191,16 @@ impl<T> HeaderMap<T> {
11931191 }
11941192
11951193 let raw_links = self . raw_links ( ) ;
1196- let extra_values = & mut self . extra_values as * mut _ ;
1194+ let extra_values = & mut self . extra_values ;
1195+
1196+ let next = links. map ( |l| {
1197+ drain_all_extra_values ( raw_links, extra_values, l. next )
1198+ . into_iter ( )
1199+ } ) ;
11971200
11981201 ValueDrain {
1199- raw_links,
1200- extra_values,
12011202 first : Some ( old) ,
1202- next : links . map ( |l| l . next ) ,
1203+ next : next,
12031204 lt : PhantomData ,
12041205 }
12051206 }
@@ -1368,6 +1369,10 @@ impl<T> HeaderMap<T> {
13681369 }
13691370
13701371 /// Remove an entry from the map.
1372+ ///
1373+ /// Warning: To avoid inconsistent state, extra values _must_ be removed
1374+ /// for the `found` index (via `remove_all_extra_values` or similar)
1375+ /// _before_ this method is called.
13711376 #[ inline]
13721377 fn remove_found ( & mut self , probe : usize , found : usize ) -> Bucket < T > {
13731378 // index `probe` and entry `found` is to be removed
@@ -1587,7 +1592,12 @@ impl<T> HeaderMap<T> {
15871592
15881593/// Removes the `ExtraValue` at the given index.
15891594#[ inline]
1590- fn remove_extra_value < T > ( mut raw_links : RawLinks < T > , extra_values : & mut Vec < ExtraValue < T > > , idx : usize ) -> ExtraValue < T > {
1595+ fn remove_extra_value < T > (
1596+ mut raw_links : RawLinks < T > ,
1597+ extra_values : & mut Vec < ExtraValue < T > > ,
1598+ idx : usize )
1599+ -> ExtraValue < T >
1600+ {
15911601 let prev;
15921602 let next;
15931603
@@ -1703,6 +1713,26 @@ fn remove_extra_value<T>(mut raw_links: RawLinks<T>, extra_values: &mut Vec<Extr
17031713 extra
17041714}
17051715
1716+ fn drain_all_extra_values < T > (
1717+ raw_links : RawLinks < T > ,
1718+ extra_values : & mut Vec < ExtraValue < T > > ,
1719+ mut head : usize )
1720+ -> Vec < T >
1721+ {
1722+ let mut vec = Vec :: new ( ) ;
1723+ loop {
1724+ let extra = remove_extra_value ( raw_links, extra_values, head) ;
1725+ vec. push ( extra. value ) ;
1726+
1727+ if let Link :: Extra ( idx) = extra. next {
1728+ head = idx;
1729+ } else {
1730+ break ;
1731+ }
1732+ }
1733+ vec
1734+ }
1735+
17061736impl < ' a , T > IntoIterator for & ' a HeaderMap < T > {
17071737 type Item = ( & ' a HeaderName , & ' a T ) ;
17081738 type IntoIter = Iter < ' a , T > ;
@@ -2936,14 +2966,19 @@ impl<'a, T> OccupiedEntry<'a, T> {
29362966 /// The key and all values associated with the entry are removed and
29372967 /// returned.
29382968 pub fn remove_entry_mult ( self ) -> ( HeaderName , ValueDrain < ' a , T > ) {
2939- let entry = self . map . remove_found ( self . probe , self . index ) ;
29402969 let raw_links = self . map . raw_links ( ) ;
2941- let extra_values = & mut self . map . extra_values as * mut _ ;
2970+ let extra_values = & mut self . map . extra_values ;
2971+
2972+ let next = self . map . entries [ self . index ] . links . map ( |l| {
2973+ drain_all_extra_values ( raw_links, extra_values, l. next )
2974+ . into_iter ( )
2975+ } ) ;
2976+
2977+ let entry = self . map . remove_found ( self . probe , self . index ) ;
2978+
29422979 let drain = ValueDrain {
2943- raw_links,
2944- extra_values,
29452980 first : Some ( entry. value ) ,
2946- next : entry . links . map ( |l| l . next ) ,
2981+ next,
29472982 lt : PhantomData ,
29482983 } ;
29492984 ( entry. key , drain)
@@ -3036,31 +3071,26 @@ impl<'a, T> Iterator for ValueDrain<'a, T> {
30363071 fn next ( & mut self ) -> Option < T > {
30373072 if self . first . is_some ( ) {
30383073 self . first . take ( )
3039- } else if let Some ( next) = self . next {
3040- // Remove the extra value
3041- let extra = unsafe {
3042- remove_extra_value ( self . raw_links , & mut * self . extra_values , next)
3043- } ;
3044-
3045- match extra. next {
3046- Link :: Extra ( idx) => self . next = Some ( idx) ,
3047- Link :: Entry ( _) => self . next = None ,
3048- }
3049-
3050- Some ( extra. value )
3074+ } else if let Some ( ref mut extras) = self . next {
3075+ extras. next ( )
30513076 } else {
30523077 None
30533078 }
30543079 }
30553080
30563081 fn size_hint ( & self ) -> ( usize , Option < usize > ) {
3057- match ( & self . first , self . next ) {
3082+ match ( & self . first , & self . next ) {
30583083 // Exactly 1
3059- ( & Some ( _) , None ) => ( 1 , Some ( 1 ) ) ,
3060- // At least 1
3061- ( & _, Some ( _) ) => ( 1 , None ) ,
3084+ ( & Some ( _) , & None ) => ( 1 , Some ( 1 ) ) ,
3085+ // 1 + extras
3086+ ( & Some ( _) , & Some ( ref extras) ) => {
3087+ let ( l, u) = extras. size_hint ( ) ;
3088+ ( l + 1 , u. map ( |u| u + 1 ) )
3089+ } ,
3090+ // Extras only
3091+ ( & None , & Some ( ref extras) ) => extras. size_hint ( ) ,
30623092 // No more
3063- ( & None , None ) => ( 0 , Some ( 0 ) ) ,
3093+ ( & None , & None ) => ( 0 , Some ( 0 ) ) ,
30643094 }
30653095 }
30663096}
0 commit comments