Description
The lifetime on the get()
method's return value is bound to the lifetime of Entry
. This is intended, as far as I can tell; however, the into_mut
method allows the Entry
to be converted into a reference bound to the HashMap
's lifetime. But there is no way to get an immutable reference bound to the HashMap
's lifetime.
This issue originally arose from this reddit thread. A minimal usecase example is:
fn get_symbol<'a>(symbols: &'a mut HashMap<u32, String>, id: u32) -> &'a str {
match symbols.entry(id) {
Entry::Occupied(e) => e.get().to_string(), // BAD! Should be e.into_mut().
Entry::Vacant(e) => {
// <snipped bookkeeping>...
let new_symbol = "foobar".to_string();
e.insert(new_symbol).as_str()
}
}
}
From my understanding, it should be safe to add an into_ref(self) -> &'a V
method to fill this hole. It would be implemented as:
pub fn into_mut(self) -> &'a mut V {
self.elem.into_refs().1
}
because the underlying structure FullBucket
already supports an into_refs()
method (with the same safety reasoning as into_mut_refs()
.)
It may also be useful to have an into_key(self) -> &'a K
method. It should be just as safe (and would use basically the same implementation).
This was previously opened as an issue (#39099) but was self-closed when the poster found the into_mut()
workaround.
I'd be happy to open a PR for this, but I want to make sure I'm not missing anything obvious here.