Skip to content

[RFC] Entry API v3: replace Entry::get with Entry::default and Entry::default_with #22930

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Mar 27, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 27 additions & 12 deletions src/libcollections/btree/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1143,15 +1143,39 @@ impl<'a, K, V> DoubleEndedIterator for RangeMut<'a, K, V> {
}

impl<'a, K: Ord, V> Entry<'a, K, V> {
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
#[unstable(feature = "std_misc",
reason = "will soon be replaced by or_insert")]
#[deprecated(since = "1.0",
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => Err(entry),
}
}

#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default),
}
}

#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default()),
}
}
}

impl<'a, K: Ord, V> VacantEntry<'a, K, V> {
Expand Down Expand Up @@ -1563,21 +1587,12 @@ impl<K: Ord, V> BTreeMap<K, V> {
/// ```
/// # #![feature(collections)]
/// use std::collections::BTreeMap;
/// use std::collections::btree_map::Entry;
///
/// let mut count: BTreeMap<&str, usize> = BTreeMap::new();
///
/// // count the number of occurrences of letters in the vec
/// for x in vec!["a","b","a","c","a","b"].iter() {
/// match count.entry(*x) {
/// Entry::Vacant(view) => {
/// view.insert(1);
/// },
/// Entry::Occupied(mut view) => {
/// let v = view.get_mut();
/// *v += 1;
/// },
/// }
/// for x in vec!["a","b","a","c","a","b"] {
/// *count.entry(x).or_insert(0) += 1;
/// }
///
/// assert_eq!(count["a"], 3);
Expand Down
37 changes: 26 additions & 11 deletions src/libcollections/vec_map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,21 +632,12 @@ impl<V> VecMap<V> {
/// ```
/// # #![feature(collections)]
/// use std::collections::VecMap;
/// use std::collections::vec_map::Entry;
///
/// let mut count: VecMap<u32> = VecMap::new();
///
/// // count the number of occurrences of numbers in the vec
/// for x in vec![1, 2, 1, 2, 3, 4, 1, 2, 4].iter() {
/// match count.entry(*x) {
/// Entry::Vacant(view) => {
/// view.insert(1);
/// },
/// Entry::Occupied(mut view) => {
/// let v = view.get_mut();
/// *v += 1;
/// },
/// }
/// for x in vec![1, 2, 1, 2, 3, 4, 1, 2, 4] {
/// *count.entry(x).or_insert(0) += 1;
/// }
///
/// assert_eq!(count[1], 3);
Expand Down Expand Up @@ -675,13 +666,37 @@ impl<V> VecMap<V> {
impl<'a, V> Entry<'a, V> {
#[unstable(feature = "collections",
reason = "will soon be replaced by or_insert")]
#[deprecated(since = "1.0",
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, V>> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => Err(entry),
}
}

#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default),
}
}

#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default()),
}
}
}

