From 3293ab14e24d136d0482bb18afef577aebed251e Mon Sep 17 00:00:00 2001 From: Jorge Aparicio Date: Fri, 21 Nov 2014 17:10:42 -0500 Subject: [PATCH] Deprecate MaybeOwned[Vector] in favor of Cow --- src/libcollections/hash/mod.rs | 8 +++ src/libcollections/str.rs | 54 ++++++++++++--- src/libcollections/string.rs | 48 ++++++++----- src/libcollections/vec.rs | 22 ++++++ src/libcore/borrow.rs | 69 +++++++++++++++++++ src/libgraphviz/lib.rs | 63 ++++++++--------- src/libgraphviz/maybe_owned_vec.rs | 10 +++ src/libregex/re.rs | 16 ++--- src/librustc/middle/borrowck/graphviz.rs | 5 +- src/librustc/middle/cfg/graphviz.rs | 12 ++-- src/libstd/path/mod.rs | 6 +- src/libstd/path/posix.rs | 4 +- src/libstd/path/windows.rs | 4 +- src/libstd/prelude.rs | 3 +- src/libstd/rt/mod.rs | 4 +- src/libstd/task.rs | 22 +++--- src/libsyntax/parse/lexer/mod.rs | 8 +-- src/libsyntax/parse/parser.rs | 4 +- src/test/run-fail/panic-task-name-send-str.rs | 2 +- src/test/run-pass/send_str_hashmap.rs | 62 ++++++++--------- src/test/run-pass/send_str_treemap.rs | 66 +++++++++--------- 21 files changed, 323 insertions(+), 169 deletions(-) diff --git a/src/libcollections/hash/mod.rs b/src/libcollections/hash/mod.rs index b1ff3da947b7..4173ffc5d2fd 100644 --- a/src/libcollections/hash/mod.rs +++ b/src/libcollections/hash/mod.rs @@ -67,6 +67,7 @@ use alloc::boxed::Box; use alloc::rc::Rc; +use core::borrow::{Cow, ToOwned}; use core::intrinsics::TypeId; use core::mem; use core::num::Int; @@ -284,6 +285,13 @@ fn hash(&self, state: &mut S) { } } +impl<'a, T, Sized? B, S> Hash for Cow<'a, T, B> where B: Hash + ToOwned { + #[inline] + fn hash(&self, state: &mut S) { + Hash::hash(&**self, state) + } +} + ////////////////////////////////////////////////////////////////////////////// #[cfg(test)] diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs index 9982eaefff8f..7b53fead6b22 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, ToOwned}; +use core::borrow::{BorrowFrom, Cow, ToOwned}; use core::default::Default; use core::fmt; use core::cmp; @@ -67,7 +67,7 @@ use hash; use ring_buf::RingBuf; -use string::{String, ToString}; +use string::String; use unicode; use vec::Vec; @@ -425,6 +425,7 @@ macro_rules! utf8_acc_cont_byte( /// A string type that can hold either a `String` or a `&str`. /// This can be useful as an optimization when an allocation is sometimes /// needed but not always. +#[deprecated = "use std::str::CowString"] pub enum MaybeOwned<'a> { /// A borrowed string. Slice(&'a str), @@ -432,15 +433,16 @@ pub enum MaybeOwned<'a> { Owned(String) } -/// A specialization of `MaybeOwned` to be sendable. -pub type SendStr = MaybeOwned<'static>; +/// A specialization of `CowString` to be sendable. +pub type SendStr = CowString<'static>; +#[deprecated = "use std::str::CowString"] impl<'a> MaybeOwned<'a> { /// Returns `true` if this `MaybeOwned` wraps an owned string. /// /// # Example /// - /// ```rust + /// ``` ignore /// let string = String::from_str("orange"); /// let maybe_owned_string = string.into_maybe_owned(); /// assert_eq!(true, maybe_owned_string.is_owned()); @@ -457,7 +459,7 @@ pub fn is_owned(&self) -> bool { /// /// # Example /// - /// ```rust + /// ``` ignore /// let string = "orange"; /// let maybe_owned_string = string.as_slice().into_maybe_owned(); /// assert_eq!(true, maybe_owned_string.is_slice()); @@ -475,46 +477,56 @@ pub fn is_slice(&self) -> bool { pub fn len(&self) -> uint { self.as_slice().len() } /// Returns true if the string contains no bytes + #[allow(deprecated)] #[inline] pub fn is_empty(&self) -> bool { self.len() == 0 } } +#[deprecated = "use std::borrow::IntoCow"] /// Trait for moving into a `MaybeOwned`. pub trait IntoMaybeOwned<'a> { /// Moves `self` into a `MaybeOwned`. fn into_maybe_owned(self) -> MaybeOwned<'a>; } +#[deprecated = "use std::borrow::IntoCow"] +#[allow(deprecated)] impl<'a> IntoMaybeOwned<'a> for String { /// # Example /// - /// ```rust + /// ``` ignore /// let owned_string = String::from_str("orange"); /// let maybe_owned_string = owned_string.into_maybe_owned(); /// assert_eq!(true, maybe_owned_string.is_owned()); /// ``` + #[allow(deprecated)] #[inline] fn into_maybe_owned(self) -> MaybeOwned<'a> { Owned(self) } } +#[deprecated = "use std::borrow::IntoCow"] +#[allow(deprecated)] impl<'a> IntoMaybeOwned<'a> for &'a str { /// # Example /// - /// ```rust + /// ``` ignore /// let string = "orange"; /// let maybe_owned_str = string.as_slice().into_maybe_owned(); /// assert_eq!(false, maybe_owned_str.is_owned()); /// ``` + #[allow(deprecated)] #[inline] fn into_maybe_owned(self) -> MaybeOwned<'a> { Slice(self) } } +#[allow(deprecated)] +#[deprecated = "use std::borrow::IntoCow"] impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> { /// # Example /// - /// ```rust + /// ``` ignore /// let str = "orange"; /// let maybe_owned_str = str.as_slice().into_maybe_owned(); /// let maybe_maybe_owned_str = maybe_owned_str.into_maybe_owned(); @@ -524,6 +536,7 @@ impl<'a> IntoMaybeOwned<'a> for MaybeOwned<'a> { fn into_maybe_owned(self) -> MaybeOwned<'a> { self } } +#[deprecated = "use std::str::CowString"] impl<'a> PartialEq for MaybeOwned<'a> { #[inline] fn eq(&self, other: &MaybeOwned) -> bool { @@ -531,8 +544,10 @@ fn eq(&self, other: &MaybeOwned) -> bool { } } +#[deprecated = "use std::str::CowString"] impl<'a> Eq for MaybeOwned<'a> {} +#[deprecated = "use std::str::CowString"] impl<'a> PartialOrd for MaybeOwned<'a> { #[inline] fn partial_cmp(&self, other: &MaybeOwned) -> Option { @@ -540,6 +555,7 @@ fn partial_cmp(&self, other: &MaybeOwned) -> Option { } } +#[deprecated = "use std::str::CowString"] impl<'a> Ord for MaybeOwned<'a> { #[inline] fn cmp(&self, other: &MaybeOwned) -> Ordering { @@ -547,6 +563,7 @@ fn cmp(&self, other: &MaybeOwned) -> Ordering { } } +#[deprecated = "use std::str::CowString"] impl<'a, S: Str> Equiv for MaybeOwned<'a> { #[inline] fn equiv(&self, other: &S) -> bool { @@ -554,7 +571,9 @@ fn equiv(&self, other: &S) -> bool { } } +#[deprecated = "use std::str::CowString"] impl<'a> Str for MaybeOwned<'a> { + #[allow(deprecated)] #[inline] fn as_slice<'b>(&'b self) -> &'b str { match *self { @@ -564,7 +583,9 @@ fn as_slice<'b>(&'b self) -> &'b str { } } +#[deprecated = "use std::str::CowString"] impl<'a> StrAllocating for MaybeOwned<'a> { + #[allow(deprecated)] #[inline] fn into_string(self) -> String { match self { @@ -574,7 +595,9 @@ fn into_string(self) -> String { } } +#[deprecated = "use std::str::CowString"] impl<'a> Clone for MaybeOwned<'a> { + #[allow(deprecated)] #[inline] fn clone(&self) -> MaybeOwned<'a> { match *self { @@ -584,11 +607,14 @@ fn clone(&self) -> MaybeOwned<'a> { } } +#[deprecated = "use std::str::CowString"] impl<'a> Default for MaybeOwned<'a> { + #[allow(deprecated)] #[inline] fn default() -> MaybeOwned<'a> { Slice("") } } +#[deprecated = "use std::str::CowString"] impl<'a, H: hash::Writer> hash::Hash for MaybeOwned<'a> { #[inline] fn hash(&self, hasher: &mut H) { @@ -596,6 +622,7 @@ fn hash(&self, hasher: &mut H) { } } +#[deprecated = "use std::str::CowString"] impl<'a> fmt::Show for MaybeOwned<'a> { #[inline] fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { @@ -613,7 +640,7 @@ fn borrow_from(owned: &String) -> &str { owned[] } #[unstable = "trait is unstable"] impl ToOwned for str { - fn to_owned(&self) -> String { self.to_string() } + fn to_owned(&self) -> String { self.into_string() } } /// Unsafe string operations. @@ -622,6 +649,13 @@ pub mod raw { pub use core::str::raw::{slice_unchecked}; } +/* +Section: CowString +*/ + +/// A clone-on-write string +pub type CowString<'a> = Cow<'a, String, str>; + /* Section: Trait implementations */ diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs index dd9dad9a42f7..38b67fbd7445 100644 --- a/src/libcollections/string.rs +++ b/src/libcollections/string.rs @@ -14,6 +14,7 @@ use core::prelude::*; +use core::borrow::{Cow, IntoCow}; use core::default::Default; use core::fmt; use core::mem; @@ -25,8 +26,7 @@ use hash; use slice::CloneSliceAllocPrelude; use str; -use str::{CharRange, FromStr, StrAllocating, MaybeOwned, Owned}; -use str::Slice as MaybeOwnedSlice; // So many `Slice`s... +use str::{CharRange, CowString, FromStr, StrAllocating, Owned}; use vec::{DerefVec, Vec, as_vec}; /// A growable string stored as a UTF-8 encoded buffer. @@ -121,9 +121,9 @@ pub fn from_utf8(vec: Vec) -> Result> { /// assert_eq!(output.as_slice(), "Hello \uFFFDWorld"); /// ``` #[unstable = "return type may change"] - pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> MaybeOwned<'a> { + pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> { if str::is_utf8(v) { - return MaybeOwnedSlice(unsafe { mem::transmute(v) }) + return Cow::Borrowed(unsafe { mem::transmute(v) }) } static TAG_CONT_U8: u8 = 128u8; @@ -234,7 +234,7 @@ macro_rules! error(() => ({ res.as_mut_vec().push_all(v[subseqidx..total]) }; } - Owned(res.into_string()) + Cow::Owned(res.into_string()) } /// Decode a UTF-16 encoded vector `v` into a `String`, returning `None` @@ -868,6 +868,18 @@ fn to_string(&self) -> String { } } +impl IntoCow<'static, String, str> for String { + fn into_cow(self) -> CowString<'static> { + Cow::Owned(self) + } +} + +impl<'a> IntoCow<'a, String, str> for &'a str { + fn into_cow(self) -> CowString<'a> { + Cow::Borrowed(self) + } +} + /// Unsafe operations #[deprecated] pub mod raw { @@ -921,11 +933,11 @@ mod tests { use std::prelude::*; use test::Bencher; + use slice::CloneSliceAllocPrelude; + use str::{Str, StrPrelude}; use str; - use str::{Str, StrPrelude, Owned}; use super::{as_string, String, ToString}; use vec::Vec; - use slice::CloneSliceAllocPrelude; #[test] fn test_as_string() { @@ -955,39 +967,39 @@ fn test_from_utf8() { #[test] fn test_from_utf8_lossy() { let xs = b"hello"; - assert_eq!(String::from_utf8_lossy(xs), str::Slice("hello")); + assert_eq!(String::from_utf8_lossy(xs), "hello".into_cow()); let xs = "ศไทย中华Việt Nam".as_bytes(); - assert_eq!(String::from_utf8_lossy(xs), str::Slice("ศไทย中华Việt Nam")); + assert_eq!(String::from_utf8_lossy(xs), "ศไทย中华Việt Nam".into_cow()); let xs = b"Hello\xC2 There\xFF Goodbye"; assert_eq!(String::from_utf8_lossy(xs), - Owned(String::from_str("Hello\uFFFD There\uFFFD Goodbye"))); + String::from_str("Hello\uFFFD There\uFFFD Goodbye").into_cow()); let xs = b"Hello\xC0\x80 There\xE6\x83 Goodbye"; assert_eq!(String::from_utf8_lossy(xs), - Owned(String::from_str("Hello\uFFFD\uFFFD There\uFFFD Goodbye"))); + String::from_str("Hello\uFFFD\uFFFD There\uFFFD Goodbye").into_cow()); let xs = b"\xF5foo\xF5\x80bar"; assert_eq!(String::from_utf8_lossy(xs), - Owned(String::from_str("\uFFFDfoo\uFFFD\uFFFDbar"))); + String::from_str("\uFFFDfoo\uFFFD\uFFFDbar").into_cow()); let xs = b"\xF1foo\xF1\x80bar\xF1\x80\x80baz"; assert_eq!(String::from_utf8_lossy(xs), - Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFDbaz"))); + String::from_str("\uFFFDfoo\uFFFDbar\uFFFDbaz").into_cow()); let xs = b"\xF4foo\xF4\x80bar\xF4\xBFbaz"; assert_eq!(String::from_utf8_lossy(xs), - Owned(String::from_str("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz"))); + String::from_str("\uFFFDfoo\uFFFDbar\uFFFD\uFFFDbaz").into_cow()); let xs = b"\xF0\x80\x80\x80foo\xF0\x90\x80\x80bar"; - assert_eq!(String::from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFD\uFFFD\ - foo\U00010000bar"))); + assert_eq!(String::from_utf8_lossy(xs), String::from_str("\uFFFD\uFFFD\uFFFD\uFFFD\ + foo\U00010000bar").into_cow()); // surrogates let xs = b"\xED\xA0\x80foo\xED\xBF\xBFbar"; - assert_eq!(String::from_utf8_lossy(xs), Owned(String::from_str("\uFFFD\uFFFD\uFFFDfoo\ - \uFFFD\uFFFD\uFFFDbar"))); + assert_eq!(String::from_utf8_lossy(xs), String::from_str("\uFFFD\uFFFD\uFFFDfoo\ + \uFFFD\uFFFD\uFFFDbar").into_cow()); } #[test] diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs index a3291e01942f..ec520a93c1ea 100644 --- a/src/libcollections/vec.rs +++ b/src/libcollections/vec.rs @@ -16,6 +16,7 @@ use alloc::boxed::Box; use alloc::heap::{EMPTY, allocate, reallocate, deallocate}; +use core::borrow::{Cow, IntoCow}; use core::cmp::max; use core::default::Default; use core::fmt; @@ -107,6 +108,27 @@ pub struct Vec { cap: uint, } +/// A clone-on-write vector +pub type CowVec<'a, T> = Cow<'a, Vec, [T]>; + +impl<'a, T> FromIterator for CowVec<'a, T> where T: Clone { + fn from_iter>(it: I) -> CowVec<'a, T> { + Cow::Owned(FromIterator::from_iter(it)) + } +} + +impl<'a, T: 'a> IntoCow<'a, Vec, [T]> for Vec where T: Clone { + fn into_cow(self) -> CowVec<'a, T> { + Cow::Owned(self) + } +} + +impl<'a, T> IntoCow<'a, Vec, [T]> for &'a [T] where T: Clone { + fn into_cow(self) -> CowVec<'a, T> { + Cow::Borrowed(self) + } +} + impl Vec { /// Constructs a new, empty `Vec`. /// diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs index da0e23e1a5e2..06fda8d60928 100644 --- a/src/libcore/borrow.rs +++ b/src/libcore/borrow.rs @@ -45,8 +45,11 @@ #![unstable = "recently added as part of collections reform"] use clone::Clone; +use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd}; +use fmt; use kinds::Sized; use ops::Deref; +use option::Option; use self::Cow::*; /// A trait for borrowing data. @@ -81,6 +84,24 @@ impl<'a, Sized? T> BorrowFromMut<&'a mut T> for T { fn borrow_from_mut<'b>(owned: &'b mut &'a mut T) -> &'b mut T { &mut **owned } } +impl<'a, T, Sized? B> BorrowFrom> for B where B: ToOwned { + fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B { + &**owned + } +} + +/// Trait for moving into a `Cow` +pub trait IntoCow<'a, T, Sized? B> { + /// Moves `self` into `Cow` + fn into_cow(self) -> Cow<'a, T, B>; +} + +impl<'a, T, Sized? B> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned { + fn into_cow(self) -> Cow<'a, T, B> { + self + } +} + /// A generalization of Clone to borrowed data. pub trait ToOwned for Sized?: BorrowFrom { /// Create owned data from borrowed data, usually by copying. @@ -139,6 +160,22 @@ pub fn into_owned(self) -> T { Owned(owned) => owned } } + + /// Returns true if this `Cow` wraps a borrowed value + pub fn is_borrowed(&self) -> bool { + match *self { + Borrowed(_) => true, + _ => false, + } + } + + /// Returns true if this `Cow` wraps an owned value + pub fn is_owned(&self) -> bool { + match *self { + Owned(_) => true, + _ => false, + } + } } impl<'a, T, Sized? B> Deref for Cow<'a, T, B> where B: ToOwned { @@ -149,3 +186,35 @@ fn deref(&self) -> &B { } } } + +impl<'a, T, Sized? B> Eq for Cow<'a, T, B> where B: Eq + ToOwned {} + +impl<'a, T, Sized? B> Ord for Cow<'a, T, B> where B: Ord + ToOwned { + #[inline] + fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering { + Ord::cmp(&**self, &**other) + } +} + +impl<'a, T, Sized? B> PartialEq for Cow<'a, T, B> where B: PartialEq + ToOwned { + #[inline] + fn eq(&self, other: &Cow<'a, T, B>) -> bool { + PartialEq::eq(&**self, &**other) + } +} + +impl<'a, T, Sized? B> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned { + #[inline] + fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option { + PartialOrd::partial_cmp(&**self, &**other) + } +} + +impl<'a, T, Sized? B> fmt::Show for Cow<'a, T, B> where B: fmt::Show + ToOwned, T: fmt::Show { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + match *self { + Borrowed(ref b) => fmt::Show::fmt(b, f), + Owned(ref o) => fmt::Show::fmt(o, f), + } + } +} diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs index 3ad546edf8de..f149ec509af0 100644 --- a/src/libgraphviz/lib.rs +++ b/src/libgraphviz/lib.rs @@ -37,7 +37,7 @@ Each node label is derived directly from the int representing the node, while the edge labels are all empty strings. -This example also illustrates how to use `MaybeOwnedVector` to return +This example also illustrates how to use `CowVec` to return an owned vector or a borrowed slice as appropriate: we construct the node vector from scratch, but borrow the edge list (rather than constructing a copy of all the edges from scratch). @@ -48,7 +48,6 @@ ```rust use graphviz as dot; -use graphviz::maybe_owned_vec::IntoMaybeOwnedVector; type Nd = int; type Ed = (int,int); @@ -77,12 +76,12 @@ fn nodes(&self) -> dot::Nodes<'a,Nd> { } nodes.sort(); nodes.dedup(); - nodes.into_maybe_owned() + nodes.into_cow() } fn edges(&'a self) -> dot::Edges<'a,Ed> { let &Edges(ref edges) = self; - edges.as_slice().into_maybe_owned() + edges.as_slice().into_cow() } fn source(&self, e: &Ed) -> Nd { let &(s,_) = e; s } @@ -137,8 +136,8 @@ pub fn main() { Since both the set of nodes and the set of edges are always constructed from scratch via iterators, we use the `collect()` method from the `Iterator` trait to collect the nodes and edges into freshly -constructed growable `Vec` values (rather use the `into_maybe_owned` -from the `IntoMaybeOwnedVector` trait as was used in the first example +constructed growable `Vec` values (rather use the `into_cow` +from the `IntoCow` trait as was used in the first example above). The output from this example renders four nodes that make up the @@ -148,7 +147,6 @@ pub fn main() { ```rust use graphviz as dot; -use std::str; type Nd = uint; type Ed<'a> = &'a (uint, uint); @@ -168,10 +166,10 @@ fn node_id(&'a self, n: &Nd) -> dot::Id<'a> { dot::Id::new(format!("N{}", n)).unwrap() } fn node_label<'a>(&'a self, n: &Nd) -> dot::LabelText<'a> { - dot::LabelStr(str::Slice(self.nodes[*n].as_slice())) + dot::LabelStr(self.nodes[*n].as_slice().into_cow()) } fn edge_label<'a>(&'a self, _: &Ed) -> dot::LabelText<'a> { - dot::LabelStr(str::Slice("⊆")) + dot::LabelStr("⊆".into_cow()) } } @@ -204,7 +202,6 @@ pub fn main() { ```rust use graphviz as dot; -use std::str; type Nd<'a> = (uint, &'a str); type Ed<'a> = (Nd<'a>, Nd<'a>); @@ -225,10 +222,10 @@ fn node_id(&'a self, n: &Nd<'a>) -> dot::Id<'a> { } fn node_label<'a>(&'a self, n: &Nd<'a>) -> dot::LabelText<'a> { let &(i, _) = n; - dot::LabelStr(str::Slice(self.nodes[i].as_slice())) + dot::LabelStr(self.nodes[i].as_slice().into_cow()) } fn edge_label<'a>(&'a self, _: &Ed<'a>) -> dot::LabelText<'a> { - dot::LabelStr(str::Slice("⊆")) + dot::LabelStr("⊆".into_cow()) } } @@ -279,8 +276,8 @@ pub fn main() { pub use self::LabelText::*; use std::io; -use std::str; -use self::maybe_owned_vec::MaybeOwnedVector; +use std::str::CowString; +use std::vec::CowVec; pub mod maybe_owned_vec; @@ -290,7 +287,7 @@ pub enum LabelText<'a> { /// /// Occurrences of backslashes (`\`) are escaped, and thus appear /// as backslashes in the rendered label. - LabelStr(str::MaybeOwned<'a>), + LabelStr(CowString<'a>), /// This kind of label uses the graphviz label escString type: /// http://www.graphviz.org/content/attrs#kescString @@ -302,7 +299,7 @@ pub enum LabelText<'a> { /// to break a line (centering the line preceding the `\n`), there /// are also the escape sequences `\l` which left-justifies the /// preceding line and `\r` which right-justifies it. - EscStr(str::MaybeOwned<'a>), + EscStr(CowString<'a>), } // There is a tension in the design of the labelling API. @@ -339,7 +336,7 @@ pub enum LabelText<'a> { /// `Id` is a Graphviz `ID`. pub struct Id<'a> { - name: str::MaybeOwned<'a>, + name: CowString<'a>, } impl<'a> Id<'a> { @@ -357,10 +354,10 @@ impl<'a> Id<'a> { /// /// Passing an invalid string (containing spaces, brackets, /// quotes, ...) will return an empty `Err` value. - pub fn new>(name: Name) -> Result, ()> { - let name = name.into_maybe_owned(); + pub fn new>(name: Name) -> Result, ()> { + let name = name.into_cow(); { - let mut chars = name.as_slice().chars(); + let mut chars = name.chars(); match chars.next() { Some(c) if is_letter_or_underscore(c) => { ; }, _ => return Err(()) @@ -383,10 +380,10 @@ fn in_range(low: char, c: char, high: char) -> bool { } pub fn as_slice(&'a self) -> &'a str { - self.name.as_slice() + &*self.name } - pub fn name(self) -> str::MaybeOwned<'a> { + pub fn name(self) -> CowString<'a> { self.name } } @@ -421,7 +418,7 @@ fn node_label(&'a self, n: &N) -> LabelText<'a> { /// default is in fact the empty string. fn edge_label(&'a self, e: &E) -> LabelText<'a> { let _ignored = e; - LabelStr(str::Slice("")) + LabelStr("".into_cow()) } } @@ -454,11 +451,11 @@ pub fn escape(&self) -> String { /// yields same content as self. The result obeys the law /// render(`lt`) == render(`EscStr(lt.pre_escaped_content())`) for /// all `lt: LabelText`. - fn pre_escaped_content(self) -> str::MaybeOwned<'a> { + fn pre_escaped_content(self) -> CowString<'a> { match self { EscStr(s) => s, - LabelStr(s) => if s.as_slice().contains_char('\\') { - str::Owned(s.as_slice().escape_default()) + LabelStr(s) => if s.contains_char('\\') { + s.escape_default().into_cow() } else { s }, @@ -476,12 +473,12 @@ pub fn suffix_line(self, suffix: LabelText) -> LabelText<'static> { let suffix = suffix.pre_escaped_content(); prefix.push_str(r"\n\n"); prefix.push_str(suffix.as_slice()); - EscStr(str::Owned(prefix)) + EscStr(prefix.into_cow()) } } -pub type Nodes<'a,N> = MaybeOwnedVector<'a,N>; -pub type Edges<'a,E> = MaybeOwnedVector<'a,E>; +pub type Nodes<'a,N> = CowVec<'a,N>; +pub type Edges<'a,E> = CowVec<'a,E>; // (The type parameters in GraphWalk should be associated items, // when/if Rust supports such.) @@ -496,7 +493,7 @@ pub fn suffix_line(self, suffix: LabelText) -> LabelText<'static> { /// that is bound by the self lifetime `'a`. /// /// The `nodes` and `edges` method each return instantiations of -/// `MaybeOwnedVector` to leave implementers the freedom to create +/// `CowVec` to leave implementers the freedom to create /// entirely new vectors or to pass back slices into internally owned /// vectors. pub trait GraphWalk<'a, N, E> { @@ -512,7 +509,7 @@ pub trait GraphWalk<'a, N, E> { /// Renders directed graph `g` into the writer `w` in DOT syntax. /// (Main entry point for the library.) -pub fn render<'a, N:'a, E:'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>( +pub fn render<'a, N:Clone+'a, E:Clone+'a, G:Labeller<'a,N,E>+GraphWalk<'a,N,E>, W:Writer>( g: &'a G, w: &mut W) -> io::IoResult<()> { @@ -647,12 +644,12 @@ fn node_id(&'a self, n: &Node) -> Id<'a> { } fn node_label(&'a self, n: &Node) -> LabelText<'a> { match self.node_labels[*n] { - Some(ref l) => LabelStr(str::Slice(l.as_slice())), + Some(ref l) => LabelStr(l.into_cow()), None => LabelStr(id_name(n).name()), } } fn edge_label(&'a self, e: & &'a Edge) -> LabelText<'a> { - LabelStr(str::Slice(e.label.as_slice())) + LabelStr(e.label.into_cow()) } } diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs index 70b3971c6b80..6482a514115a 100644 --- a/src/libgraphviz/maybe_owned_vec.rs +++ b/src/libgraphviz/maybe_owned_vec.rs @@ -8,6 +8,8 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. +#![deprecated = "use std::vec::CowVec"] + pub use self::MaybeOwnedVector::*; use std::default::Default; @@ -46,12 +48,16 @@ pub trait IntoMaybeOwnedVector<'a,T> { fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T>; } +#[allow(deprecated)] impl<'a,T:'a> IntoMaybeOwnedVector<'a,T> for Vec { + #[allow(deprecated)] #[inline] fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { Growable(self) } } +#[allow(deprecated)] impl<'a,T> IntoMaybeOwnedVector<'a,T> for &'a [T] { + #[allow(deprecated)] #[inline] fn into_maybe_owned(self) -> MaybeOwnedVector<'a,T> { Borrowed(self) } } @@ -66,6 +72,7 @@ pub fn iter(&'a self) -> slice::Items<'a,T> { pub fn len(&self) -> uint { self.as_slice().len() } + #[allow(deprecated)] pub fn is_empty(&self) -> bool { self.len() == 0 } } @@ -114,6 +121,7 @@ fn as_slice<'a>(&'a self) -> &'a [T] { } impl<'a,T> FromIterator for MaybeOwnedVector<'a,T> { + #[allow(deprecated)] fn from_iter>(iterator: I) -> MaybeOwnedVector<'a,T> { // If we are building from scratch, might as well build the // most flexible variant. @@ -143,6 +151,7 @@ fn permutations(&self) -> Permutations { } impl<'a, T: Clone> Clone for MaybeOwnedVector<'a, T> { + #[allow(deprecated)] fn clone(&self) -> MaybeOwnedVector<'a, T> { match *self { Growable(ref v) => Growable(v.clone()), @@ -152,6 +161,7 @@ fn clone(&self) -> MaybeOwnedVector<'a, T> { } impl<'a, T> Default for MaybeOwnedVector<'a, T> { + #[allow(deprecated)] fn default() -> MaybeOwnedVector<'a, T> { Growable(Vec::new()) } diff --git a/src/libregex/re.rs b/src/libregex/re.rs index e70491a785c3..58ce72a31736 100644 --- a/src/libregex/re.rs +++ b/src/libregex/re.rs @@ -13,7 +13,7 @@ use std::collections::HashMap; use std::fmt; -use std::str::{MaybeOwned, Owned, Slice}; +use std::str::CowString; use compile::Program; use parse; @@ -565,25 +565,25 @@ pub trait Replacer { /// /// The `'a` lifetime refers to the lifetime of a borrowed string when /// a new owned string isn't needed (e.g., for `NoExpand`). - fn reg_replace<'a>(&'a mut self, caps: &Captures) -> MaybeOwned<'a>; + fn reg_replace<'a>(&'a mut self, caps: &Captures) -> CowString<'a>; } impl<'t> Replacer for NoExpand<'t> { - fn reg_replace<'a>(&'a mut self, _: &Captures) -> MaybeOwned<'a> { + fn reg_replace<'a>(&'a mut self, _: &Captures) -> CowString<'a> { let NoExpand(s) = *self; - Slice(s) + s.into_cow() } } impl<'t> Replacer for &'t str { - fn reg_replace<'a>(&'a mut self, caps: &Captures) -> MaybeOwned<'a> { - Owned(caps.expand(*self)) + fn reg_replace<'a>(&'a mut self, caps: &Captures) -> CowString<'a> { + caps.expand(*self).into_cow() } } impl<'t> Replacer for |&Captures|: 't -> String { - fn reg_replace<'a>(&'a mut self, caps: &Captures) -> MaybeOwned<'a> { - Owned((*self)(caps)) + fn reg_replace<'a>(&'a mut self, caps: &Captures) -> CowString<'a> { + (*self)(caps).into_cow() } } diff --git a/src/librustc/middle/borrowck/graphviz.rs b/src/librustc/middle/borrowck/graphviz.rs index 4a2f57735e18..c12a81cc7394 100644 --- a/src/librustc/middle/borrowck/graphviz.rs +++ b/src/librustc/middle/borrowck/graphviz.rs @@ -26,7 +26,6 @@ use middle::dataflow; use std::rc::Rc; -use std::str; #[deriving(Show)] pub enum Variant { @@ -137,8 +136,8 @@ fn node_label(&'a self, n: &Node<'a>) -> dot::LabelText<'a> { let suffix = self.dataflow_for(dataflow::Exit, n); let inner_label = self.inner.node_label(n); inner_label - .prefix_line(dot::LabelStr(str::Owned(prefix))) - .suffix_line(dot::LabelStr(str::Owned(suffix))) + .prefix_line(dot::LabelStr(prefix.into_cow())) + .suffix_line(dot::LabelStr(suffix.into_cow())) } fn edge_label(&'a self, e: &Edge<'a>) -> dot::LabelText<'a> { self.inner.edge_label(e) } } diff --git a/src/librustc/middle/cfg/graphviz.rs b/src/librustc/middle/cfg/graphviz.rs index ba6dd2a5107a..8e0e8ee1c5ee 100644 --- a/src/librustc/middle/cfg/graphviz.rs +++ b/src/librustc/middle/cfg/graphviz.rs @@ -58,16 +58,16 @@ fn node_id(&'a self, &(i,_): &Node<'a>) -> dot::Id<'a> { fn node_label(&'a self, &(i, n): &Node<'a>) -> dot::LabelText<'a> { if i == self.cfg.entry { - dot::LabelStr("entry".into_maybe_owned()) + dot::LabelStr("entry".into_cow()) } else if i == self.cfg.exit { - dot::LabelStr("exit".into_maybe_owned()) + dot::LabelStr("exit".into_cow()) } else if n.data.id == ast::DUMMY_NODE_ID { - dot::LabelStr("(dummy_node)".into_maybe_owned()) + dot::LabelStr("(dummy_node)".into_cow()) } else { let s = self.ast_map.node_to_string(n.data.id); // left-aligns the lines let s = replace_newline_with_backslash_l(s); - dot::EscStr(s.into_maybe_owned()) + dot::EscStr(s.into_cow()) } } @@ -86,7 +86,7 @@ fn edge_label(&self, e: &Edge<'a>) -> dot::LabelText<'a> { label.push_str(format!("exiting scope_{} {}", i, s.as_slice()).as_slice()); } - dot::EscStr(label.into_maybe_owned()) + dot::EscStr(label.into_cow()) } } @@ -94,7 +94,7 @@ impl<'a> dot::GraphWalk<'a, Node<'a>, Edge<'a>> for &'a cfg::CFG { fn nodes(&'a self) -> dot::Nodes<'a, Node<'a>> { let mut v = Vec::new(); self.graph.each_node(|i, nd| { v.push((i, nd)); true }); - dot::maybe_owned_vec::Growable(v) + v.into_cow() } fn edges(&'a self) -> dot::Edges<'a, Edge<'a>> { self.graph.all_edges().iter().collect() diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs index a185a29a7006..ce3440ead400 100644 --- a/src/libstd/path/mod.rs +++ b/src/libstd/path/mod.rs @@ -74,7 +74,7 @@ use iter::Iterator; use option::{Option, None, Some}; use str; -use str::{MaybeOwned, Str, StrPrelude}; +use str::{CowString, MaybeOwned, Str, StrPrelude}; use string::String; use slice::{AsSlice, CloneSliceAllocPrelude}; use slice::{PartialEqSlicePrelude, SlicePrelude}; @@ -830,7 +830,7 @@ pub struct Display<'a, P:'a> { impl<'a, P: GenericPath> fmt::Show for Display<'a, P> { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - self.as_maybe_owned().as_slice().fmt(f) + self.as_cow().fmt(f) } } @@ -840,7 +840,7 @@ impl<'a, P: GenericPath> Display<'a, P> { /// If the path is not UTF-8, invalid sequences will be replaced with the /// Unicode replacement char. This involves allocation. #[inline] - pub fn as_maybe_owned(&self) -> MaybeOwned<'a> { + pub fn as_cow(&self) -> CowString<'a> { String::from_utf8_lossy(if self.filename { match self.path.filename() { None => { diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs index 2b444fdc32ba..bdce759a1df3 100644 --- a/src/libstd/path/posix.rs +++ b/src/libstd/path/posix.rs @@ -551,14 +551,14 @@ macro_rules! t( ($path:expr, $exp:expr) => ( { let path = Path::new($path); - let mo = path.display().as_maybe_owned(); + let mo = path.display().as_cow(); assert!(mo.as_slice() == $exp); } ); ($path:expr, $exp:expr, filename) => ( { let path = Path::new($path); - let mo = path.filename_display().as_maybe_owned(); + let mo = path.filename_display().as_cow(); assert!(mo.as_slice() == $exp); } ) diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs index 9f81de72980c..fc3677101313 100644 --- a/src/libstd/path/windows.rs +++ b/src/libstd/path/windows.rs @@ -1326,10 +1326,10 @@ fn test_display_str() { assert_eq!(path.filename_display().to_string(), "".to_string()); let path = Path::new("foo"); - let mo = path.display().as_maybe_owned(); + let mo = path.display().as_cow(); assert_eq!(mo.as_slice(), "foo"); let path = Path::new(b"\\"); - let mo = path.filename_display().as_maybe_owned(); + let mo = path.filename_display().as_cow(); assert_eq!(mo.as_slice(), ""); } diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs index 65f45c3f97e1..756ff1c58f30 100644 --- a/src/libstd/prelude.rs +++ b/src/libstd/prelude.rs @@ -58,6 +58,7 @@ #[doc(no_inline)] pub use ascii::{Ascii, AsciiCast, OwnedAsciiCast, AsciiStr}; #[doc(no_inline)] pub use ascii::IntoBytes; +#[doc(no_inline)] pub use borrow::IntoCow; #[doc(no_inline)] pub use c_str::ToCStr; #[doc(no_inline)] pub use char::{Char, UnicodeChar}; #[doc(no_inline)] pub use clone::Clone; @@ -78,7 +79,7 @@ #[doc(no_inline)] pub use result::Result::{Ok, Err}; #[doc(no_inline)] pub use io::{Buffer, Writer, Reader, Seek, BufferPrelude}; #[doc(no_inline)] pub use str::{Str, StrVector, StrPrelude}; -#[doc(no_inline)] pub use str::{IntoMaybeOwned, StrAllocating, UnicodeStrPrelude}; +#[doc(no_inline)] pub use str::{StrAllocating, UnicodeStrPrelude}; #[doc(no_inline)] pub use tuple::{Tuple1, Tuple2, Tuple3, Tuple4}; #[doc(no_inline)] pub use tuple::{Tuple5, Tuple6, Tuple7, Tuple8}; #[doc(no_inline)] pub use tuple::{Tuple9, Tuple10, Tuple11, Tuple12}; diff --git a/src/libstd/rt/mod.rs b/src/libstd/rt/mod.rs index 21b4edb63758..872a54522418 100644 --- a/src/libstd/rt/mod.rs +++ b/src/libstd/rt/mod.rs @@ -56,6 +56,7 @@ #![allow(dead_code)] +use borrow::IntoCow; use failure; use rustrt; use os; @@ -113,7 +114,6 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int { use prelude::*; use rt; use rustrt::task::Task; - use str; let something_around_the_top_of_the_stack = 1; let addr = &something_around_the_top_of_the_stack as *const int; @@ -147,7 +147,7 @@ pub fn start(argc: int, argv: *const *const u8, main: proc()) -> int { let mut main = Some(main); let mut task = box Task::new(Some((my_stack_bottom, my_stack_top)), Some(rustrt::thread::main_guard_page())); - task.name = Some(str::Slice("
")); + task.name = Some("
".into_cow()); drop(task.run(|| { unsafe { rustrt::stack::record_os_managed_stack_bounds(my_stack_bottom, my_stack_top); diff --git a/src/libstd/task.rs b/src/libstd/task.rs index c852b4efbd8a..a0ee08570d90 100644 --- a/src/libstd/task.rs +++ b/src/libstd/task.rs @@ -44,16 +44,17 @@ will likely be renamed from `task` to `thread`."] use any::Any; +use borrow::IntoCow; +use boxed::Box; use comm::channel; use io::{Writer, stdio}; use kinds::{Send, marker}; use option::{None, Some, Option}; -use boxed::Box; use result::Result; use rustrt::local::Local; -use rustrt::task; use rustrt::task::Task; -use str::{Str, SendStr, IntoMaybeOwned}; +use rustrt::task; +use str::{Str, SendStr}; use string::{String, ToString}; use sync::Future; @@ -101,8 +102,8 @@ impl TaskBuilder { /// Name the task-to-be. Currently the name is used for identification /// only in panic messages. #[unstable = "IntoMaybeOwned will probably change."] - pub fn named>(mut self, name: T) -> TaskBuilder { - self.name = Some(name.into_maybe_owned()); + pub fn named>(mut self, name: T) -> TaskBuilder { + self.name = Some(name.into_cow()); self } @@ -264,12 +265,13 @@ pub fn failing() -> bool { #[cfg(test)] mod test { use any::{Any, AnyRefExt}; + use borrow::IntoCow; use boxed::BoxAny; - use result; - use result::{Ok, Err}; - use string::String; - use std::io::{ChanReader, ChanWriter}; use prelude::*; + use result::{Ok, Err}; + use result; + use std::io::{ChanReader, ChanWriter}; + use string::String; use super::*; // !!! These tests are dangerous. If something is buggy, they will hang, !!! @@ -298,7 +300,7 @@ fn test_static_named_task() { #[test] fn test_send_named_task() { - TaskBuilder::new().named("ada lovelace".into_maybe_owned()).try(proc() { + TaskBuilder::new().named("ada lovelace".into_cow()).try(proc() { assert!(name().unwrap() == "ada lovelace".to_string()); }).map_err(|_| ()).unwrap(); } diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs index a88029e087b1..b5358e7d4859 100644 --- a/src/libsyntax/parse/lexer/mod.rs +++ b/src/libsyntax/parse/lexer/mod.rs @@ -272,13 +272,13 @@ fn with_str_from_to(&self, start: BytePos, end: BytePos, f: |s: &str| -> T) - /// Converts CRLF to LF in the given string, raising an error on bare CR. fn translate_crlf<'a>(&self, start: BytePos, - s: &'a str, errmsg: &'a str) -> str::MaybeOwned<'a> { + s: &'a str, errmsg: &'a str) -> str::CowString<'a> { let mut i = 0u; while i < s.len() { let str::CharRange { ch, next } = s.char_range_at(i); if ch == '\r' { if next < s.len() && s.char_at(next) == '\n' { - return translate_crlf_(self, start, s, errmsg, i).into_maybe_owned(); + return translate_crlf_(self, start, s, errmsg, i).into_cow(); } let pos = start + BytePos(i as u32); let end_pos = start + BytePos(next as u32); @@ -286,7 +286,7 @@ fn translate_crlf<'a>(&self, start: BytePos, } i = next; } - return s.into_maybe_owned(); + return s.into_cow(); fn translate_crlf_(rdr: &StringReader, start: BytePos, s: &str, errmsg: &str, mut i: uint) -> String { @@ -550,7 +550,7 @@ fn scan_block_comment(&mut self) -> Option { let string = if has_cr { self.translate_crlf(start_bpos, string, "bare CR not allowed in block doc-comment") - } else { string.into_maybe_owned() }; + } else { string.into_cow() }; token::DocComment(token::intern(string.as_slice())) } else { token::Comment diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index a9306c71240e..c731a0005f88 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -4966,10 +4966,10 @@ fn eval_src_mod_from_path(&mut self, let mut err = String::from_str("circular modules: "); let len = included_mod_stack.len(); for p in included_mod_stack.slice(i, len).iter() { - err.push_str(p.display().as_maybe_owned().as_slice()); + err.push_str(p.display().as_cow().as_slice()); err.push_str(" -> "); } - err.push_str(path.display().as_maybe_owned().as_slice()); + err.push_str(path.display().as_cow().as_slice()); self.span_fatal(id_sp, err.as_slice()); } None => () diff --git a/src/test/run-fail/panic-task-name-send-str.rs b/src/test/run-fail/panic-task-name-send-str.rs index 73fca2465909..fb4fb5c2f708 100644 --- a/src/test/run-fail/panic-task-name-send-str.rs +++ b/src/test/run-fail/panic-task-name-send-str.rs @@ -12,7 +12,7 @@ fn main() { let r: Result = - ::std::task::TaskBuilder::new().named("send name".into_maybe_owned()) + ::std::task::TaskBuilder::new().named("send name".into_cow()) .try(proc() { panic!("test"); 3i diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs index 55003a07b5bb..ef485723c7e2 100644 --- a/src/test/run-pass/send_str_hashmap.rs +++ b/src/test/run-pass/send_str_hashmap.rs @@ -10,51 +10,51 @@ extern crate collections; -use std::str::{SendStr, Owned, Slice}; use std::collections::HashMap; use std::option::Some; +use std::str::SendStr; pub fn main() { let mut map: HashMap = HashMap::new(); - assert!(map.insert(Slice("foo"), 42).is_none()); - assert!(map.insert(Owned("foo".to_string()), 42).is_some()); - assert!(map.insert(Slice("foo"), 42).is_some()); - assert!(map.insert(Owned("foo".to_string()), 42).is_some()); + assert!(map.insert("foo".into_cow(), 42).is_none()); + assert!(map.insert("foo".to_string().into_cow(), 42).is_some()); + assert!(map.insert("foo".into_cow(), 42).is_some()); + assert!(map.insert("foo".to_string().into_cow(), 42).is_some()); - assert!(map.insert(Slice("foo"), 43).is_some()); - assert!(map.insert(Owned("foo".to_string()), 44).is_some()); - assert!(map.insert(Slice("foo"), 45).is_some()); - assert!(map.insert(Owned("foo".to_string()), 46).is_some()); + assert!(map.insert("foo".into_cow(), 43).is_some()); + assert!(map.insert("foo".to_string().into_cow(), 44).is_some()); + assert!(map.insert("foo".into_cow(), 45).is_some()); + assert!(map.insert("foo".to_string().into_cow(), 46).is_some()); let v = 46; - assert_eq!(map.get(&Owned("foo".to_string())), Some(&v)); - assert_eq!(map.get(&Slice("foo")), Some(&v)); + assert_eq!(map.get(&"foo".to_string().into_cow()), Some(&v)); + assert_eq!(map.get(&"foo".into_cow()), Some(&v)); let (a, b, c, d) = (50, 51, 52, 53); - assert!(map.insert(Slice("abc"), a).is_none()); - assert!(map.insert(Owned("bcd".to_string()), b).is_none()); - assert!(map.insert(Slice("cde"), c).is_none()); - assert!(map.insert(Owned("def".to_string()), d).is_none()); + assert!(map.insert("abc".into_cow(), a).is_none()); + assert!(map.insert("bcd".to_string().into_cow(), b).is_none()); + assert!(map.insert("cde".into_cow(), c).is_none()); + assert!(map.insert("def".to_string().into_cow(), d).is_none()); - assert!(map.insert(Slice("abc"), a).is_some()); - assert!(map.insert(Owned("bcd".to_string()), b).is_some()); - assert!(map.insert(Slice("cde"), c).is_some()); - assert!(map.insert(Owned("def".to_string()), d).is_some()); + assert!(map.insert("abc".into_cow(), a).is_some()); + assert!(map.insert("bcd".to_string().into_cow(), b).is_some()); + assert!(map.insert("cde".into_cow(), c).is_some()); + assert!(map.insert("def".to_string().into_cow(), d).is_some()); - assert!(map.insert(Owned("abc".to_string()), a).is_some()); - assert!(map.insert(Slice("bcd"), b).is_some()); - assert!(map.insert(Owned("cde".to_string()), c).is_some()); - assert!(map.insert(Slice("def"), d).is_some()); + assert!(map.insert("abc".to_string().into_cow(), a).is_some()); + assert!(map.insert("bcd".into_cow(), b).is_some()); + assert!(map.insert("cde".to_string().into_cow(), c).is_some()); + assert!(map.insert("def".into_cow(), d).is_some()); - assert_eq!(map.find_equiv("abc"), Some(&a)); - assert_eq!(map.find_equiv("bcd"), Some(&b)); - assert_eq!(map.find_equiv("cde"), Some(&c)); - assert_eq!(map.find_equiv("def"), Some(&d)); + assert_eq!(map.get("abc"), Some(&a)); + assert_eq!(map.get("bcd"), Some(&b)); + assert_eq!(map.get("cde"), Some(&c)); + assert_eq!(map.get("def"), Some(&d)); - assert_eq!(map.find_equiv(&Slice("abc")), Some(&a)); - assert_eq!(map.find_equiv(&Slice("bcd")), Some(&b)); - assert_eq!(map.find_equiv(&Slice("cde")), Some(&c)); - assert_eq!(map.find_equiv(&Slice("def")), Some(&d)); + assert_eq!(map.get(&"abc".into_cow()), Some(&a)); + assert_eq!(map.get(&"bcd".into_cow()), Some(&b)); + assert_eq!(map.get(&"cde".into_cow()), Some(&c)); + assert_eq!(map.get(&"def".into_cow()), Some(&d)); } diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs index 0d8814198475..f72ca109b6e6 100644 --- a/src/test/run-pass/send_str_treemap.rs +++ b/src/test/run-pass/send_str_treemap.rs @@ -10,56 +10,56 @@ extern crate collections; -use std::str::{SendStr, Owned, Slice}; -use std::string::ToString; use self::collections::TreeMap; use std::option::Some; +use std::str::SendStr; +use std::string::ToString; pub fn main() { let mut map: TreeMap = TreeMap::new(); - assert!(map.insert(Slice("foo"), 42).is_none()); - assert!(map.insert(Owned("foo".to_string()), 42).is_some()); - assert!(map.insert(Slice("foo"), 42).is_some()); - assert!(map.insert(Owned("foo".to_string()), 42).is_some()); + assert!(map.insert("foo".into_cow(), 42).is_none()); + assert!(map.insert("foo".to_string().into_cow(), 42).is_some()); + assert!(map.insert("foo".into_cow(), 42).is_some()); + assert!(map.insert("foo".to_string().into_cow(), 42).is_some()); - assert!(map.insert(Slice("foo"), 43).is_some()); - assert!(map.insert(Owned("foo".to_string()), 44).is_some()); - assert!(map.insert(Slice("foo"), 45).is_some()); - assert!(map.insert(Owned("foo".to_string()), 46).is_some()); + assert!(map.insert("foo".into_cow(), 43).is_some()); + assert!(map.insert("foo".to_string().into_cow(), 44).is_some()); + assert!(map.insert("foo".into_cow(), 45).is_some()); + assert!(map.insert("foo".to_string().into_cow(), 46).is_some()); let v = 46; - assert_eq!(map.get(&Owned("foo".to_string())), Some(&v)); - assert_eq!(map.get(&Slice("foo")), Some(&v)); + assert_eq!(map.get(&"foo".to_string().into_cow()), Some(&v)); + assert_eq!(map.get(&"foo".into_cow()), Some(&v)); let (a, b, c, d) = (50, 51, 52, 53); - assert!(map.insert(Slice("abc"), a).is_none()); - assert!(map.insert(Owned("bcd".to_string()), b).is_none()); - assert!(map.insert(Slice("cde"), c).is_none()); - assert!(map.insert(Owned("def".to_string()), d).is_none()); + assert!(map.insert("abc".into_cow(), a).is_none()); + assert!(map.insert("bcd".to_string().into_cow(), b).is_none()); + assert!(map.insert("cde".into_cow(), c).is_none()); + assert!(map.insert("def".to_string().into_cow(), d).is_none()); - assert!(map.insert(Slice("abc"), a).is_some()); - assert!(map.insert(Owned("bcd".to_string()), b).is_some()); - assert!(map.insert(Slice("cde"), c).is_some()); - assert!(map.insert(Owned("def".to_string()), d).is_some()); + assert!(map.insert("abc".into_cow(), a).is_some()); + assert!(map.insert("bcd".to_string().into_cow(), b).is_some()); + assert!(map.insert("cde".into_cow(), c).is_some()); + assert!(map.insert("def".to_string().into_cow(), d).is_some()); - assert!(map.insert(Owned("abc".to_string()), a).is_some()); - assert!(map.insert(Slice("bcd"), b).is_some()); - assert!(map.insert(Owned("cde".to_string()), c).is_some()); - assert!(map.insert(Slice("def"), d).is_some()); + assert!(map.insert("abc".to_string().into_cow(), a).is_some()); + assert!(map.insert("bcd".into_cow(), b).is_some()); + assert!(map.insert("cde".to_string().into_cow(), c).is_some()); + assert!(map.insert("def".into_cow(), d).is_some()); - assert_eq!(map.get(&Slice("abc")), Some(&a)); - assert_eq!(map.get(&Slice("bcd")), Some(&b)); - assert_eq!(map.get(&Slice("cde")), Some(&c)); - assert_eq!(map.get(&Slice("def")), Some(&d)); + assert_eq!(map.get(&"abc".into_cow()), Some(&a)); + assert_eq!(map.get(&"bcd".into_cow()), Some(&b)); + assert_eq!(map.get(&"cde".into_cow()), Some(&c)); + assert_eq!(map.get(&"def".into_cow()), Some(&d)); - assert_eq!(map.get(&Owned("abc".to_string())), Some(&a)); - assert_eq!(map.get(&Owned("bcd".to_string())), Some(&b)); - assert_eq!(map.get(&Owned("cde".to_string())), Some(&c)); - assert_eq!(map.get(&Owned("def".to_string())), Some(&d)); + assert_eq!(map.get(&"abc".to_string().into_cow()), Some(&a)); + assert_eq!(map.get(&"bcd".to_string().into_cow()), Some(&b)); + assert_eq!(map.get(&"cde".to_string().into_cow()), Some(&c)); + assert_eq!(map.get(&"def".to_string().into_cow()), Some(&d)); - assert!(map.remove(&Slice("foo")).is_some()); + assert!(map.remove(&"foo".into_cow()).is_some()); assert_eq!(map.into_iter().map(|(k, v)| format!("{}{}", k, v)) .collect::>() .concat(),