1
Fork 0

auto merge of #17378 : Gankro/rust/hashmap-entry, r=aturon

Deprecates the `find_or_*` family of "internal mutation" methods on `HashMap` in
favour of the "external mutation" Entry API as part of RFC 60. Part of #17320,
but this still needs to be done on the rest of the maps. However they don't have
any internal mutation methods defined, so they can be done without deprecating
or breaking anything. Work on `BTree` is part of the complete rewrite in #17334.

The implemented API deviates from the API described in the RFC in two key places:

* `VacantEntry.set` yields a mutable reference to the inserted element to avoid code
duplication where complex logic needs to be done *regardless* of whether the entry
was vacant or not.
* `OccupiedEntry.into_mut` was added so that it is possible to return a reference
into the map beyond the lifetime of the Entry itself, providing functional parity
to `VacantEntry.set`.

This allows the full find_or_insert functionality to be implemented using this API.
A PR will be submitted to the RFC to amend this.

[breaking-change]
This commit is contained in:
bors 2014-09-25 03:32:36 +00:00
commit 5e13d3aa00
16 changed files with 386 additions and 50 deletions

View file

@ -34,6 +34,7 @@
//! both occur before the crate is rendered.
use std::collections::{HashMap, HashSet};
use std::collections::hashmap::{Occupied, Vacant};
use std::fmt;
use std::io::fs::PathExtensions;
use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
@ -802,9 +803,10 @@ impl DocFolder for Cache {
clean::ImplItem(ref i) => {
match i.trait_ {
Some(clean::ResolvedPath{ did, .. }) => {
let v = self.implementors.find_or_insert_with(did, |_| {
Vec::new()
});
let v = match self.implementors.entry(did) {
Vacant(entry) => entry.set(Vec::with_capacity(1)),
Occupied(entry) => entry.into_mut(),
};
v.push(Implementor {
def_id: item.def_id,
generics: i.generics.clone(),
@ -999,9 +1001,10 @@ impl DocFolder for Cache {
match did {
Some(did) => {
let v = self.impls.find_or_insert_with(did, |_| {
Vec::new()
});
let v = match self.impls.entry(did) {
Vacant(entry) => entry.set(Vec::with_capacity(1)),
Occupied(entry) => entry.into_mut(),
};
v.push(Impl {
impl_: i,
dox: dox,
@ -2143,7 +2146,10 @@ fn build_sidebar(m: &clean::Module) -> HashMap<String, Vec<String>> {
None => continue,
Some(ref s) => s.to_string(),
};
let v = map.find_or_insert_with(short.to_string(), |_| Vec::new());
let v = match map.entry(short.to_string()) {
Vacant(entry) => entry.set(Vec::with_capacity(1)),
Occupied(entry) => entry.into_mut(),
};
v.push(myname);
}