impl<'a, V> VacantEntry<'a, V> {
Expand Down
4 changes: 2 additions & 2 deletions src/librustc/metadata/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -426,8 +426,8 @@ impl<'a> Context<'a> {
info!("lib candidate: {}", path.display());

let hash_str = hash.to_string();
let slot = candidates.entry(hash_str).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert((HashMap::new(), HashMap::new())));
let slot = candidates.entry(hash_str)
.or_insert_with(|| (HashMap::new(), HashMap::new()));
let (ref mut rlibs, ref mut dylibs) = *slot;
if rlib {
rlibs.insert(fs::realpath(path).unwrap(), kind);
Expand Down
14 changes: 2 additions & 12 deletions src/librustc/middle/dataflow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,12 +160,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,

cfg.graph.each_node(|node_idx, node| {
if let cfg::CFGNodeData::AST(id) = node.data {
match index.entry(id).get() {
Ok(v) => v.push(node_idx),
Err(e) => {
e.insert(vec![node_idx]);
}
}
index.entry(id).or_insert(vec![]).push(node_idx);
}
true
});
Expand All @@ -185,12 +180,7 @@ fn build_nodeid_to_index(decl: Option<&ast::FnDecl>,
visit::walk_fn_decl(&mut formals, decl);
impl<'a, 'v> visit::Visitor<'v> for Formals<'a> {
fn visit_pat(&mut self, p: &ast::Pat) {
match self.index.entry(p.id).get() {
Ok(v) => v.push(self.entry),
Err(e) => {
e.insert(vec![self.entry]);
}
}
self.index.entry(p.id).or_insert(vec![]).push(self.entry);
visit::walk_pat(self, p)
}
}
Expand Down
7 changes: 2 additions & 5 deletions src/librustc/middle/traits/fulfill.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
use middle::infer::{InferCtxt};
use middle::ty::{self, RegionEscape, Ty};
use std::collections::HashSet;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::default::Default;
use syntax::ast;
use util::common::ErrorReported;
Expand Down Expand Up @@ -437,9 +436,7 @@ fn register_region_obligation<'tcx>(tcx: &ty::ctxt<'tcx>,
debug!("register_region_obligation({})",
region_obligation.repr(tcx));

match region_obligations.entry(region_obligation.cause.body_id) {
Vacant(entry) => { entry.insert(vec![region_obligation]); },
Occupied(mut entry) => { entry.get_mut().push(region_obligation); },
}
region_obligations.entry(region_obligation.cause.body_id).or_insert(vec![])
.push(region_obligation);

}
8 changes: 2 additions & 6 deletions src/librustc/middle/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5669,9 +5669,7 @@ pub fn lookup_field_type<'tcx>(tcx: &ctxt<'tcx>,
node_id_to_type(tcx, id.node)
} else {
let mut tcache = tcx.tcache.borrow_mut();
let pty = tcache.entry(id).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(csearch::get_field_type(tcx, struct_id, id)));
pty.ty
tcache.entry(id).or_insert_with(|| csearch::get_field_type(tcx, struct_id, id)).ty
};
ty.subst(tcx, substs)
}
Expand Down Expand Up @@ -6819,9 +6817,7 @@ pub fn replace_late_bound_regions<'tcx, T, F>(
debug!("region={}", region.repr(tcx));
match region {
ty::ReLateBound(debruijn, br) if debruijn.depth == current_depth => {
let region =
* map.entry(br).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(mapf(br)));
let region = *map.entry(br).or_insert_with(|| mapf(br));

if let ty::ReLateBound(debruijn1, br) = region {
// If the callback returns a late-bound region,
Expand Down
6 changes: 1 addition & 5 deletions src/librustc/session/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ use syntax::parse::token::InternedString;

use getopts;
use std::collections::HashMap;
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::env;
use std::fmt;
use std::path::PathBuf;
Expand Down Expand Up @@ -1037,10 +1036,7 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
None => early_error("--extern value must be of the format `foo=bar`"),
};

match externs.entry(name.to_string()) {
Vacant(entry) => { entry.insert(vec![location.to_string()]); },
Occupied(mut entry) => { entry.get_mut().push(location.to_string()); },
}
externs.entry(name.to_string()).or_insert(vec![]).push(location.to_string());
}

let crate_name = matches.opt_str("crate-name");
Expand Down
1 change: 0 additions & 1 deletion src/librustc_resolve/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@
#![feature(rustc_diagnostic_macros)]
#![feature(rustc_private)]
#![feature(staged_api)]
#![feature(std_misc)]

#[macro_use] extern crate log;
#[macro_use] extern crate syntax;
Expand Down
7 changes: 2 additions & 5 deletions src/librustc_resolve/resolve_imports.rs
Original file line number Diff line number Diff line change
Expand Up @@ -836,11 +836,8 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
let is_public = import_directive.is_public;

let mut import_resolutions = module_.import_resolutions.borrow_mut();
let dest_import_resolution = import_resolutions.entry(name).get().unwrap_or_else(
|vacant_entry| {
// Create a new import resolution from this child.
vacant_entry.insert(ImportResolution::new(id, is_public))
});
let dest_import_resolution = import_resolutions.entry(name)
.or_insert_with(|| ImportResolution::new(id, is_public));

debug!("(resolving glob import) writing resolution `{}` in `{}` \
to `{}`",
Expand Down
7 changes: 1 addition & 6 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@ use util::nodemap::{DefIdMap, FnvHashMap, NodeMap};
use util::lev_distance::lev_distance;

use std::cell::{Cell, Ref, RefCell};
use std::collections::hash_map::Entry::{Occupied, Vacant};
use std::mem::replace;
use std::rc::Rc;
use std::iter::repeat;
Expand Down Expand Up @@ -1362,11 +1361,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
closure_def_id: ast::DefId,
r: DeferredCallResolutionHandler<'tcx>) {
let mut deferred_call_resolutions = self.inh.deferred_call_resolutions.borrow_mut();
let mut vec = match deferred_call_resolutions.entry(closure_def_id) {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(Vec::new()),
};
vec.push(r);
deferred_call_resolutions.entry(closure_def_id).or_insert(vec![]).push(r);
}

