diff --git a/src/grammar/verify.rs b/src/grammar/verify.rs index a4641c40165ac..159a62f011072 100644 --- a/src/grammar/verify.rs +++ b/src/grammar/verify.rs @@ -178,7 +178,7 @@ fn parse_antlr_token(s: &str, tokens: &HashMap) -> TokenAndSpan { let toknum = m.name("toknum"); let content = m.name("content"); - let proto_tok = tokens.find_equiv(&toknum).expect(format!("didn't find token {} in the map", + let proto_tok = tokens.get(&toknum).expect(format!("didn't find token {} in the map", toknum).as_slice()); let nm = parse::token::intern(content); diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs index 0b6d9e356b910..007e01ef9820c 100644 --- a/src/libcollections/btree/map.rs +++ b/src/libcollections/btree/map.rs @@ -21,6 +21,7 @@ use core::prelude::*; use self::StackOp::*; use super::node::*; +use core::borrow::BorrowFrom; use std::hash::{Writer, Hash}; use core::default::Default; use core::{iter, fmt, mem}; @@ -184,6 +185,9 @@ impl BTreeMap { /// Returns a reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -195,7 +199,7 @@ impl BTreeMap { /// assert_eq!(map.get(&2), None); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get(&self, key: &K) -> Option<&V> { + pub fn get(&self, key: &Q) -> Option<&V> where Q: BorrowFrom + Ord { let mut cur_node = &self.root; loop { match cur_node.search(key) { @@ -213,6 +217,9 @@ impl BTreeMap { /// Returns true if the map contains a value for the specified key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -224,7 +231,7 @@ impl BTreeMap { /// assert_eq!(map.contains_key(&2), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains_key(&self, key: &K) -> bool { + pub fn contains_key(&self, key: &Q) -> bool where Q: BorrowFrom + Ord { self.get(key).is_some() } @@ -236,6 +243,9 @@ impl BTreeMap { /// Returns a mutable reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -251,7 +261,7 @@ impl BTreeMap { /// ``` // See `get` for implementation notes, this is basically a copy-paste with mut's added #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom + Ord { // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration let mut temp_node = &mut self.root; loop { @@ -410,6 +420,9 @@ impl BTreeMap { /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -421,7 +434,7 @@ impl BTreeMap { /// assert_eq!(map.remove(&1), None); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, key: &K) -> Option { + pub fn remove(&mut self, key: &Q) -> Option where Q: BorrowFrom + Ord { // See `swap` for a more thorough description of the stuff going on in here let mut stack = stack::PartialSearchStack::new(self); loop { @@ -790,14 +803,18 @@ impl Show for BTreeMap { } } -impl Index for BTreeMap { - fn index(&self, key: &K) -> &V { +impl Index for BTreeMap + where Q: BorrowFrom + Ord +{ + fn index(&self, key: &Q) -> &V { self.get(key).expect("no entry found for key") } } -impl IndexMut for BTreeMap { - fn index_mut(&mut self, key: &K) -> &mut V { +impl IndexMut for BTreeMap + where Q: BorrowFrom + Ord +{ + fn index_mut(&mut self, key: &Q) -> &mut V { self.get_mut(key).expect("no entry found for key") } } diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs index 6e9341231ad69..bdd7aa9c61172 100644 --- a/src/libcollections/btree/node.rs +++ b/src/libcollections/btree/node.rs @@ -19,6 +19,7 @@ use core::prelude::*; use core::{slice, mem, ptr}; use core::iter::Zip; +use core::borrow::BorrowFrom; use vec; use vec::Vec; @@ -73,19 +74,19 @@ impl Node { /// Searches for the given key in the node. If it finds an exact match, /// `Found` will be yielded with the matching index. If it doesn't find an exact match, /// `GoDown` will be yielded with the index of the subtree the key must lie in. - pub fn search(&self, key: &K) -> SearchResult { + pub fn search(&self, key: &Q) -> SearchResult where Q: BorrowFrom + Ord { // FIXME(Gankro): Tune when to search linear or binary based on B (and maybe K/V). // For the B configured as of this writing (B = 6), binary search was *significantly* // worse for uints. self.search_linear(key) } - fn search_linear(&self, key: &K) -> SearchResult { + fn search_linear(&self, key: &Q) -> SearchResult where Q: BorrowFrom + Ord { for (i, k) in self.keys.iter().enumerate() { - match k.cmp(key) { - Less => {}, + match key.cmp(BorrowFrom::borrow_from(k)) { + Greater => {}, Equal => return Found(i), - Greater => return GoDown(i), + Less => return GoDown(i), } } GoDown(self.len()) diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs index 56edf7719bb22..64ae4f6a50867 100644 --- a/src/libcollections/btree/set.rs +++ b/src/libcollections/btree/set.rs @@ -15,6 +15,7 @@ use core::prelude::*; use btree_map::{BTreeMap, Keys, MoveEntries}; use std::hash::Hash; +use core::borrow::BorrowFrom; use core::default::Default; use core::{iter, fmt}; use core::iter::Peekable; @@ -167,6 +168,10 @@ impl BTreeSet { /// Returns `true` if the set contains a value. /// + /// The value may be any borrowed form of the set's value type, + /// but the ordering on the borrowed form *must* match the + /// ordering on the value type. + /// /// # Example /// /// ``` @@ -177,7 +182,7 @@ impl BTreeSet { /// assert_eq!(set.contains(&4), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains(&self, value: &T) -> bool { + pub fn contains(&self, value: &Q) -> bool where Q: BorrowFrom + Ord { self.map.contains_key(value) } @@ -291,6 +296,10 @@ impl BTreeSet { /// Removes a value from the set. Returns `true` if the value was /// present in the set. /// + /// The value may be any borrowed form of the set's value type, + /// but the ordering on the borrowed form *must* match the + /// ordering on the value type. + /// /// # Example /// /// ``` @@ -303,7 +312,7 @@ impl BTreeSet { /// assert_eq!(set.remove(&2), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, value: &T) -> bool { + pub fn remove(&mut self, value: &Q) -> bool where Q: BorrowFrom + Ord { self.map.remove(value).is_some() } } diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs index 000c3e08c677b..132a07af6b67b 100644 --- a/src/libcollections/slice.rs +++ b/src/libcollections/slice.rs @@ -89,6 +89,7 @@ use self::Direction::*; use alloc::boxed::Box; +use core::borrow::{BorrowFrom, BorrowFromMut}; use core::cmp; use core::kinds::Sized; use core::mem::size_of; @@ -647,6 +648,16 @@ impl SliceAllocPrelude for [T] { } } +#[unstable = "trait is unstable"] +impl BorrowFrom> for [T] { + fn borrow_from(owned: &Vec) -> &[T] { owned[] } +} + +#[unstable = "trait is unstable"] +impl BorrowFromMut> for [T] { + fn borrow_from_mut(owned: &mut Vec) -> &mut [T] { owned[mut] } +} + /// Unsafe operations pub mod raw { pub use core::slice::raw::{buf_as_slice, mut_buf_as_slice}; diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index ae8e92fc6cb9d..9ae009d8f6a59 100644 --- a/src/libcollections/str.rs +++ b/src/libcollections/str.rs @@ -54,7 +54,7 @@ pub use self::MaybeOwned::*; use self::RecompositionState::*; use self::DecompositionType::*; - +use core::borrow::BorrowFrom; use core::default::Default; use core::fmt; use core::cmp; @@ -604,6 +604,11 @@ impl<'a> fmt::Show for MaybeOwned<'a> { } } +#[unstable = "trait is unstable"] +impl BorrowFrom for str { + fn borrow_from(owned: &String) -> &str { owned[] } +} + /// Unsafe string operations. pub mod raw { pub use core::str::raw::{from_utf8, c_str_to_static_slice, slice_bytes}; diff --git a/src/libcollections/tree/map.rs b/src/libcollections/tree/map.rs index 50bfeafc43e29..119268c27eeac 100644 --- a/src/libcollections/tree/map.rs +++ b/src/libcollections/tree/map.rs @@ -11,6 +11,8 @@ use core::prelude::*; use alloc::boxed::Box; + +use core::borrow::BorrowFrom; use core::default::Default; use core::fmt; use core::fmt::Show; @@ -188,16 +190,16 @@ impl Default for TreeMap { fn default() -> TreeMap { TreeMap::new() } } -impl Index for TreeMap { +impl Index for TreeMap where Q: BorrowFrom + Ord { #[inline] - fn index<'a>(&'a self, i: &K) -> &'a V { + fn index<'a>(&'a self, i: &Q) -> &'a V { self.get(i).expect("no entry found for key") } } -impl IndexMut for TreeMap { +impl IndexMut for TreeMap where Q: BorrowFrom + Ord { #[inline] - fn index_mut<'a>(&'a mut self, i: &K) -> &'a mut V { + fn index_mut<'a>(&'a mut self, i: &Q) -> &'a mut V { self.get_mut(i).expect("no entry found for key") } } @@ -446,6 +448,9 @@ impl TreeMap { /// Returns a reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -458,12 +463,17 @@ impl TreeMap { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get(&self, key: &K) -> Option<&V> { - tree_find_with(&self.root, |k2| key.cmp(k2)) + pub fn get(&self, key: &Q) -> Option<&V> + where Q: BorrowFrom + Ord + { + tree_find_with(&self.root, |k2| key.cmp(BorrowFrom::borrow_from(k2))) } /// Returns true if the map contains a value for the specified key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -476,7 +486,9 @@ impl TreeMap { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains_key(&self, key: &K) -> bool { + pub fn contains_key(&self, key: &Q) -> bool + where Q: BorrowFrom + Ord + { self.get(key).is_some() } @@ -488,6 +500,9 @@ impl TreeMap { /// Returns a mutable reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -503,8 +518,10 @@ impl TreeMap { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get_mut(&mut self, key: &K) -> Option<&mut V> { - tree_find_with_mut(&mut self.root, |x| key.cmp(x)) + pub fn get_mut(&mut self, key: &Q) -> Option<&mut V> + where Q: BorrowFrom + Ord + { + tree_find_with_mut(&mut self.root, |x| key.cmp(BorrowFrom::borrow_from(x))) } /// Deprecated: Renamed to `insert`. @@ -545,6 +562,9 @@ impl TreeMap { /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// + /// The key may be any borrowed form of the map's key type, but the ordering + /// on the borrowed form *must* match the ordering on the key type. + /// /// # Example /// /// ``` @@ -556,7 +576,9 @@ impl TreeMap { /// assert_eq!(map.remove(&1), None); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, key: &K) -> Option { + pub fn remove(&mut self, key: &Q) -> Option + where Q: BorrowFrom + Ord + { let ret = remove(&mut self.root, key); if ret.is_some() { self.length -= 1 } ret @@ -589,6 +611,7 @@ impl TreeMap { /// assert_eq!((*ua.unwrap()).as_slice(), "Curl-Rust/0.1"); /// ``` #[inline] + #[experimental = "likely to be renamed, may be removed"] pub fn find_with(&self, f:|&K| -> Ordering) -> Option<&V> { tree_find_with(&self.root, f) } @@ -613,6 +636,7 @@ impl TreeMap { /// assert_eq!(t.get(&"User-Agent"), Some(&new_ua)); /// ``` #[inline] + #[experimental = "likely to be renamed, may be removed"] pub fn find_with_mut<'a>(&'a mut self, f:|&K| -> Ordering) -> Option<&'a mut V> { tree_find_with_mut(&mut self.root, f) } @@ -1168,10 +1192,11 @@ fn insert(node: &mut Option>>, } } -fn remove(node: &mut Option>>, - key: &K) -> Option { +fn remove(node: &mut Option>>, key: &Q) -> Option + where K: Ord, Q: BorrowFrom + Ord +{ fn heir_swap(node: &mut Box>, - child: &mut Option>>) { + child: &mut Option>>) { // *could* be done without recursion, but it won't borrow check for x in child.iter_mut() { if x.right.is_some() { @@ -1188,7 +1213,7 @@ fn remove(node: &mut Option>>, return None; // bottom of tree } Some(ref mut save) => { - let (ret, rebalance) = match key.cmp(&save.key) { + let (ret, rebalance) = match key.cmp(BorrowFrom::borrow_from(&save.key)) { Less => (remove(&mut save.left, key), true), Greater => (remove(&mut save.right, key), true), Equal => { @@ -1918,4 +1943,3 @@ mod bench { bench_iter(b, 100000); } } - diff --git a/src/libcollections/tree/mod.rs b/src/libcollections/tree/mod.rs index ac8279c92feeb..20823a2affc7f 100644 --- a/src/libcollections/tree/mod.rs +++ b/src/libcollections/tree/mod.rs @@ -33,4 +33,4 @@ //! ``` pub mod map; -pub mod set; \ No newline at end of file +pub mod set; diff --git a/src/libcollections/tree/set.rs b/src/libcollections/tree/set.rs index abfaeed7e7ed0..6988b929df689 100644 --- a/src/libcollections/tree/set.rs +++ b/src/libcollections/tree/set.rs @@ -10,6 +10,7 @@ use core::prelude::*; +use core::borrow::BorrowFrom; use core::default::Default; use core::fmt; use core::fmt::Show; @@ -396,6 +397,10 @@ impl TreeSet { /// Returns `true` if the set contains a value. /// + /// The value may be any borrowed form of the set's value type, + /// but the ordering on the borrowed form *must* match the + /// ordering on the value type. + /// /// # Example /// /// ``` @@ -407,7 +412,9 @@ impl TreeSet { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains(&self, value: &T) -> bool { + pub fn contains(&self, value: &Q) -> bool + where Q: Ord + BorrowFrom + { self.map.contains_key(value) } @@ -519,6 +526,10 @@ impl TreeSet { /// Removes a value from the set. Returns `true` if the value was /// present in the set. /// + /// The value may be any borrowed form of the set's value type, + /// but the ordering on the borrowed form *must* match the + /// ordering on the value type. + /// /// # Example /// /// ``` @@ -532,7 +543,11 @@ impl TreeSet { /// ``` #[inline] #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() } + pub fn remove(&mut self, value: &Q) -> bool + where Q: Ord + BorrowFrom + { + self.map.remove(value).is_some() + } } /// A lazy forward iterator over a set. diff --git a/src/libcollections/trie/mod.rs b/src/libcollections/trie/mod.rs index f0f8f00a6a0db..9dcb182cd2675 100644 --- a/src/libcollections/trie/mod.rs +++ b/src/libcollections/trie/mod.rs @@ -17,4 +17,4 @@ //! `TrieMap` is ordered. pub mod map; -pub mod set; \ No newline at end of file +pub mod set; diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs new file mode 100644 index 0000000000000..34cf55334aef3 --- /dev/null +++ b/src/libcore/borrow.rs @@ -0,0 +1,126 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//! A module for working with borrowed data. +//! +//! # The `BorrowFrom` traits +//! +//! In general, there may be several ways to "borrow" a piece of data. The +//! typical ways of borrowing a type `T` are `&T` (a shared borrow) and `&mut T` +//! (a mutable borrow). But types like `Vec` provide additional kinds of +//! borrows: the borrowed slices `&[T]` and `&mut [T]`. +//! +//! When writing generic code, it is often desirable to abstract over all ways +//! of borrowing data from a given type. That is the role of the `BorrowFrom` +//! trait: if `T: BorrowFrom`, then `&T` can be borrowed from `&U`. A given +//! type can be borrowed as multiple different types. In particular, `Vec: +//! BorrowFrom>` and `[T]: BorrowFrom>`. +//! +//! # The `ToOwned` trait +//! +//! Some types make it possible to go from borrowed to owned, usually by +//! implementing the `Clone` trait. But `Clone` works only for going from `&T` +//! to `T`. The `ToOwned` trait generalizes `Clone` to construct owned data +//! from any borrow of a given type. +//! +//! # The `Cow` (clone-on-write) type +//! +//! The type `Cow` is a smart pointer providing clone-on-write functionality: it +//! can enclose and provide immutable access to borrowed data, and clone the +//! data lazily when mutation or ownership is required. The type is designed to +//! work with general borrowed data via the `BorrowFrom` trait. +//! +//! `Cow` implements both `Deref` and `DerefMut`, which means that you can call +//! methods directly on the data it encloses. The first time a mutable reference +//! is required, the data will be cloned (via `to_owned`) if it is not +//! already owned. + +#![unstable = "recently added as part of collections reform"] + +use clone::Clone; +use kinds::Sized; +use ops::Deref; + +/// A trait for borrowing data. +pub trait BorrowFrom for Sized? { + /// Immutably borrow from an owned value. + fn borrow_from(owned: &Owned) -> &Self; +} + +/// A trait for mutably borrowing data. +pub trait BorrowFromMut for Sized? : BorrowFrom { + /// Mutably borrow from an owned value. + fn borrow_from_mut(owned: &mut Owned) -> &mut Self; +} + +impl BorrowFrom for T { + fn borrow_from(owned: &T) -> &T { owned } +} + +impl BorrowFromMut for T { + fn borrow_from_mut(owned: &mut T) -> &mut T { owned } +} + +impl BorrowFrom<&'static str> for str { + fn borrow_from<'a>(owned: &'a &'static str) -> &'a str { &**owned } +} + +/// A generalization of Clone to borrowed data. +pub trait ToOwned for Sized?: BorrowFrom { + /// Create owned data from borrowed data, usually by copying. + fn to_owned(&self) -> Owned; +} + +impl ToOwned for T where T: Clone { + fn to_owned(&self) -> T { self.clone() } +} + +/// A clone-on-write smart pointer. +pub enum Cow<'a, T, B: 'a> where B: ToOwned { + /// Borrowed data. + Borrowed(&'a B), + + /// Owned data. + Owned(T) +} + +impl<'a, T, B> Cow<'a, T, B> where B: ToOwned { + /// Acquire a mutable reference to the owned form of the data. + /// + /// Copies the data if it is not already owned. + pub fn to_mut(&mut self) -> &mut T { + match *self { + Borrowed(borrowed) => { + *self = Owned(borrowed.to_owned()); + self.to_mut() + } + Owned(ref mut owned) => owned + } + } + + /// Extract the owned data. + /// + /// Copies the data if it is not already owned. + pub fn into_owned(self) -> T { + match self { + Borrowed(borrowed) => borrowed.to_owned(), + Owned(owned) => owned + } + } +} + +impl<'a, T, B> Deref for Cow<'a, T, B> where B: ToOwned { + fn deref(&self) -> &B { + match *self { + Borrowed(borrowed) => borrowed, + Owned(ref owned) => BorrowFrom::borrow_from(owned) + } + } +} diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs index 9689f7cdd7114..5e3c74477d15c 100644 --- a/src/libcore/lib.rs +++ b/src/libcore/lib.rs @@ -108,6 +108,7 @@ pub mod default; pub mod any; pub mod atomic; pub mod bool; +pub mod borrow; pub mod cell; pub mod char; pub mod panicking; diff --git a/src/libcore/ops.rs b/src/libcore/ops.rs index 3a2e178d2ea0a..b4bf5351e597b 100644 --- a/src/libcore/ops.rs +++ b/src/libcore/ops.rs @@ -638,7 +638,7 @@ shr_impl!(uint u8 u16 u32 u64 int i8 i16 i32 i64) * ``` */ #[lang="index"] -pub trait Index for Sized? { +pub trait Index for Sized? { /// The method for the indexing (`Foo[Bar]`) operation fn index<'a>(&'a self, index: &Index) -> &'a Result; } @@ -669,7 +669,7 @@ pub trait Index for Sized? { * ``` */ #[lang="index_mut"] -pub trait IndexMut for Sized? { +pub trait IndexMut for Sized? { /// The method for the indexing (`Foo[Bar]`) operation fn index_mut<'a>(&'a mut self, index: &Index) -> &'a mut Result; } diff --git a/src/libregex/re.rs b/src/libregex/re.rs index dbdb271874474..e1e2abcb1b7c5 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -726,7 +726,7 @@ impl<'t> Captures<'t> { match self.named { None => "", Some(ref h) => { - match h.find_equiv(name) { + match h.get(name) { None => "", Some(i) => self.at(*i), } diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs index 85cc413a1b801..aa6a021a210ef 100644 --- a/src/librustc/lint/context.rs +++ b/src/librustc/lint/context.rs @@ -165,7 +165,7 @@ impl LintStore { } fn register_renamed(&mut self, old_name: &str, new_name: &str) { - let target = match self.by_name.find_equiv(new_name) { + let target = match self.by_name.get(new_name) { Some(&Id(lint_id)) => lint_id.clone(), _ => panic!("invalid lint renaming of {} to {}", old_name, new_name) }; @@ -259,7 +259,7 @@ impl LintStore { fn find_lint(&self, lint_name: &str, sess: &Session, span: Option) -> Option { - match self.by_name.find_equiv(lint_name) { + match self.by_name.get(lint_name) { Some(&Id(lint_id)) => Some(lint_id), Some(&Renamed(ref new_name, lint_id)) => { let warning = format!("lint {} has been renamed to {}", @@ -282,7 +282,7 @@ impl LintStore { match self.lint_groups.iter().map(|(&x, pair)| (x, pair.ref0().clone())) .collect::>>() - .find_equiv(lint_name.as_slice()) { + .get(lint_name.as_slice()) { Some(v) => { v.iter() .map(|lint_id: &LintId| @@ -489,7 +489,7 @@ impl<'a, 'tcx> Context<'a, 'tcx> { match self.lints.find_lint(lint_name.get(), &self.tcx.sess, Some(span)) { Some(lint_id) => vec![(lint_id, level, span)], None => { - match self.lints.lint_groups.find_equiv(lint_name.get()) { + match self.lints.lint_groups.get(lint_name.get()) { Some(&(ref v, _)) => v.iter() .map(|lint_id: &LintId| (*lint_id, level, span)) diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index dbf0e4054085c..1cfe565fd7dee 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -321,7 +321,7 @@ fn existing_match(e: &Env, name: &str, // `source` stores paths which are normalized which may be different // from the strings on the command line. let source = e.sess.cstore.get_used_crate_source(cnum).unwrap(); - match e.sess.opts.externs.find_equiv(name) { + match e.sess.opts.externs.get(name) { Some(locs) => { let found = locs.iter().any(|l| { let l = fs::realpath(&Path::new(l.as_slice())).ok(); diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 2af1f12a2cd82..e0110a81c179f 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -298,7 +298,7 @@ fn item_path(item_doc: rbml::Doc) -> Vec { fn item_name(intr: &IdentInterner, item: rbml::Doc) -> ast::Name { let name = reader::get_doc(item, tag_paths_data_name); let string = name.as_str_slice(); - match intr.find_equiv(string) { + match intr.find(string) { None => token::intern(string), Some(val) => val, } @@ -1449,4 +1449,3 @@ pub fn is_associated_type(cdata: Cmd, id: ast::NodeId) -> bool { Some(item) => item_sort(item) == 't', } } - diff --git a/src/librustc/metadata/filesearch.rs b/src/librustc/metadata/filesearch.rs index aeed829f8055b..f7d666e48150d 100644 --- a/src/librustc/metadata/filesearch.rs +++ b/src/librustc/metadata/filesearch.rs @@ -54,7 +54,7 @@ impl<'a> FileSearch<'a> { debug!("filesearch: searching lib path"); let tlib_path = make_target_lib_path(self.sysroot, self.triple); - if !visited_dirs.contains_equiv(tlib_path.as_vec()) { + if !visited_dirs.contains(tlib_path.as_vec()) { match f(&tlib_path) { FileMatches => found = true, FileDoesntMatch => () @@ -69,9 +69,9 @@ impl<'a> FileSearch<'a> { let tlib_path = make_rustpkg_lib_path( self.sysroot, path, self.triple); debug!("is {} in visited_dirs? {}", tlib_path.display(), - visited_dirs.contains_equiv(&tlib_path.as_vec().to_vec())); + visited_dirs.contains(&tlib_path.as_vec().to_vec())); - if !visited_dirs.contains_equiv(tlib_path.as_vec()) { + if !visited_dirs.contains(tlib_path.as_vec()) { visited_dirs.insert(tlib_path.as_vec().to_vec()); // Don't keep searching the RUST_PATH if one match turns up -- // if we did, we'd get a "multiple matching crates" error diff --git a/src/librustc/metadata/loader.rs b/src/librustc/metadata/loader.rs index c3d92a19a2056..30bef248b4738 100644 --- a/src/librustc/metadata/loader.rs +++ b/src/librustc/metadata/loader.rs @@ -596,7 +596,7 @@ impl<'a> Context<'a> { } fn find_commandline_library(&mut self) -> Option { - let locs = match self.sess.opts.externs.find_equiv(self.crate_name) { + let locs = match self.sess.opts.externs.get(self.crate_name) { Some(s) => s, None => return None, }; diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 4fe770a1e0fb3..ffc8a83e42eda 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -132,7 +132,7 @@ impl<'a, 'v> Visitor<'v> for LanguageItemCollector<'a> { fn visit_item(&mut self, item: &ast::Item) { match extract(item.attrs.as_slice()) { Some(value) => { - let item_index = self.item_refs.find_equiv(&value).map(|x| *x); + let item_index = self.item_refs.get(value.get()).map(|x| *x); match item_index { Some(item_index) => { diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index b267d1d7f3e1e..cc51be31760a3 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -216,7 +216,7 @@ pub fn get_extern_fn(ccx: &CrateContext, ty: Type, output: ty::t) -> ValueRef { - match externs.find_equiv(name) { + match externs.get(name) { Some(n) => return *n, None => {} } @@ -226,7 +226,7 @@ pub fn get_extern_fn(ccx: &CrateContext, } fn get_extern_rust_fn(ccx: &CrateContext, fn_ty: ty::t, name: &str, did: ast::DefId) -> ValueRef { - match ccx.externs().borrow().find_equiv(name) { + match ccx.externs().borrow().get(name) { Some(n) => return *n, None => () } @@ -2983,7 +2983,7 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet) { let name = CString::new(llvm::LLVMGetValueName(val), false); if !declared.contains(&name) && - !reachable.contains_equiv(name.as_str().unwrap()) { + !reachable.contains(name.as_str().unwrap()) { llvm::SetLinkage(val, llvm::InternalLinkage); } } diff --git a/src/librustc/middle/trans/debuginfo.rs b/src/librustc/middle/trans/debuginfo.rs index eaff757679aa0..de8e80b02757b 100644 --- a/src/librustc/middle/trans/debuginfo.rs +++ b/src/librustc/middle/trans/debuginfo.rs @@ -1677,7 +1677,7 @@ fn declare_local(bcx: Block, } fn file_metadata(cx: &CrateContext, full_path: &str) -> DIFile { - match debug_context(cx).created_files.borrow().find_equiv(full_path) { + match debug_context(cx).created_files.borrow().get(full_path) { Some(file_metadata) => return *file_metadata, None => () } diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index d6a2d0c86a111..69861290b8d0d 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -336,7 +336,7 @@ impl TypeNames { } pub fn find_type(&self, s: &str) -> Option { - self.named_types.borrow().find_equiv(s).map(|x| Type::from_ref(*x)) + self.named_types.borrow().get(s).map(|x| Type::from_ref(*x)) } pub fn type_to_string(&self, ty: Type) -> String { diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 1dd651481693f..8e9ac7095dae1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2122,7 +2122,7 @@ impl<'a> fmt::Show for Sidebar<'a> { fn block(w: &mut fmt::Formatter, short: &str, longty: &str, cur: &clean::Item, cx: &Context) -> fmt::Result { - let items = match cx.sidebar.find_equiv(short) { + let items = match cx.sidebar.get(short) { Some(items) => items.as_slice(), None => return Ok(()) }; diff --git a/src/libserialize/json.rs b/src/libserialize/json.rs index 80238f6df415d..03e0452a4158d 100644 --- a/src/libserialize/json.rs +++ b/src/libserialize/json.rs @@ -901,7 +901,7 @@ impl Json { /// Otherwise, returns None. pub fn find<'a>(&'a self, key: &str) -> Option<&'a Json>{ match self { - &Object(ref map) => map.find_with(|s| key.cmp(s.as_slice())), + &Object(ref map) => map.get(key), _ => None } } @@ -926,7 +926,7 @@ impl Json { pub fn search<'a>(&'a self, key: &str) -> Option<&'a Json> { match self { &Object(ref map) => { - match map.find_with(|s| key.cmp(s.as_slice())) { + match map.get(key) { Some(json_value) => Some(json_value), None => { for (_, v) in map.iter() { diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 0471d5e902c21..69375e8d4f84e 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -14,6 +14,7 @@ pub use self::Entry::*; use self::SearchResult::*; use self::VacantEntryState::*; +use borrow::BorrowFrom; use clone::Clone; use cmp::{max, Eq, Equiv, PartialEq}; use default::Default; @@ -142,7 +143,7 @@ impl DefaultResizePolicy { // about the size of rust executables. // // Annotate exceedingly likely branches in `table::make_hash` -// and `search_hashed_generic` to reduce instruction cache pressure +// and `search_hashed` to reduce instruction cache pressure // and mispredictions once it becomes possible (blocked on issue #11092). // // Shrinking the table could simply reallocate in place after moving buckets @@ -286,10 +287,10 @@ pub struct HashMap { } /// Search for a pre-hashed key. -fn search_hashed_generic>>(table: M, - hash: &SafeHash, - is_match: |&K| -> bool) - -> SearchResult { +fn search_hashed>>(table: M, + hash: &SafeHash, + is_match: |&K| -> bool) + -> SearchResult { let size = table.size(); let mut probe = Bucket::new(table, hash); let ib = probe.index(); @@ -325,11 +326,6 @@ fn search_hashed_generic>>(table: M, TableRef(probe.into_table()) } -fn search_hashed>>(table: M, hash: &SafeHash, k: &K) - -> SearchResult { - search_hashed_generic(table, hash, |k_| *k == *k_) -} - fn pop_internal(starting_bucket: FullBucketMut) -> (K, V) { let (empty, retkey, retval) = starting_bucket.take(); let mut gap = match empty.gap_peek() { @@ -432,26 +428,32 @@ impl, V, S, H: Hasher> HashMap { fn search_equiv<'a, Sized? Q: Hash + Equiv>(&'a self, q: &Q) -> Option> { let hash = self.make_hash(q); - search_hashed_generic(&self.table, &hash, |k| q.equiv(k)).into_option() + search_hashed(&self.table, &hash, |k| q.equiv(k)).into_option() } fn search_equiv_mut<'a, Sized? Q: Hash + Equiv>(&'a mut self, q: &Q) -> Option> { let hash = self.make_hash(q); - search_hashed_generic(&mut self.table, &hash, |k| q.equiv(k)).into_option() + search_hashed(&mut self.table, &hash, |k| q.equiv(k)).into_option() } /// Search for a key, yielding the index if it's found in the hashtable. /// If you already have the hash for the key lying around, use /// search_hashed. - fn search<'a>(&'a self, k: &K) -> Option> { - let hash = self.make_hash(k); - search_hashed(&self.table, &hash, k).into_option() + fn search<'a, Sized? Q>(&'a self, q: &Q) -> Option> + where Q: BorrowFrom + Eq + Hash + { + let hash = self.make_hash(q); + search_hashed(&self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k))) + .into_option() } - fn search_mut<'a>(&'a mut self, k: &K) -> Option> { - let hash = self.make_hash(k); - search_hashed(&mut self.table, &hash, k).into_option() + fn search_mut<'a, Sized? Q>(&'a mut self, q: &Q) -> Option> + where Q: BorrowFrom + Eq + Hash + { + let hash = self.make_hash(q); + search_hashed(&mut self.table, &hash, |k| q.eq(BorrowFrom::borrow_from(k))) + .into_option() } // The caller should ensure that invariants by Robin Hood Hashing hold. @@ -748,18 +750,14 @@ impl, V, S, H: Hasher> HashMap { } } - /// Return true if the map contains a value for the specified key, - /// using equivalence. - /// - /// See [pop_equiv](#method.pop_equiv) for an extended example. + /// Deprecated: use `contains_key` and `BorrowFrom` instead. + #[deprecated = "use contains_key and BorrowFrom instead"] pub fn contains_key_equiv + Equiv>(&self, key: &Q) -> bool { self.search_equiv(key).is_some() } - /// Return the value corresponding to the key in the map, using - /// equivalence. - /// - /// See [pop_equiv](#method.pop_equiv) for an extended example. + /// Deprecated: use `get` and `BorrowFrom` instead. + #[deprecated = "use get and BorrowFrom instead"] pub fn find_equiv<'a, Sized? Q: Hash + Equiv>(&'a self, k: &Q) -> Option<&'a V> { match self.search_equiv(k) { None => None, @@ -770,52 +768,8 @@ impl, V, S, H: Hasher> HashMap { } } - /// Remove an equivalent key from the map, returning the value at the - /// key if the key was previously in the map. - /// - /// # Example - /// - /// This is a slightly silly example where we define the number's - /// parity as the equivalence class. It is important that the - /// values hash the same, which is why we implement `Hash`. - /// - /// ``` - /// use std::collections::HashMap; - /// use std::hash::Hash; - /// use std::hash::sip::SipState; - /// - /// #[deriving(Eq, PartialEq)] - /// struct EvenOrOdd { - /// num: uint - /// }; - /// - /// impl Hash for EvenOrOdd { - /// fn hash(&self, state: &mut SipState) { - /// let parity = self.num % 2; - /// parity.hash(state); - /// } - /// } - /// - /// impl Equiv for EvenOrOdd { - /// fn equiv(&self, other: &EvenOrOdd) -> bool { - /// self.num % 2 == other.num % 2 - /// } - /// } - /// - /// let mut map = HashMap::new(); - /// map.insert(EvenOrOdd { num: 3 }, "foo"); - /// - /// assert!(map.contains_key_equiv(&EvenOrOdd { num: 1 })); - /// assert!(!map.contains_key_equiv(&EvenOrOdd { num: 4 })); - /// - /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 5 }), Some(&"foo")); - /// assert_eq!(map.find_equiv(&EvenOrOdd { num: 2 }), None); - /// - /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 1 }), Some("foo")); - /// assert_eq!(map.pop_equiv(&EvenOrOdd { num: 2 }), None); - /// - /// ``` - #[experimental] + /// Deprecated: use `remove` and `BorrowFrom` instead. + #[deprecated = "use remove and BorrowFrom instead"] pub fn pop_equiv + Equiv>(&mut self, k: &Q) -> Option { if self.table.size() == 0 { return None @@ -1036,6 +990,10 @@ impl, V, S, H: Hasher> HashMap { /// Returns a reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// /// # Example /// /// ``` @@ -1047,7 +1005,9 @@ impl, V, S, H: Hasher> HashMap { /// assert_eq!(map.get(&2), None); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get(&self, k: &K) -> Option<&V> { + pub fn get(&self, k: &Q) -> Option<&V> + where Q: Hash + Eq + BorrowFrom + { self.search(k).map(|bucket| { let (_, v) = bucket.into_refs(); v @@ -1056,6 +1016,10 @@ impl, V, S, H: Hasher> HashMap { /// Returns true if the map contains a value for the specified key. /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// /// # Example /// /// ``` @@ -1067,7 +1031,9 @@ impl, V, S, H: Hasher> HashMap { /// assert_eq!(map.contains_key(&2), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains_key(&self, k: &K) -> bool { + pub fn contains_key(&self, k: &Q) -> bool + where Q: Hash + Eq + BorrowFrom + { self.search(k).is_some() } @@ -1079,6 +1045,10 @@ impl, V, S, H: Hasher> HashMap { /// Returns a mutable reference to the value corresponding to the key. /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// /// # Example /// /// ``` @@ -1093,7 +1063,9 @@ impl, V, S, H: Hasher> HashMap { /// assert_eq!(map[1], "b"); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn get_mut(&mut self, k: &K) -> Option<&mut V> { + pub fn get_mut(&mut self, k: &Q) -> Option<&mut V> + where Q: Hash + Eq + BorrowFrom + { match self.search_mut(k) { Some(bucket) => { let (_, v) = bucket.into_mut_refs(); @@ -1147,6 +1119,10 @@ impl, V, S, H: Hasher> HashMap { /// Removes a key from the map, returning the value at the key if the key /// was previously in the map. /// + /// The key may be any borrowed form of the map's key type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the key type. + /// /// # Example /// /// ``` @@ -1158,7 +1134,9 @@ impl, V, S, H: Hasher> HashMap { /// assert_eq!(map.remove(&1), None); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, k: &K) -> Option { + pub fn remove(&mut self, k: &Q) -> Option + where Q: Hash + Eq + BorrowFrom + { if self.table.size() == 0 { return None } @@ -1271,16 +1249,20 @@ impl, V, S, H: Hasher + Default> Default for HashMap } } -impl, V, S, H: Hasher> Index for HashMap { +impl + Eq, Sized? Q, V, S, H: Hasher> Index for HashMap + where Q: BorrowFrom + Hash + Eq +{ #[inline] - fn index<'a>(&'a self, index: &K) -> &'a V { + fn index<'a>(&'a self, index: &Q) -> &'a V { self.get(index).expect("no entry found for key") } } -impl, V, S, H: Hasher> IndexMut for HashMap { +impl + Eq, Sized? Q, V, S, H: Hasher> IndexMut for HashMap + where Q: BorrowFrom + Hash + Eq +{ #[inline] - fn index_mut<'a>(&'a mut self, index: &K) -> &'a mut V { + fn index_mut<'a>(&'a mut self, index: &Q) -> &'a mut V { match self.get_mut(index) { Some(v) => v, None => panic!("no entry found for key") @@ -1962,11 +1944,11 @@ mod test_map { m.insert("baz".to_string(), baz); - assert_eq!(m.find_equiv("foo"), Some(&foo)); - assert_eq!(m.find_equiv("bar"), Some(&bar)); - assert_eq!(m.find_equiv("baz"), Some(&baz)); + assert_eq!(m.get("foo"), Some(&foo)); + assert_eq!(m.get("bar"), Some(&bar)); + assert_eq!(m.get("baz"), Some(&baz)); - assert_eq!(m.find_equiv("qux"), None); + assert_eq!(m.get("qux"), None); } #[test] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 4326fae16fc91..2fbcb464358b3 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -10,6 +10,7 @@ // // ignore-lexer-test FIXME #15883 +use borrow::BorrowFrom; use cmp::{Eq, Equiv, PartialEq}; use core::kinds::Sized; use default::Default; @@ -184,47 +185,9 @@ impl, S, H: Hasher> HashSet { self.map.reserve(n) } - /// Returns true if the hash set contains a value equivalent to the - /// given query value. - /// - /// # Example - /// - /// This is a slightly silly example where we define the number's - /// parity as the equivalance class. It is important that the - /// values hash the same, which is why we implement `Hash`. - /// - /// ``` - /// use std::collections::HashSet; - /// use std::hash::Hash; - /// use std::hash::sip::SipState; - /// - /// #[deriving(Eq, PartialEq)] - /// struct EvenOrOdd { - /// num: uint - /// }; - /// - /// impl Hash for EvenOrOdd { - /// fn hash(&self, state: &mut SipState) { - /// let parity = self.num % 2; - /// parity.hash(state); - /// } - /// } - /// - /// impl Equiv for EvenOrOdd { - /// fn equiv(&self, other: &EvenOrOdd) -> bool { - /// self.num % 2 == other.num % 2 - /// } - /// } - /// - /// let mut set = HashSet::new(); - /// set.insert(EvenOrOdd { num: 3u }); - /// - /// assert!(set.contains_equiv(&EvenOrOdd { num: 3u })); - /// assert!(set.contains_equiv(&EvenOrOdd { num: 5u })); - /// assert!(!set.contains_equiv(&EvenOrOdd { num: 4u })); - /// assert!(!set.contains_equiv(&EvenOrOdd { num: 2u })); - /// - /// ``` + /// Deprecated: use `contains` and `BorrowFrom`. + #[deprecated = "use contains and BorrowFrom"] + #[allow(deprecated)] pub fn contains_equiv + Equiv>(&self, value: &Q) -> bool { self.map.contains_key_equiv(value) } @@ -427,6 +390,10 @@ impl, S, H: Hasher> HashSet { /// Returns `true` if the set contains a value. /// + /// The value may be any borrowed form of the set's value type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the value type. + /// /// # Example /// /// ``` @@ -437,7 +404,11 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(set.contains(&4), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) } + pub fn contains(&self, value: &Q) -> bool + where Q: BorrowFrom + Hash + Eq + { + self.map.contains_key(value) + } /// Returns `true` if the set has no elements in common with `other`. /// This is equivalent to checking for an empty intersection. @@ -527,6 +498,10 @@ impl, S, H: Hasher> HashSet { /// Removes a value from the set. Returns `true` if the value was /// present in the set. /// + /// The value may be any borrowed form of the set's value type, but + /// `Hash` and `Eq` on the borrowed form *must* match those for + /// the value type. + /// /// # Example /// /// ``` @@ -539,7 +514,11 @@ impl, S, H: Hasher> HashSet { /// assert_eq!(set.remove(&2), false); /// ``` #[unstable = "matches collection reform specification, waiting for dust to settle"] - pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value).is_some() } + pub fn remove(&mut self, value: &Q) -> bool + where Q: BorrowFrom + Hash + Eq + { + self.map.remove(value).is_some() + } } impl, S, H: Hasher> PartialEq for HashSet { diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 612613134d448..7f2a4c7e36569 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -141,6 +141,7 @@ extern crate rustrt; pub use core::any; pub use core::bool; +pub use core::borrow; pub use core::cell; pub use core::clone; #[cfg(not(test))] pub use core::cmp; diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs index 83340c9faac22..39ca3128ccb2b 100644 --- a/src/libstd/time/duration.rs +++ b/src/libstd/time/duration.rs @@ -554,11 +554,4 @@ mod tests { assert_eq!(format!("{:30}", Duration::days(1) + Duration::milliseconds(2345)), "P1DT2.345S".to_string()); } - - #[test] - fn span() { - use io::timer::sleep; - let dur = Duration::span(|| sleep(Duration::milliseconds(5))); - assert!(dur > Duration::milliseconds(1)); - } } diff --git a/src/libsyntax/diagnostics/registry.rs b/src/libsyntax/diagnostics/registry.rs index 71d82a41f3868..4caef247aebc2 100644 --- a/src/libsyntax/diagnostics/registry.rs +++ b/src/libsyntax/diagnostics/registry.rs @@ -20,6 +20,6 @@ impl Registry { } pub fn find_description(&self, code: &str) -> Option<&'static str> { - self.descriptions.find_equiv(code).map(|desc| *desc) + self.descriptions.get(code).map(|desc| *desc) } } diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs index 9a9724de8fb70..f1b92b4d6bc1d 100644 --- a/src/libsyntax/ext/format.rs +++ b/src/libsyntax/ext/format.rs @@ -144,7 +144,7 @@ fn parse_args(ecx: &mut ExtCtxt, sp: Span, allow_method: bool, let name = interned_name.get(); p.expect(&token::Eq); let e = p.parse_expr(); - match names.find_equiv(name) { + match names.get(name) { None => {} Some(prev) => { ecx.span_err(e.span, @@ -366,7 +366,7 @@ impl<'a, 'b> Context<'a, 'b> { self.ecx.expr_path(path) } parse::CountIsName(n) => { - let i = match self.name_positions.find_equiv(n) { + let i = match self.name_positions.get(n) { Some(&i) => i, None => 0, // error already emitted elsewhere }; @@ -410,7 +410,7 @@ impl<'a, 'b> Context<'a, 'b> { // Named arguments are converted to positional arguments at // the end of the list of arguments parse::ArgumentNamed(n) => { - let i = match self.name_positions.find_equiv(n) { + let i = match self.name_positions.get(n) { Some(&i) => i, None => 0, // error already emitted elsewhere }; diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs index 08ada3e443590..ede967bba25cd 100644 --- a/src/libsyntax/util/interner.rs +++ b/src/libsyntax/util/interner.rs @@ -14,9 +14,9 @@ use ast::Name; +use std::borrow::BorrowFrom; use std::collections::HashMap; use std::cell::RefCell; -use std::cmp::Equiv; use std::fmt; use std::hash::Hash; use std::rc::Rc; @@ -75,9 +75,10 @@ impl Interner { (*vect).len() } - pub fn find_equiv>(&self, val: &Q) -> Option { + pub fn find(&self, val: &Q) -> Option + where Q: BorrowFrom + Eq + Hash { let map = self.map.borrow(); - match (*map).find_equiv(val) { + match (*map).get(val) { Some(v) => Some(*v), None => None, } @@ -117,6 +118,12 @@ impl fmt::Show for RcStr { } } +impl BorrowFrom for str { + fn borrow_from(owned: &RcStr) -> &str { + owned.string.as_slice() + } +} + impl RcStr { pub fn new(string: &str) -> RcStr { RcStr { @@ -149,7 +156,7 @@ impl StrInterner { pub fn intern(&self, val: &str) -> Name { let mut map = self.map.borrow_mut(); - match map.find_equiv(val) { + match map.get(val) { Some(&idx) => return idx, None => (), } @@ -195,8 +202,9 @@ impl StrInterner { self.vect.borrow().len() } - pub fn find_equiv>(&self, val: &Q) -> Option { - match (*self.map.borrow()).find_equiv(val) { + pub fn find(&self, val: &Q) -> Option + where Q: BorrowFrom + Eq + Hash { + match (*self.map.borrow()).get(val) { Some(v) => Some(*v), None => None, } diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs index 0b5092a64d0f3..c1393767c8adc 100644 --- a/src/libterm/terminfo/mod.rs +++ b/src/libterm/terminfo/mod.rs @@ -78,7 +78,7 @@ impl Terminal for TerminfoTerminal { if self.num_colors > color { let s = expand(self.ti .strings - .find_equiv("setaf") + .get("setaf") .unwrap() .as_slice(), &[Number(color as int)], &mut Variables::new()); @@ -95,7 +95,7 @@ impl Terminal for TerminfoTerminal { if self.num_colors > color { let s = expand(self.ti .strings - .find_equiv("setab") + .get("setab") .unwrap() .as_slice(), &[Number(color as int)], &mut Variables::new()); @@ -113,7 +113,7 @@ impl Terminal for TerminfoTerminal { attr::BackgroundColor(c) => self.bg(c), _ => { let cap = cap_for_attr(attr); - let parm = self.ti.strings.find_equiv(cap); + let parm = self.ti.strings.get(cap); if parm.is_some() { let s = expand(parm.unwrap().as_slice(), &[], @@ -135,19 +135,19 @@ impl Terminal for TerminfoTerminal { } _ => { let cap = cap_for_attr(attr); - self.ti.strings.find_equiv(cap).is_some() + self.ti.strings.get(cap).is_some() } } } fn reset(&mut self) -> IoResult<()> { - let mut cap = self.ti.strings.find_equiv("sgr0"); + let mut cap = self.ti.strings.get("sgr0"); if cap.is_none() { // are there any terminals that have color/attrs and not sgr0? // Try falling back to sgr, then op - cap = self.ti.strings.find_equiv("sgr"); + cap = self.ti.strings.get("sgr"); if cap.is_none() { - cap = self.ti.strings.find_equiv("op"); + cap = self.ti.strings.get("op"); } } let s = cap.map_or(Err("can't find terminfo capability `sgr0`".to_string()), |op| { @@ -202,9 +202,9 @@ impl TerminfoTerminal { } let inf = ti.unwrap(); - let nc = if inf.strings.find_equiv("setaf").is_some() - && inf.strings.find_equiv("setab").is_some() { - inf.numbers.find_equiv("colors").map_or(0, |&n| n) + let nc = if inf.strings.get("setaf").is_some() + && inf.strings.get("setab").is_some() { + inf.numbers.get("colors").map_or(0, |&n| n) } else { 0 }; return Some(box TerminfoTerminal {out: out, diff --git a/src/test/bench/shootout-k-nucleotide-pipes.rs b/src/test/bench/shootout-k-nucleotide-pipes.rs index e40c477ec66ef..e39cd743ad55a 100644 --- a/src/test/bench/shootout-k-nucleotide-pipes.rs +++ b/src/test/bench/shootout-k-nucleotide-pipes.rs @@ -76,7 +76,7 @@ fn sort_and_fmt(mm: &HashMap , uint>, total: uint) -> String { // given a map, search for the frequency of a pattern fn find(mm: &HashMap , uint>, key: String) -> uint { let key = key.into_ascii().as_slice().to_lowercase().into_string(); - match mm.find_equiv(key.as_bytes()) { + match mm.get(key.as_bytes()) { option::None => { return 0u; } option::Some(&num) => { return num; } }