about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2015-02-18 15:34:32 -0800
committerAlex Crichton <alex@alexcrichton.com>2015-02-18 15:34:48 -0800
commit2cdbd288ac0606902885434e1ccd8d8bde68913d (patch)
tree9a7d37f7dd44424182797c76d49ba0ece99f9513
parent365bd9a9e3b9dafa98e26982353fd28a6ca1efef (diff)
parenta99e698628cbd396c8100ef776d10ac61d911847 (diff)
downloadrust-2cdbd288ac0606902885434e1ccd8d8bde68913d.tar.gz
rust-2cdbd288ac0606902885434e1ccd8d8bde68913d.zip
rollup merge of #22210: aturon/stab-final-borrow
Conflicts:
	src/libcollections/btree/map.rs
	src/libcollections/str.rs
	src/libcollections/vec.rs
	src/libcore/borrow.rs
	src/libcore/hash/mod.rs
	src/libstd/collections/hash/map.rs
	src/libstd/collections/hash/set.rs
-rw-r--r--src/liballoc/arc.rs7
-rw-r--r--src/liballoc/rc.rs7
-rw-r--r--src/libcollections/borrow.rs316
-rw-r--r--src/libcollections/borrow_stage0.rs313
-rw-r--r--src/libcollections/btree/map.rs14
-rw-r--r--src/libcollections/btree/node.rs9
-rw-r--r--src/libcollections/btree/set.rs6
-rw-r--r--src/libcollections/lib.rs7
-rw-r--r--src/libcollections/slice.rs19
-rw-r--r--src/libcollections/str.rs13
-rw-r--r--src/libcollections/string.rs35
-rw-r--r--src/libcollections/vec.rs44
-rw-r--r--src/libcore/borrow.rs265
-rw-r--r--src/libcore/hash/mod.rs118
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libgraphviz/lib.rs6
-rw-r--r--src/librustc/middle/ty.rs8
-rw-r--r--src/libstd/collections/hash/map.rs26
-rw-r--r--src/libstd/collections/hash/set.rs6
-rw-r--r--src/libstd/ffi/os_str.rs9
-rw-r--r--src/libstd/lib.rs2
-rwxr-xr-xsrc/libstd/path.rs18
-rw-r--r--src/libsyntax/util/interner.rs12
-rw-r--r--src/test/compile-fail/ufcs-qpath-missing-params.rs3
-rw-r--r--src/test/run-make/save-analysis/foo.rs2
-rw-r--r--src/test/run-pass/const-polymorphic-paths.rs4
-rw-r--r--src/test/run-pass/send_str_hashmap.rs2
-rw-r--r--src/test/run-pass/send_str_treemap.rs2
-rw-r--r--src/test/run-pass/traits-issue-22019.rs6
29 files changed, 766 insertions, 514 deletions
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 343ede4e2cf..934e6ab2159 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -73,7 +73,6 @@ use core::prelude::*;
 
 use core::atomic;
 use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
-use core::borrow::BorrowFrom;
 use core::fmt;
 use core::cmp::{Ordering};
 use core::default::Default;
@@ -244,12 +243,6 @@ impl<T> Clone for Arc<T> {
     }
 }
 