fn remove_deferred_call_resolutions(&self,
Expand Down
13 changes: 4 additions & 9 deletions src/librustdoc/html/render.rs
Original file line number Diff line number Diff line change
Expand Up @@ -876,9 +876,7 @@ impl DocFolder for Cache {
if let clean::ImplItem(ref i) = item.inner {
match i.trait_ {
Some(clean::ResolvedPath{ did, .. }) => {
let v = self.implementors.entry(did).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
v.push(Implementor {
self.implementors.entry(did).or_insert(vec![]).push(Implementor {
def_id: item.def_id,
generics: i.generics.clone(),
trait_: i.trait_.as_ref().unwrap().clone(),
Expand Down Expand Up @@ -1080,9 +1078,7 @@ impl DocFolder for Cache {
};

if let Some(did) = did {
let v = self.impls.entry(did).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
v.push(Impl {
self.impls.entry(did).or_insert(vec![]).push(Impl {
impl_: i,
dox: dox,
stability: item.stability.clone(),
Expand Down Expand Up @@ -1334,9 +1330,8 @@ impl Context {
Some(ref s) => s.to_string(),
};
let short = short.to_string();
let v = map.entry(short).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
v.push((myname, Some(plain_summary_line(item.doc_value()))));
map.entry(short).or_insert(vec![])
.push((myname, Some(plain_summary_line(item.doc_value()))));
}

for (_, items) in &mut map {
Expand Down
4 changes: 1 addition & 3 deletions src/librustdoc/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,7 @@ fn parse_externs(matches: &getopts::Matches) -> Result<core::Externs, String> {
}
};
let name = name.to_string();
let locs = externs.entry(name).get().unwrap_or_else(
|vacant_entry| vacant_entry.insert(Vec::with_capacity(1)));
locs.push(location.to_string());
externs.entry(name).or_insert(vec![]).push(location.to_string());
}
Ok(externs)
}
Expand Down
27 changes: 26 additions & 1 deletion src/libstd/collections/hash/map.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ use hash::{Hash, SipHasher};
use iter::{self, Iterator, ExactSizeIterator, IntoIterator, IteratorExt, FromIterator, Extend, Map};
use marker::Sized;
use mem::{self, replace};
use ops::{Deref, FnMut, Index};
use ops::{Deref, FnMut, FnOnce, Index};
use option::Option::{self, Some, None};
use rand::{self, Rng};
use result::Result::{self, Ok, Err};
Expand Down Expand Up @@ -1488,12 +1488,37 @@ impl<'a, K, V> Entry<'a, K, V> {
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant.
#[unstable(feature = "std_misc",
reason = "will soon be replaced by or_insert")]
#[deprecated(since = "1.0",
reason = "replaced with more ergonomic `or_insert` and `or_insert_with`")]
/// Returns a mutable reference to the entry if occupied, or the VacantEntry if vacant
pub fn get(self) -> Result<&'a mut V, VacantEntry<'a, K, V>> {
match self {
Occupied(entry) => Ok(entry.into_mut()),
Vacant(entry) => Err(entry),
}
}

#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the default if empty, and returns
/// a mutable reference to the value in the entry.
pub fn or_insert(self, default: V) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default),
}
}

#[unstable(feature = "collections",
reason = "matches entry v3 specification, waiting for dust to settle")]
/// Ensures a value is in the entry by inserting the result of the default function if empty,
/// and returns a mutable reference to the value in the entry.
pub fn or_insert_with<F: FnOnce() -> V>(self, default: F) -> &'a mut V {
match self {
Occupied(entry) => entry.into_mut(),
Vacant(entry) => entry.insert(default()),
}
}
}

impl<'a, K, V> OccupiedEntry<'a, K, V> {
Expand Down
10 changes: 2 additions & 8 deletions src/libstd/collections/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -307,10 +307,7 @@
//! let message = "she sells sea shells by the sea shore";
//!
//! for c in message.chars() {
//! match count.entry(c) {
//! Entry::Vacant(entry) => { entry.insert(1); },
//! Entry::Occupied(mut entry) => *entry.get_mut() += 1,
//! }
//! *count.entry(c).or_insert(0) += 1;
//! }
//!
//! assert_eq!(count.get(&'s'), Some(&8));
Expand Down Expand Up @@ -343,10 +340,7 @@
//! for id in orders.into_iter() {
//! // If this is the first time we've seen this customer, initialize them
//! // with no blood alcohol. Otherwise, just retrieve them.
//! let person = match blood_alcohol.entry(id) {
//! Entry::Vacant(entry) => entry.insert(Person{id: id, blood_alcohol: 0.0}),
//! Entry::Occupied(entry) => entry.into_mut(),
//! };
//! let person = blood_alcohol.entry(id).or_insert(Person{id: id, blood_alcohol: 0.0});
//!
//! // Reduce their blood alcohol level. It takes time to order and drink a beer!
//! person.blood_alcohol *= 0.9;
Expand Down
Loading