@@ -2983,10 +2983,10 @@ where
29832983/// }
29842984/// assert!(map["b"] == 20 && map.len() == 2);
29852985/// ```
2986- pub struct VacantEntryRef < ' a , ' b , K , Q : ?Sized , V , S , A : Allocator = Global > {
2986+ pub struct VacantEntryRef < ' map , ' key , K , Q : ?Sized , V , S , A : Allocator = Global > {
29872987 hash : u64 ,
2988- key : & ' b Q ,
2989- table : & ' a mut HashMap < K , V , S , A > ,
2988+ key : & ' key Q ,
2989+ table : & ' map mut HashMap < K , V , S , A > ,
29902990}
29912991
29922992impl < K , Q , V , S , A > Debug for VacantEntryRef < ' _ , ' _ , K , Q , V , S , A >
@@ -4332,7 +4332,7 @@ impl<'a, 'b, K, Q: ?Sized, V: Default, S, A: Allocator> EntryRef<'a, 'b, K, Q, V
43324332 }
43334333}
43344334
4335- impl < ' a , ' b , K , Q : ?Sized , V , S , A : Allocator > VacantEntryRef < ' a , ' b , K , Q , V , S , A > {
4335+ impl < ' map , ' key , K , Q : ?Sized , V , S , A : Allocator > VacantEntryRef < ' map , ' key , K , Q , V , S , A > {
43364336 /// Gets a reference to the key that would be used when inserting a value
43374337 /// through the `VacantEntryRef`.
43384338 ///
@@ -4346,7 +4346,7 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43464346 /// assert_eq!(map.entry_ref(key).key(), "poneyland");
43474347 /// ```
43484348 #[ cfg_attr( feature = "inline-more" , inline) ]
4349- pub fn key ( & self ) -> & ' b Q {
4349+ pub fn key ( & self ) -> & ' key Q {
43504350 self . key
43514351 }
43524352
@@ -4368,10 +4368,10 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43684368 /// assert_eq!(map["poneyland"], 37);
43694369 /// ```
43704370 #[ cfg_attr( feature = "inline-more" , inline) ]
4371- pub fn insert ( self , value : V ) -> & ' a mut V
4371+ pub fn insert ( self , value : V ) -> & ' map mut V
43724372 where
43734373 K : Hash ,
4374- & ' b Q : Into < K > ,
4374+ & ' key Q : Into < K > ,
43754375 S : BuildHasher ,
43764376 {
43774377 let table = & mut self . table . table ;
@@ -4383,6 +4383,55 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
43834383 & mut entry. 1
43844384 }
43854385
4386+ /// [insert](Self::insert) a value by providing the key at insertion time.
4387+ /// Returns a mutable reference to the inserted value.
4388+ ///
4389+ /// Useful if Into is not implemented for converting from &Q to K.
4390+ /// ```compile_fail
4391+ /// # use hashbrown::hash_map::EntryRef;
4392+ /// # use hashbrown::HashMap;
4393+ /// // note that our key is a (small) tuple
4394+ /// let mut h = HashMap::<(String,), char>::new();
4395+ /// let k = (String::from("c"),);
4396+ /// match h.entry_ref(&k) {
4397+ /// // fails here, as &(i32) does not implement Into<(i32)>
4398+ /// EntryRef::Vacant(r) => r.insert('c'),
4399+ /// EntryRef::Occupied(r) => r.get(),
4400+ /// };
4401+ /// ```
4402+ /// ```
4403+ /// # use hashbrown::hash_map::EntryRef;
4404+ /// # use hashbrown::HashMap;
4405+ /// let mut h = HashMap::<(String,), char>::new();
4406+ /// let k = (String::from("c"),);
4407+ /// match h.entry_ref(&k) {
4408+ /// // works, because we manually clone when needed.
4409+ /// EntryRef::Vacant(r) => r.insert_with_key(k.clone(),'c'),
4410+ /// // in this branch we avoided the clone
4411+ /// EntryRef::Occupied(r) => r.get(),
4412+ /// };
4413+ /// ```
4414+ ///
4415+ #[ cfg_attr( feature = "inline-more" , inline) ]
4416+ pub fn insert_with_key ( self , key : K , value : V ) -> & ' map mut V
4417+ where
4418+ K : Hash ,
4419+ Q : Equivalent < K > ,
4420+ S : BuildHasher ,
4421+ {
4422+ let table = & mut self . table . table ;
4423+ assert ! (
4424+ ( self . key) . equivalent( & key) ,
4425+ "The key used for Entry creation and the one used for insertion are not equivalent"
4426+ ) ;
4427+ let entry = table. insert_entry (
4428+ self . hash ,
4429+ ( key, value) ,
4430+ make_hasher :: < _ , V , S > ( & self . table . hash_builder ) ,
4431+ ) ;
4432+ & mut entry. 1
4433+ }
4434+
43864435 /// Sets the value of the entry with the [`VacantEntryRef`]'s key,
43874436 /// and returns an [`OccupiedEntry`].
43884437 ///
@@ -4400,10 +4449,10 @@ impl<'a, 'b, K, Q: ?Sized, V, S, A: Allocator> VacantEntryRef<'a, 'b, K, Q, V, S
44004449 /// }
44014450 /// ```
44024451 #[ cfg_attr( feature = "inline-more" , inline) ]
4403- pub fn insert_entry ( self , value : V ) -> OccupiedEntry < ' a , K , V , S , A >
4452+ pub fn insert_entry ( self , value : V ) -> OccupiedEntry < ' map , K , V , S , A >
44044453 where
44054454 K : Hash ,
4406- & ' b Q : Into < K > ,
4455+ & ' key Q : Into < K > ,
44074456 S : BuildHasher ,
44084457 {
44094458 let elem = self . table . table . insert (
0 commit comments