-impl<T> BorrowFrom<Arc<T>> for T {
-    fn borrow_from(owned: &Arc<T>) -> &T {
-        &**owned
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Deref for Arc<T> {
     type Target = T;
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index 65513465dd2..9d395115431 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -144,7 +144,6 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::borrow::BorrowFrom;
 use core::cell::Cell;
 use core::clone::Clone;
 use core::cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering};
@@ -349,12 +348,6 @@ impl<T: Clone> Rc<T> {
     }
 }
 
-impl<T> BorrowFrom<Rc<T>> for T {
-    fn borrow_from(owned: &Rc<T>) -> &T {
-        &**owned
-    }
-}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T> Deref for Rc<T> {
     type Target = T;
diff --git a/src/libcollections/borrow.rs b/src/libcollections/borrow.rs
new file mode 100644
index 00000000000..901d7a73b51
--- /dev/null
+++ b/src/libcollections/borrow.rs
@@ -0,0 +1,316 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A module for working with borrowed data.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use core::clone::Clone;
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::hash::{Hash, Hasher};
+use core::marker::Sized;
+use core::ops::Deref;
+use core::option::Option;
+
+use fmt;
+use alloc::{rc, arc};
+
+use self::Cow::*;
+
+/// A trait for borrowing data.
+///
+/// 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<T>` 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 `Borrow`
+/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
+/// type can be borrowed as multiple different types. In particular, `Vec<T>:
+/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Borrow<Borrowed: ?Sized> {
+    /// Immutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow(&self) -> &Borrowed;
+}
+
+/// A trait for mutably borrowing data.
+///
+/// Similar to `Borrow`, but for mutable borrows.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
+    /// Mutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow_mut(&mut self) -> &mut Borrowed;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> Borrow<T> for T {
+    fn borrow(&self) -> &T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> BorrowMut<T> for T {
+    fn borrow_mut(&mut self) -> &mut T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
+    fn borrow_mut(&mut self) -> &mut T { &mut **self }
+}
+
+impl<T> Borrow<T> for rc::Rc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+impl<T> Borrow<T> for arc::Arc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
+    fn borrow(&self) -> &B {
+        &**self
+    }
+}
+
+/// A generalization of Clone to borrowed data.
+///
+/// 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.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait ToOwned {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Owned: Borrow<Self>;
+
+    /// Create owned data from borrowed data, usually by copying.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_owned(&self) -> Self::Owned;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ToOwned for T where T: Clone {
+    type Owned = T;
+    fn to_owned(&self) -> T { self.clone() }
+}
+
+/// A clone-on-write smart pointer.
+///
+/// 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 `Borrow` trait.
+///
+/// `Cow` implements both `Deref`, which means that you can call
+/// non-mutating methods directly on the data it encloses. If mutation
+/// is desired, `to_mut` will obtain a mutable references to an owned
+/// value, cloning if necessary.
+///
+/// # Example
+///
+/// ```rust
+/// use std::borrow::Cow;
+///
+/// fn abs_all(input: &mut Cow<[int]>) {
+///     for i in 0..input.len() {
+///         let v = input[i];
+///         if v < 0 {
+///             // clones into a vector the first time (if not already owned)
+///             input.to_mut()[i] = -v;
+///         }
+///     }
+/// }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
+    /// Borrowed data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Borrowed(&'a B),
+
+    /// Owned data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Owned(<B as ToOwned>::Owned)
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
+    fn clone(&self) -> Cow<'a, B> {
+        match *self {
+            Borrowed(b) => Borrowed(b),
+            Owned(ref o) => {
+                let b: &B = o.borrow();
+                Owned(b.to_owned())
+            },
+        }
+    }
+}
+
+impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned {
+    /// Acquire a mutable reference to the owned form of the data.
+    ///
+    /// Copies the data if it is not already owned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
+        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.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_owned(self) -> <B as ToOwned>::Owned {
+        match self {
+            Borrowed(borrowed) => borrowed.to_owned(),
+            Owned(owned) => owned
+        }
+    }
+
+    /// Returns true if this `Cow` wraps a borrowed value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_borrowed(&self) -> bool {
+        match *self {
+            Borrowed(_) => true,
+            _ => false,
+        }
+    }
+
+    /// Returns true if this `Cow` wraps an owned value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_owned(&self) -> bool {
+        match *self {
+            Owned(_) => true,
+            _ => false,
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Deref for Cow<'a, B> where B: ToOwned {
+    type Target = B;
+
+    fn deref(&self) -> &B {
+        match *self {
+            Borrowed(borrowed) => borrowed,
+            Owned(ref owned) => owned.borrow()
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Ord for Cow<'a, B> where B: Ord + ToOwned {
+    #[inline]
+    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
+        Ord::cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
+    B: PartialEq<C> + ToOwned, C: ToOwned,
+{
+    #[inline]
+    fn eq(&self, other: &Cow<'b, C>) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where B: PartialOrd + ToOwned,
+{
+    #[inline]
+    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
+    B: fmt::Debug + ToOwned,
+    <B as ToOwned>::Owned: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Debug::fmt(b, f),
+            Owned(ref o) => fmt::Debug::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
+    B: fmt::Display + ToOwned,
+    <B as ToOwned>::Owned: fmt::Display,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Display::fmt(b, f),
+            Owned(ref o) => fmt::Display::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(stage0)]
+impl<'a, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, B> where B: Hash<S> + ToOwned
+{
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        Hash::hash(&**self, state)
+    }
+}
+#[stable(feature = "rust1", since = "1.0.0")]
+#[cfg(not(stage0))]
+impl<'a, B: ?Sized> Hash for Cow<'a, B> where B: Hash + ToOwned
+{
+    #[inline]
+    fn hash<H: Hasher>(&self, state: &mut H) {
+        Hash::hash(&**self, state)
+    }
+}
+
+/// Trait for moving into a `Cow`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
+    /// Moves `self` into `Cow`
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into_cow(self) -> Cow<'a, B>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
+    fn into_cow(self) -> Cow<'a, B> {
+        self
+    }
+}
diff --git a/src/libcollections/borrow_stage0.rs b/src/libcollections/borrow_stage0.rs
new file mode 100644
index 00000000000..c1d74b16ce6
--- /dev/null
+++ b/src/libcollections/borrow_stage0.rs
@@ -0,0 +1,313 @@
+// 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 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+//! A module for working with borrowed data.
+
+#![stable(feature = "rust1", since = "1.0.0")]
+
+use core::clone::Clone;
+use core::cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
+use core::hash::{Hash, Hasher};
+use core::marker::Sized;
+use core::ops::Deref;
+use core::option::Option;
+
+use fmt;
+use alloc::{rc, arc};
+
+use self::Cow::*;
+
+/// A trait for borrowing data.
+///
+/// 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<T>` 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 `Borrow`
+/// trait: if `T: Borrow<U>`, then `&U` can be borrowed from `&T`.  A given
+/// type can be borrowed as multiple different types. In particular, `Vec<T>:
+/// Borrow<Vec<T>>` and `Vec<T>: Borrow<[T]>`.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait Borrow<Borrowed: ?Sized> {
+    /// Immutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow(&self) -> &Borrowed;
+}
+
+/// A trait for mutably borrowing data.
+///
+/// Similar to `Borrow`, but for mutable borrows.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait BorrowMut<Borrowed: ?Sized> : Borrow<Borrowed> {
+    /// Mutably borrow from an owned value.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn borrow_mut(&mut self) -> &mut Borrowed;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> Borrow<T> for T {
+    fn borrow(&self) -> &T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: ?Sized> BorrowMut<T> for T {
+    fn borrow_mut(&mut self) -> &mut T { self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> Borrow<T> for &'a mut T {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, T: ?Sized> BorrowMut<T> for &'a mut T {
+    fn borrow_mut(&mut self) -> &mut T { &mut **self }
+}
+
+impl<T> Borrow<T> for rc::Rc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+impl<T> Borrow<T> for arc::Arc<T> {
+    fn borrow(&self) -> &T { &**self }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Borrow<B> for Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
+    fn borrow(&self) -> &B {
+        &**self
+    }
+}
+
+/// A generalization of Clone to borrowed data.
+///
+/// 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.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait ToOwned {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    type Owned: Borrow<Self>;
+
+    /// Create owned data from borrowed data, usually by copying.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn to_owned(&self) -> Self::Owned;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> ToOwned for T where T: Clone {
+    type Owned = T;
+    fn to_owned(&self) -> T { self.clone() }
+}
+
+/// A clone-on-write smart pointer.
+///
+/// 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 `Borrow` trait.
+///
+/// `Cow` implements both `Deref`, which means that you can call
+/// non-mutating methods directly on the data it encloses. If mutation
+/// is desired, `to_mut` will obtain a mutable references to an owned
+/// value, cloning if necessary.
+///
+/// # Example
+///
+/// ```rust
+/// use std::borrow::Cow;
+///
+/// fn abs_all(input: &mut Cow<[int]>) {
+///     for i in 0..input.len() {
+///         let v = input[i];
+///         if v < 0 {
+///             // clones into a vector the first time (if not already owned)
+///             input.to_mut()[i] = -v;
+///         }
+///     }
+/// }
+/// ```
+#[stable(feature = "rust1", since = "1.0.0")]
+pub enum Cow<'a, B: ?Sized + 'a> where B: ToOwned {
+    /// Borrowed data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Borrowed(&'a B),
+
+    /// Owned data.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Owned(<B as ToOwned>::Owned)
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Clone for Cow<'a, B> where B: ToOwned {
+    fn clone(&self) -> Cow<'a, B> {
+        match *self {
+            Borrowed(b) => Borrowed(b),
+            Owned(ref o) => {
+                let b: &B = o.borrow();
+                Owned(b.to_owned())
+            },
+        }
+    }
+}
+
+impl<'a, B: ?Sized> Cow<'a, B> where B: ToOwned, <B as ToOwned>::Owned: 'a {
+    /// Acquire a mutable reference to the owned form of the data.
+    ///
+    /// Copies the data if it is not already owned.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned where <B as ToOwned>::Owned: 'a {
+        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.
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub fn into_owned(self) -> <B as ToOwned>::Owned {
+        match self {
+            Borrowed(borrowed) => borrowed.to_owned(),
+            Owned(owned) => owned
+        }
+    }
+
+    /// Returns true if this `Cow` wraps a borrowed value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_borrowed(&self) -> bool {
+        match *self {
+            Borrowed(_) => true,
+            _ => false,
+        }
+    }
+
+    /// Returns true if this `Cow` wraps an owned value
+    #[deprecated(since = "1.0.0", reason = "match on the enum instead")]
+    #[unstable(feature = "std_misc")]
+    pub fn is_owned(&self) -> bool {
+        match *self {
+            Owned(_) => true,
+            _ => false,
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Deref for Cow<'a, B> where
+    B: ToOwned, <B as ToOwned>::Owned: 'a
+{
+    type Target = B;
+
+    fn deref(&self) -> &B {
+        match *self {
+            Borrowed(borrowed) => borrowed,
+            Owned(ref owned) => owned.borrow()
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Eq for Cow<'a, B> where B: Eq + ToOwned, <B as ToOwned>::Owned: 'a {}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> Ord for Cow<'a, B> where
+    B: Ord + ToOwned, <B as ToOwned>::Owned: 'a
+{
+    #[inline]
+    fn cmp(&self, other: &Cow<'a, B>) -> Ordering {
+        Ord::cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, 'b, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, C>> for Cow<'a, B> where
+    B: PartialEq<C> + ToOwned, C: ToOwned,
+    <B as ToOwned>::Owned: 'a, <C as ToOwned>::Owned: 'b,
+{
+    #[inline]
+    fn eq(&self, other: &Cow<'b, C>) -> bool {
+        PartialEq::eq(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> PartialOrd for Cow<'a, B> where
+    B: PartialOrd + ToOwned, <B as ToOwned>::Owned: 'a
+{
+    #[inline]
+    fn partial_cmp(&self, other: &Cow<'a, B>) -> Option<Ordering> {
+        PartialOrd::partial_cmp(&**self, &**other)
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Debug for Cow<'a, B> where
+    B: fmt::Debug + ToOwned,
+    <B as ToOwned>::Owned: fmt::Debug,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Debug::fmt(b, f),
+            Owned(ref o) => fmt::Debug::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized> fmt::Display for Cow<'a, B> where
+    B: fmt::Display + ToOwned,
+    <B as ToOwned>::Owned: fmt::Display,
+{
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        match *self {
+            Borrowed(ref b) => fmt::Display::fmt(b, f),
+            Owned(ref o) => fmt::Display::fmt(o, f),
+        }
+    }
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a, B: ?Sized, S: Hasher> Hash<S> for Cow<'a, B> where
+    B: Hash<S> + ToOwned, <B as ToOwned>::Owned: 'a
+{
+    #[inline]
+    fn hash(&self, state: &mut S) {
+        Hash::hash(&**self, state)
+    }
+}
+
+/// Trait for moving into a `Cow`
+#[stable(feature = "rust1", since = "1.0.0")]
+pub trait IntoCow<'a, B: ?Sized> where B: ToOwned {
+    /// Moves `self` into `Cow`
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn into_cow(self) -> Cow<'a, B>;
+}
+
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a,  B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
+    fn into_cow(self) -> Cow<'a, B> {
+        self
+    }
+}
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index a985a24f7ae..c6cd6895728 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -19,7 +19,6 @@ use self::Entry::*;
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering;
 use core::default::Default;
 use core::fmt::Debug;
@@ -29,6 +28,7 @@ use core::ops::{Index, IndexMut};
 use core::{iter, fmt, mem};
 use Bound::{self, Included, Excluded, Unbounded};
 
+use borrow::Borrow;
 use vec_deque::VecDeque;
 
 use self::Continuation::{Continue, Finished};
@@ -208,7 +208,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert_eq!(map.get(&2), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where Q: BorrowFrom<K> + Ord {
+    pub fn get<Q: ?Sized>(&self, key: &Q) -> Option<&V> where K: Borrow<Q>, Q: Ord {
         let mut cur_node = &self.root;
         loop {
             match Node::search(cur_node, key) {
@@ -240,7 +240,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert_eq!(map.contains_key(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where Q: BorrowFrom<K> + Ord {
+    pub fn contains_key<Q: ?Sized>(&self, key: &Q) -> bool where K: Borrow<Q>, Q: Ord {
         self.get(key).is_some()
     }
 
@@ -264,7 +264,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// ```
     // See `get` for implementation notes, this is basically a copy-paste with mut's added
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where Q: BorrowFrom<K> + Ord {
+    pub fn get_mut<Q: ?Sized>(&mut self, key: &Q) -> Option<&mut V> where K: Borrow<Q>, Q: Ord {
         // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration
         let mut temp_node = &mut self.root;
         loop {
@@ -434,7 +434,7 @@ impl<K: Ord, V> BTreeMap<K, V> {
     /// assert_eq!(map.remove(&1), None);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where Q: BorrowFrom<K> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, key: &Q) -> Option<V> where K: Borrow<Q>, Q: Ord {
         // See `swap` for a more thorough description of the stuff going on in here
         let mut stack = stack::PartialSearchStack::new(self);
         loop {
@@ -913,7 +913,7 @@ impl<K: Debug, V: Debug> Debug for BTreeMap<K, V> {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
-    where Q: BorrowFrom<K> + Ord
+    where K: Borrow<Q>, Q: Ord
 {
     type Output = V;
 
@@ -924,7 +924,7 @@ impl<K: Ord, Q: ?Sized, V> Index<Q> for BTreeMap<K, V>
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K: Ord, Q: ?Sized, V> IndexMut<Q> for BTreeMap<K, V>
-    where Q: BorrowFrom<K> + Ord
+    where K: Borrow<Q>, Q: 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 24523d4dcc9..8f5ee35fcb2 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -18,7 +18,6 @@ pub use self::TraversalItem::*;
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering::{Greater, Less, Equal};
 use core::iter::Zip;
 use core::ops::{Deref, DerefMut, Index, IndexMut};
@@ -26,6 +25,8 @@ use core::ptr::Unique;
 use core::{slice, mem, ptr, cmp, num, raw};
 use alloc::heap;
 
+use borrow::Borrow;
+
 /// Represents the result of an Insertion: either the item fit, or the node had to split
 pub enum InsertionResult<K, V> {
     /// The inserted element fit
@@ -543,7 +544,7 @@ impl<K: Ord, V> Node<K, V> {
     /// `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<Q: ?Sized, NodeRef: Deref<Target=Node<K, V>>>(node: NodeRef, key: &Q)
-                  -> SearchResult<NodeRef> where Q: BorrowFrom<K> + Ord {
+                  -> SearchResult<NodeRef> where K: Borrow<Q>, Q: 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 usizes.
@@ -1491,9 +1492,9 @@ macro_rules! node_slice_impl {
         impl<'a, K: Ord + 'a, V: 'a> $NodeSlice<'a, K, V> {
             /// Performs linear search in a slice. Returns a tuple of (index, is_exact_match).
             fn search_linear<Q: ?Sized>(&self, key: &Q) -> (usize, bool)
-                    where Q: BorrowFrom<K> + Ord {
+                    where K: Borrow<Q>, Q: Ord {
                 for (i, k) in self.keys.iter().enumerate() {
-                    match key.cmp(BorrowFrom::borrow_from(k)) {
+                    match key.cmp(k.borrow()) {
                         Greater => {},
                         Equal => return (i, true),
                         Less => return (i, false),
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 61497186623..929b2f58043 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -13,7 +13,6 @@
 
 use core::prelude::*;
 
-use core::borrow::BorrowFrom;
 use core::cmp::Ordering::{self, Less, Greater, Equal};
 use core::default::Default;
 use core::fmt::Debug;
@@ -21,6 +20,7 @@ use core::fmt;
 use core::iter::{Peekable, Map, FromIterator, IntoIterator};
 use core::ops::{BitOr, BitAnd, BitXor, Sub};
 
+use borrow::Borrow;
 use btree_map::{BTreeMap, Keys};
 use Bound;
 
@@ -336,7 +336,7 @@ impl<T: Ord> BTreeSet<T> {
     /// assert_eq!(set.contains(&4), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool where T: Borrow<Q>, Q: Ord {
         self.map.contains_key(value)
     }
 
@@ -466,7 +466,7 @@ impl<T: Ord> BTreeSet<T> {
     /// assert_eq!(set.remove(&2), false);
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where Q: BorrowFrom<T> + Ord {
+    pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool where T: Borrow<Q>, Q: Ord {
         self.map.remove(value).is_some()
     }
 }
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 335b15c4340..8fce626755e 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -96,6 +96,13 @@ pub mod string;
 pub mod vec;
 pub mod vec_map;
 
+#[cfg(stage0)]
+#[path = "borrow_stage0.rs"]
+pub mod borrow;
+
+#[cfg(not(stage0))]
+pub mod borrow;
+
 #[unstable(feature = "collections",
            reason = "RFC 509")]
 pub mod bit_vec {
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index 06ae8127c00..a0cb98267fa 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -88,7 +88,6 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use alloc::boxed::Box;
-use core::borrow::{BorrowFrom, BorrowFromMut, ToOwned};
 use core::clone::Clone;
 use core::cmp::Ordering::{self, Greater, Less};
 use core::cmp::{self, Ord, PartialEq};
@@ -105,6 +104,7 @@ use core::result::Result;
 use core::slice as core_slice;
 use self::Direction::*;
 
+use borrow::{Borrow, BorrowMut, ToOwned};
 use vec::Vec;
 
 pub use core::slice::{Chunks, AsSlice, Windows};
@@ -1175,18 +1175,19 @@ impl ElementSwaps {
 // Standard trait implementations for slices
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T> BorrowFrom<Vec<T>> for [T] {
-    fn borrow_from(owned: &Vec<T>) -> &[T] { &owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> Borrow<[T]> for Vec<T> {
+    fn borrow(&self) -> &[T] { &self[] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T> BorrowFromMut<Vec<T>> for [T] {
-    fn borrow_from_mut(owned: &mut Vec<T>) -> &mut [T] { &mut owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T> BorrowMut<[T]> for Vec<T> {
+    fn borrow_mut(&mut self) -> &mut [T] { &mut self[] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl<T: Clone> ToOwned<Vec<T>> for [T] {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<T: Clone> ToOwned for [T] {
+    type Owned = Vec<T>;
     fn to_owned(&self) -> Vec<T> { self.to_vec() }
 }
 
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 94d81c74cd3..cdc503500d2 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -55,7 +55,6 @@
 use self::RecompositionState::*;
 use self::DecompositionType::*;
 
-use core::borrow::{BorrowFrom, ToOwned};
 use core::char::CharExt;
 use core::clone::Clone;
 use core::iter::AdditiveIterator;
@@ -69,6 +68,7 @@ use core::str as core_str;
 use unicode::str::{UnicodeStr, Utf16Encoder};
 
 use vec_deque::VecDeque;
+use borrow::{Borrow, ToOwned};
 use slice::SliceExt;
 use string::String;
 use unicode;
@@ -386,13 +386,14 @@ macro_rules! utf8_acc_cont_byte {
     ($ch:expr, $byte:expr) => (($ch << 6) | ($byte & 63u8) as u32)
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl BorrowFrom<String> for str {
-    fn borrow_from(owned: &String) -> &str { &owned[] }
+#[stable(feature = "rust1", since = "1.0.0")]
+impl Borrow<str> for String {
+    fn borrow(&self) -> &str { &self[] }
 }
 
-#[unstable(feature = "collections", reason = "trait is unstable")]
-impl ToOwned<String> for str {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl ToOwned for str {
+    type Owned = String;
     fn to_owned(&self) -> String {
         unsafe {
             String::from_utf8_unchecked(self.as_bytes().to_owned())
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index db889725abd..5e48336dfad 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -16,7 +16,6 @@
 
 use core::prelude::*;
 
-use core::borrow::{Cow, IntoCow};
 use core::default::Default;
 use core::error::Error;
 use core::fmt;
@@ -29,6 +28,7 @@ use core::raw::Slice as RawSlice;
 use unicode::str as unicode_str;
 use unicode::str::Utf16Item;
 
+use borrow::{Cow, IntoCow};
 use str::{self, CharRange, FromStr, Utf8Error};
 use vec::{DerefVec, Vec, as_vec};
 
@@ -142,7 +142,7 @@ impl String {
     /// assert_eq!(output.as_slice(), "Hello \u{FFFD}World");
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> CowString<'a> {
+    pub fn from_utf8_lossy<'a>(v: &'a [u8]) -> Cow<'a, str> {
         let mut i = 0;
         match str::from_utf8(v) {
             Ok(s) => return Cow::Borrowed(s),
@@ -782,10 +782,10 @@ macro_rules! impl_eq {
 }
 
 impl_eq! { String, &'a str }
-impl_eq! { CowString<'a>, String }
+impl_eq! { Cow<'a, str>, String }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
+impl<'a, 'b> PartialEq<&'b str> for Cow<'a, str> {
     #[inline]
     fn eq(&self, other: &&'b str) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
@@ -793,11 +793,11 @@ impl<'a, 'b> PartialEq<&'b str> for CowString<'a> {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> PartialEq<CowString<'a>> for &'b str {
+impl<'a, 'b> PartialEq<Cow<'a, str>> for &'b str {
     #[inline]
-    fn eq(&self, other: &CowString<'a>) -> bool { PartialEq::eq(&**self, &**other) }
+    fn eq(&self, other: &Cow<'a, str>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
-    fn ne(&self, other: &CowString<'a>) -> bool { PartialEq::ne(&**self, &**other) }
+    fn ne(&self, other: &Cow<'a, str>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
 #[unstable(feature = "collections", reason = "waiting on Str stabilization")]
@@ -969,31 +969,34 @@ impl<T: fmt::Display + ?Sized> ToString for T {
     }
 }
 
-impl IntoCow<'static, String, str> for String {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl IntoCow<'static, str> for String {
     #[inline]
-    fn into_cow(self) -> CowString<'static> {
+    fn into_cow(self) -> Cow<'static, str> {
         Cow::Owned(self)
     }
 }
 
-impl<'a> IntoCow<'a, String, str> for &'a str {
+#[stable(feature = "rust1", since = "1.0.0")]
+impl<'a> IntoCow<'a, str> for &'a str {
     #[inline]
-    fn into_cow(self) -> CowString<'a> {
+    fn into_cow(self) -> Cow<'a, str> {
         Cow::Borrowed(self)
     }
 }
 
-/// A clone-on-write string
-#[stable(feature = "rust1", since = "1.0.0")]
-pub type CowString<'a> = Cow<'a, String, str>;
-
-impl<'a> Str for CowString<'a> {
+impl<'a> Str for Cow<'a, str> {
     #[inline]
     fn as_slice<'b>(&'b self) -> &'b str {
         &**self
     }
 }
 
+/// A clone-on-write string
+#[deprecated(since = "1.0.0", reason = "use Cow<'a, str> instead")]
+#[stable(feature = "rust1", since = "1.0.0")]
+pub type CowString<'a> = Cow<'a, str>;
+
 #[stable(feature = "rust1", since = "1.0.0")]
 impl fmt::Write for String {
     #[inline]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index c77a6b9e8e5..e303d776003 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -50,7 +50,6 @@ use core::prelude::*;
 
 use alloc::boxed::Box;
 use alloc::heap::{EMPTY, allocate, reallocate, deallocate};
-use core::borrow::{Cow, IntoCow};
 use core::cmp::max;
 use core::cmp::{Ordering};
 use core::default::Default;
@@ -69,6 +68,8 @@ use core::raw::Slice as RawSlice;
 use core::slice;
 use core::usize;
 
+use borrow::{Cow, IntoCow};
+
 /// A growable list type, written `Vec<T>` but pronounced 'vector.'
 ///
 /// # Examples
@@ -1529,34 +1530,34 @@ macro_rules! impl_eq {
 impl_eq! { Vec<A>, &'b [B] }
 impl_eq! { Vec<A>, &'b mut [B] }
 
-impl<'a, A, B> PartialEq<Vec<B>> for CowVec<'a, A> where A: PartialEq<B> + Clone {
+impl<'a, A, B> PartialEq<Vec<B>> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
     #[inline]
     fn eq(&self, other: &Vec<B>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
     fn ne(&self, other: &Vec<B>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
-impl<'a, A, B> PartialEq<CowVec<'a, A>> for Vec<B> where A: Clone, B: PartialEq<A> {
+impl<'a, A, B> PartialEq<Cow<'a, [A]>> for Vec<B> where A: Clone, B: PartialEq<A> {
     #[inline]
-    fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+    fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
     #[inline]
-    fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+    fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
 }
 
 macro_rules! impl_eq_for_cowvec {
     ($rhs:ty) => {
-        impl<'a, 'b, A, B> PartialEq<$rhs> for CowVec<'a, A> where A: PartialEq<B> + Clone {
+        impl<'a, 'b, A, B> PartialEq<$rhs> for Cow<'a, [A]> where A: PartialEq<B> + Clone {
             #[inline]
             fn eq(&self, other: &$rhs) -> bool { PartialEq::eq(&**self, &**other) }
             #[inline]
             fn ne(&self, other: &$rhs) -> bool { PartialEq::ne(&**self, &**other) }
         }
 
-        impl<'a, 'b, A, B> PartialEq<CowVec<'a, A>> for $rhs where A: Clone, B: PartialEq<A> {
+        impl<'a, 'b, A, B> PartialEq<Cow<'a, [A]>> for $rhs where A: Clone, B: PartialEq<A> {
             #[inline]
-            fn eq(&self, other: &CowVec<'a, A>) -> bool { PartialEq::eq(&**self, &**other) }
+            fn eq(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::eq(&**self, &**other) }
             #[inline]
-            fn ne(&self, other: &CowVec<'a, A>) -> bool { PartialEq::ne(&**self, &**other) }
+            fn ne(&self, other: &Cow<'a, [A]>) -> bool { PartialEq::ne(&**self, &**other) }
         }
     }
 }
@@ -1564,8 +1565,7 @@ macro_rules! impl_eq_for_cowvec {
 impl_eq_for_cowvec! { &'b [B] }
 impl_eq_for_cowvec! { &'b mut [B] }
 
-#[unstable(feature = "collections",
-           reason = "waiting on PartialOrd stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: PartialOrd> PartialOrd for Vec<T> {
     #[inline]
     fn partial_cmp(&self, other: &Vec<T>) -> Option<Ordering> {
@@ -1573,10 +1573,10 @@ impl<T: PartialOrd> PartialOrd for Vec<T> {
     }
 }
 
-#[unstable(feature = "collections", reason = "waiting on Eq stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Eq> Eq for Vec<T> {}
 
-#[unstable(feature = "collections", reason = "waiting on Ord stability")]
+#[stable(feature = "rust1", since = "1.0.0")]
 impl<T: Ord> Ord for Vec<T> {
     #[inline]
     fn cmp(&self, other: &Vec<T>) -> Ordering {
@@ -1659,26 +1659,26 @@ impl<T: fmt::Debug> fmt::Debug for Vec<T> {
 // Clone-on-write
 ////////////////////////////////////////////////////////////////////////////////
 
-#[unstable(feature = "collections",
-           reason = "unclear how valuable this alias is")]
 /// A clone-on-write vector
-pub type CowVec<'a, T> = Cow<'a, Vec<T>, [T]>;
+#[deprecated(since = "1.0.0", reason = "use Cow<'a, [T]> instead")]
+#[unstable(feature = "collections")]
+pub type CowVec<'a, T> = Cow<'a, [T]>;
 
 #[unstable(feature = "collections")]
-impl<'a, T> FromIterator<T> for CowVec<'a, T> where T: Clone {
-    fn from_iter<I: IntoIterator<Item=T>>(it: I) -> CowVec<'a, T> {
+impl<'a, T> FromIterator<T> for Cow<'a, [T]> where T: Clone {
+    fn from_iter<I: IntoIterator<Item=T>>(it: I) -> Cow<'a, [T]> {
         Cow::Owned(FromIterator::from_iter(it))
     }
 }
 
-impl<'a, T: 'a> IntoCow<'a, Vec<T>, [T]> for Vec<T> where T: Clone {
-    fn into_cow(self) -> CowVec<'a, T> {
+impl<'a, T: 'a> IntoCow<'a, [T]> for Vec<T> where T: Clone {
+    fn into_cow(self) -> Cow<'a, [T]> {
         Cow::Owned(self)
     }
 }
 
-impl<'a, T> IntoCow<'a, Vec<T>, [T]> for &'a [T] where T: Clone {
-    fn into_cow(self) -> CowVec<'a, T> {
+impl<'a, T> IntoCow<'a, [T]> for &'a [T] where T: Clone {
+    fn into_cow(self) -> Cow<'a, [T]> {
         Cow::Borrowed(self)
     }
 }
diff --git a/src/libcore/borrow.rs b/src/libcore/borrow.rs
deleted file mode 100644
index 3131952d94d..00000000000
--- a/src/libcore/borrow.rs
+++ /dev/null
@@ -1,265 +0,0 @@
-// 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 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, 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<T>` 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<U>`, then `&T` can be borrowed from `&U`.  A given
-//! type can be borrowed as multiple different types. In particular, `Vec<T>:
-//! BorrowFrom<Vec<T>>` and `[T]: BorrowFrom<Vec<T>>`.
-//!
-//! # 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`, which means that you can call
-//! non-mutating methods directly on the data it encloses. If mutation
-//! is desired, `to_mut` will obtain a mutable references to an owned
-//! value, cloning if necessary.
-
-#![unstable(feature = "core",
-            reason = "recently added as part of collections reform")]
-
-use clone::Clone;
-use cmp::{Eq, Ord, Ordering, PartialEq, PartialOrd};
-use fmt;
-use marker::Sized;
-use ops::Deref;
-use option::Option;
-use self::Cow::*;
-
-/// A trait for borrowing data.
-#[old_orphan_check]
-pub trait BorrowFrom<Owned: ?Sized> {
-    /// Immutably borrow from an owned value.
-    fn borrow_from(owned: &Owned) -> &Self;
-}
-
-/// A trait for mutably borrowing data.
-#[old_orphan_check]
-pub trait BorrowFromMut<Owned: ?Sized> : BorrowFrom<Owned> {
-    /// Mutably borrow from an owned value.
-    fn borrow_from_mut(owned: &mut Owned) -> &mut Self;
-}
-
-impl<T: ?Sized> BorrowFrom<T> for T {
-    fn borrow_from(owned: &T) -> &T { owned }
-}
-
-impl<T: ?Sized> BorrowFromMut<T> for T {
-    fn borrow_from_mut(owned: &mut T) -> &mut T { owned }
-}
-
-impl<'a, T: ?Sized> BorrowFrom<&'a T> for T {
-    fn borrow_from<'b>(owned: &'b &'a T) -> &'b T { &**owned }
-}
-
-impl<'a, T: ?Sized> BorrowFrom<&'a mut T> for T {
-    fn borrow_from<'b>(owned: &'b &'a mut T) -> &'b T { &**owned }
-}
-
-impl<'a, T: ?Sized> 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, B: ?Sized> BorrowFrom<Cow<'a, T, B>> for B where B: ToOwned<T> {
-    fn borrow_from<'b>(owned: &'b Cow<'a, T, B>) -> &'b B {
-        &**owned
-    }
-}
-
-/// Trait for moving into a `Cow`
-#[old_orphan_check]
-pub trait IntoCow<'a, T, B: ?Sized> {
-    /// Moves `self` into `Cow`
-    fn into_cow(self) -> Cow<'a, T, B>;
-}
-
-impl<'a, T, B: ?Sized> IntoCow<'a, T, B> for Cow<'a, T, B> where B: ToOwned<T> {
-    fn into_cow(self) -> Cow<'a, T, B> {
-        self
-    }
-}
-
-/// A generalization of Clone to borrowed data.
-#[old_orphan_check]
-pub trait ToOwned<Owned>: BorrowFrom<Owned> {
-    /// Create owned data from borrowed data, usually by copying.
-    fn to_owned(&self) -> Owned;
-}
-
-impl<T> ToOwned<T> for T where T: Clone {
-    fn to_owned(&self) -> T { self.clone() }
-}
-
-/// A clone-on-write smart pointer.
-///
-/// # Example
-///
-/// ```rust
-/// use std::borrow::Cow;
-///
-/// fn abs_all(input: &mut Cow<Vec<i32>, [i32]>) {
-///     for i in 0..input.len() {
-///         let v = input[i];
-///         if v < 0 {
-///             // clones into a vector the first time (if not already owned)
-///             input.to_mut()[i] = -v;
-///         }
-///     }
-/// }
-/// ```
-pub enum Cow<'a, T, B: ?Sized + 'a> where B: ToOwned<T> {
-    /// Borrowed data.
-    Borrowed(&'a B),
-
-    /// Owned data.
-    Owned(T)
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Clone for Cow<'a, T, B> where B: ToOwned<T> {
-    fn clone(&self) -> Cow<'a, T, B> {
-        match *self {
-            Borrowed(b) => Borrowed(b),
-            Owned(ref o) => {
-                let b: &B = BorrowFrom::borrow_from(o);
-                Owned(b.to_owned())
-            },
-        }
-    }
-}
-
-impl<'a, T, B: ?Sized> Cow<'a, T, B> where B: ToOwned<T> {
-    /// 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
-        }
-    }
-
-    /// 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,
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Deref for Cow<'a, T, B> where B: ToOwned<T>  {
-    type Target = B;
-
-    fn deref(&self) -> &B {
-        match *self {
-            Borrowed(borrowed) => borrowed,
-            Owned(ref owned) => BorrowFrom::borrow_from(owned)
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Eq for Cow<'a, T, B> where B: Eq + ToOwned<T> {}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> Ord for Cow<'a, T, B> where B: Ord + ToOwned<T> {
-    #[inline]
-    fn cmp(&self, other: &Cow<'a, T, B>) -> Ordering {
-        Ord::cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b, T, U, B: ?Sized, C: ?Sized> PartialEq<Cow<'b, U, C>> for Cow<'a, T, B> where
-    B: PartialEq<C> + ToOwned<T>,
-    C: ToOwned<U>,
-{
-    #[inline]
-    fn eq(&self, other: &Cow<'b, U, C>) -> bool {
-        PartialEq::eq(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> PartialOrd for Cow<'a, T, B> where B: PartialOrd + ToOwned<T> {
-    #[inline]
-    fn partial_cmp(&self, other: &Cow<'a, T, B>) -> Option<Ordering> {
-        PartialOrd::partial_cmp(&**self, &**other)
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> fmt::Debug for Cow<'a, T, B> where
-    B: fmt::Debug + ToOwned<T>,
-    T: fmt::Debug,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Borrowed(ref b) => fmt::Debug::fmt(b, f),
-            Owned(ref o) => fmt::Debug::fmt(o, f),
-        }
-    }
-}
-
-#[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, T, B: ?Sized> fmt::Display for Cow<'a, T, B> where
-    B: fmt::Display + ToOwned<T>,
-    T: fmt::Display,
-{
-    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            Borrowed(ref b) => fmt::Display::fmt(b, f),
-            Owned(ref o) => fmt::Display::fmt(o, f),
-        }
-    }
-}
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index b9a5122dd9c..3d0c9761dda 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -58,8 +58,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+use prelude::*;
+
 use default::Default;
-use marker::Sized;
 use mem;
 
 pub use self::sip::SipHasher;
@@ -398,119 +399,4 @@ mod impls {
             }
         )*}
     }
-
-    impl_write! {
-        (u8, write_u8),
-        (u16, write_u16),
-        (u32, write_u32),
-        (u64, write_u64),
-        (usize, write_usize),
-        (i8, write_i8),
-        (i16, write_i16),
-        (i32, write_i32),
-        (i64, write_i64),
-        (isize, write_isize),
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for bool {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            state.write_u8(*self as u8)
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for char {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            state.write_u32(*self as u32)
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl Hash for str {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            state.write(self.as_bytes());
-            state.write_u8(0xff)
-        }
-    }
-
-    macro_rules! impl_hash_tuple {
-        () => (
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl Hash for () {
-                fn hash<H: Hasher>(&self, _state: &mut H) {}
-            }
-        );
-
-        ( $($name:ident)+) => (
-            #[stable(feature = "rust1", since = "1.0.0")]
-            impl<$($name: Hash),*> Hash for ($($name,)*) {
-                #[allow(non_snake_case)]
-                fn hash<S: Hasher>(&self, state: &mut S) {
-                    let ($(ref $name,)*) = *self;
-                    $($name.hash(state);)*
-                }
-            }
-        );
-    }
-
-    impl_hash_tuple! {}
-    impl_hash_tuple! { A }
-    impl_hash_tuple! { A B }
-    impl_hash_tuple! { A B C }
-    impl_hash_tuple! { A B C D }
-    impl_hash_tuple! { A B C D E }
-    impl_hash_tuple! { A B C D E F }
-    impl_hash_tuple! { A B C D E F G }
-    impl_hash_tuple! { A B C D E F G H }
-    impl_hash_tuple! { A B C D E F G H I }
-    impl_hash_tuple! { A B C D E F G H I J }
-    impl_hash_tuple! { A B C D E F G H I J K }
-    impl_hash_tuple! { A B C D E F G H I J K L }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl<T: Hash> Hash for [T] {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            self.len().hash(state);
-            Hash::hash_slice(self, state)
-        }
-    }
-
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl<'a, T: ?Sized + Hash> Hash for &'a T {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            (**self).hash(state);
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl<'a, T: ?Sized + Hash> Hash for &'a mut T {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            (**self).hash(state);
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl<T> Hash for *const T {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            state.write_usize(*self as usize)
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl<T> Hash for *mut T {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            state.write_usize(*self as usize)
-        }
-    }
-
-    #[stable(feature = "rust1", since = "1.0.0")]
-    impl<'a, T, B: ?Sized> Hash for Cow<'a, T, B>
-        where B: Hash + ToOwned<T>
-    {
-        fn hash<H: Hasher>(&self, state: &mut H) {
-            Hash::hash(&**self, state)
-        }
-    }
 }
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index f0c60ffe4bf..3c58480ff0c 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -126,7 +126,6 @@ pub mod default;
 
 pub mod any;
 pub mod atomic;
-pub mod borrow;
 pub mod cell;
 pub mod char;
 pub mod panicking;
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 230deabee00..28a97b1e8db 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -358,7 +358,7 @@ impl<'a> Id<'a> {
     ///
     /// Passing an invalid string (containing spaces, brackets,
     /// quotes, ...) will return an empty `Err` value.
-    pub fn new<Name: IntoCow<'a, String, str>>(name: Name) -> Result<Id<'a>, ()> {
+    pub fn new<Name: IntoCow<'a, str>>(name: Name) -> Result<Id<'a>, ()> {
         let name = name.into_cow();
         {
             let mut chars = name.chars();
@@ -427,11 +427,11 @@ pub trait Labeller<'a,N,E> {
 }
 
 impl<'a> LabelText<'a> {
-    pub fn label<S:IntoCow<'a, String, str>>(s: S) -> LabelText<'a> {
+    pub fn label<S:IntoCow<'a, str>>(s: S) -> LabelText<'a> {
         LabelStr(s.into_cow())
     }
 
-    pub fn escaped<S:IntoCow<'a, String, str>>(s: S) -> LabelText<'a> {
+    pub fn escaped<S:IntoCow<'a, str>>(s: S) -> LabelText<'a> {
         EscStr(s.into_cow())
     }
 
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index f70c5554c6e..f6d523cda85 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -68,7 +68,7 @@ use util::nodemap::{NodeMap, NodeSet, DefIdMap, DefIdSet};
 use util::nodemap::{FnvHashMap};
 
 use arena::TypedArena;
-use std::borrow::{BorrowFrom, Cow};
+use std::borrow::{Borrow, Cow};
 use std::cell::{Cell, RefCell};
 use std::cmp;
 use std::fmt;
@@ -1001,9 +1001,9 @@ impl<'tcx> Hash for InternedTy<'tcx> {
     }
 }
 
-impl<'tcx> BorrowFrom<InternedTy<'tcx>> for sty<'tcx> {
-    fn borrow_from<'a>(ty: &'a InternedTy<'tcx>) -> &'a sty<'tcx> {
-        &ty.ty.sty
+impl<'tcx> Borrow<sty<'tcx>> for InternedTy<'tcx> {
+    fn borrow<'a>(&'a self) -> &'a sty<'tcx> {
+        &self.ty.sty
     }
 }
 
diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs
index 04f8bb0b0db..ade4f1f0533 100644
--- a/src/libstd/collections/hash/map.rs
+++ b/src/libstd/collections/hash/map.rs
@@ -14,7 +14,7 @@ use self::Entry::*;
 use self::SearchResult::*;
 use self::VacantEntryState::*;
 
-use borrow::BorrowFrom;
+use borrow::Borrow;
 use clone::Clone;
 use cmp::{max, Eq, PartialEq};
 use default::Default;
@@ -451,18 +451,18 @@ impl<K, V, S> HashMap<K, V, S>
     /// If you already have the hash for the key lying around, use
     /// search_hashed.
     fn search<'a, Q: ?Sized>(&'a self, q: &Q) -> Option<FullBucketImm<'a, K, V>>
-        where Q: BorrowFrom<K> + Eq + Hash
+        where K: Borrow<Q>, Q: Eq + Hash
     {
         let hash = self.make_hash(q);
-        search_hashed(&self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
+        search_hashed(&self.table, hash, |k| q.eq(k.borrow()))
             .into_option()
     }
 
     fn search_mut<'a, Q: ?Sized>(&'a mut self, q: &Q) -> Option<FullBucketMut<'a, K, V>>
-        where Q: BorrowFrom<K> + Eq + Hash
+        where K: Borrow<Q>, Q: Eq + Hash
     {
         let hash = self.make_hash(q);
-        search_hashed(&mut self.table, hash, |k| q.eq(BorrowFrom::borrow_from(k)))
+        search_hashed(&mut self.table, hash, |k| q.eq(k.borrow()))
             .into_option()
     }
 
@@ -1033,7 +1033,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get<Q: ?Sized>(&self, k: &Q) -> Option<&V>
-        where Q: Hash + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search(k).map(|bucket| bucket.into_refs().1)
     }
@@ -1056,7 +1056,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains_key<Q: ?Sized>(&self, k: &Q) -> bool
-        where Q: Hash + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search(k).is_some()
     }
@@ -1082,7 +1082,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn get_mut<Q: ?Sized>(&mut self, k: &Q) -> Option<&mut V>
-        where Q: Hash + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         self.search_mut(k).map(|bucket| bucket.into_mut_refs().1)
     }
@@ -1134,7 +1134,7 @@ impl<K, V, S> HashMap<K, V, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, k: &Q) -> Option<V>
-        where Q: Hash + Eq + BorrowFrom<K>
+        where K: Borrow<Q>, Q: Hash + Eq
     {
         if self.table.size() == 0 {
             return None
@@ -1236,8 +1236,8 @@ impl<K, V, S> Default for HashMap<K, V, S>
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S>
-    where K: Eq + Hash,
-          Q: Eq + Hash + BorrowFrom<K>,
+    where K: Eq + Hash + Borrow<Q>,
+          Q: Eq + Hash,
           S: HashState,
 {
     type Output = V;
@@ -1250,8 +1250,8 @@ impl<K, Q: ?Sized, V, S> Index<Q> for HashMap<K, V, S>
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<K, V, S, Q: ?Sized> IndexMut<Q> for HashMap<K, V, S>
-    where K: Eq + Hash,
-          Q: Eq + Hash + BorrowFrom<K>,
+    where K: Eq + Hash + Borrow<Q>,
+          Q: Eq + Hash,
           S: HashState,
 {
     #[inline]
diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs
index 751dc86f533..e0631a64d44 100644
--- a/src/libstd/collections/hash/set.rs
+++ b/src/libstd/collections/hash/set.rs
@@ -10,7 +10,7 @@
 //
 // ignore-lexer-test FIXME #15883
 
-use borrow::BorrowFrom;
+use borrow::Borrow;
 use clone::Clone;
 use cmp::{Eq, PartialEq};
 use core::marker::Sized;
@@ -460,7 +460,7 @@ impl<T, S> HashSet<T, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn contains<Q: ?Sized>(&self, value: &Q) -> bool
-        where Q: BorrowFrom<T> + Hash + Eq
+        where T: Borrow<Q>, Q: Hash + Eq
     {
         self.map.contains_key(value)
     }
@@ -570,7 +570,7 @@ impl<T, S> HashSet<T, S>
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn remove<Q: ?Sized>(&mut self, value: &Q) -> bool
-        where Q: BorrowFrom<T> + Hash + Eq
+        where T: Borrow<Q>, Q: Hash + Eq
     {
         self.map.remove(value).is_some()
     }
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 4e50e1c293f..feace0bd702 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -34,7 +34,7 @@
 
 use core::prelude::*;
 
-use core::borrow::{BorrowFrom, ToOwned};
+use borrow::{Borrow, ToOwned};
 use fmt::{self, Debug};
 use mem;
 use string::{String, CowString};
@@ -285,11 +285,12 @@ impl Debug for OsStr {
     }
 }
 
-impl BorrowFrom<OsString> for OsStr {
-    fn borrow_from(owned: &OsString) -> &OsStr { &owned[] }
+impl Borrow<OsStr> for OsString {
+    fn borrow(&self) -> &OsStr { &self[] }
 }
 
-impl ToOwned<OsString> for OsStr {
+impl ToOwned for OsStr {
+    type Owned = OsString;
     fn to_owned(&self) -> OsString { self.to_os_string() }
 }
 
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 7c9a8a7b4b5..fbd403ea593 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -161,7 +161,6 @@ extern crate libc;
 // NB: These reexports are in the order they should be listed in rustdoc
 
 pub use core::any;
-pub use core::borrow;
 pub use core::cell;
 pub use core::clone;
 #[cfg(not(test))] pub use core::cmp;
@@ -184,6 +183,7 @@ pub use core::error;
 #[cfg(not(test))] pub use alloc::boxed;
 pub use alloc::rc;
 
+pub use core_collections::borrow;
 pub use core_collections::fmt;
 pub use core_collections::slice;
 pub use core_collections::str;
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index 2ad07462f20..3d95d0f19d1 100755
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -108,12 +108,11 @@
 use core::prelude::*;
 
 use ascii::*;
-use borrow::BorrowFrom;
+use borrow::{Borrow, ToOwned, Cow};
 use cmp;
 use iter::{self, IntoIterator};
 use mem;
 use ops::{self, Deref};
-use string::CowString;
 use vec::Vec;
 use fmt;
 
@@ -982,12 +981,17 @@ impl ops::Deref for PathBuf {
     }
 }
 
-impl BorrowFrom<PathBuf> for Path {
-    fn borrow_from(owned: &PathBuf) -> &Path {
-        owned.deref()
+impl Borrow<Path> for PathBuf {
+    fn borrow(&self) -> &Path {
+        self.deref()
     }
 }
 
+impl ToOwned for Path {
+    type Owned = PathBuf;
+    fn to_owned(&self) -> PathBuf { self.to_path_buf() }
+}
+
 impl cmp::PartialEq for PathBuf {
     fn eq(&self, other: &PathBuf) -> bool {
         self.components() == other.components()
@@ -1066,10 +1070,10 @@ impl Path {
         self.inner.to_str()
     }
 
-    /// Convert a `Path` to a `CowString`.
+    /// Convert a `Path` to a `Cow<str>`.
     ///
     /// Any non-Unicode sequences are replaced with U+FFFD REPLACEMENT CHARACTER.
-    pub fn to_string_lossy(&self) -> CowString {
+    pub fn to_string_lossy(&self) -> Cow<str> {
         self.inner.to_string_lossy()
     }
 
diff --git a/src/libsyntax/util/interner.rs b/src/libsyntax/util/interner.rs
index 58b5c44c960..2e8f43be120 100644
--- a/src/libsyntax/util/interner.rs
+++ b/src/libsyntax/util/interner.rs
@@ -14,7 +14,7 @@
 
 use ast::Name;
 
-use std::borrow::BorrowFrom;
+use std::borrow::Borrow;
 use std::cell::RefCell;
 use std::cmp::Ordering;
 use std::collections::HashMap;
@@ -80,7 +80,7 @@ impl<T: Eq + Hash<Hasher> + Clone + 'static> Interner<T> {
     }
 
     pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
-    where Q: BorrowFrom<T> + Eq + Hash<Hasher> {
+    where T: Borrow<Q>, Q: Eq + Hash<Hasher> {
         let map = self.map.borrow();
         match (*map).get(val) {
             Some(v) => Some(*v),
@@ -193,9 +193,9 @@ impl fmt::Display for RcStr {
     }
 }
 
-impl BorrowFrom<RcStr> for str {
-    fn borrow_from(owned: &RcStr) -> &str {
-        &owned.string[]
+impl Borrow<str> for RcStr {
+    fn borrow(&self) -> &str {
+        &self.string[]
     }
 }
 
@@ -277,7 +277,7 @@ impl StrInterner {
 
     #[cfg(stage0)]
     pub fn find<Q: ?Sized>(&self, val: &Q) -> Option<Name>
-    where Q: BorrowFrom<RcStr> + Eq + Hash<Hasher> {
+    where RcStr: Borrow<Q>, Q: Eq + Hash<Hasher> {
         match (*self.map.borrow()).get(val) {
             Some(v) => Some(*v),
             None => None,
diff --git a/src/test/compile-fail/ufcs-qpath-missing-params.rs b/src/test/compile-fail/ufcs-qpath-missing-params.rs
index 5fa66eb98e1..f4e18265fd9 100644
--- a/src/test/compile-fail/ufcs-qpath-missing-params.rs
+++ b/src/test/compile-fail/ufcs-qpath-missing-params.rs
@@ -12,6 +12,5 @@ use std::borrow::IntoCow;
 
 fn main() {
     <String as IntoCow>::into_cow("foo".to_string());
-    //~^ ERROR wrong number of type arguments: expected 2, found 0
+    //~^ ERROR wrong number of type arguments: expected 1, found 0
 }
-
diff --git a/src/test/run-make/save-analysis/foo.rs b/src/test/run-make/save-analysis/foo.rs
index db70a245232..fbbecfbf2a6 100644
--- a/src/test/run-make/save-analysis/foo.rs
+++ b/src/test/run-make/save-analysis/foo.rs
@@ -34,7 +34,7 @@ use std::mem::size_of;
 static uni: &'static str = "Les Miséééééééérables";
 static yy: usize = 25;
 
-static bob: Option<std::vec::CowVec<'static, isize>> = None;
+static bob: Option<std::borrow::Cow<'static, [isize]>> = None;
 
 // buglink test - see issue #1337.
 
diff --git a/src/test/run-pass/const-polymorphic-paths.rs b/src/test/run-pass/const-polymorphic-paths.rs
index e9d10536b75..dce12030f79 100644
--- a/src/test/run-pass/const-polymorphic-paths.rs
+++ b/src/test/run-pass/const-polymorphic-paths.rs
@@ -100,8 +100,8 @@ tests! {
     Add::add, fn(i32, i32) -> i32, (5, 6);
     <i32 as Add<_>>::add, fn(i32, i32) -> i32, (5, 6);
     <i32 as Add<i32>>::add, fn(i32, i32) -> i32, (5, 6);
-    <String as IntoCow<_, _>>::into_cow, fn(String) -> Cow<'static, String, str>,
+    <String as IntoCow<_>>::into_cow, fn(String) -> Cow<'static, str>,
         ("foo".to_string());
-    <String as IntoCow<'static, _, _>>::into_cow, fn(String) -> Cow<'static, String, str>,
+    <String as IntoCow<'static, _>>::into_cow, fn(String) -> Cow<'static, str>,
         ("foo".to_string());
 }
diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs
index c58654670d1..33e4fa85bcb 100644
--- a/src/test/run-pass/send_str_hashmap.rs
+++ b/src/test/run-pass/send_str_hashmap.rs
@@ -13,7 +13,7 @@ extern crate collections;
 use std::collections::HashMap;
 use std::borrow::{Cow, IntoCow};
 
-type SendStr = Cow<'static, String, str>;
+type SendStr = Cow<'static, str>;
 
 pub fn main() {
     let mut map: HashMap<SendStr, uint> = HashMap::new();
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index 438724a2b06..3390369242d 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -13,7 +13,7 @@ extern crate collections;
 use self::collections::BTreeMap;
 use std::borrow::{Cow, IntoCow};
 
-type SendStr = Cow<'static, String, str>;
+type SendStr = Cow<'static, str>;
 
 pub fn main() {
     let mut map: BTreeMap<SendStr, uint> = BTreeMap::new();
diff --git a/src/test/run-pass/traits-issue-22019.rs b/src/test/run-pass/traits-issue-22019.rs
index 5d3195e1937..7e0f60d55a8 100644
--- a/src/test/run-pass/traits-issue-22019.rs
+++ b/src/test/run-pass/traits-issue-22019.rs
@@ -23,18 +23,18 @@ pub type Node<'a> = &'a CFGNode;
 
 pub trait GraphWalk<'c, N> {
     /// Returns all the nodes in this graph.
-    fn nodes(&'c self) where [N]:ToOwned<Vec<N>>;
+    fn nodes(&'c self) where [N]:ToOwned<Owned=Vec<N>>;
 }
 
 impl<'g> GraphWalk<'g, Node<'g>> for u32
 {
-    fn nodes(&'g self) where [Node<'g>]:ToOwned<Vec<Node<'g>>>
+    fn nodes(&'g self) where [Node<'g>]:ToOwned<Owned=Vec<Node<'g>>>
     { loop { } }
 }
 
 impl<'h> GraphWalk<'h, Node<'h>> for u64
 {
-    fn nodes(&'h self) where [Node<'h>]:ToOwned<Vec<Node<'h>>>
+    fn nodes(&'h self) where [Node<'h>]:ToOwned<Owned=Vec<Node<'h>>>
     { loop { } }
 }