diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs index 309c7a44c5d..e3d829b4ee3 100644 --- a/src/librustc/driver/config.rs +++ b/src/librustc/driver/config.rs @@ -31,6 +31,7 @@ use syntax::parse; use syntax::parse::token::InternedString; use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; use getopts::{optopt, optmulti, optflag, optflagopt}; use getopts; use std::cell::{RefCell}; @@ -808,8 +809,11 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options { Some(s) => s, None => early_error("--extern value must be of the format `foo=bar`"), }; - let locs = externs.find_or_insert(name.to_string(), Vec::new()); - locs.push(location.to_string()); + + match externs.entry(name.to_string()) { + Vacant(entry) => { entry.set(vec![location.to_string()]); }, + Occupied(mut entry) => { entry.get_mut().push(location.to_string()); }, + } } let crate_name = matches.opt_str("crate-name"); diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs index 473c3935769..c73c5e019dd 100644 --- a/src/librustc/lint/builtin.rs +++ b/src/librustc/lint/builtin.rs @@ -36,6 +36,7 @@ use lint::{Context, LintPass, LintArray}; use std::cmp; use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; use std::slice; use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64}; use syntax::abi; @@ -1204,6 +1205,7 @@ impl UnusedMut { fn check_unused_mut_pat(&self, cx: &Context, pats: &[P]) { // collect all mutable pattern and group their NodeIDs by their Identifier to // avoid false warnings in match arms with multiple patterns + let mut mutables = HashMap::new(); for p in pats.iter() { pat_util::pat_bindings(&cx.tcx.def_map, &**p, |mode, id, _, path1| { @@ -1211,8 +1213,10 @@ impl UnusedMut { match mode { ast::BindByValue(ast::MutMutable) => { if !token::get_ident(ident).get().starts_with("_") { - mutables.insert_or_update_with(ident.name.uint(), - vec!(id), |_, old| { old.push(id); }); + match mutables.entry(ident.name.uint()) { + Vacant(entry) => { entry.set(vec![id]); }, + Occupied(mut entry) => { entry.get_mut().push(id); }, + } } } _ => { diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 342a42fbb26..e2d997a93fe 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -24,6 +24,7 @@ use plugin::load::PluginMetadata; use std::rc::Rc; use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; use syntax::ast; use syntax::abi; use syntax::attr; @@ -82,7 +83,10 @@ fn dump_crates(cstore: &CStore) { fn warn_if_multiple_versions(diag: &SpanHandler, cstore: &CStore) { let mut map = HashMap::new(); cstore.iter_crate_data(|cnum, data| { - map.find_or_insert_with(data.name(), |_| Vec::new()).push(cnum); + match map.entry(data.name()) { + Vacant(entry) => { entry.set(vec![cnum]); }, + Occupied(mut entry) => { entry.get_mut().push(cnum); }, + } }); for (name, dupes) in map.into_iter() { diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index f63705bfb99..dc97b6c0df8 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -237,6 +237,7 @@ use std::slice; use std::string; use std::collections::{HashMap, HashSet}; +use std::collections::hashmap::{Occupied, Vacant}; use flate; use time; @@ -428,15 +429,18 @@ impl<'a> Context<'a> { return FileDoesntMatch }; info!("lib candidate: {}", path.display()); - let slot = candidates.find_or_insert_with(hash.to_string(), |_| { - (HashSet::new(), HashSet::new()) - }); + + let slot = match candidates.entry(hash.to_string()) { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.set((HashSet::new(), HashSet::new())), + }; let (ref mut rlibs, ref mut dylibs) = *slot; if rlib { rlibs.insert(fs::realpath(path).unwrap()); } else { dylibs.insert(fs::realpath(path).unwrap()); } + FileMatches }); diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 8c7c8eda2d2..98d2cefac0f 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -28,6 +28,7 @@ use syntax::visit; use syntax::{ast, ast_map, ast_util}; use std::rc::Rc; +use std::collections::hashmap::Vacant; // // This pass classifies expressions by their constant-ness. @@ -321,7 +322,10 @@ pub fn const_expr_to_pat(tcx: &ty::ctxt, expr: &Expr) -> P { ExprCall(ref callee, ref args) => { let def = tcx.def_map.borrow().get_copy(&callee.id); - tcx.def_map.borrow_mut().find_or_insert(expr.id, def); + match tcx.def_map.borrow_mut().entry(expr.id) { + Vacant(entry) => { entry.set(def); } + _ => {} + }; let path = match def { def::DefStruct(def_id) => def_to_path(tcx, def_id), def::DefVariant(_, variant_did, _) => def_to_path(tcx, variant_did), diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 6fa33f4b5aa..b357d9a4534 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -58,6 +58,7 @@ use syntax::visit; use syntax::visit::Visitor; use std::collections::{HashMap, HashSet}; +use std::collections::hashmap::{Occupied, Vacant}; use std::cell::{Cell, RefCell}; use std::gc::GC; use std::mem::replace; @@ -2813,10 +2814,13 @@ impl<'a> Resolver<'a> { let is_public = import_directive.is_public; let mut import_resolutions = module_.import_resolutions.borrow_mut(); - let dest_import_resolution = import_resolutions.find_or_insert_with(name, |_| { - // Create a new import resolution from this child. - ImportResolution::new(id, is_public) - }); + let dest_import_resolution = match import_resolutions.entry(name) { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => { + // Create a new import resolution from this child. + entry.set(ImportResolution::new(id, is_public)) + } + }; debug!("(resolving glob import) writing resolution `{}` in `{}` \ to `{}`", @@ -5991,19 +5995,21 @@ impl<'a> Resolver<'a> { assert!(match lp {LastImport{..} => false, _ => true}, "Import should only be used for `use` directives"); self.last_private.insert(node_id, lp); - self.def_map.borrow_mut().insert_or_update_with(node_id, def, |_, old_value| { + + match self.def_map.borrow_mut().entry(node_id) { // Resolve appears to "resolve" the same ID multiple // times, so here is a sanity check it at least comes to // the same conclusion! - nmatsakis - if def != *old_value { + Occupied(entry) => if def != *entry.get() { self.session .bug(format!("node_id {:?} resolved first to {:?} and \ then {:?}", node_id, - *old_value, + *entry.get(), def).as_slice()); - } - }); + }, + Vacant(entry) => { entry.set(def); }, + } } fn enforce_default_binding_mode(&mut self, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 897bc4517f4..f6898a6bdf9 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -50,6 +50,7 @@ use std::mem; use std::ops; use std::rc::Rc; use std::collections::{HashMap, HashSet}; +use std::collections::hashmap::{Occupied, Vacant}; use arena::TypedArena; use syntax::abi; use syntax::ast::{CrateNum, DefId, FnStyle, Ident, ItemTrait, LOCAL_CRATE}; @@ -4641,9 +4642,10 @@ pub fn lookup_field_type(tcx: &ctxt, node_id_to_type(tcx, id.node) } else { let mut tcache = tcx.tcache.borrow_mut(); - let pty = tcache.find_or_insert_with(id, |_| { - csearch::get_field_type(tcx, struct_id, id) - }); + let pty = match tcache.entry(id) { + Occupied(entry) => entry.into_mut(), + Vacant(entry) => entry.set(csearch::get_field_type(tcx, struct_id, id)), + }; pty.ty }; t.subst(tcx, substs) diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index c8728d375f6..8a28293e8ae 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -122,6 +122,7 @@ use util::nodemap::{DefIdMap, FnvHashMap, NodeMap}; use std::cell::{Cell, RefCell}; use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; use std::mem::replace; use std::rc::Rc; use std::slice; @@ -2017,11 +2018,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { */ let mut region_obligations = self.inh.region_obligations.borrow_mut(); - let v = region_obligations.find_or_insert_with(self.body_id, - |_| Vec::new()); - v.push(RegionObligation { sub_region: r, + let region_obligation = RegionObligation { sub_region: r, sup_type: ty, - origin: origin }); + origin: origin }; + + match region_obligations.entry(self.body_id) { + Vacant(entry) => { entry.set(vec![region_obligation]); }, + Occupied(mut entry) => { entry.get_mut().push(region_obligation); }, + } } pub fn add_obligations_for_parameters(&self, diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 8bcbe4b7929..db9877698a3 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -18,6 +18,7 @@ use middle::ty_fold::TypeFolder; use syntax::ast; use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; use util::ppaux::Repr; // Helper functions related to manipulating region types. @@ -35,7 +36,10 @@ pub fn replace_late_bound_regions_in_fn_sig( debug!("region r={}", r.to_string()); match r { ty::ReLateBound(s, br) if s == fn_sig.binder_id => { - *map.find_or_insert_with(br, |_| mapf(br)) + * match map.entry(br) { + Vacant(entry) => entry.set(mapf(br)), + Occupied(entry) => entry.into_mut(), + } } _ => r } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2107854c52b..b9de64bb900 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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}; @@ -801,9 +802,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(), @@ -998,9 +1000,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, @@ -2141,7 +2144,10 @@ fn build_sidebar(m: &clean::Module) -> HashMap> { 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); } diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index f8eb40a3894..237a88ded71 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -31,6 +31,7 @@ extern crate time; use std::io; use std::io::{File, MemWriter}; use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; use serialize::{json, Decodable, Encodable}; use externalfiles::ExternalHtml; @@ -340,7 +341,10 @@ fn parse_externs(matches: &getopts::Matches) -> Result { return Err("--extern value must be of the format `foo=bar`".to_string()); } }; - let locs = externs.find_or_insert(name.to_string(), Vec::new()); + let locs = match externs.entry(name.to_string()) { + Vacant(entry) => entry.set(Vec::with_capacity(1)), + Occupied(entry) => entry.into_mut(), + }; locs.push(location.to_string()); } Ok(externs) diff --git a/src/libsyntax/ext/mtwt.rs b/src/libsyntax/ext/mtwt.rs index 2c94db52967..6fe4f5b324c 100644 --- a/src/libsyntax/ext/mtwt.rs +++ b/src/libsyntax/ext/mtwt.rs @@ -20,6 +20,7 @@ use ast::{Ident, Mrk, Name, SyntaxContext}; use std::cell::RefCell; use std::rc::Rc; use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; /// The SCTable contains a table of SyntaxContext_'s. It /// represents a flattened tree structure, to avoid having @@ -65,10 +66,10 @@ pub fn apply_mark(m: Mrk, ctxt: SyntaxContext) -> SyntaxContext { /// Extend a syntax context with a given mark and sctable (explicit memoization) fn apply_mark_internal(m: Mrk, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext { let key = (ctxt, m); - let new_ctxt = |_: &(SyntaxContext, Mrk)| - idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt)); - - *table.mark_memo.borrow_mut().find_or_insert_with(key, new_ctxt) + * match table.mark_memo.borrow_mut().entry(key) { + Vacant(entry) => entry.set(idx_push(&mut *table.table.borrow_mut(), Mark(m, ctxt))), + Occupied(entry) => entry.into_mut(), + } } /// Extend a syntax context with a given rename @@ -83,10 +84,11 @@ fn apply_rename_internal(id: Ident, ctxt: SyntaxContext, table: &SCTable) -> SyntaxContext { let key = (ctxt, id, to); - let new_ctxt = |_: &(SyntaxContext, Ident, Name)| - idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt)); - *table.rename_memo.borrow_mut().find_or_insert_with(key, new_ctxt) + * match table.rename_memo.borrow_mut().entry(key) { + Vacant(entry) => entry.set(idx_push(&mut *table.table.borrow_mut(), Rename(id, to, ctxt))), + Occupied(entry) => entry.into_mut(), + } } /// Apply a list of renamings to a context diff --git a/src/libtest/stats.rs b/src/libtest/stats.rs index 7087d4c4238..83a178d7b55 100644 --- a/src/libtest/stats.rs +++ b/src/libtest/stats.rs @@ -11,6 +11,7 @@ #![allow(missing_doc)] use std::collections::hashmap; +use std::collections::hashmap::{Occupied, Vacant}; use std::fmt::Show; use std::hash::Hash; use std::io; @@ -443,7 +444,10 @@ pub fn write_boxplot( pub fn freq_count, U: Eq+Hash>(mut iter: T) -> hashmap::HashMap { let mut map: hashmap::HashMap = hashmap::HashMap::new(); for elem in iter { - map.insert_or_update_with(elem, 1, |_, count| *count += 1); + match map.entry(elem) { + Occupied(mut entry) => { *entry.get_mut() += 1; }, + Vacant(entry) => { entry.set(1); }, + } } map } diff --git a/src/liburl/lib.rs b/src/liburl/lib.rs index b5ffdef22e9..0b227b68ca8 100644 --- a/src/liburl/lib.rs +++ b/src/liburl/lib.rs @@ -23,6 +23,7 @@ #![feature(default_type_params)] use std::collections::HashMap; +use std::collections::hashmap::{Occupied, Vacant}; use std::fmt; use std::from_str::FromStr; use std::hash; @@ -342,8 +343,10 @@ pub fn decode_form_urlencoded(s: &[u8]) key: String, value: String) { if key.len() > 0 && value.len() > 0 { - let values = map.find_or_insert_with(key, |_| vec!()); - values.push(value); + match map.entry(key) { + Vacant(entry) => { entry.set(vec![value]); }, + Occupied(mut entry) => { entry.get_mut().push(value); }, + } } }