@@ -1313,6 +1313,7 @@ impl<'a, K, V> InternalEntry<K, V, &'a mut RawTable<K, V>> {
13131313 match self {
13141314 InternalEntry :: Occupied { elem } => {
13151315 Some ( Occupied ( OccupiedEntry {
1316+ key : Some ( key) ,
13161317 elem : elem
13171318 } ) )
13181319 }
@@ -1347,6 +1348,7 @@ pub enum Entry<'a, K: 'a, V: 'a> {
13471348/// A view into a single occupied location in a HashMap.
13481349#[ stable( feature = "rust1" , since = "1.0.0" ) ]
13491350pub struct OccupiedEntry < ' a , K : ' a , V : ' a > {
1351+ key : Option < K > ,
13501352 elem : FullBucket < K , V , & ' a mut RawTable < K , V > > ,
13511353}
13521354
@@ -1552,6 +1554,12 @@ impl<'a, K, V> OccupiedEntry<'a, K, V> {
15521554 pub fn remove ( self ) -> V {
15531555 pop_internal ( self . elem ) . 1
15541556 }
1557+ /// Returns a key that was used for search.
1558+ ///
1559+ /// The key was retained for further use.
1560+ fn take_key ( & mut self ) -> Option < K > {
1561+ self . key . take ( )
1562+ }
15551563}
15561564
15571565impl < ' a , K : ' a , V : ' a > VacantEntry < ' a , K , V > {
@@ -1661,20 +1669,16 @@ impl<K, S, Q: ?Sized> super::Recover<Q> for HashMap<K, (), S>
16611669 }
16621670
16631671 fn replace ( & mut self , key : K ) -> Option < K > {
1664- let hash = self . make_hash ( & key) ;
16651672 self . reserve ( 1 ) ;
16661673
1667- match search_hashed ( & mut self . table , hash, |k| * k == key) {
1668- InternalEntry :: Occupied { mut elem } => {
1669- Some ( mem:: replace ( elem. read_mut ( ) . 0 , key) )
1674+ match self . entry ( key) {
1675+ Occupied ( mut occupied) => {
1676+ let key = occupied. take_key ( ) . unwrap ( ) ;
1677+ Some ( mem:: replace ( occupied. elem . read_mut ( ) . 0 , key) )
16701678 }
1671- other => {
1672- if let Some ( Vacant ( vacant) ) = other. into_entry ( key) {
1673- vacant. insert ( ( ) ) ;
1674- None
1675- } else {
1676- unreachable ! ( )
1677- }
1679+ Vacant ( vacant) => {
1680+ vacant. insert ( ( ) ) ;
1681+ None
16781682 }
16791683 }
16801684 }
0 commit comments