From bd9c18125fb4c4e7b33408edb22dadf9ee73c449 Mon Sep 17 00:00:00 2001
From: gamazeps <gamaz3ps@gmail.com>
Date: Thu, 30 Oct 2014 19:00:47 +0100
Subject: [PATCH 01/15] Doc: Clears up trim_char doc

Closes #18451
---
 src/libcore/str.rs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index e8cd93ba7dc42..d42d2006cff5c 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -1535,7 +1535,7 @@ pub trait StrSlice<'a> {
     /// ```
     fn ends_with(&self, needle: &str) -> bool;
 
-    /// Returns a string with characters that match `to_trim` removed.
+    /// Returns a string with characters that match `to_trim` removed from the left and the right.
     ///
     /// # Arguments
     ///

From 696f72e84e8420933270be5cde3735b372cee8c5 Mon Sep 17 00:00:00 2001
From: Jakub Bukaj <jakub@jakub.cc>
Date: Thu, 30 Oct 2014 23:44:42 +0100
Subject: [PATCH 02/15] Add a `repeat` function to the prelude

Implements a part of RFC 235.

[breaking-change]
---
 src/libcore/iter.rs     | 7 ++++++-
 src/libcore/prelude.rs  | 2 +-
 src/libcoretest/iter.rs | 8 ++++++++
 src/libstd/prelude.rs   | 2 +-
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/src/libcore/iter.rs b/src/libcore/iter.rs
index e2a4fdfe79bf1..39b319e6ac867 100644
--- a/src/libcore/iter.rs
+++ b/src/libcore/iter.rs
@@ -2155,7 +2155,7 @@ type IterateState<'a, T> = (|T|: 'a -> T, Option<T>, bool);
 /// from a given seed value.
 pub type Iterate<'a, T> = Unfold<'a, T, IterateState<'a, T>>;
 
-/// Creates a new iterator that produces an infinite sequence of
+/// Create a new iterator that produces an infinite sequence of
 /// repeated applications of the given function `f`.
 pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
     Unfold::new((f, Some(seed), true), |st| {
@@ -2174,6 +2174,11 @@ pub fn iterate<'a, T: Clone>(seed: T, f: |T|: 'a -> T) -> Iterate<'a, T> {
     })
 }
 
+/// Create a new iterator that endlessly repeats the element `elt`.
+pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
+    Repeat::new(elt)
+}
+
 /// Functions for lexicographical ordering of sequences.
 ///
 /// Lexicographical ordering through `<`, `<=`, `>=`, `>` requires
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index 680f91945d103..543a1560747b9 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -41,7 +41,7 @@ pub use option::{Option, Some, None};
 pub use result::{Result, Ok, Err};
 
 // Reexported functions
-pub use iter::range;
+pub use iter::{range, repeat};
 pub use mem::drop;
 
 // Reexported types and traits
diff --git a/src/libcoretest/iter.rs b/src/libcoretest/iter.rs
index 98db377b0d576..5d333d48e96d4 100644
--- a/src/libcoretest/iter.rs
+++ b/src/libcoretest/iter.rs
@@ -846,6 +846,14 @@ fn test_iterate() {
     assert_eq!(it.next(), Some(8u));
 }
 
+#[test]
+fn test_repeat() {
+    let mut it = repeat(42u);
+    assert_eq!(it.next(), Some(42u));
+    assert_eq!(it.next(), Some(42u));
+    assert_eq!(it.next(), Some(42u));
+}
+
 #[bench]
 fn bench_rposition(b: &mut Bencher) {
     let it: Vec<uint> = range(0u, 300).collect();
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index db9f3114cda14..f9217e89cdd71 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -53,7 +53,7 @@
 
 // Reexported functions
 #[doc(no_inline)] pub use from_str::from_str;
-#[doc(no_inline)] pub use iter::range;
+#[doc(no_inline)] pub use iter::{range, repeat};
 #[doc(no_inline)] pub use mem::drop;
 
 // Reexported types and traits

From e23f5c8e2630fc9df7e54911eae0746edccd30aa Mon Sep 17 00:00:00 2001
From: Vadim Chugunov <vadimcn@gmail.com>
Date: Thu, 30 Oct 2014 17:26:07 -0700
Subject: [PATCH 03/15] Really fix #17982 this time.

---
 src/libterm/win.rs | 9 ++-------
 1 file changed, 2 insertions(+), 7 deletions(-)

diff --git a/src/libterm/win.rs b/src/libterm/win.rs
index 7ce6fb658b56d..9a67ee8836bae 100644
--- a/src/libterm/win.rs
+++ b/src/libterm/win.rs
@@ -71,8 +71,7 @@ fn color_to_bits(color: color::Color) -> u16 {
 }
 
 fn bits_to_color(bits: u16) -> color::Color {
-    let bits = bits & 0x7;
-    let color = match bits {
+    let color = match bits & 0x7 {
         0 => color::BLACK,
         0x1 => color::BLUE,
         0x2 => color::GREEN,
@@ -84,11 +83,7 @@ fn bits_to_color(bits: u16) -> color::Color {
         _ => unreachable!()
     };
 
-    if bits >= 8 {
-        color | 0x8
-    } else {
-        color
-    }
+    color | (bits & 0x8) // copy the hi-intensity bit
 }
 
 impl<T: Writer+Send> WinConsole<T> {

From 8e6e846d8a26e5a9d3aafd0bdcc18ed3ddf0cbca Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Mon, 20 Oct 2014 23:04:16 -0700
Subject: [PATCH 04/15] rustc: Implement -l and include! tweaks

This is an implementation of the rustc bits of [RFC 403][rfc]. This adds a new
flag to the compiler, `-l`, as well as tweaking the `include!` macro (and
related source-centric macros).

The compiler's new `-l` flag is used to link libraries in from the command line.
This flag stacks with `#[link]` directives already found in the program. The
purpose of this flag, also stated in the RFC, is to ease linking against native
libraries which have wildly different requirements across platforms and even
within distributions of one platform. This flag accepts a string of the form
`NAME[:KIND]` where `KIND` is optional or one of dylib, static, or framework.
This is roughly equivalent to if the equivalent `#[link]` directive were just
written in the program.

The `include!` macro has been modified to recursively expand macros to allow
usage of `concat!` as an argument, for example. The use case spelled out in RFC
403 was for `env!` to be used as well to include compile-time generated files.
The macro also received a bit of tweaking to allow it to expand to either an
expression or a series of items, depending on what context it's used in.

[rfc]: https://github.com/rust-lang/rfcs/pull/403
---
 src/librustc/driver/config.rs                 | 27 +++++++++-
 src/librustc/metadata/creader.rs              | 50 ++++++++++++-------
 src/librustc/metadata/cstore.rs               |  2 +-
 src/libsyntax/ext/base.rs                     | 23 +++------
 src/libsyntax/ext/source_util.rs              | 35 ++++++++++---
 .../auxiliary/macro-include-items-expr.rs     | 13 +++++
 .../auxiliary/macro-include-items-item.rs     | 13 +++++
 src/test/compile-fail/manual-link-bad-form.rs | 17 +++++++
 src/test/compile-fail/manual-link-bad-kind.rs | 16 ++++++
 .../compile-fail/manual-link-framework.rs     | 17 +++++++
 src/test/run-make/manual-link/Makefile        |  7 +++
 src/test/run-make/manual-link/bar.c           |  1 +
 src/test/run-make/manual-link/foo.c           |  1 +
 src/test/run-make/manual-link/foo.rs          | 19 +++++++
 src/test/run-make/manual-link/main.rs         | 15 ++++++
 src/test/run-pass/macro-include-items.rs      | 18 +++++++
 16 files changed, 234 insertions(+), 40 deletions(-)
 create mode 100644 src/test/auxiliary/macro-include-items-expr.rs
 create mode 100644 src/test/auxiliary/macro-include-items-item.rs
 create mode 100644 src/test/compile-fail/manual-link-bad-form.rs
 create mode 100644 src/test/compile-fail/manual-link-bad-kind.rs
 create mode 100644 src/test/compile-fail/manual-link-framework.rs
 create mode 100644 src/test/run-make/manual-link/Makefile
 create mode 100644 src/test/run-make/manual-link/bar.c
 create mode 100644 src/test/run-make/manual-link/foo.c
 create mode 100644 src/test/run-make/manual-link/foo.rs
 create mode 100644 src/test/run-make/manual-link/main.rs
 create mode 100644 src/test/run-pass/macro-include-items.rs

diff --git a/src/librustc/driver/config.rs b/src/librustc/driver/config.rs
index 43687a31453d0..b07b58e56b5d5 100644
--- a/src/librustc/driver/config.rs
+++ b/src/librustc/driver/config.rs
@@ -20,6 +20,7 @@ use back::write;
 use back::target_strs;
 use back::{arm, x86, x86_64, mips, mipsel};
 use lint;
+use metadata::cstore;
 
 use syntax::abi;
 use syntax::ast;
@@ -78,6 +79,7 @@ pub struct Options {
     // parsed code. It remains mutable in case its replacements wants to use
     // this.
     pub addl_lib_search_paths: RefCell<Vec<Path>>,
+    pub libs: Vec<(String, cstore::NativeLibaryKind)>,
     pub maybe_sysroot: Option<Path>,
     pub target_triple: String,
     // User-specified cfg meta items. The compiler itself will add additional
@@ -130,6 +132,7 @@ pub fn basic_options() -> Options {
         externs: HashMap::new(),
         crate_name: None,
         alt_std_name: None,
+        libs: Vec::new(),
     }
 }
 
@@ -575,6 +578,10 @@ pub fn optgroups() -> Vec<getopts::OptGroup> {
         optflag("h", "help", "Display this message"),
         optmulti("", "cfg", "Configure the compilation environment", "SPEC"),
         optmulti("L", "",   "Add a directory to the library search path", "PATH"),
+        optmulti("l", "",   "Link the generated crate(s) to the specified native
+                             library NAME. The optional KIND can be one of,
+                             static, dylib, or framework. If omitted, dylib is
+                             assumed.", "NAME[:KIND]"),
         optmulti("", "crate-type", "Comma separated list of types of crates
                                     for the compiler to emit",
                  "[bin|lib|rlib|dylib|staticlib]"),
@@ -767,6 +774,23 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         Path::new(s.as_slice())
     }).collect();
 
+    let libs = matches.opt_strs("l").into_iter().map(|s| {
+        let mut parts = s.as_slice().rsplitn(1, ':');
+        let kind = parts.next().unwrap();
+        let (name, kind) = match (parts.next(), kind) {
+            (None, name) |
+            (Some(name), "dylib") => (name, cstore::NativeUnknown),
+            (Some(name), "framework") => (name, cstore::NativeFramework),
+            (Some(name), "static") => (name, cstore::NativeStatic),
+            (_, s) => {
+                early_error(format!("unknown library kind `{}`, expected \
+                                     one of dylib, framework, or static",
+                                    s).as_slice());
+            }
+        };
+        (name.to_string(), kind)
+    }).collect();
+
     let cfg = parse_cfgspecs(matches.opt_strs("cfg"));
     let test = matches.opt_present("test");
     let write_dependency_info = (matches.opt_present("dep-info"),
@@ -843,7 +867,8 @@ pub fn build_session_options(matches: &getopts::Matches) -> Options {
         color: color,
         externs: externs,
         crate_name: crate_name,
-        alt_std_name: None
+        alt_std_name: None,
+        libs: libs,
     }
 }
 
diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs
index 43d0156d72770..100ccf78f3e81 100644
--- a/src/librustc/metadata/creader.rs
+++ b/src/librustc/metadata/creader.rs
@@ -52,7 +52,11 @@ pub fn read_crates(sess: &Session,
     visit_crate(&e, krate);
     visit::walk_crate(&mut e, krate);
     dump_crates(&sess.cstore);
-    warn_if_multiple_versions(sess.diagnostic(), &sess.cstore)
+    warn_if_multiple_versions(sess.diagnostic(), &sess.cstore);
+
+    for &(ref name, kind) in sess.opts.libs.iter() {
+        register_native_lib(sess, None, name.clone(), kind);
+    }
 }
 
 impl<'a, 'v> visit::Visitor<'v> for Env<'a> {
@@ -233,14 +237,7 @@ fn visit_item(e: &Env, i: &ast::Item) {
                             Some(k) => {
                                 if k.equiv(&("static")) {
                                     cstore::NativeStatic
-                                } else if (e.sess.targ_cfg.os == abi::OsMacos ||
-                                           e.sess.targ_cfg.os == abi::OsiOS) &&
-                                          k.equiv(&("framework")) {
-                                    cstore::NativeFramework
                                 } else if k.equiv(&("framework")) {
-                                    e.sess.span_err(m.span,
-                                        "native frameworks are only available \
-                                         on OSX targets");
                                     cstore::NativeUnknown
                                 } else {
                                     e.sess.span_err(m.span,
@@ -263,15 +260,8 @@ fn visit_item(e: &Env, i: &ast::Item) {
                                 InternedString::new("foo")
                             }
                         };
-                        if n.get().is_empty() {
-                            e.sess.span_err(m.span,
-                                            "#[link(name = \"\")] given with \
-                                             empty name");
-                        } else {
-                            e.sess
-                             .cstore
-                             .add_used_library(n.get().to_string(), kind);
-                        }
+                        register_native_lib(e.sess, Some(m.span),
+                                            n.get().to_string(), kind);
                     }
                     None => {}
                 }
@@ -281,6 +271,32 @@ fn visit_item(e: &Env, i: &ast::Item) {
     }
 }
 
+fn register_native_lib(sess: &Session, span: Option<Span>, name: String,
+                       kind: cstore::NativeLibaryKind) {
+    if name.as_slice().is_empty() {
+        match span {
+            Some(span) => {
+                sess.span_err(span, "#[link(name = \"\")] given with \
+                                     empty name");
+            }
+            None => {
+                sess.err("empty library name given via `-l`");
+            }
+        }
+        return
+    }
+    let is_osx = sess.targ_cfg.os == abi::OsMacos ||
+                 sess.targ_cfg.os == abi::OsiOS;
+    if kind == cstore::NativeFramework && !is_osx {
+        let msg = "native frameworks are only available on OSX targets";
+        match span {
+            Some(span) => sess.span_err(span, msg),
+            None => sess.err(msg),
+        }
+    }
+    sess.cstore.add_used_library(name, kind);
+}
+
 fn existing_match(e: &Env, name: &str,
                   hash: Option<&Svh>) -> Option<ast::CrateNum> {
     let mut ret = None;
diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs
index 1d1012d9e4f04..e8c5f6f4910e0 100644
--- a/src/librustc/metadata/cstore.rs
+++ b/src/librustc/metadata/cstore.rs
@@ -50,7 +50,7 @@ pub enum LinkagePreference {
     RequireStatic,
 }
 
-#[deriving(PartialEq, FromPrimitive)]
+#[deriving(PartialEq, FromPrimitive, Clone)]
 pub enum NativeLibaryKind {
     NativeStatic,    // native static library (.a archive)
     NativeFramework, // OSX-specific
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index a8326e79ef368..d474cc8cf0a3e 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -675,26 +675,19 @@ pub fn check_zero_tts(cx: &ExtCtxt,
 
 /// Extract the string literal from the first token of `tts`. If this
 /// is not a string literal, emit an error and return None.
-pub fn get_single_str_from_tts(cx: &ExtCtxt,
+pub fn get_single_str_from_tts(cx: &mut ExtCtxt,
                                sp: Span,
                                tts: &[ast::TokenTree],
                                name: &str)
                                -> Option<String> {
-    if tts.len() != 1 {
-        cx.span_err(sp, format!("{} takes 1 argument.", name).as_slice());
-    } else {
-        match tts[0] {
-            ast::TtToken(_, token::LitStr(ident)) => return Some(parse::str_lit(ident.as_str())),
-            ast::TtToken(_, token::LitStrRaw(ident, _)) => {
-                return Some(parse::raw_str_lit(ident.as_str()))
-            }
-            _ => {
-                cx.span_err(sp,
-                            format!("{} requires a string.", name).as_slice())
-            }
-        }
+    let mut p = cx.new_parser_from_tts(tts);
+    let ret = cx.expander().fold_expr(p.parse_expr());
+    if p.token != token::Eof {
+        cx.span_err(sp, format!("{} takes 1 argument", name).as_slice());
     }
-    None
+    expr_to_string(cx, ret, "argument must be a string literal").map(|(s, _)| {
+        s.get().to_string()
+    })
 }
 
 /// Extract comma-separated expressions from `tts`. If there is a
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 41967b0680cff..f192308440998 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -9,14 +9,16 @@
 // except according to those terms.
 
 use ast;
-use codemap;
 use codemap::{Pos, Span};
+use codemap;
 use ext::base::*;
 use ext::base;
 use ext::build::AstBuilder;
-use parse;
 use parse::token;
+use parse;
 use print::pprust;
+use ptr::P;
+use util::small_vector::SmallVector;
 
 use std::io::File;
 use std::rc::Rc;
@@ -82,14 +84,14 @@ pub fn expand_mod(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
 /// include! : parse the given file as an expr
 /// This is generally a bad idea because it's going to behave
 /// unhygienically.
-pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
-                      -> Box<base::MacResult+'static> {
+pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
+                           -> Box<base::MacResult+'cx> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
         Some(f) => f,
         None => return DummyResult::expr(sp),
     };
     // The file will be added to the code map by the parser
-    let mut p =
+    let p =
         parse::new_sub_parser_from_file(cx.parse_sess(),
                                         cx.cfg(),
                                         &res_rel_file(cx,
@@ -98,7 +100,28 @@ pub fn expand_include(cx: &mut ExtCtxt, sp: Span, tts: &[ast::TokenTree])
                                         true,
                                         None,
                                         sp);
-    base::MacExpr::new(p.parse_expr())
+
+    struct ExpandResult<'a> {
+        p: parse::parser::Parser<'a>,
+    }
+    impl<'a> base::MacResult for ExpandResult<'a> {
+        fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
+            Some(self.p.parse_expr())
+        }
+        fn make_items(mut self: Box<ExpandResult<'a>>)
+                      -> Option<SmallVector<P<ast::Item>>> {
+            let mut ret = SmallVector::zero();
+            loop {
+                match self.p.parse_item_with_outer_attributes() {
+                    Some(item) => ret.push(item),
+                    None => break
+                }
+            }
+            Some(ret)
+        }
+    }
+
+    box ExpandResult { p: p }
 }
 
 // include_str! : read the given file, insert it as a literal string expr
diff --git a/src/test/auxiliary/macro-include-items-expr.rs b/src/test/auxiliary/macro-include-items-expr.rs
new file mode 100644
index 0000000000000..aea3c749930b6
--- /dev/null
+++ b/src/test/auxiliary/macro-include-items-expr.rs
@@ -0,0 +1,13 @@
+// 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.
+
+// ignore-test: this is not a test
+
+1
diff --git a/src/test/auxiliary/macro-include-items-item.rs b/src/test/auxiliary/macro-include-items-item.rs
new file mode 100644
index 0000000000000..da72aaef80591
--- /dev/null
+++ b/src/test/auxiliary/macro-include-items-item.rs
@@ -0,0 +1,13 @@
+// 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.
+
+// ignore-test: this is not a test
+
+fn foo() { bar() }
diff --git a/src/test/compile-fail/manual-link-bad-form.rs b/src/test/compile-fail/manual-link-bad-form.rs
new file mode 100644
index 0000000000000..bd2a3eba0b5b8
--- /dev/null
+++ b/src/test/compile-fail/manual-link-bad-form.rs
@@ -0,0 +1,17 @@
+// 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.
+
+// compile-flags:-l :static
+// error-pattern: empty library name given via `-l`
+
+fn main() {
+}
+
+
diff --git a/src/test/compile-fail/manual-link-bad-kind.rs b/src/test/compile-fail/manual-link-bad-kind.rs
new file mode 100644
index 0000000000000..4614440ddafd5
--- /dev/null
+++ b/src/test/compile-fail/manual-link-bad-kind.rs
@@ -0,0 +1,16 @@
+// 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.
+
+// compile-flags:-l foo:bar
+// error-pattern: unknown library kind `bar`, expected one of dylib, framework, or static
+
+fn main() {
+}
+
diff --git a/src/test/compile-fail/manual-link-framework.rs b/src/test/compile-fail/manual-link-framework.rs
new file mode 100644
index 0000000000000..96cc35049ee40
--- /dev/null
+++ b/src/test/compile-fail/manual-link-framework.rs
@@ -0,0 +1,17 @@
+// 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.
+
+// ignore-macos
+// ignore-ios
+// compile-flags:-l foo:framework
+// error-pattern: native frameworks are only available on OSX targets
+
+fn main() {
+}
diff --git a/src/test/run-make/manual-link/Makefile b/src/test/run-make/manual-link/Makefile
new file mode 100644
index 0000000000000..d2a02adc9d4a4
--- /dev/null
+++ b/src/test/run-make/manual-link/Makefile
@@ -0,0 +1,7 @@
+-include ../tools.mk
+
+all: $(TMPDIR)/libbar.a
+	$(RUSTC) foo.rs -lbar:static
+	$(RUSTC) main.rs
+	$(call RUN,main)
+
diff --git a/src/test/run-make/manual-link/bar.c b/src/test/run-make/manual-link/bar.c
new file mode 100644
index 0000000000000..e42599986781f
--- /dev/null
+++ b/src/test/run-make/manual-link/bar.c
@@ -0,0 +1 @@
+void bar() {}
diff --git a/src/test/run-make/manual-link/foo.c b/src/test/run-make/manual-link/foo.c
new file mode 100644
index 0000000000000..e42599986781f
--- /dev/null
+++ b/src/test/run-make/manual-link/foo.c
@@ -0,0 +1 @@
+void bar() {}
diff --git a/src/test/run-make/manual-link/foo.rs b/src/test/run-make/manual-link/foo.rs
new file mode 100644
index 0000000000000..d67a4057afbfc
--- /dev/null
+++ b/src/test/run-make/manual-link/foo.rs
@@ -0,0 +1,19 @@
+// 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.
+
+#![crate_type = "rlib"]
+
+extern {
+    fn bar();
+}
+
+pub fn foo() {
+    unsafe { bar(); }
+}
diff --git a/src/test/run-make/manual-link/main.rs b/src/test/run-make/manual-link/main.rs
new file mode 100644
index 0000000000000..756a47f386ae3
--- /dev/null
+++ b/src/test/run-make/manual-link/main.rs
@@ -0,0 +1,15 @@
+// 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.
+
+extern crate foo;
+
+fn main() {
+    foo::foo();
+}
diff --git a/src/test/run-pass/macro-include-items.rs b/src/test/run-pass/macro-include-items.rs
new file mode 100644
index 0000000000000..03eec668edde8
--- /dev/null
+++ b/src/test/run-pass/macro-include-items.rs
@@ -0,0 +1,18 @@
+// 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.
+
+fn bar() {}
+
+include!(concat!("", "", "../auxiliary/", "macro-include-items-item.rs"))
+
+fn main() {
+    foo();
+    assert_eq!(include!(concat!("", "../auxiliary/", "macro-include-items-expr.rs")), 1u);
+}

From 8c1d2ab633aa606f802e0a4d8ff51a0a04f724ea Mon Sep 17 00:00:00 2001
From: Steven Fackler <sfackler@gmail.com>
Date: Sat, 18 Oct 2014 23:46:08 -0700
Subject: [PATCH 05/15] Local crate half of enum namespacing

---
 src/librustc/middle/resolve.rs                | 28 +++++++++++++++++++
 .../enum-and-module-in-same-scope.rs          |  2 +-
 2 files changed, 29 insertions(+), 1 deletion(-)

diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 383a60e51da7b..45e0ff76b6fc5 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -492,6 +492,7 @@ enum ModuleKind {
     NormalModuleKind,
     TraitModuleKind,
     ImplModuleKind,
+    EnumModuleKind,
     AnonymousModuleKind,
 }
 
@@ -1282,7 +1283,25 @@ impl<'a> Resolver<'a> {
                 name_bindings.define_type
                     (DefTy(local_def(item.id), true), sp, is_public);
 
+                let parent_link = self.get_parent_link(parent.clone(), ident);
+                // We want to make sure the module type is EnumModuleKind
+                // even if there's already an ImplModuleKind module defined,
+                // since that's how we prevent duplicate enum definitions
+                name_bindings.set_module_kind(parent_link,
+                                              Some(local_def(item.id)),
+                                              EnumModuleKind,
+                                              false,
+                                              is_public,
+                                              sp);
+
                 for variant in (*enum_definition).variants.iter() {
+                    self.build_reduced_graph_for_variant(
+                        &**variant,
+                        local_def(item.id),
+                        ModuleReducedGraphParent(name_bindings.get_module()),
+                        is_public);
+
+                    // Temporary staging hack
                     self.build_reduced_graph_for_variant(
                         &**variant,
                         local_def(item.id),
@@ -1347,6 +1366,12 @@ impl<'a> Resolver<'a> {
                                                 ImplModuleKind => {
                                 ModuleReducedGraphParent(child.get_module())
                             }
+                            Some(ref child) if child.get_module_if_available()
+                                                .is_some() &&
+                                           child.get_module().kind.get() ==
+                                                EnumModuleKind => {
+                                ModuleReducedGraphParent(child.get_module())
+                            }
                             // Create the module
                             _ => {
                                 let name_bindings =
@@ -3400,6 +3425,7 @@ impl<'a> Resolver<'a> {
                         }
                         TraitModuleKind |
                         ImplModuleKind |
+                        EnumModuleKind |
                         AnonymousModuleKind => {
                             search_module = parent_module_node.upgrade().unwrap();
                         }
@@ -3497,6 +3523,7 @@ impl<'a> Resolver<'a> {
                         NormalModuleKind => return Some(new_module),
                         TraitModuleKind |
                         ImplModuleKind |
+                        EnumModuleKind |
                         AnonymousModuleKind => module_ = new_module,
                     }
                 }
@@ -3512,6 +3539,7 @@ impl<'a> Resolver<'a> {
             NormalModuleKind => return module_,
             TraitModuleKind |
             ImplModuleKind |
+            EnumModuleKind |
             AnonymousModuleKind => {
                 match self.get_nearest_normal_module_parent(module_.clone()) {
                     None => module_,
diff --git a/src/test/compile-fail/enum-and-module-in-same-scope.rs b/src/test/compile-fail/enum-and-module-in-same-scope.rs
index 7464764666cd9..7526c6753e632 100644
--- a/src/test/compile-fail/enum-and-module-in-same-scope.rs
+++ b/src/test/compile-fail/enum-and-module-in-same-scope.rs
@@ -13,7 +13,7 @@ mod Foo {
 }
 
 enum Foo {  //~ ERROR duplicate definition of type or module `Foo`
-    X
+    X //~ ERROR duplicate definition of value `X`
 }
 
 fn main() {}

From 8612455b6493ba28c710c8b2507558625e989fc2 Mon Sep 17 00:00:00 2001
From: Steven Fackler <sfackler@gmail.com>
Date: Sun, 19 Oct 2014 10:49:24 -0700
Subject: [PATCH 06/15] Fix cross-crate enum namespacing

---
 src/librustc/metadata/csearch.rs |  7 +++++++
 src/librustc/metadata/decoder.rs | 18 ++++++++++++++++++
 src/librustc/middle/resolve.rs   | 31 +++++++++++++++++++++++++++++++
 3 files changed, 56 insertions(+)

diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index 507aaf137cdf5..ccdc0b2ba23d5 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -15,6 +15,7 @@
 use metadata::common::*;
 use metadata::cstore;
 use metadata::decoder;
+use middle::def;
 use middle::lang_items;
 use middle::resolve;
 use middle::ty;
@@ -115,6 +116,12 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId,
     decoder::maybe_get_item_ast(&*cdata, tcx, def.node, decode_inlined_item)
 }
 
+pub fn get_enum_variant_defs(cstore: &cstore::CStore, enum_id: ast::DefId)
+                             -> Vec<(def::Def, ast::Ident, ast::Visibility)> {
+    let cdata = cstore.get_crate_data(enum_id.krate);
+    decoder::get_enum_variant_defs(&*cstore.intr, &*cdata, enum_id.node)
+}
+
 pub fn get_enum_variants(tcx: &ty::ctxt, def: ast::DefId)
                       -> Vec<Rc<ty::VariantInfo>> {
     let cstore = &tcx.sess.cstore;
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index e126449b2481e..f773f5092e35d 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -662,6 +662,24 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
     }
 }
 
+pub fn get_enum_variant_defs(intr: &IdentInterner,
+                             cdata: Cmd,
+                             id: ast::NodeId)
+                             -> Vec<(def::Def, ast::Ident, ast::Visibility)> {
+    let data = cdata.data();
+    let items = reader::get_doc(rbml::Doc::new(data), tag_items);
+    let item = find_item(id, items);
+    enum_variant_ids(item, cdata).iter().map(|did| {
+        let item = find_item(did.node, items);
+        let name = item_name(intr, item);
+        let visibility = item_visibility(item);
+        match item_to_def_like(item, *did, cdata.cnum) {
+            DlDef(def @ def::DefVariant(..)) => (def, name, visibility),
+            _ => unreachable!()
+        }
+    }).collect()
+}
+
 pub fn get_enum_variants(intr: Rc<IdentInterner>, cdata: Cmd, id: ast::NodeId,
                      tcx: &ty::ctxt) -> Vec<Rc<ty::VariantInfo>> {
     let data = cdata.data();
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 45e0ff76b6fc5..e54fe92f5e7e6 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1806,6 +1806,7 @@ impl<'a> Resolver<'a> {
         }
 
         let kind = match def {
+            DefTy(_, true) => EnumModuleKind,
             DefStruct(..) | DefTy(..) => ImplModuleKind,
             _ => NormalModuleKind
         };
@@ -1840,6 +1841,7 @@ impl<'a> Resolver<'a> {
 
         match def {
           DefMod(_) | DefForeignMod(_) => {}
+          // Still here for staging
           DefVariant(enum_did, variant_id, is_struct) => {
             debug!("(building reduced graph for external crate) building \
                     variant {}",
@@ -1905,6 +1907,35 @@ impl<'a> Resolver<'a> {
                                                   is_public,
                                                   DUMMY_SP)
           }
+          DefTy(def_id, true) => { // enums
+              debug!("(building reduced graph for external crate) building enum {}", final_ident);
+              child_name_bindings.define_type(def, DUMMY_SP, is_public);
+              let enum_module = ModuleReducedGraphParent(child_name_bindings.get_module());
+
+              let variants = csearch::get_enum_variant_defs(&self.session.cstore, def_id);
+              for &(v_def, name, vis) in variants.iter() {
+                  let (variant_id, is_struct) = match v_def {
+                      DefVariant(_, variant_id, is_struct) => (variant_id, is_struct),
+                      _ => unreachable!()
+                  };
+                  let child = self.add_child(name, enum_module.clone(),
+                                             OverwriteDuplicates,
+                                             DUMMY_SP);
+
+                  // If this variant is public, then it was publicly reexported,
+                  // otherwise we need to inherit the visibility of the enum
+                  // definition.
+                  let variant_exported = vis == ast::Public || is_exported;
+                  if is_struct {
+                      child.define_type(v_def, DUMMY_SP, variant_exported);
+                      // Not adding fields for variants as they are not accessed with a self receiver
+                      self.structs.insert(variant_id, Vec::new());
+                  } else {
+                      child.define_value(v_def, DUMMY_SP, variant_exported);
+                  }
+              }
+
+          }
           DefTy(..) | DefAssociatedTy(..) => {
               debug!("(building reduced graph for external \
                       crate) building type {}", final_ident);

From a1d713df9c1f3cd6d61a769c5a2f140d7b7b7124 Mon Sep 17 00:00:00 2001
From: Steven Fackler <sfackler@gmail.com>
Date: Tue, 21 Oct 2014 23:11:01 -0700
Subject: [PATCH 07/15] Switch is_public to a bitflags type for NsDefs

Preparation for importability tracking
---
 src/librustc/middle/resolve.rs | 119 ++++++++++++++++++++-------------
 1 file changed, 72 insertions(+), 47 deletions(-)

diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index e54fe92f5e7e6..b0296261827be 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -569,10 +569,17 @@ impl Module {
     }
 }
 
+bitflags! {
+    #[deriving(Show)]
+    flags DefModifiers: u8 {
+        const PUBLIC = 0b0000_0001,
+    }
+}
+
 // Records a possibly-private type definition.
 #[deriving(Clone)]
 struct TypeNsDef {
-    is_public: bool, // see note in ImportResolution about how to use this
+    modifiers: DefModifiers, // see note in ImportResolution about how to use this
     module_def: Option<Rc<Module>>,
     type_def: Option<Def>,
     type_span: Option<Span>
@@ -581,7 +588,7 @@ struct TypeNsDef {
 // Records a possibly-private value definition.
 #[deriving(Clone, Show)]
 struct ValueNsDef {
-    is_public: bool, // see note in ImportResolution about how to use this
+    modifiers: DefModifiers, // see note in ImportResolution about how to use this
     def: Def,
     value_span: Option<Span>,
 }
@@ -617,13 +624,14 @@ impl NameBindings {
                      is_public: bool,
                      sp: Span) {
         // Merges the module with the existing type def or creates a new one.
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
         let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
                                           is_public));
         let type_def = self.type_def.borrow().clone();
         match type_def {
             None => {
                 *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    is_public: is_public,
+                    modifiers: modifiers,
                     module_def: Some(module_),
                     type_def: None,
                     type_span: Some(sp)
@@ -631,7 +639,7 @@ impl NameBindings {
             }
             Some(type_def) => {
                 *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    is_public: is_public,
+                    modifiers: modifiers,
                     module_def: Some(module_),
                     type_span: Some(sp),
                     type_def: type_def.type_def
@@ -648,13 +656,14 @@ impl NameBindings {
                        external: bool,
                        is_public: bool,
                        _sp: Span) {
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
         let type_def = self.type_def.borrow().clone();
         match type_def {
             None => {
                 let module = Module::new(parent_link, def_id, kind,
                                          external, is_public);
                 *self.type_def.borrow_mut() = Some(TypeNsDef {
-                    is_public: is_public,
+                    modifiers: modifiers,
                     module_def: Some(Rc::new(module)),
                     type_def: None,
                     type_span: None,
@@ -669,7 +678,7 @@ impl NameBindings {
                                                  external,
                                                  is_public);
                         *self.type_def.borrow_mut() = Some(TypeNsDef {
-                            is_public: is_public,
+                            modifiers: modifiers,
                             module_def: Some(Rc::new(module)),
                             type_def: type_def.type_def,
                             type_span: None,
@@ -682,7 +691,7 @@ impl NameBindings {
     }
 
     /// Records a type definition.
-    fn define_type(&self, def: Def, sp: Span, is_public: bool) {
+    fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
         // Merges the type with the existing type def or creates a new one.
         let type_def = self.type_def.borrow().clone();
         match type_def {
@@ -691,7 +700,7 @@ impl NameBindings {
                     module_def: None,
                     type_def: Some(def),
                     type_span: Some(sp),
-                    is_public: is_public,
+                    modifiers: modifiers,
                 });
             }
             Some(type_def) => {
@@ -699,18 +708,18 @@ impl NameBindings {
                     type_def: Some(def),
                     type_span: Some(sp),
                     module_def: type_def.module_def,
-                    is_public: is_public,
+                    modifiers: modifiers,
                 });
             }
         }
     }
 
     /// Records a value definition.
-    fn define_value(&self, def: Def, sp: Span, is_public: bool) {
+    fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
         *self.value_def.borrow_mut() = Some(ValueNsDef {
             def: def,
             value_span: Some(sp),
-            is_public: is_public,
+            modifiers: modifiers,
         });
     }
 
@@ -746,10 +755,10 @@ impl NameBindings {
     fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
         match namespace {
             TypeNS => match *self.type_def.borrow() {
-                Some(ref def) => def.is_public, None => false
+                Some(ref def) => def.modifiers.contains(PUBLIC), None => false
             },
             ValueNS => match *self.value_def.borrow() {
-                Some(ref def) => def.is_public, None => false
+                Some(ref def) => def.modifiers.contains(PUBLIC), None => false
             }
         }
     }
@@ -1215,6 +1224,7 @@ impl<'a> Resolver<'a> {
         let name = item.ident.name;
         let sp = item.span;
         let is_public = item.vis == ast::Public;
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
 
         match item.node {
             ItemMod(..) => {
@@ -1242,13 +1252,13 @@ impl<'a> Resolver<'a> {
                 let mutbl = m == ast::MutMutable;
 
                 name_bindings.define_value
-                    (DefStatic(local_def(item.id), mutbl), sp, is_public);
+                    (DefStatic(local_def(item.id), mutbl), sp, modifiers);
                 parent
             }
             ItemConst(_, _) => {
                 self.add_child(name, parent.clone(), ForbidDuplicateValues, sp)
                     .define_value(DefConst(local_def(item.id)),
-                                  sp, is_public);
+                                  sp, modifiers);
                 parent
             }
             ItemFn(_, fn_style, _, _, _) => {
@@ -1256,7 +1266,7 @@ impl<'a> Resolver<'a> {
                     self.add_child(name, parent.clone(), ForbidDuplicateValues, sp);
 
                 let def = DefFn(local_def(item.id), fn_style, false);
-                name_bindings.define_value(def, sp, is_public);
+                name_bindings.define_value(def, sp, modifiers);
                 parent
             }
 
@@ -1269,7 +1279,7 @@ impl<'a> Resolver<'a> {
                                    sp);
 
                 name_bindings.define_type
-                    (DefTy(local_def(item.id), false), sp, is_public);
+                    (DefTy(local_def(item.id), false), sp, modifiers);
                 parent
             }
 
@@ -1281,7 +1291,7 @@ impl<'a> Resolver<'a> {
                                    sp);
 
                 name_bindings.define_type
-                    (DefTy(local_def(item.id), true), sp, is_public);
+                    (DefTy(local_def(item.id), true), sp, modifiers);
 
                 let parent_link = self.get_parent_link(parent.clone(), ident);
                 // We want to make sure the module type is EnumModuleKind
@@ -1322,14 +1332,14 @@ impl<'a> Resolver<'a> {
                 let name_bindings = self.add_child(name, parent.clone(), forbid, sp);
 
                 // Define a name in the type namespace.
-                name_bindings.define_type(DefTy(local_def(item.id), false), sp, is_public);
+                name_bindings.define_type(DefTy(local_def(item.id), false), sp, modifiers);
 
                 // If this is a newtype or unit-like struct, define a name
                 // in the value namespace as well
                 match ctor_id {
                     Some(cid) => {
                         name_bindings.define_value(DefStruct(local_def(cid)),
-                                                   sp, is_public);
+                                                   sp, modifiers);
                     }
                     None => {}
                 }
@@ -1429,12 +1439,15 @@ impl<'a> Resolver<'a> {
                                         }
                                     };
 
-                                    let is_public =
-                                        method.pe_vis() == ast::Public;
+                                    let modifiers = if method.pe_vis() == ast::Public {
+                                        PUBLIC
+                                    } else {
+                                        DefModifiers::empty()
+                                    };
                                     method_name_bindings.define_value(
                                         def,
                                         method.span,
-                                        is_public);
+                                        modifiers);
                                 }
                                 TypeImplItem(ref typedef) => {
                                     // Add the typedef to the module.
@@ -1447,12 +1460,15 @@ impl<'a> Resolver<'a> {
                                             typedef.span);
                                     let def = DefAssociatedTy(local_def(
                                             typedef.id));
-                                    let is_public = typedef.vis ==
-                                        ast::Public;
+                                    let modifiers = if typedef.vis == ast::Public {
+                                        PUBLIC
+                                    } else {
+                                        DefModifiers::empty()
+                                    };
                                     typedef_name_bindings.define_type(
                                         def,
                                         typedef.span,
-                                        is_public);
+                                        modifiers);
                                 }
                             }
                         }
@@ -1528,7 +1544,7 @@ impl<'a> Resolver<'a> {
                                                ty_m.span);
                             method_name_bindings.define_value(def,
                                                               ty_m.span,
-                                                              true);
+                                                              PUBLIC);
 
                             (name, static_flag)
                         }
@@ -1543,7 +1559,7 @@ impl<'a> Resolver<'a> {
                                                associated_type.span);
                             name_bindings.define_type(def,
                                                       associated_type.span,
-                                                      true);
+                                                      PUBLIC);
 
                             (associated_type.ident.name, TypeTraitItemKind)
                         }
@@ -1552,7 +1568,7 @@ impl<'a> Resolver<'a> {
                     self.trait_item_map.insert((name, def_id), kind);
                 }
 
-                name_bindings.define_type(DefTrait(def_id), sp, is_public);
+                name_bindings.define_type(DefTrait(def_id), sp, modifiers);
                 parent
             }
             ItemMac(..) => parent
@@ -1567,6 +1583,7 @@ impl<'a> Resolver<'a> {
                                        parent: ReducedGraphParent,
                                        is_public: bool) {
         let name = variant.node.name.name;
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
         let is_exported = match variant.node.kind {
             TupleVariantKind(_) => false,
             StructVariantKind(_) => {
@@ -1581,10 +1598,10 @@ impl<'a> Resolver<'a> {
                                    variant.span);
         child.define_value(DefVariant(item_id,
                                       local_def(variant.node.id), is_exported),
-                           variant.span, is_public);
+                           variant.span, modifiers);
         child.define_type(DefVariant(item_id,
                                      local_def(variant.node.id), is_exported),
-                          variant.span, is_public);
+                          variant.span, modifiers);
     }
 
     /// Constructs the reduced graph for one 'view item'. View items consist
@@ -1730,6 +1747,7 @@ impl<'a> Resolver<'a> {
                                             f: |&mut Resolver|) {
         let name = foreign_item.ident.name;
         let is_public = foreign_item.vis == ast::Public;
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
         let name_bindings =
             self.add_child(name, parent, ForbidDuplicateValues,
                            foreign_item.span);
@@ -1737,7 +1755,7 @@ impl<'a> Resolver<'a> {
         match foreign_item.node {
             ForeignItemFn(_, ref generics) => {
                 let def = DefFn(local_def(foreign_item.id), UnsafeFn, false);
-                name_bindings.define_value(def, foreign_item.span, is_public);
+                name_bindings.define_value(def, foreign_item.span, modifiers);
 
                 self.with_type_parameter_rib(
                     HasTypeParameters(generics,
@@ -1748,7 +1766,7 @@ impl<'a> Resolver<'a> {
             }
             ForeignItemStatic(_, m) => {
                 let def = DefStatic(local_def(foreign_item.id), m);
-                name_bindings.define_value(def, foreign_item.span, is_public);
+                name_bindings.define_value(def, foreign_item.span, modifiers);
 
                 f(self)
             }
@@ -1793,6 +1811,7 @@ impl<'a> Resolver<'a> {
                 external crate) building external def, priv {}",
                vis);
         let is_public = vis == ast::Public;
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
         let is_exported = is_public && match new_parent {
             ModuleReducedGraphParent(ref module) => {
                 match module.def_id.get() {
@@ -1851,23 +1870,24 @@ impl<'a> Resolver<'a> {
             // definition.
             let is_exported = is_public ||
                               self.external_exports.contains(&enum_did);
+            let modifiers = if is_exported { PUBLIC } else { DefModifiers::empty() };
             if is_struct {
-                child_name_bindings.define_type(def, DUMMY_SP, is_exported);
+                child_name_bindings.define_type(def, DUMMY_SP, modifiers);
                 // Not adding fields for variants as they are not accessed with a self receiver
                 self.structs.insert(variant_id, Vec::new());
             } else {
-                child_name_bindings.define_value(def, DUMMY_SP, is_exported);
+                child_name_bindings.define_value(def, DUMMY_SP, modifiers);
             }
           }
           DefFn(ctor_id, _, true) => {
             child_name_bindings.define_value(
                 csearch::get_tuple_struct_definition_if_ctor(&self.session.cstore, ctor_id)
-                    .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, is_public);
+                    .map_or(def, |_| DefStruct(ctor_id)), DUMMY_SP, modifiers);
           }
           DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) => {
             debug!("(building reduced graph for external \
                     crate) building value (fn/static) {}", final_ident);
-            child_name_bindings.define_value(def, DUMMY_SP, is_public);
+            child_name_bindings.define_value(def, DUMMY_SP, modifiers);
           }
           DefTrait(def_id) => {
               debug!("(building reduced graph for external \
@@ -1896,7 +1916,7 @@ impl<'a> Resolver<'a> {
                   }
               }
 
-              child_name_bindings.define_type(def, DUMMY_SP, is_public);
+              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
 
               // Define a module if necessary.
               let parent_link = self.get_parent_link(new_parent, name);
@@ -1909,7 +1929,7 @@ impl<'a> Resolver<'a> {
           }
           DefTy(def_id, true) => { // enums
               debug!("(building reduced graph for external crate) building enum {}", final_ident);
-              child_name_bindings.define_type(def, DUMMY_SP, is_public);
+              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
               let enum_module = ModuleReducedGraphParent(child_name_bindings.get_module());
 
               let variants = csearch::get_enum_variant_defs(&self.session.cstore, def_id);
@@ -1926,12 +1946,13 @@ impl<'a> Resolver<'a> {
                   // otherwise we need to inherit the visibility of the enum
                   // definition.
                   let variant_exported = vis == ast::Public || is_exported;
+                  let modifiers = if variant_exported { PUBLIC } else { DefModifiers::empty() };
                   if is_struct {
-                      child.define_type(v_def, DUMMY_SP, variant_exported);
+                      child.define_type(v_def, DUMMY_SP, modifiers);
                       // Not adding fields for variants as they are not accessed with a self receiver
                       self.structs.insert(variant_id, Vec::new());
                   } else {
-                      child.define_value(v_def, DUMMY_SP, variant_exported);
+                      child.define_value(v_def, DUMMY_SP, modifiers);
                   }
               }
 
@@ -1940,19 +1961,19 @@ impl<'a> Resolver<'a> {
               debug!("(building reduced graph for external \
                       crate) building type {}", final_ident);
 
-              child_name_bindings.define_type(def, DUMMY_SP, is_public);
+              child_name_bindings.define_type(def, DUMMY_SP, modifiers);
           }
           DefStruct(def_id) => {
             debug!("(building reduced graph for external \
                     crate) building type and value for {}",
                    final_ident);
-            child_name_bindings.define_type(def, DUMMY_SP, is_public);
+            child_name_bindings.define_type(def, DUMMY_SP, modifiers);
             let fields = csearch::get_struct_fields(&self.session.cstore, def_id).iter().map(|f| {
                 f.name
             }).collect::<Vec<_>>();
 
             if fields.len() == 0 {
-                child_name_bindings.define_value(def, DUMMY_SP, is_public);
+                child_name_bindings.define_value(def, DUMMY_SP, modifiers);
             }
 
             // Record the def ID and fields of this struct.
@@ -2089,9 +2110,13 @@ impl<'a> Resolver<'a> {
                                         static_method_info.fn_style,
                                         false);
 
+                                    let modifiers = if visibility == ast::Public {
+                                        PUBLIC
+                                    } else {
+                                        DefModifiers::empty()
+                                    };
                                     method_name_bindings.define_value(
-                                        def, DUMMY_SP,
-                                        visibility == ast::Public);
+                                        def, DUMMY_SP, modifiers);
                                 }
                             }
 
@@ -2462,7 +2487,7 @@ impl<'a> Resolver<'a> {
     fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
         NameBindings {
             type_def: RefCell::new(Some(TypeNsDef {
-                is_public: false,
+                modifiers: DefModifiers::empty(),
                 module_def: Some(module),
                 type_def: None,
                 type_span: None

From 24d9db9cb3d4c1bacd8ba62bc96c8f8f116c1e44 Mon Sep 17 00:00:00 2001
From: Steven Fackler <sfackler@gmail.com>
Date: Tue, 21 Oct 2014 23:15:56 -0700
Subject: [PATCH 08/15] Basic tests

---
 src/test/auxiliary/namespaced_enums.rs       | 17 +++++++++++++
 src/test/run-pass/namespaced-enums-xcrate.rs | 25 ++++++++++++++++++++
 src/test/run-pass/namespaced-enums.rs        | 24 +++++++++++++++++++
 3 files changed, 66 insertions(+)
 create mode 100644 src/test/auxiliary/namespaced_enums.rs
 create mode 100644 src/test/run-pass/namespaced-enums-xcrate.rs
 create mode 100644 src/test/run-pass/namespaced-enums.rs

diff --git a/src/test/auxiliary/namespaced_enums.rs b/src/test/auxiliary/namespaced_enums.rs
new file mode 100644
index 0000000000000..8fbfbc1ad90d8
--- /dev/null
+++ b/src/test/auxiliary/namespaced_enums.rs
@@ -0,0 +1,17 @@
+// 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.
+#![feature(struct_variant)]
+
+pub enum Foo {
+    A,
+    B(int),
+    C { a: int },
+}
+
diff --git a/src/test/run-pass/namespaced-enums-xcrate.rs b/src/test/run-pass/namespaced-enums-xcrate.rs
new file mode 100644
index 0000000000000..c5f80eaea5a31
--- /dev/null
+++ b/src/test/run-pass/namespaced-enums-xcrate.rs
@@ -0,0 +1,25 @@
+// 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.
+
+// aux-build:namespaced_enums.rs
+#![feature(struct_variant)]
+
+extern crate namespaced_enums;
+
+use namespaced_enums::Foo;
+
+fn _foo (f: Foo) {
+    match f {
+        Foo::A | Foo::B(_) | Foo::C { .. } => {}
+    }
+}
+
+pub fn main() {}
+
diff --git a/src/test/run-pass/namespaced-enums.rs b/src/test/run-pass/namespaced-enums.rs
new file mode 100644
index 0000000000000..afa39c326b60c
--- /dev/null
+++ b/src/test/run-pass/namespaced-enums.rs
@@ -0,0 +1,24 @@
+// 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.
+#![feature(struct_variant)]
+
+enum Foo {
+    A,
+    B(int),
+    C { a: int },
+}
+
+fn _foo (f: Foo) {
+    match f {
+        Foo::A | Foo::B(_) | Foo::C { .. } => {}
+    }
+}
+
+pub fn main() {}

From b052e239c1f28606ac5b281e87ece735bd8e240b Mon Sep 17 00:00:00 2001
From: Steven Fackler <sfackler@gmail.com>
Date: Thu, 23 Oct 2014 08:47:29 -0700
Subject: [PATCH 09/15] Fix import restrictions

I am not happy with the way that we track importability for external
crates
---
 src/librustc/middle/resolve.rs                | 134 +++++++++++-------
 src/test/auxiliary/namespaced_enums.rs        |   5 +
 src/test/auxiliary/use_from_trait_xc.rs       |   8 +-
 ...spaced-enum-glob-import-no-impls-xcrate.rs |  28 ++++
 .../namespaced-enum-glob-import-no-impls.rs   |  36 +++++
 src/test/compile-fail/use-from-trait-xc.rs    |  11 +-
 src/test/compile-fail/use-from-trait.rs       |   4 +-
 .../namespaced-enum-glob-import-xcrate.rs     |  34 +++++
 .../run-pass/namespaced-enum-glob-import.rs   |  42 ++++++
 9 files changed, 245 insertions(+), 57 deletions(-)
 create mode 100644 src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs
 create mode 100644 src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs
 create mode 100644 src/test/run-pass/namespaced-enum-glob-import-xcrate.rs
 create mode 100644 src/test/run-pass/namespaced-enum-glob-import.rs

diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index b0296261827be..51ca2b5ea1788 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -572,7 +572,8 @@ impl Module {
 bitflags! {
     #[deriving(Show)]
     flags DefModifiers: u8 {
-        const PUBLIC = 0b0000_0001,
+        const PUBLIC     = 0b0000_0001,
+        const IMPORTABLE = 0b0000_0010,
     }
 }
 
@@ -624,7 +625,7 @@ impl NameBindings {
                      is_public: bool,
                      sp: Span) {
         // Merges the module with the existing type def or creates a new one.
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
         let module_ = Rc::new(Module::new(parent_link, def_id, kind, external,
                                           is_public));
         let type_def = self.type_def.borrow().clone();
@@ -656,7 +657,7 @@ impl NameBindings {
                        external: bool,
                        is_public: bool,
                        _sp: Span) {
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
         let type_def = self.type_def.borrow().clone();
         match type_def {
             None => {
@@ -692,6 +693,7 @@ impl NameBindings {
 
     /// Records a type definition.
     fn define_type(&self, def: Def, sp: Span, modifiers: DefModifiers) {
+        debug!("defining type for def {} with modifiers {}", def, modifiers);
         // Merges the type with the existing type def or creates a new one.
         let type_def = self.type_def.borrow().clone();
         match type_def {
@@ -716,6 +718,7 @@ impl NameBindings {
 
     /// Records a value definition.
     fn define_value(&self, def: Def, sp: Span, modifiers: DefModifiers) {
+        debug!("defining value for def {} with modifiers {}", def, modifiers);
         *self.value_def.borrow_mut() = Some(ValueNsDef {
             def: def,
             value_span: Some(sp),
@@ -753,12 +756,16 @@ impl NameBindings {
     }
 
     fn defined_in_public_namespace(&self, namespace: Namespace) -> bool {
+        self.defined_in_namespace_with(namespace, PUBLIC)
+    }
+
+    fn defined_in_namespace_with(&self, namespace: Namespace, modifiers: DefModifiers) -> bool {
         match namespace {
             TypeNS => match *self.type_def.borrow() {
-                Some(ref def) => def.modifiers.contains(PUBLIC), None => false
+                Some(ref def) => def.modifiers.contains(modifiers), None => false
             },
             ValueNS => match *self.value_def.borrow() {
-                Some(ref def) => def.modifiers.contains(PUBLIC), None => false
+                Some(ref def) => def.modifiers.contains(modifiers), None => false
             }
         }
     }
@@ -1224,7 +1231,7 @@ impl<'a> Resolver<'a> {
         let name = item.ident.name;
         let sp = item.span;
         let is_public = item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
 
         match item.node {
             ItemMod(..) => {
@@ -1439,6 +1446,7 @@ impl<'a> Resolver<'a> {
                                         }
                                     };
 
+                                    // NB: not IMPORTABLE
                                     let modifiers = if method.pe_vis() == ast::Public {
                                         PUBLIC
                                     } else {
@@ -1460,6 +1468,7 @@ impl<'a> Resolver<'a> {
                                             typedef.span);
                                     let def = DefAssociatedTy(local_def(
                                             typedef.id));
+                                    // NB: not IMPORTABLE
                                     let modifiers = if typedef.vis == ast::Public {
                                         PUBLIC
                                     } else {
@@ -1542,6 +1551,7 @@ impl<'a> Resolver<'a> {
                                                module_parent.clone(),
                                                ForbidDuplicateTypesAndValues,
                                                ty_m.span);
+                            // NB: not IMPORTABLE
                             method_name_bindings.define_value(def,
                                                               ty_m.span,
                                                               PUBLIC);
@@ -1557,6 +1567,7 @@ impl<'a> Resolver<'a> {
                                                module_parent.clone(),
                                                ForbidDuplicateTypesAndValues,
                                                associated_type.span);
+                            // NB: not IMPORTABLE
                             name_bindings.define_type(def,
                                                       associated_type.span,
                                                       PUBLIC);
@@ -1583,7 +1594,7 @@ impl<'a> Resolver<'a> {
                                        parent: ReducedGraphParent,
                                        is_public: bool) {
         let name = variant.node.name.name;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
+        let modifiers = IMPORTABLE | if is_public { PUBLIC } else { DefModifiers::empty() };
         let is_exported = match variant.node.kind {
             TupleVariantKind(_) => false,
             StructVariantKind(_) => {
@@ -1747,7 +1758,7 @@ impl<'a> Resolver<'a> {
                                             f: |&mut Resolver|) {
         let name = foreign_item.ident.name;
         let is_public = foreign_item.vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
         let name_bindings =
             self.add_child(name, parent, ForbidDuplicateValues,
                            foreign_item.span);
@@ -1811,7 +1822,7 @@ impl<'a> Resolver<'a> {
                 external crate) building external def, priv {}",
                vis);
         let is_public = vis == ast::Public;
-        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() };
+        let modifiers = if is_public { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
         let is_exported = is_public && match new_parent {
             ModuleReducedGraphParent(ref module) => {
                 match module.def_id.get() {
@@ -1870,7 +1881,7 @@ impl<'a> Resolver<'a> {
             // definition.
             let is_exported = is_public ||
                               self.external_exports.contains(&enum_did);
-            let modifiers = if is_exported { PUBLIC } else { DefModifiers::empty() };
+            let modifiers = if is_exported { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
             if is_struct {
                 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
                 // Not adding fields for variants as they are not accessed with a self receiver
@@ -1887,6 +1898,14 @@ impl<'a> Resolver<'a> {
           DefFn(..) | DefStaticMethod(..) | DefStatic(..) | DefConst(..) => {
             debug!("(building reduced graph for external \
                     crate) building value (fn/static) {}", final_ident);
+            // impl methods have already been defined with the correct importability modifier
+            let mut modifiers = match *child_name_bindings.value_def.borrow() {
+                Some(ref def) => (modifiers & !IMPORTABLE) | (def.modifiers & IMPORTABLE),
+                None => modifiers
+            };
+            if new_parent.module().kind.get() != NormalModuleKind {
+                modifiers = modifiers & !IMPORTABLE;
+            }
             child_name_bindings.define_value(def, DUMMY_SP, modifiers);
           }
           DefTrait(def_id) => {
@@ -1946,16 +1965,20 @@ impl<'a> Resolver<'a> {
                   // otherwise we need to inherit the visibility of the enum
                   // definition.
                   let variant_exported = vis == ast::Public || is_exported;
-                  let modifiers = if variant_exported { PUBLIC } else { DefModifiers::empty() };
+                  let modifiers = IMPORTABLE | if variant_exported {
+                      PUBLIC
+                  } else {
+                      DefModifiers::empty()
+                  };
                   if is_struct {
                       child.define_type(v_def, DUMMY_SP, modifiers);
-                      // Not adding fields for variants as they are not accessed with a self receiver
+                      // Not adding fields for variants as they are not accessed with a self
+                      // receiver
                       self.structs.insert(variant_id, Vec::new());
                   } else {
                       child.define_value(v_def, DUMMY_SP, modifiers);
                   }
               }
-
           }
           DefTy(..) | DefAssociatedTy(..) => {
               debug!("(building reduced graph for external \
@@ -2110,6 +2133,7 @@ impl<'a> Resolver<'a> {
                                         static_method_info.fn_style,
                                         false);
 
+                                    // NB: not IMPORTABLE
                                     let modifiers = if visibility == ast::Public {
                                         PUBLIC
                                     } else {
@@ -2487,7 +2511,7 @@ impl<'a> Resolver<'a> {
     fn create_name_bindings_from_module(module: Rc<Module>) -> NameBindings {
         NameBindings {
             type_def: RefCell::new(Some(TypeNsDef {
-                modifiers: DefModifiers::empty(),
+                modifiers: IMPORTABLE,
                 module_def: Some(module),
                 type_def: None,
                 type_span: None
@@ -2689,6 +2713,12 @@ impl<'a> Resolver<'a> {
                     target,
                     ValueNS);
 
+                self.check_that_import_is_importable(
+                    &**name_bindings,
+                    directive.span,
+                    target.name,
+                    ValueNS);
+
                 import_resolution.value_target =
                     Some(Target::new(target_module.clone(),
                                      name_bindings.clone(),
@@ -2712,6 +2742,12 @@ impl<'a> Resolver<'a> {
                     target,
                     TypeNS);
 
+                self.check_that_import_is_importable(
+                    &**name_bindings,
+                    directive.span,
+                    target.name,
+                    TypeNS);
+
                 import_resolution.type_target =
                     Some(Target::new(target_module.clone(),
                                      name_bindings.clone(),
@@ -2922,7 +2958,7 @@ impl<'a> Resolver<'a> {
                self.module_to_string(module_));
 
         // Merge the child item into the import resolution.
-        if name_bindings.defined_in_public_namespace(ValueNS) {
+        if name_bindings.defined_in_namespace_with(ValueNS, IMPORTABLE | PUBLIC) {
             debug!("(resolving glob import) ... for value target");
             dest_import_resolution.value_target =
                 Some(Target::new(containing_module.clone(),
@@ -2930,7 +2966,7 @@ impl<'a> Resolver<'a> {
                                  import_directive.shadowable));
             dest_import_resolution.value_id = id;
         }
-        if name_bindings.defined_in_public_namespace(TypeNS) {
+        if name_bindings.defined_in_namespace_with(TypeNS, IMPORTABLE | PUBLIC) {
             debug!("(resolving glob import) ... for type target");
             dest_import_resolution.type_target =
                 Some(Target::new(containing_module,
@@ -2972,6 +3008,19 @@ impl<'a> Resolver<'a> {
         }
     }
 
+    /// Checks that an import is actually importable
+    fn check_that_import_is_importable(&mut self,
+                                       name_bindings: &NameBindings,
+                                       import_span: Span,
+                                       name: Name,
+                                       namespace: Namespace) {
+        if !name_bindings.defined_in_namespace_with(namespace, IMPORTABLE) {
+            let msg = format!("`{}` is not directly importable",
+                              token::get_name(name));
+            self.session.span_err(import_span, msg.as_slice());
+        }
+    }
+
     /// Checks that imported names and items don't have the same name.
     fn check_for_conflicts_between_imports_and_items(&mut self,
                                                      module: &Module,
@@ -3224,43 +3273,28 @@ impl<'a> Resolver<'a> {
                                     return Failed(Some((span, msg)));
                                 }
                                 Some(ref module_def) => {
-                                    // If we're doing the search for an
-                                    // import, do not allow traits and impls
-                                    // to be selected.
-                                    match (name_search_type,
-                                           module_def.kind.get()) {
-                                        (ImportSearch, TraitModuleKind) |
-                                        (ImportSearch, ImplModuleKind) => {
-                                            let msg =
-                                                "Cannot import from a trait or \
-                                                type implementation".to_string();
-                                            return Failed(Some((span, msg)));
+                                    search_module = module_def.clone();
+
+                                    // track extern crates for unused_extern_crate lint
+                                    match module_def.def_id.get() {
+                                        Some(did) => {
+                                            self.used_crates.insert(did.krate);
                                         }
-                                        (_, _) => {
-                                            search_module = module_def.clone();
-
-                                            // track extern crates for unused_extern_crates lint
-                                            match module_def.def_id.get() {
-                                                Some(did) => {
-                                                    self.used_crates.insert(did.krate);
-                                                }
-                                                _ => {}
-                                            }
+                                        _ => {}
+                                    }
 
-                                            // Keep track of the closest
-                                            // private module used when
-                                            // resolving this import chain.
-                                            if !used_proxy &&
-                                               !search_module.is_public {
-                                                match search_module.def_id
-                                                                   .get() {
-                                                    Some(did) => {
-                                                        closest_private =
-                                                            LastMod(DependsOn(did));
-                                                    }
-                                                    None => {}
-                                                }
+                                    // Keep track of the closest
+                                    // private module used when
+                                    // resolving this import chain.
+                                    if !used_proxy &&
+                                       !search_module.is_public {
+                                        match search_module.def_id
+                                                           .get() {
+                                            Some(did) => {
+                                                closest_private =
+                                                    LastMod(DependsOn(did));
                                             }
+                                            None => {}
                                         }
                                     }
                                 }
diff --git a/src/test/auxiliary/namespaced_enums.rs b/src/test/auxiliary/namespaced_enums.rs
index 8fbfbc1ad90d8..a6e6f9b019160 100644
--- a/src/test/auxiliary/namespaced_enums.rs
+++ b/src/test/auxiliary/namespaced_enums.rs
@@ -15,3 +15,8 @@ pub enum Foo {
     C { a: int },
 }
 
+impl Foo {
+    pub fn foo() {}
+    pub fn bar(&self) {}
+}
+
diff --git a/src/test/auxiliary/use_from_trait_xc.rs b/src/test/auxiliary/use_from_trait_xc.rs
index 8c547c2800204..22e0d3168cadc 100644
--- a/src/test/auxiliary/use_from_trait_xc.rs
+++ b/src/test/auxiliary/use_from_trait_xc.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-pub use self::sub::Bar;
+pub use self::sub::{Bar, Baz};
 
 pub trait Trait {
     fn foo();
@@ -26,4 +26,10 @@ mod sub {
     impl Bar {
         pub fn new() {}
     }
+
+    pub enum Baz {}
+
+    impl Baz {
+        pub fn new() {}
+    }
 }
diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs
new file mode 100644
index 0000000000000..09916a11f72e7
--- /dev/null
+++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls-xcrate.rs
@@ -0,0 +1,28 @@
+// 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.
+
+// aux-build:namespaced_enums.rs
+#![feature(struct_variant, globs)]
+
+extern crate namespaced_enums;
+
+mod m {
+    pub use namespaced_enums::Foo::*;
+}
+
+pub fn main() {
+    use namespaced_enums::Foo::*;
+
+    foo(); //~ ERROR unresolved name `foo`
+    m::foo(); //~ ERROR unresolved name `m::foo`
+    bar(); //~ ERROR unresolved name `bar`
+    m::bar(); //~ ERROR unresolved name `m::bar`
+}
+
diff --git a/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs
new file mode 100644
index 0000000000000..1554d410070d6
--- /dev/null
+++ b/src/test/compile-fail/namespaced-enum-glob-import-no-impls.rs
@@ -0,0 +1,36 @@
+// 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.
+#![feature(struct_variant, globs)]
+
+mod m2 {
+    pub enum Foo {
+        A,
+        B(int),
+        C { a: int },
+    }
+
+    impl Foo {
+        pub fn foo() {}
+        pub fn bar(&self) {}
+    }
+}
+
+mod m {
+    pub use m2::Foo::*;
+}
+
+pub fn main() {
+    use m2::Foo::*;
+
+    foo(); //~ ERROR unresolved name `foo`
+    m::foo(); //~ ERROR unresolved name `m::foo`
+    bar(); //~ ERROR unresolved name `bar`
+    m::bar(); //~ ERROR unresolved name `m::bar`
+}
diff --git a/src/test/compile-fail/use-from-trait-xc.rs b/src/test/compile-fail/use-from-trait-xc.rs
index cea85955d3795..ff2824135801a 100644
--- a/src/test/compile-fail/use-from-trait-xc.rs
+++ b/src/test/compile-fail/use-from-trait-xc.rs
@@ -13,12 +13,15 @@
 extern crate use_from_trait_xc;
 
 use use_from_trait_xc::Trait::foo;
-//~^ ERROR unresolved import `use_from_trait_xc::Trait::foo`. Cannot import from a trait or type imp
+//~^ ERROR `foo` is not directly importable
 
 use use_from_trait_xc::Foo::new;
-//~^ ERROR unresolved import `use_from_trait_xc::Foo::new`. Cannot import from a trait or type imple
+//~^ ERROR `new` is not directly importable
 
-use use_from_trait_xc::Bar::new;
-//~^ ERROR unresolved import `use_from_trait_xc::Bar::new`. Cannot import from a trait or type
+use use_from_trait_xc::Bar::new as bnew;
+//~^ ERROR `bnew` is not directly importable
+
+use use_from_trait_xc::Baz::new as baznew;
+//~^ ERROR `baznew` is not directly importable
 
 fn main() {}
diff --git a/src/test/compile-fail/use-from-trait.rs b/src/test/compile-fail/use-from-trait.rs
index c9eea3c5df255..2a97155dd2efb 100644
--- a/src/test/compile-fail/use-from-trait.rs
+++ b/src/test/compile-fail/use-from-trait.rs
@@ -9,9 +9,9 @@
 // except according to those terms.
 
 use Trait::foo;
-//~^ ERROR unresolved import `Trait::foo`. Cannot import from a trait or type implementation
+//~^ ERROR `foo` is not directly importable
 use Foo::new;
-//~^ ERROR unresolved import `Foo::new`. Cannot import from a trait or type implementation
+//~^ ERROR `new` is not directly importable
 
 pub trait Trait {
     fn foo();
diff --git a/src/test/run-pass/namespaced-enum-glob-import-xcrate.rs b/src/test/run-pass/namespaced-enum-glob-import-xcrate.rs
new file mode 100644
index 0000000000000..35fb66769543b
--- /dev/null
+++ b/src/test/run-pass/namespaced-enum-glob-import-xcrate.rs
@@ -0,0 +1,34 @@
+// 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.
+
+// aux-build:namespaced_enums.rs
+#![feature(globs, struct_variant)]
+
+extern crate namespaced_enums;
+
+fn _f(f: namespaced_enums::Foo) {
+    use namespaced_enums::Foo::*;
+
+    match f {
+        A | B(_) | C { .. } => {}
+    }
+}
+
+mod m {
+    pub use namespaced_enums::Foo::*;
+}
+
+fn _f2(f: namespaced_enums::Foo) {
+    match f {
+        m::A | m::B(_) | m::C { .. } => {}
+    }
+}
+
+pub fn main() {}
diff --git a/src/test/run-pass/namespaced-enum-glob-import.rs b/src/test/run-pass/namespaced-enum-glob-import.rs
new file mode 100644
index 0000000000000..fe6f342738360
--- /dev/null
+++ b/src/test/run-pass/namespaced-enum-glob-import.rs
@@ -0,0 +1,42 @@
+// 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.
+#![feature(globs, struct_variant)]
+
+mod m2 {
+    pub enum Foo {
+        A,
+        B(int),
+        C { a: int },
+    }
+
+    impl Foo {
+        pub fn foo() {}
+    }
+}
+
+mod m {
+    pub use m2::Foo::*;
+}
+
+fn _f(f: m2::Foo) {
+    use m2::Foo::*;
+
+    match f {
+        A | B(_) | C { .. } => {}
+    }
+}
+
+fn _f2(f: m2::Foo) {
+    match f {
+        m::A | m::B(_) | m::C { .. } => {}
+    }
+}
+
+pub fn main() {}

From cc87941988d2588749bf698dbeb147e2b8fbebf1 Mon Sep 17 00:00:00 2001
From: Steven Fackler <sfackler@gmail.com>
Date: Thu, 30 Oct 2014 22:16:52 -0700
Subject: [PATCH 10/15] Make variant flat reexports work

---
 src/librustc/middle/resolve.rs                | 28 ++++++----
 .../auxiliary/namespaced_enum_emulate_flat.rs | 38 ++++++++++++++
 .../namespaced-enum-emulate-flat-xc.rs        | 32 ++++++++++++
 .../run-pass/namespaced-enum-emulate-flat.rs  | 51 +++++++++++++++++++
 4 files changed, 138 insertions(+), 11 deletions(-)
 create mode 100644 src/test/auxiliary/namespaced_enum_emulate_flat.rs
 create mode 100644 src/test/run-pass/namespaced-enum-emulate-flat-xc.rs
 create mode 100644 src/test/run-pass/namespaced-enum-emulate-flat.rs

diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 51ca2b5ea1788..9c17b88698ad1 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -572,8 +572,9 @@ impl Module {
 bitflags! {
     #[deriving(Show)]
     flags DefModifiers: u8 {
-        const PUBLIC     = 0b0000_0001,
-        const IMPORTABLE = 0b0000_0010,
+        const PUBLIC            = 0b0000_0001,
+        const IMPORTABLE        = 0b0000_0010,
+        const ENUM_STAGING_HACK = 0b0000_0100,
     }
 }
 
@@ -1316,14 +1317,14 @@ impl<'a> Resolver<'a> {
                         &**variant,
                         local_def(item.id),
                         ModuleReducedGraphParent(name_bindings.get_module()),
-                        is_public);
+                        modifiers);
 
                     // Temporary staging hack
                     self.build_reduced_graph_for_variant(
                         &**variant,
                         local_def(item.id),
                         parent.clone(),
-                        is_public);
+                        modifiers | ENUM_STAGING_HACK);
                 }
                 parent
             }
@@ -1592,9 +1593,8 @@ impl<'a> Resolver<'a> {
                                        variant: &Variant,
                                        item_id: DefId,
                                        parent: ReducedGraphParent,
-                                       is_public: bool) {
+                                       modifiers: DefModifiers) {
         let name = variant.node.name.name;
-        let modifiers = IMPORTABLE | if is_public { PUBLIC } else { DefModifiers::empty() };
         let is_exported = match variant.node.kind {
             TupleVariantKind(_) => false,
             StructVariantKind(_) => {
@@ -1881,7 +1881,11 @@ impl<'a> Resolver<'a> {
             // definition.
             let is_exported = is_public ||
                               self.external_exports.contains(&enum_did);
-            let modifiers = if is_exported { PUBLIC } else { DefModifiers::empty() } | IMPORTABLE;
+            let modifiers = IMPORTABLE | ENUM_STAGING_HACK | if is_exported {
+                PUBLIC
+            } else {
+                DefModifiers::empty()
+            };
             if is_struct {
                 child_name_bindings.define_type(def, DUMMY_SP, modifiers);
                 // Not adding fields for variants as they are not accessed with a self receiver
@@ -3060,8 +3064,8 @@ impl<'a> Resolver<'a> {
         match import_resolution.value_target {
             Some(ref target) if !target.shadowable => {
                 match *name_bindings.value_def.borrow() {
-                    None => {}
-                    Some(ref value) => {
+                    // We want to allow the "flat" def of enum variants to be shadowed
+                    Some(ref value) if !value.modifiers.contains(ENUM_STAGING_HACK) => {
                         let msg = format!("import `{}` conflicts with value \
                                            in this module",
                                           token::get_name(name).get());
@@ -3075,6 +3079,7 @@ impl<'a> Resolver<'a> {
                             }
                         }
                     }
+                    _ => {}
                 }
             }
             Some(_) | None => {}
@@ -3083,8 +3088,8 @@ impl<'a> Resolver<'a> {
         match import_resolution.type_target {
             Some(ref target) if !target.shadowable => {
                 match *name_bindings.type_def.borrow() {
-                    None => {}
-                    Some(ref ty) => {
+                    // We want to allow the "flat" def of enum variants to be shadowed
+                    Some(ref ty) if !ty.modifiers.contains(ENUM_STAGING_HACK) => {
                         match ty.module_def {
                             None => {
                                 let msg = format!("import `{}` conflicts with type in \
@@ -3135,6 +3140,7 @@ impl<'a> Resolver<'a> {
                             }
                         }
                     }
+                    _ => {}
                 }
             }
             Some(_) | None => {}
diff --git a/src/test/auxiliary/namespaced_enum_emulate_flat.rs b/src/test/auxiliary/namespaced_enum_emulate_flat.rs
new file mode 100644
index 0000000000000..3a11f30049c6a
--- /dev/null
+++ b/src/test/auxiliary/namespaced_enum_emulate_flat.rs
@@ -0,0 +1,38 @@
+// 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.
+#![feature(globs, struct_variant)]
+
+pub use Foo::*;
+
+pub enum Foo {
+    A,
+    B(int),
+    C { a: int },
+}
+
+impl Foo {
+    pub fn foo() {}
+}
+
+pub mod nest {
+    pub use self::Bar::*;
+
+    pub enum Bar {
+        D,
+        E(int),
+        F { a: int },
+    }
+
+    impl Bar {
+        pub fn foo() {}
+    }
+}
+
+
diff --git a/src/test/run-pass/namespaced-enum-emulate-flat-xc.rs b/src/test/run-pass/namespaced-enum-emulate-flat-xc.rs
new file mode 100644
index 0000000000000..540a0acb12316
--- /dev/null
+++ b/src/test/run-pass/namespaced-enum-emulate-flat-xc.rs
@@ -0,0 +1,32 @@
+// 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.
+
+// aux-build:namespaced_enum_emulate_flat.rs
+#![feature(struct_variant)]
+
+extern crate namespaced_enum_emulate_flat;
+
+use namespaced_enum_emulate_flat::{Foo, A, B, C};
+use namespaced_enum_emulate_flat::nest::{Bar, D, E, F};
+
+fn _f(f: Foo) {
+    match f {
+        A | B(_) | C { .. } => {}
+    }
+}
+
+fn _f2(f: Bar) {
+    match f {
+        D | E(_) | F { .. } => {}
+    }
+}
+
+pub fn main() {}
+
diff --git a/src/test/run-pass/namespaced-enum-emulate-flat.rs b/src/test/run-pass/namespaced-enum-emulate-flat.rs
new file mode 100644
index 0000000000000..2aad9bcff5613
--- /dev/null
+++ b/src/test/run-pass/namespaced-enum-emulate-flat.rs
@@ -0,0 +1,51 @@
+// 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.
+#![feature(globs, struct_variant)]
+
+pub use Foo::*;
+use nest::{Bar, D, E, F};
+
+pub enum Foo {
+    A,
+    B(int),
+    C { a: int },
+}
+
+impl Foo {
+    pub fn foo() {}
+}
+
+fn _f(f: Foo) {
+    match f {
+        A | B(_) | C { .. } => {}
+    }
+}
+
+mod nest {
+    pub use self::Bar::*;
+
+    pub enum Bar {
+        D,
+        E(int),
+        F { a: int },
+    }
+
+    impl Bar {
+        pub fn foo() {}
+    }
+}
+
+fn _f2(f: Bar) {
+    match f {
+        D | E(_) | F { .. } => {}
+    }
+}
+
+fn main() {}

From 1d074a1eb02468f7adf2a5a1a5ac44c7e6850604 Mon Sep 17 00:00:00 2001
From: Steven Fackler <sfackler@gmail.com>
Date: Thu, 30 Oct 2014 23:08:53 -0700
Subject: [PATCH 11/15] Rebase cleanup

---
 src/librustc/metadata/csearch.rs | 2 +-
 src/librustc/metadata/decoder.rs | 2 +-
 src/librustc/middle/resolve.rs   | 6 +++---
 3 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs
index ccdc0b2ba23d5..93227322c5be8 100644
--- a/src/librustc/metadata/csearch.rs
+++ b/src/librustc/metadata/csearch.rs
@@ -117,7 +117,7 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: ast::DefId,
 }
 
 pub fn get_enum_variant_defs(cstore: &cstore::CStore, enum_id: ast::DefId)
-                             -> Vec<(def::Def, ast::Ident, ast::Visibility)> {
+                             -> Vec<(def::Def, ast::Name, ast::Visibility)> {
     let cdata = cstore.get_crate_data(enum_id.krate);
     decoder::get_enum_variant_defs(&*cstore.intr, &*cdata, enum_id.node)
 }
diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs
index f773f5092e35d..aba8e5284a0ac 100644
--- a/src/librustc/metadata/decoder.rs
+++ b/src/librustc/metadata/decoder.rs
@@ -665,7 +665,7 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: ast::NodeI
 pub fn get_enum_variant_defs(intr: &IdentInterner,
                              cdata: Cmd,
                              id: ast::NodeId)
-                             -> Vec<(def::Def, ast::Ident, ast::Visibility)> {
+                             -> Vec<(def::Def, ast::Name, ast::Visibility)> {
     let data = cdata.data();
     let items = reader::get_doc(rbml::Doc::new(data), tag_items);
     let item = find_item(id, items);
diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs
index 9c17b88698ad1..67dfe2b27456c 100644
--- a/src/librustc/middle/resolve.rs
+++ b/src/librustc/middle/resolve.rs
@@ -1301,7 +1301,7 @@ impl<'a> Resolver<'a> {
                 name_bindings.define_type
                     (DefTy(local_def(item.id), true), sp, modifiers);
 
-                let parent_link = self.get_parent_link(parent.clone(), ident);
+                let parent_link = self.get_parent_link(parent.clone(), name);
                 // We want to make sure the module type is EnumModuleKind
                 // even if there's already an ImplModuleKind module defined,
                 // since that's how we prevent duplicate enum definitions
@@ -2720,7 +2720,7 @@ impl<'a> Resolver<'a> {
                 self.check_that_import_is_importable(
                     &**name_bindings,
                     directive.span,
-                    target.name,
+                    target,
                     ValueNS);
 
                 import_resolution.value_target =
@@ -2749,7 +2749,7 @@ impl<'a> Resolver<'a> {
                 self.check_that_import_is_importable(
                     &**name_bindings,
                     directive.span,
-                    target.name,
+                    target,
                     TypeNS);
 
                 import_resolution.type_target =

From 1cb8d1d6a2d150eef4b0a8a487e1024bb9ff8e75 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Sat, 25 Oct 2014 11:01:15 -0500
Subject: [PATCH 12/15] DSTify BytesContainer

---
 src/libstd/path/mod.rs     | 55 +++++++++++++++++++++-----------------
 src/libstd/path/posix.rs   | 11 --------
 src/libstd/path/windows.rs | 19 +------------
 3 files changed, 31 insertions(+), 54 deletions(-)

diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index 6a1229902464e..79f12a6ef50f6 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -68,6 +68,7 @@ println!("path exists: {}", path.exists());
 #![experimental]
 
 use collections::{Collection, MutableSeq};
+use core::kinds::Sized;
 use c_str::CString;
 use clone::Clone;
 use fmt;
@@ -627,7 +628,7 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
     /// ```
     #[inline]
     fn push_many<T: BytesContainer>(&mut self, paths: &[T]) {
-        let t: Option<T> = None;
+        let t: Option<&T> = None;
         if BytesContainer::is_str(t) {
             for p in paths.iter() {
                 self.push(p.container_as_str().unwrap())
@@ -792,14 +793,9 @@ pub trait GenericPath: Clone + GenericPathUnsafe {
 }
 
 /// A trait that represents something bytes-like (e.g. a &[u8] or a &str)
-pub trait BytesContainer {
+pub trait BytesContainer for Sized? {
     /// Returns a &[u8] representing the receiver
     fn container_as_bytes<'a>(&'a self) -> &'a [u8];
-    /// Consumes the receiver and converts it into Vec<u8>
-    #[inline]
-    fn container_into_owned_bytes(self) -> Vec<u8> {
-        self.container_as_bytes().to_vec()
-    }
     /// Returns the receiver interpreted as a utf-8 string, if possible
     #[inline]
     fn container_as_str<'a>(&'a self) -> Option<&'a str> {
@@ -808,7 +804,7 @@ pub trait BytesContainer {
     /// Returns whether .container_as_str() is guaranteed to not fail
     // FIXME (#8888): Remove unused arg once ::<for T> works
     #[inline]
-    fn is_str(_: Option<Self>) -> bool { false }
+    fn is_str(_: Option<&Self>) -> bool { false }
 }
 
 /// A trait that represents the unsafe operations on GenericPaths
@@ -860,48 +856,44 @@ impl<'a, P: GenericPath> Display<'a, P> {
     }
 }
 
-impl<'a> BytesContainer for &'a str {
+impl BytesContainer for str {
     #[inline]
-    fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
+    fn container_as_bytes(&self) -> &[u8] {
         self.as_bytes()
     }
     #[inline]
-    fn container_as_str<'a>(&'a self) -> Option<&'a str> {
-        Some(*self)
+    fn container_as_str(&self) -> Option<&str> {
+        Some(self)
     }
     #[inline]
-    fn is_str(_: Option<&'a str>) -> bool { true }
+    fn is_str(_: Option<&str>) -> bool { true }
 }
 
 impl BytesContainer for String {
     #[inline]
-    fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
+    fn container_as_bytes(&self) -> &[u8] {
         self.as_bytes()
     }
     #[inline]
-    fn container_as_str<'a>(&'a self) -> Option<&'a str> {
+    fn container_as_str(&self) -> Option<&str> {
         Some(self.as_slice())
     }
     #[inline]
-    fn is_str(_: Option<String>) -> bool { true }
+    fn is_str(_: Option<&String>) -> bool { true }
 }
 
-impl<'a> BytesContainer for &'a [u8] {
+impl BytesContainer for [u8] {
     #[inline]
-    fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
-        *self
+    fn container_as_bytes(&self) -> &[u8] {
+        self
     }
 }
 
 impl BytesContainer for Vec<u8> {
     #[inline]
-    fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
+    fn container_as_bytes(&self) -> &[u8] {
         self.as_slice()
     }
-    #[inline]
-    fn container_into_owned_bytes(self) -> Vec<u8> {
-        self
-    }
 }
 
 impl BytesContainer for CString {
@@ -921,7 +913,20 @@ impl<'a> BytesContainer for str::MaybeOwned<'a> {
         Some(self.as_slice())
     }
     #[inline]
-    fn is_str(_: Option<str::MaybeOwned>) -> bool { true }
+    fn is_str(_: Option<&str::MaybeOwned>) -> bool { true }
+}
+
+impl<'a, Sized? T: BytesContainer> BytesContainer for &'a T {
+    #[inline]
+    fn container_as_bytes(&self) -> &[u8] {
+        (**self).container_as_bytes()
+    }
+    #[inline]
+    fn container_as_str(&self) -> Option<&str> {
+        (**self).container_as_str()
+    }
+    #[inline]
+    fn is_str(_: Option<& &'a T>) -> bool { BytesContainer::is_str(None::<&T>) }
 }
 
 #[inline(always)]
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 0d7a467b313f2..d3933fc10c67c 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -130,17 +130,6 @@ impl BytesContainer for Path {
     fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
         self.as_vec()
     }
-    #[inline]
-    fn container_into_owned_bytes(self) -> Vec<u8> {
-        self.into_vec()
-    }
-}
-
-impl<'a> BytesContainer for &'a Path {
-    #[inline]
-    fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
-        self.as_vec()
-    }
 }
 
 impl GenericPathUnsafe for Path {
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 1ddc027a07eab..1816de74f01f2 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -157,23 +157,6 @@ impl<S: hash::Writer> hash::Hash<S> for Path {
 }
 
 impl BytesContainer for Path {
-    #[inline]
-    fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
-        self.as_vec()
-    }
-    #[inline]
-    fn container_into_owned_bytes(self) -> Vec<u8> {
-        self.into_vec()
-    }
-    #[inline]
-    fn container_as_str<'a>(&'a self) -> Option<&'a str> {
-        self.as_str()
-    }
-    #[inline]
-    fn is_str(_: Option<Path>) -> bool { true }
-}
-
-impl<'a> BytesContainer for &'a Path {
     #[inline]
     fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
         self.as_vec()
@@ -183,7 +166,7 @@ impl<'a> BytesContainer for &'a Path {
         self.as_str()
     }
     #[inline]
-    fn is_str(_: Option<&'a Path>) -> bool { true }
+    fn is_str(_: Option<&Path>) -> bool { true }
 }
 
 impl GenericPathUnsafe for Path {

From cac515c946a7fc26d17e8d58602ebc8093021872 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 31 Oct 2014 00:03:52 -0500
Subject: [PATCH 13/15] Remove unnecessary allocations

---
 src/compiletest/runtest.rs                             | 2 +-
 src/librustc/driver/session.rs                         | 2 +-
 src/libstd/io/process.rs                               | 2 +-
 src/libterm/terminfo/searcher.rs                       | 2 +-
 src/test/run-pass/process-spawn-with-unicode-params.rs | 2 +-
 5 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs
index a40913a5db2a2..c669fd844fb3e 100644
--- a/src/compiletest/runtest.rs
+++ b/src/compiletest/runtest.rs
@@ -616,7 +616,7 @@ fn find_rust_src_root(config: &Config) -> Option<Path> {
     let path_postfix = Path::new("src/etc/lldb_batchmode.py");
 
     while path.pop() {
-        if path.join(path_postfix.clone()).is_file() {
+        if path.join(&path_postfix).is_file() {
             return Some(path);
         }
     }
diff --git a/src/librustc/driver/session.rs b/src/librustc/driver/session.rs
index 55e07321c7101..f8e778ce15f6a 100644
--- a/src/librustc/driver/session.rs
+++ b/src/librustc/driver/session.rs
@@ -231,7 +231,7 @@ pub fn build_session_(sopts: config::Options,
         if path.is_absolute() {
             path.clone()
         } else {
-            os::getcwd().join(path.clone())
+            os::getcwd().join(&path)
         }
     );
 
diff --git a/src/libstd/io/process.rs b/src/libstd/io/process.rs
index 4e5f8822acb40..312a4c41ac9a6 100644
--- a/src/libstd/io/process.rs
+++ b/src/libstd/io/process.rs
@@ -918,7 +918,7 @@ mod tests {
         let prog = pwd_cmd().cwd(&parent_dir).spawn().unwrap();
 
         let output = String::from_utf8(prog.wait_with_output().unwrap().output).unwrap();
-        let child_dir = Path::new(output.as_slice().trim().into_string());
+        let child_dir = Path::new(output.as_slice().trim());
 
         let parent_stat = parent_dir.stat().unwrap();
         let child_stat = child_dir.stat().unwrap();
diff --git a/src/libterm/terminfo/searcher.rs b/src/libterm/terminfo/searcher.rs
index a89afab505b8d..61ff88a2fa338 100644
--- a/src/libterm/terminfo/searcher.rs
+++ b/src/libterm/terminfo/searcher.rs
@@ -41,7 +41,7 @@ pub fn get_dbpath_for_term(term: &str) -> Option<Box<Path>> {
                     if i == "" {
                         dirs_to_search.push(Path::new("/usr/share/terminfo"));
                     } else {
-                        dirs_to_search.push(Path::new(i.to_string()));
+                        dirs_to_search.push(Path::new(i));
                     }
                 },
                 // Found nothing in TERMINFO_DIRS, use the default paths:
diff --git a/src/test/run-pass/process-spawn-with-unicode-params.rs b/src/test/run-pass/process-spawn-with-unicode-params.rs
index 9716d79f4c82a..490614ef12144 100644
--- a/src/test/run-pass/process-spawn-with-unicode-params.rs
+++ b/src/test/run-pass/process-spawn-with-unicode-params.rs
@@ -48,7 +48,7 @@ fn main() {
 
         let child_filestem = Path::new(child_name);
         let child_filename = child_filestem.with_extension(my_ext);
-        let child_path     = cwd.join(child_filename.clone());
+        let child_path     = cwd.join(child_filename);
 
         // make a separate directory for the child
         drop(fs::mkdir(&cwd, io::USER_RWX).is_ok());

From dd9dda7a1c87170fe241345f6da88874921ec433 Mon Sep 17 00:00:00 2001
From: Jorge Aparicio <japaricious@gmail.com>
Date: Fri, 24 Oct 2014 19:23:22 -0500
Subject: [PATCH 14/15] DSTify ToCStr

---
 src/librustrt/c_str.rs     | 44 +++++++++++++++++++++++++-------------
 src/libstd/path/posix.rs   | 12 -----------
 src/libstd/path/windows.rs | 12 -----------
 3 files changed, 29 insertions(+), 39 deletions(-)

diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs
index ddb4df4fdc538..92d8e4005bf8c 100644
--- a/src/librustrt/c_str.rs
+++ b/src/librustrt/c_str.rs
@@ -74,7 +74,7 @@ fn main() {
 use collections::string::String;
 use collections::hash;
 use core::fmt;
-use core::kinds::marker;
+use core::kinds::{Sized, marker};
 use core::mem;
 use core::prelude::{Clone, Collection, Drop, Eq, ImmutableSlice, Iterator};
 use core::prelude::{MutableSlice, None, Option, Ordering, PartialEq};
@@ -286,7 +286,7 @@ impl fmt::Show for CString {
 }
 
 /// A generic trait for converting a value to a CString.
-pub trait ToCStr {
+pub trait ToCStr for Sized? {
     /// Copy the receiver into a CString.
     ///
     /// # Failure
@@ -329,15 +329,7 @@ pub trait ToCStr {
     }
 }
 
-// FIXME (#12938): Until DST lands, we cannot decompose &str into &
-// and str, so we cannot usefully take ToCStr arguments by reference
-// (without forcing an additional & around &str). So we are instead
-// temporarily adding an instance for ~str and String, so that we can
-// take ToCStr as owned. When DST lands, the string instances should
-// be revisited, and arguments bound by ToCStr should be passed by
-// reference.
-
-impl<'a> ToCStr for &'a str {
+impl ToCStr for str {
     #[inline]
     fn to_c_str(&self) -> CString {
         self.as_bytes().to_c_str()
@@ -384,10 +376,10 @@ impl ToCStr for String {
 // The length of the stack allocated buffer for `vec.with_c_str()`
 const BUF_LEN: uint = 128;
 
-impl<'a> ToCStr for &'a [u8] {
+impl ToCStr for [u8] {
     fn to_c_str(&self) -> CString {
         let mut cs = unsafe { self.to_c_str_unchecked() };
-        check_for_null(*self, cs.as_mut_ptr());
+        check_for_null(self, cs.as_mut_ptr());
         cs
     }
 
@@ -403,11 +395,33 @@ impl<'a> ToCStr for &'a [u8] {
     }
 
     fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
-        unsafe { with_c_str(*self, true, f) }
+        unsafe { with_c_str(self, true, f) }
+    }
+
+    unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
+        with_c_str(self, false, f)
+    }
+}
+
+impl<'a, Sized? T: ToCStr> ToCStr for &'a T {
+    #[inline]
+    fn to_c_str(&self) -> CString {
+        (**self).to_c_str()
+    }
+
+    #[inline]
+    unsafe fn to_c_str_unchecked(&self) -> CString {
+        (**self).to_c_str_unchecked()
+    }
+
+    #[inline]
+    fn with_c_str<T>(&self, f: |*const libc::c_char| -> T) -> T {
+        (**self).with_c_str(f)
     }
 
+    #[inline]
     unsafe fn with_c_str_unchecked<T>(&self, f: |*const libc::c_char| -> T) -> T {
-        with_c_str(*self, false, f)
+        (**self).with_c_str_unchecked(f)
     }
 }
 
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 0d7a467b313f2..8a50ecc5ca669 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -106,18 +106,6 @@ impl ToCStr for Path {
     }
 }
 
-impl<'a> ToCStr for &'a Path {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        (*self).to_c_str()
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        (*self).to_c_str_unchecked()
-    }
-}
-
 impl<S: hash::Writer> hash::Hash<S> for Path {
     #[inline]
     fn hash(&self, state: &mut S) {
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 1ddc027a07eab..e4bead6d8ab8f 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -130,18 +130,6 @@ impl ToCStr for Path {
     }
 }
 
-impl<'a> ToCStr for &'a Path {
-    #[inline]
-    fn to_c_str(&self) -> CString {
-        (*self).to_c_str()
-    }
-
-    #[inline]
-    unsafe fn to_c_str_unchecked(&self) -> CString {
-        (*self).to_c_str_unchecked()
-    }
-}
-
 impl<S: hash::Writer> hash::Hash<S> for Path {
     #[cfg(not(test))]
     #[inline]

From 75dd1cf8a5664839d7f8d6aa348662d65745581c Mon Sep 17 00:00:00 2001
From: Alex Crichton <alex@alexcrichton.com>
Date: Thu, 30 Oct 2014 13:43:24 -0700
Subject: [PATCH 15/15] collections: Remove all collections traits

As part of the collections reform RFC, this commit removes all collections
traits in favor of inherent methods on collections themselves. All methods
should continue to be available on all collections.

This is a breaking change with all of the collections traits being removed and
no longer being in the prelude. In order to update old code you should move the
trait implementations to inherent implementations directly on the type itself.

Note that some traits had default methods which will also need to be implemented
to maintain backwards compatibility.

[breaking-change]
cc #18424
---
 src/libcollections/bench.rs                   |  88 ++++
 src/libcollections/bitv.rs                    | 114 ++--
 src/libcollections/btree/map.rs               | 223 ++++++--
 src/libcollections/btree/node.rs              |   1 -
 src/libcollections/btree/set.rs               | 162 +++++-
 src/libcollections/deque.rs                   |  96 ----
 src/libcollections/dlist.rs                   | 186 ++++---
 src/libcollections/enum_set.rs                |   2 -
 src/libcollections/hash/sip.rs                |   2 -
 src/libcollections/lib.rs                     | 459 +----------------
 src/libcollections/priority_queue.rs          |  21 +-
 src/libcollections/ringbuf.rs                 | 312 ++++++++---
 src/libcollections/slice.rs                   |   5 +-
 src/libcollections/smallintmap.rs             | 319 ++++++++----
 src/libcollections/str.rs                     |  28 +-
 src/libcollections/string.rs                  |  43 +-
 src/libcollections/treemap.rs                 | 487 ++++++++++++++----
 src/libcollections/trie.rs                    | 480 ++++++++++++-----
 src/libcollections/vec.rs                     | 167 +++---
 src/libcore/char.rs                           |   2 +-
 src/libcore/collections.rs                    |  38 --
 src/libcore/fmt/float.rs                      |   4 +-
 src/libcore/fmt/mod.rs                        |   1 -
 src/libcore/fmt/num.rs                        |   3 +-
 src/libcore/lib.rs                            |   1 -
 src/libcore/prelude.rs                        |   1 -
 src/libcore/slice.rs                          |  46 +-
 src/libcore/str.rs                            |  35 +-
 src/libgraphviz/maybe_owned_vec.rs            |  11 +-
 src/libregex/re.rs                            |  10 +-
 src/librlibc/lib.rs                           |   1 -
 src/librustc/middle/trans/adt.rs              |   1 -
 src/librustc/util/common.rs                   |   8 +-
 src/librustrt/at_exit_imp.rs                  |   1 -
 src/librustrt/c_str.rs                        |  20 +-
 src/librustrt/local_data.rs                   |   3 -
 src/libstd/ascii.rs                           |   1 -
 src/libstd/c_vec.rs                           |  11 +-
 src/libstd/collections/hashmap/map.rs         | 294 ++++++++---
 src/libstd/collections/hashmap/set.rs         | 174 ++++++-
 src/libstd/collections/lru_cache.rs           |  25 +-
 src/libstd/collections/mod.rs                 |   2 -
 src/libstd/dynamic_lib.rs                     |   2 -
 src/libstd/io/buffered.rs                     |   1 -
 src/libstd/io/comm_adapters.rs                |   1 -
 src/libstd/io/extensions.rs                   |   2 -
 src/libstd/io/fs.rs                           |   1 -
 src/libstd/io/mem.rs                          |   4 +-
 src/libstd/io/mod.rs                          |   1 -
 src/libstd/io/net/ip.rs                       |   3 +-
 src/libstd/num/strconv.rs                     |   1 -
 src/libstd/os.rs                              |   1 -
 src/libstd/path/mod.rs                        |   1 -
 src/libstd/path/posix.rs                      |   1 -
 src/libstd/path/windows.rs                    |   1 -
 src/libstd/prelude.rs                         |   2 -
 src/libstd/rand/os.rs                         |   3 +-
 src/libstd/rand/reader.rs                     |   2 +-
 src/libstd/rt/backtrace.rs                    |   3 -
 src/libsync/deque.rs                          |   2 +-
 src/libsync/raw.rs                            |   2 +-
 src/libsyntax/owned_slice.rs                  |   8 +-
 src/libsyntax/util/small_vector.rs            |  20 +-
 src/libunicode/u_str.rs                       |   2 +-
 src/test/bench/core-map.rs                    |  28 +-
 src/test/bench/core-set.rs                    |  23 +
 src/test/compile-fail/issue-16562.rs          |   2 +
 src/test/compile-fail/issue-16747.rs          |   2 +
 src/test/compile-fail/map-types.rs            |   6 +-
 .../class-impl-very-parameterized-trait.rs    |  12 -
 src/test/run-pass/issue-2383.rs               |   1 -
 src/test/run-pass/send_str_hashmap.rs         |   1 -
 src/test/run-pass/send_str_treemap.rs         |   1 -
 73 files changed, 2461 insertions(+), 1567 deletions(-)
 create mode 100644 src/libcollections/bench.rs
 delete mode 100644 src/libcollections/deque.rs
 delete mode 100644 src/libcore/collections.rs

diff --git a/src/libcollections/bench.rs b/src/libcollections/bench.rs
new file mode 100644
index 0000000000000..a212f22f89929
--- /dev/null
+++ b/src/libcollections/bench.rs
@@ -0,0 +1,88 @@
+// Copyright 2013-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.
+
+use std::prelude::*;
+use std::rand;
+use std::rand::Rng;
+use test::Bencher;
+
+pub fn insert_rand_n<M>(n: uint, map: &mut M, b: &mut Bencher,
+                        insert: |&mut M, uint|,
+                        remove: |&mut M, uint|) {
+    // setup
+    let mut rng = rand::weak_rng();
+
+    for _ in range(0, n) {
+        insert(map, rng.gen::<uint>() % n);
+    }
+
+    // measure
+    b.iter(|| {
+        let k = rng.gen::<uint>() % n;
+        insert(map, k);
+        remove(map, k);
+    })
+}
+
+pub fn insert_seq_n<M>(n: uint, map: &mut M, b: &mut Bencher,
+                       insert: |&mut M, uint|,
+                       remove: |&mut M, uint|) {
+    // setup
+    for i in range(0u, n) {
+        insert(map, i * 2);
+    }
+
+    // measure
+    let mut i = 1;
+    b.iter(|| {
+        insert(map, i);
+        remove(map, i);
+        i = (i + 2) % n;
+    })
+}
+
+pub fn find_rand_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
+                         insert: |&mut M, uint|,
+                         find: |&M, uint| -> T) {
+    // setup
+    let mut rng = rand::weak_rng();
+    let mut keys = Vec::from_fn(n, |_| rng.gen::<uint>() % n);
+
+    for k in keys.iter() {
+        insert(map, *k);
+    }
+
+    rng.shuffle(keys.as_mut_slice());
+
+    // measure
+    let mut i = 0;
+    b.iter(|| {
+        let t = find(map, keys[i]);
+        i = (i + 1) % n;
+        t
+    })
+}
+
+pub fn find_seq_n<M, T>(n: uint, map: &mut M, b: &mut Bencher,
+                        insert: |&mut M, uint|,
+                        find: |&M, uint| -> T) {
+    // setup
+    for i in range(0u, n) {
+        insert(map, i);
+    }
+
+    // measure
+    let mut i = 0;
+    b.iter(|| {
+        let x = find(map, i);
+        i = (i + 1) % n;
+        x
+    })
+}
diff --git a/src/libcollections/bitv.rs b/src/libcollections/bitv.rs
index 1b12fdcb8dc04..26e0c73724c6a 100644
--- a/src/libcollections/bitv.rs
+++ b/src/libcollections/bitv.rs
@@ -70,7 +70,6 @@ use core::slice;
 use core::u32;
 use std::hash;
 
-use {Mutable, Set, MutableSet, MutableSeq};
 use vec::Vec;
 
 type MatchWords<'a> = Chain<MaskWords<'a>, Skip<Take<Enumerate<Repeat<u32>>>>>;
@@ -755,6 +754,20 @@ impl Bitv {
         }
         self.set(insert_pos, elem);
     }
+
+    /// Return the total number of bits in this vector
+    #[inline]
+    pub fn len(&self) -> uint { self.nbits }
+
+    /// Returns true if there are no bits in this vector
+    #[inline]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears all bits in this vector.
+    #[inline]
+    pub fn clear(&mut self) {
+        for w in self.storage.iter_mut() { *w = 0u32; }
+    }
 }
 
 /// Transforms a byte-vector into a `Bitv`. Each byte becomes eight bits,
@@ -804,18 +817,6 @@ impl Default for Bitv {
     fn default() -> Bitv { Bitv::new() }
 }
 
-impl Collection for Bitv {
-    #[inline]
-    fn len(&self) -> uint { self.nbits }
-}
-
-impl Mutable for Bitv {
-    #[inline]
-    fn clear(&mut self) {
-        for w in self.storage.iter_mut() { *w = 0u32; }
-    }
-}
-
 impl FromIterator<bool> for Bitv {
     fn from_iter<I:Iterator<bool>>(iterator: I) -> Bitv {
         let mut ret = Bitv::new();
@@ -1466,61 +1467,45 @@ impl BitvSet {
     pub fn symmetric_difference_with(&mut self, other: &BitvSet) {
         self.other_op(other, |w1, w2| w1 ^ w2);
     }
-}
-
-impl fmt::Show for BitvSet {
-    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(fmt, "{{"));
-        let mut first = true;
-        for n in self.iter() {
-            if !first {
-                try!(write!(fmt, ", "));
-            }
-            try!(write!(fmt, "{}", n));
-            first = false;
-        }
-        write!(fmt, "}}")
-    }
-}
 
-impl<S: hash::Writer> hash::Hash<S> for BitvSet {
-    fn hash(&self, state: &mut S) {
-        for pos in self.iter() {
-            pos.hash(state);
-        }
+    /// Return the number of set bits in this set.
+    #[inline]
+    pub fn len(&self) -> uint  {
+        let &BitvSet(ref bitv) = self;
+        bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones())
     }
-}
 
-impl Collection for BitvSet {
+    /// Returns whether there are no bits set in this set
     #[inline]
-    fn len(&self) -> uint  {
+    pub fn is_empty(&self) -> bool {
         let &BitvSet(ref bitv) = self;
-        bitv.storage.iter().fold(0, |acc, &n| acc + n.count_ones())
+        bitv.storage.iter().all(|&n| n == 0)
     }
-}
 
-impl Mutable for BitvSet {
+    /// Clears all bits in this set
     #[inline]
-    fn clear(&mut self) {
+    pub fn clear(&mut self) {
         let &BitvSet(ref mut bitv) = self;
         bitv.clear();
     }
-}
 
-impl Set<uint> for BitvSet {
+    /// Returns `true` if this set contains the specified integer.
     #[inline]
-    fn contains(&self, value: &uint) -> bool {
+    pub fn contains(&self, value: &uint) -> bool {
         let &BitvSet(ref bitv) = self;
         *value < bitv.nbits && bitv.get(*value)
     }
 
+    /// Returns `true` if the set has no elements in common with `other`.
+    /// This is equivalent to checking for an empty intersection.
     #[inline]
-    fn is_disjoint(&self, other: &BitvSet) -> bool {
+    pub fn is_disjoint(&self, other: &BitvSet) -> bool {
         self.intersection(other).next().is_none()
     }
 
+    /// Returns `true` if the set is a subset of another.
     #[inline]
-    fn is_subset(&self, other: &BitvSet) -> bool {
+    pub fn is_subset(&self, other: &BitvSet) -> bool {
         let &BitvSet(ref self_bitv) = self;
         let &BitvSet(ref other_bitv) = other;
 
@@ -1531,14 +1516,15 @@ impl Set<uint> for BitvSet {
         self_bitv.mask_words(other_bitv.storage.len()).all(|(_, w)| w == 0)
     }
 
+    /// Returns `true` if the set is a superset of another.
     #[inline]
-    fn is_superset(&self, other: &BitvSet) -> bool {
+    pub fn is_superset(&self, other: &BitvSet) -> bool {
         other.is_subset(self)
     }
-}
 
-impl MutableSet<uint> for BitvSet {
-    fn insert(&mut self, value: uint) -> bool {
+    /// Adds a value to the set. Returns `true` if the value was not already
+    /// present in the set.
+    pub fn insert(&mut self, value: uint) -> bool {
         if self.contains(&value) {
             return false;
         }
@@ -1554,7 +1540,9 @@ impl MutableSet<uint> for BitvSet {
         return true;
     }
 
-    fn remove(&mut self, value: &uint) -> bool {
+    /// Removes a value from the set. Returns `true` if the value was
+    /// present in the set.
+    pub fn remove(&mut self, value: &uint) -> bool {
         if !self.contains(value) {
             return false;
         }
@@ -1564,6 +1552,29 @@ impl MutableSet<uint> for BitvSet {
     }
 }
 
+impl fmt::Show for BitvSet {
+    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
+        try!(write!(fmt, "{{"));
+        let mut first = true;
+        for n in self.iter() {
+            if !first {
+                try!(write!(fmt, ", "));
+            }
+            try!(write!(fmt, "{}", n));
+            first = false;
+        }
+        write!(fmt, "}}")
+    }
+}
+
+impl<S: hash::Writer> hash::Hash<S> for BitvSet {
+    fn hash(&self, state: &mut S) {
+        for pos in self.iter() {
+            pos.hash(state);
+        }
+    }
+}
+
 /// An iterator for `BitvSet`.
 pub struct BitPositions<'a> {
     set: &'a BitvSet,
@@ -1643,7 +1654,6 @@ mod tests {
     use std::rand::Rng;
     use test::Bencher;
 
-    use {Set, Mutable, MutableSet, MutableSeq};
     use bitv::{Bitv, BitvSet, from_fn, from_bytes};
     use bitv;
     use vec::Vec;
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index dc7d935619f9e..4570d49ba0ace 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -23,11 +23,8 @@ use core::default::Default;
 use core::{iter, fmt, mem};
 use core::fmt::Show;
 
-use {Deque, Map, MutableMap, Mutable, MutableSeq};
 use ringbuf::RingBuf;
 
-
-
 /// A map based on a B-Tree.
 ///
 /// B-Trees represent a fundamental compromise between cache-efficiency and actually minimizing
@@ -145,9 +142,25 @@ impl<K: Ord, V> BTreeMap<K, V> {
             b: b,
         }
     }
-}
 
-impl<K: Ord, V> Map<K, V> for BTreeMap<K, V> {
+    /// Clears the map, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut a = BTreeMap::new();
+    /// a.insert(1u, "a");
+    /// a.clear();
+    /// assert!(a.is_empty());
+    /// ```
+    pub fn clear(&mut self) {
+        let b = self.b;
+        // avoid recursive destructors by manually traversing the tree
+        for _ in mem::replace(self, BTreeMap::with_b(b)).into_iter() {};
+    }
+
     // Searching in a B-Tree is pretty straightforward.
     //
     // Start at the root. Try to find the key in the current node. If we find it, return it.
@@ -155,7 +168,20 @@ impl<K: Ord, V> Map<K, V> for BTreeMap<K, V> {
     // the search key. If no such key exists (they're *all* smaller), then just take the last
     // edge in the node. If we're in a leaf and we don't find our key, then it's not
     // in the tree.
-    fn find(&self, key: &K) -> Option<&V> {
+
+    /// Returns a reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.find(&1), Some(&"a"));
+    /// assert_eq!(map.find(&2), None);
+    /// ```
+    pub fn find(&self, key: &K) -> Option<&V> {
         let mut cur_node = &self.root;
         loop {
             match cur_node.search(key) {
@@ -170,11 +196,41 @@ impl<K: Ord, V> Map<K, V> for BTreeMap<K, V> {
             }
         }
     }
-}
 
-impl<K: Ord, V> MutableMap<K, V> for BTreeMap<K, V> {
+    /// Returns true if the map contains a value for the specified key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.contains_key(&1), true);
+    /// assert_eq!(map.contains_key(&2), false);
+    /// ```
+    #[inline]
+    pub fn contains_key(&self, key: &K) -> bool {
+        self.find(key).is_some()
+    }
+
+    /// Returns a mutable reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// map.insert(1u, "a");
+    /// match map.find_mut(&1) {
+    ///     Some(x) => *x = "b",
+    ///     None => (),
+    /// }
+    /// assert_eq!(map[1], "b");
+    /// ```
     // See `find` for implementation notes, this is basically a copy-paste with mut's added
-    fn find_mut(&mut self, key: &K) -> Option<&mut V> {
+    pub fn find_mut(&mut self, key: &K) -> Option<&mut V> {
         // temp_node is a Borrowck hack for having a mutable value outlive a loop iteration
         let mut temp_node = &mut self.root;
         loop {
@@ -218,7 +274,23 @@ impl<K: Ord, V> MutableMap<K, V> for BTreeMap<K, V> {
     // 2) While ODS may potentially return the pair we *just* inserted after
     // the split, we will never do this. Again, this shouldn't effect the analysis.
 
-    fn swap(&mut self, key: K, mut value: V) -> Option<V> {
+    /// Inserts a key-value pair from the map. If the key already had a value
+    /// present in the map, that value is returned. Otherwise, `None` is returned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// assert_eq!(map.swap(37u, "a"), None);
+    /// assert_eq!(map.is_empty(), false);
+    ///
+    /// map.insert(37, "b");
+    /// assert_eq!(map.swap(37, "c"), Some("b"));
+    /// assert_eq!(map[37], "c");
+    /// ```
+    pub fn swap(&mut self, key: K, mut value: V) -> Option<V> {
         // This is a stack of rawptrs to nodes paired with indices, respectively
         // representing the nodes and edges of our search path. We have to store rawptrs
         // because as far as Rust is concerned, we can mutate aliased data with such a
@@ -266,6 +338,25 @@ impl<K: Ord, V> MutableMap<K, V> for BTreeMap<K, V> {
         }
     }
 
+    /// Inserts a key-value pair into the map. An existing value for a
+    /// key is replaced by the new value. Returns `true` if the key did
+    /// not already exist in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// assert_eq!(map.insert(2u, "value"), true);
+    /// assert_eq!(map.insert(2, "value2"), false);
+    /// assert_eq!(map[2], "value2");
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, key: K, value: V) -> bool {
+        self.swap(key, value).is_none()
+    }
+
     // Deletion is the most complicated operation for a B-Tree.
     //
     // First we do the same kind of search described in
@@ -301,7 +392,20 @@ impl<K: Ord, V> MutableMap<K, V> for BTreeMap<K, V> {
     //      the underflow handling process on the parent. If merging merges the last two children
     //      of the root, then we replace the root with the merged node.
 
-    fn pop(&mut self, key: &K) -> Option<V> {
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.pop(&1), Some("a"));
+    /// assert_eq!(map.pop(&1), None);
+    /// ```
+    pub fn pop(&mut self, key: &K) -> Option<V> {
         // See `swap` for a more thorough description of the stuff going on in here
         let mut stack = stack::PartialSearchStack::new(self);
         loop {
@@ -322,6 +426,24 @@ impl<K: Ord, V> MutableMap<K, V> for BTreeMap<K, V> {
             }
         }
     }
+
+    /// Removes a key-value pair from the map. Returns `true` if the key
+    /// was present in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut map = BTreeMap::new();
+    /// assert_eq!(map.remove(&1u), false);
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove(&1), true);
+    /// ```
+    #[inline]
+    pub fn remove(&mut self, key: &K) -> bool {
+        self.pop(key).is_some()
+    }
 }
 
 /// The stack module provides a safe interface for constructing and manipulating a stack of ptrs
@@ -331,7 +453,6 @@ mod stack {
     use core::prelude::*;
     use super::BTreeMap;
     use super::super::node::*;
-    use {MutableMap, MutableSeq};
     use vec::Vec;
 
     type StackItem<K, V> = (*mut Node<K, V>, uint);
@@ -603,20 +724,6 @@ mod stack {
     }
 }
 
-impl<K, V> Collection for BTreeMap<K, V> {
-    fn len(&self) -> uint {
-        self.length
-    }
-}
-
-impl<K: Ord, V> Mutable for BTreeMap<K, V> {
-    fn clear(&mut self) {
-        let b = self.b;
-        // avoid recursive destructors by manually traversing the tree
-        for _ in mem::replace(self, BTreeMap::with_b(b)).into_iter() {};
-    }
-}
-
 impl<K: Ord, V> FromIterator<(K, V)> for BTreeMap<K, V> {
     fn from_iter<T: Iterator<(K, V)>>(iter: T) -> BTreeMap<K, V> {
         let mut map = BTreeMap::new();
@@ -950,6 +1057,34 @@ impl<K, V> BTreeMap<K, V> {
     pub fn values<'a>(&'a self) -> Values<'a, K, V> {
         self.iter().map(|(_, v)| v)
     }
+
+    /// Return the number of elements in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut a = BTreeMap::new();
+    /// assert_eq!(a.len(), 0);
+    /// a.insert(1u, "a");
+    /// assert_eq!(a.len(), 1);
+    /// ```
+    pub fn len(&self) -> uint { self.length }
+
+    /// Return true if the map contains no elements.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeMap;
+    ///
+    /// let mut a = BTreeMap::new();
+    /// assert!(a.is_empty());
+    /// a.insert(1u, "a");
+    /// assert!(!a.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl<K: Ord, V> BTreeMap<K, V> {
@@ -993,7 +1128,6 @@ impl<K: Ord, V> BTreeMap<K, V> {
 mod test {
     use std::prelude::*;
 
-    use {Map, MutableMap};
     use super::{BTreeMap, Occupied, Vacant};
 
     #[test]
@@ -1199,58 +1333,73 @@ mod bench {
     use test::{Bencher, black_box};
 
     use super::BTreeMap;
-    use MutableMap;
-    use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
+    use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
 
     #[bench]
     pub fn insert_rand_100(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        insert_rand_n(100, &mut m, b);
+        insert_rand_n(100, &mut m, b,
+                      |m, i| { m.insert(i, 1); },
+                      |m, i| { m.remove(&i); });
     }
 
     #[bench]
     pub fn insert_rand_10_000(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        insert_rand_n(10_000, &mut m, b);
+        insert_rand_n(10_000, &mut m, b,
+                      |m, i| { m.insert(i, 1); },
+                      |m, i| { m.remove(&i); });
     }
 
     // Insert seq
     #[bench]
     pub fn insert_seq_100(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        insert_seq_n(100, &mut m, b);
+        insert_seq_n(100, &mut m, b,
+                     |m, i| { m.insert(i, 1); },
+                     |m, i| { m.remove(&i); });
     }
 
     #[bench]
     pub fn insert_seq_10_000(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        insert_seq_n(10_000, &mut m, b);
+        insert_seq_n(10_000, &mut m, b,
+                     |m, i| { m.insert(i, 1); },
+                     |m, i| { m.remove(&i); });
     }
 
     // Find rand
     #[bench]
     pub fn find_rand_100(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        find_rand_n(100, &mut m, b);
+        find_rand_n(100, &mut m, b,
+                    |m, i| { m.insert(i, 1); },
+                    |m, i| { m.find(&i); });
     }
 
     #[bench]
     pub fn find_rand_10_000(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        find_rand_n(10_000, &mut m, b);
+        find_rand_n(10_000, &mut m, b,
+                    |m, i| { m.insert(i, 1); },
+                    |m, i| { m.find(&i); });
     }
 
     // Find seq
     #[bench]
     pub fn find_seq_100(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        find_seq_n(100, &mut m, b);
+        find_seq_n(100, &mut m, b,
+                   |m, i| { m.insert(i, 1); },
+                   |m, i| { m.find(&i); });
     }
 
     #[bench]
     pub fn find_seq_10_000(b: &mut Bencher) {
         let mut m : BTreeMap<uint,uint> = BTreeMap::new();
-        find_seq_n(10_000, &mut m, b);
+        find_seq_n(10_000, &mut m, b,
+                   |m, i| { m.insert(i, 1); },
+                   |m, i| { m.find(&i); });
     }
 
     fn bench_iter(b: &mut Bencher, size: uint) {
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index 6b491096e7da4..a15d31ba2842a 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -15,7 +15,6 @@ use core::prelude::*;
 
 use core::{slice, mem, ptr};
 use core::iter::Zip;
-use MutableSeq;
 
 use vec;
 use vec::Vec;
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 8958f0ef5bee7..eac74098758ae 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -20,8 +20,6 @@ use core::{iter, fmt};
 use core::iter::Peekable;
 use core::fmt::Show;
 
-use {Mutable, Set, MutableSet, MutableMap, Map};
-
 /// A set based on a B-Tree.
 ///
 /// See BTreeMap's documentation for a detailed discussion of this collection's performance
@@ -109,30 +107,104 @@ impl<T: Ord> BTreeSet<T> {
     pub fn union<'a>(&'a self, other: &'a BTreeSet<T>) -> UnionItems<'a, T> {
         UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
     }
-}
-
-impl<T> Collection for BTreeSet<T> {
-    fn len(&self) -> uint {
-        self.map.len()
-    }
-}
 
-impl<T: Ord> Mutable for BTreeSet<T> {
-    fn clear(&mut self) {
+    /// Return the number of elements in the set
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut v = BTreeSet::new();
+    /// assert_eq!(v.len(), 0);
+    /// v.insert(1i);
+    /// assert_eq!(v.len(), 1);
+    /// ```
+    pub fn len(&self) -> uint { self.map.len() }
+
+    /// Returns true if the set contains no elements
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut v = BTreeSet::new();
+    /// assert!(v.is_empty());
+    /// v.insert(1i);
+    /// assert!(!v.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the set, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut v = BTreeSet::new();
+    /// v.insert(1i);
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    pub fn clear(&mut self) {
         self.map.clear()
     }
-}
 
-impl<T: Ord> Set<T> for BTreeSet<T> {
-    fn contains(&self, value: &T) -> bool {
+    /// Returns `true` if the set contains a value.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let set: BTreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+    /// assert_eq!(set.contains(&1), true);
+    /// assert_eq!(set.contains(&4), false);
+    /// ```
+    pub fn contains(&self, value: &T) -> bool {
         self.map.find(value).is_some()
     }
 
-    fn is_disjoint(&self, other: &BTreeSet<T>) -> bool {
+    /// Returns `true` if the set has no elements in common with `other`.
+    /// This is equivalent to checking for an empty intersection.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let a: BTreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+    /// let mut b: BTreeSet<int> = BTreeSet::new();
+    ///
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(4);
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(1);
+    /// assert_eq!(a.is_disjoint(&b), false);
+    /// ```
+    pub fn is_disjoint(&self, other: &BTreeSet<T>) -> bool {
         self.intersection(other).next().is_none()
     }
 
-    fn is_subset(&self, other: &BTreeSet<T>) -> bool {
+    /// Returns `true` if the set is a subset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let sup: BTreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+    /// let mut set: BTreeSet<int> = BTreeSet::new();
+    ///
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(2);
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(4);
+    /// assert_eq!(set.is_subset(&sup), false);
+    /// ```
+    pub fn is_subset(&self, other: &BTreeSet<T>) -> bool {
         // Stolen from TreeMap
         let mut x = self.iter();
         let mut y = other.iter();
@@ -156,14 +228,63 @@ impl<T: Ord> Set<T> for BTreeSet<T> {
         }
         true
     }
-}
 
-impl<T: Ord> MutableSet<T> for BTreeSet<T>{
-    fn insert(&mut self, value: T) -> bool {
+    /// Returns `true` if the set is a superset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let sub: BTreeSet<int> = [1i, 2].iter().map(|&x| x).collect();
+    /// let mut set: BTreeSet<int> = BTreeSet::new();
+    ///
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(0);
+    /// set.insert(1);
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(2);
+    /// assert_eq!(set.is_superset(&sub), true);
+    /// ```
+    pub fn is_superset(&self, other: &BTreeSet<T>) -> bool {
+        other.is_subset(self)
+    }
+
+    /// Adds a value to the set. Returns `true` if the value was not already
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut set = BTreeSet::new();
+    ///
+    /// assert_eq!(set.insert(2i), true);
+    /// assert_eq!(set.insert(2i), false);
+    /// assert_eq!(set.len(), 1);
+    /// ```
+    pub fn insert(&mut self, value: T) -> bool {
         self.map.insert(value, ())
     }
 
-    fn remove(&mut self, value: &T) -> bool {
+    /// Removes a value from the set. Returns `true` if the value was
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut set = BTreeSet::new();
+    ///
+    /// set.insert(2i);
+    /// assert_eq!(set.remove(&2), true);
+    /// assert_eq!(set.remove(&2), false);
+    /// ```
+    pub fn remove(&mut self, value: &T) -> bool {
         self.map.remove(value)
     }
 }
@@ -273,7 +394,6 @@ impl<'a, T: Ord> Iterator<&'a T> for UnionItems<'a, T> {
 mod test {
     use std::prelude::*;
 
-    use {Set, MutableSet};
     use super::BTreeSet;
     use std::hash;
 
diff --git a/src/libcollections/deque.rs b/src/libcollections/deque.rs
deleted file mode 100644
index d7970ed8d60c3..0000000000000
--- a/src/libcollections/deque.rs
+++ /dev/null
@@ -1,96 +0,0 @@
-// Copyright 2013-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.
-
-//! Container traits for collections.
-
-#[cfg(test)]
-pub mod bench {
-    use std::prelude::*;
-    use std::rand;
-    use std::rand::Rng;
-    use test::Bencher;
-    use MutableMap;
-
-    pub fn insert_rand_n<M: MutableMap<uint, uint>>(n: uint,
-                                                    map: &mut M,
-                                                    b: &mut Bencher) {
-        // setup
-        let mut rng = rand::weak_rng();
-
-        map.clear();
-        for _ in range(0, n) {
-            map.insert(rng.gen::<uint>() % n, 1);
-        }
-
-        // measure
-        b.iter(|| {
-            let k = rng.gen::<uint>() % n;
-            map.insert(k, 1);
-            map.remove(&k);
-        })
-    }
-
-    pub fn insert_seq_n<M: MutableMap<uint, uint>>(n: uint,
-                                                   map: &mut M,
-                                                   b: &mut Bencher) {
-        // setup
-        map.clear();
-        for i in range(0u, n) {
-            map.insert(i*2, 1);
-        }
-
-        // measure
-        let mut i = 1;
-        b.iter(|| {
-            map.insert(i, 1);
-            map.remove(&i);
-            i = (i + 2) % n;
-        })
-    }
-
-    pub fn find_rand_n<M:MutableMap<uint,uint>>(n: uint,
-                                                map: &mut M,
-                                                b: &mut Bencher) {
-        // setup
-        let mut rng = rand::weak_rng();
-        let mut keys = Vec::from_fn(n, |_| rng.gen::<uint>() % n);
-
-        for k in keys.iter() {
-            map.insert(*k, 1);
-        }
-
-        rng.shuffle(keys.as_mut_slice());
-
-        // measure
-        let mut i = 0;
-        b.iter(|| {
-            map.find(&keys[i]);
-            i = (i + 1) % n;
-        })
-    }
-
-    pub fn find_seq_n<M:MutableMap<uint,uint>>(n: uint,
-                                               map: &mut M,
-                                               b: &mut Bencher) {
-        // setup
-        for i in range(0u, n) {
-            map.insert(i, 1);
-        }
-
-        // measure
-        let mut i = 0;
-        b.iter(|| {
-            let x = map.find(&i);
-            i = (i + 1) % n;
-            x
-        })
-     }
-}
-
diff --git a/src/libcollections/dlist.rs b/src/libcollections/dlist.rs
index 22d487bd3a0db..a1e286d124574 100644
--- a/src/libcollections/dlist.rs
+++ b/src/libcollections/dlist.rs
@@ -31,8 +31,6 @@ use core::mem;
 use core::ptr;
 use std::hash::{Writer, Hash};
 
-use {Mutable, Deque, MutableSeq};
-
 /// A doubly-linked list.
 pub struct DList<T> {
     length: uint,
@@ -129,34 +127,6 @@ fn link_with_prev<T>(mut next: Box<Node<T>>, prev: Rawlink<Node<T>>)
     Some(next)
 }
 
-impl<T> Collection for DList<T> {
-    /// Returns `true` if the `DList` is empty.
-    ///
-    /// This operation should compute in O(1) time.
-    #[inline]
-    fn is_empty(&self) -> bool {
-        self.list_head.is_none()
-    }
-
-    /// Returns the length of the `DList`.
-    ///
-    /// This operation should compute in O(1) time.
-    #[inline]
-    fn len(&self) -> uint {
-        self.length
-    }
-}
-
-impl<T> Mutable for DList<T> {
-    /// Removes all elements from the `DList`.
-    ///
-    /// This operation should compute in O(n) time.
-    #[inline]
-    fn clear(&mut self) {
-        *self = DList::new()
-    }
-}
-
 // private methods
 impl<T> DList<T> {
     /// Add a Node first in the list
@@ -217,60 +187,6 @@ impl<T> DList<T> {
     }
 }
 
-impl<T> Deque<T> for DList<T> {
-    /// Provides a reference to the front element, or `None` if the list is
-    /// empty.
-    #[inline]
-    fn front<'a>(&'a self) -> Option<&'a T> {
-        self.list_head.as_ref().map(|head| &head.value)
-    }
-
-    /// Provides a mutable reference to the front element, or `None` if the list
-    /// is empty.
-    #[inline]
-    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
-        self.list_head.as_mut().map(|head| &mut head.value)
-    }
-
-    /// Provides a reference to the back element, or `None` if the list is
-    /// empty.
-    #[inline]
-    fn back<'a>(&'a self) -> Option<&'a T> {
-        self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value)
-    }
-
-    /// Provides a mutable reference to the back element, or `None` if the list
-    /// is empty.
-    #[inline]
-    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
-        self.list_tail.resolve().map(|tail| &mut tail.value)
-    }
-
-    /// Adds an element first in the list.
-    ///
-    /// This operation should compute in O(1) time.
-    fn push_front(&mut self, elt: T) {
-        self.push_front_node(box Node::new(elt))
-    }
-
-    /// Removes the first element and returns it, or `None` if the list is
-    /// empty.
-    ///
-    /// This operation should compute in O(1) time.
-    fn pop_front(&mut self) -> Option<T> {
-        self.pop_front_node().map(|box Node{value, ..}| value)
-    }
-}
-
-impl<T> MutableSeq<T> for DList<T> {
-    fn push(&mut self, elt: T) {
-        self.push_back_node(box Node::new(elt))
-    }
-    fn pop(&mut self) -> Option<T> {
-        self.pop_back_node().map(|box Node{value, ..}| value)
-    }
-}
-
 impl<T> Default for DList<T> {
     #[inline]
     fn default() -> DList<T> { DList::new() }
@@ -495,6 +411,107 @@ impl<T> DList<T> {
     pub fn into_iter(self) -> MoveItems<T> {
         MoveItems{list: self}
     }
+
+    /// Returns `true` if the `DList` is empty.
+    ///
+    /// This operation should compute in O(1) time.
+    #[inline]
+    pub fn is_empty(&self) -> bool {
+        self.list_head.is_none()
+    }
+
+    /// Returns the length of the `DList`.
+    ///
+    /// This operation should compute in O(1) time.
+    #[inline]
+    pub fn len(&self) -> uint {
+        self.length
+    }
+
+    /// Removes all elements from the `DList`.
+    ///
+    /// This operation should compute in O(n) time.
+    #[inline]
+    pub fn clear(&mut self) {
+        *self = DList::new()
+    }
+
+    /// Provides a reference to the front element, or `None` if the list is
+    /// empty.
+    #[inline]
+    pub fn front<'a>(&'a self) -> Option<&'a T> {
+        self.list_head.as_ref().map(|head| &head.value)
+    }
+
+    /// Provides a mutable reference to the front element, or `None` if the list
+    /// is empty.
+    #[inline]
+    pub fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+        self.list_head.as_mut().map(|head| &mut head.value)
+    }
+
+    /// Provides a reference to the back element, or `None` if the list is
+    /// empty.
+    #[inline]
+    pub fn back<'a>(&'a self) -> Option<&'a T> {
+        self.list_tail.resolve_immut().as_ref().map(|tail| &tail.value)
+    }
+
+    /// Provides a mutable reference to the back element, or `None` if the list
+    /// is empty.
+    #[inline]
+    pub fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
+        self.list_tail.resolve().map(|tail| &mut tail.value)
+    }
+
+    /// Adds an element first in the list.
+    ///
+    /// This operation should compute in O(1) time.
+    pub fn push_front(&mut self, elt: T) {
+        self.push_front_node(box Node::new(elt))
+    }
+
+    /// Removes the first element and returns it, or `None` if the list is
+    /// empty.
+    ///
+    /// This operation should compute in O(1) time.
+    pub fn pop_front(&mut self) -> Option<T> {
+        self.pop_front_node().map(|box Node{value, ..}| value)
+    }
+
+    /// Appends an element to the back of a list
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::collections::DList;
+    ///
+    /// let mut d = DList::new();
+    /// d.push(1i);
+    /// d.push(3);
+    /// assert_eq!(3, *d.back().unwrap());
+    /// ```
+    pub fn push(&mut self, elt: T) {
+        self.push_back_node(box Node::new(elt))
+    }
+
+    /// Removes the last element from a list and returns it, or `None` if
+    /// it is empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::collections::DList;
+    ///
+    /// let mut d = DList::new();
+    /// assert_eq!(d.pop(), None);
+    /// d.push(1i);
+    /// d.push(3);
+    /// assert_eq!(d.pop(), Some(3));
+    /// ```
+    pub fn pop(&mut self) -> Option<T> {
+        self.pop_back_node().map(|box Node{value, ..}| value)
+    }
 }
 
 impl<T: Ord> DList<T> {
@@ -745,7 +762,6 @@ mod tests {
     use test::Bencher;
     use test;
 
-    use {Deque, MutableSeq};
     use super::{DList, Node, ListInsertion};
     use vec::Vec;
 
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index f282549f6f9a4..b78c1897b0659 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -157,8 +157,6 @@ mod test {
 
     use enum_set::{EnumSet, CLike};
 
-    use MutableSeq;
-
     #[deriving(PartialEq, Show)]
     #[repr(uint)]
     enum Foo {
diff --git a/src/libcollections/hash/sip.rs b/src/libcollections/hash/sip.rs
index 4ac06a884a669..cef27212d44e8 100644
--- a/src/libcollections/hash/sip.rs
+++ b/src/libcollections/hash/sip.rs
@@ -279,8 +279,6 @@ mod tests {
     use super::super::{Hash, Writer};
     use super::{SipState, hash, hash_with_keys};
 
-    use MutableSeq;
-
     // Hash just the bytes of the slice, without length prefix
     struct Bytes<'a>(&'a [u8]);
 
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index 20ad5b6334f32..e28bc76648015 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -37,11 +37,8 @@ extern crate alloc;
 #[cfg(test)] #[phase(plugin, link)] extern crate std;
 #[cfg(test)] #[phase(plugin, link)] extern crate log;
 
-use core::prelude::Option;
-
 pub use bitv::{Bitv, BitvSet};
 pub use btree::{BTreeMap, BTreeSet};
-pub use core::prelude::Collection;
 pub use dlist::DList;
 pub use enum_set::EnumSet;
 pub use priority_queue::PriorityQueue;
@@ -69,457 +66,7 @@ pub mod string;
 pub mod vec;
 pub mod hash;
 
-mod deque;
-
-/// A mutable container type.
-pub trait Mutable: Collection {
-    /// Clears the container, removing all values.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// let mut v = vec![1i, 2, 3];
-    /// v.clear();
-    /// assert!(v.is_empty());
-    /// ```
-    fn clear(&mut self);
-}
-
-/// A key-value store where values may be looked up by their keys. This trait
-/// provides basic operations to operate on these stores.
-pub trait Map<K, V>: Collection {
-    /// Returns a reference to the value corresponding to the key.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1i);
-    /// assert_eq!(map.find(&"a"), Some(&1i));
-    /// assert_eq!(map.find(&"b"), None);
-    /// ```
-    fn find<'a>(&'a self, key: &K) -> Option<&'a V>;
-
-    /// Returns true if the map contains a value for the specified key.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1i);
-    /// assert_eq!(map.contains_key(&"a"), true);
-    /// assert_eq!(map.contains_key(&"b"), false);
-    /// ```
-    #[inline]
-    fn contains_key(&self, key: &K) -> bool {
-        self.find(key).is_some()
-    }
-}
-
-/// A key-value store (map) where the values can be modified.
-pub trait MutableMap<K, V>: Map<K, V> + Mutable {
-    /// Inserts a key-value pair into the map. An existing value for a
-    /// key is replaced by the new value. Returns `true` if the key did
-    /// not already exist in the map.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// assert_eq!(map.insert("key", 2i), true);
-    /// assert_eq!(map.insert("key", 9i), false);
-    /// assert_eq!(map["key"], 9i);
-    /// ```
-    #[inline]
-    fn insert(&mut self, key: K, value: V) -> bool {
-        self.swap(key, value).is_none()
-    }
-
-    /// Removes a key-value pair from the map. Returns `true` if the key
-    /// was present in the map.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// assert_eq!(map.remove(&"key"), false);
-    /// map.insert("key", 2i);
-    /// assert_eq!(map.remove(&"key"), true);
-    /// ```
-    #[inline]
-    fn remove(&mut self, key: &K) -> bool {
-        self.pop(key).is_some()
-    }
-
-    /// Inserts a key-value pair into the map. If the key already had a value
-    /// present in the map, that value is returned. Otherwise, `None` is
-    /// returned.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// assert_eq!(map.swap("a", 37i), None);
-    /// assert_eq!(map.is_empty(), false);
-    ///
-    /// map.insert("a", 1i);
-    /// assert_eq!(map.swap("a", 37i), Some(1i));
-    /// assert_eq!(map["a"], 37i);
-    /// ```
-    fn swap(&mut self, k: K, v: V) -> Option<V>;
-
-    /// Removes a key from the map, returning the value at the key if the key
-    /// was previously in the map.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map: HashMap<&str, int> = HashMap::new();
-    /// map.insert("a", 1i);
-    /// assert_eq!(map.pop(&"a"), Some(1i));
-    /// assert_eq!(map.pop(&"a"), None);
-    /// ```
-    fn pop(&mut self, k: &K) -> Option<V>;
-
-    /// Returns a mutable reference to the value corresponding to the key.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashMap;
-    ///
-    /// let mut map = HashMap::new();
-    /// map.insert("a", 1i);
-    /// match map.find_mut(&"a") {
-    ///     Some(x) => *x = 7i,
-    ///     None => (),
-    /// }
-    /// assert_eq!(map["a"], 7i);
-    /// ```
-    fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V>;
-}
-
-/// A group of objects which are each distinct from one another. This
-/// trait represents actions which can be performed on sets to iterate over
-/// them.
-pub trait Set<T>: Collection {
-    /// Returns `true` if the set contains a value.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let set: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
-    /// assert_eq!(set.contains(&1), true);
-    /// assert_eq!(set.contains(&4), false);
-    /// ```
-    fn contains(&self, value: &T) -> bool;
-
-    /// Returns `true` if the set has no elements in common with `other`.
-    /// This is equivalent to checking for an empty intersection.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let a: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
-    /// let mut b: HashSet<int> = HashSet::new();
-    ///
-    /// assert_eq!(a.is_disjoint(&b), true);
-    /// b.insert(4);
-    /// assert_eq!(a.is_disjoint(&b), true);
-    /// b.insert(1);
-    /// assert_eq!(a.is_disjoint(&b), false);
-    /// ```
-    fn is_disjoint(&self, other: &Self) -> bool;
-
-    /// Returns `true` if the set is a subset of another.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let sup: HashSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
-    /// let mut set: HashSet<int> = HashSet::new();
-    ///
-    /// assert_eq!(set.is_subset(&sup), true);
-    /// set.insert(2);
-    /// assert_eq!(set.is_subset(&sup), true);
-    /// set.insert(4);
-    /// assert_eq!(set.is_subset(&sup), false);
-    /// ```
-    fn is_subset(&self, other: &Self) -> bool;
-
-    /// Returns `true` if the set is a superset of another.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let sub: HashSet<int> = [1i, 2].iter().map(|&x| x).collect();
-    /// let mut set: HashSet<int> = HashSet::new();
-    ///
-    /// assert_eq!(set.is_superset(&sub), false);
-    ///
-    /// set.insert(0);
-    /// set.insert(1);
-    /// assert_eq!(set.is_superset(&sub), false);
-    ///
-    /// set.insert(2);
-    /// assert_eq!(set.is_superset(&sub), true);
-    /// ```
-    fn is_superset(&self, other: &Self) -> bool {
-        other.is_subset(self)
-    }
-
-    // FIXME #8154: Add difference, sym. difference, intersection and union iterators
-}
-
-/// A mutable collection of values which are distinct from one another that
-/// can be mutated.
-pub trait MutableSet<T>: Set<T> + Mutable {
-    /// Adds a value to the set. Returns `true` if the value was not already
-    /// present in the set.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut set = HashSet::new();
-    ///
-    /// assert_eq!(set.insert(2i), true);
-    /// assert_eq!(set.insert(2i), false);
-    /// assert_eq!(set.len(), 1);
-    /// ```
-    fn insert(&mut self, value: T) -> bool;
-
-    /// Removes a value from the set. Returns `true` if the value was
-    /// present in the set.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::HashSet;
-    ///
-    /// let mut set = HashSet::new();
-    ///
-    /// set.insert(2i);
-    /// assert_eq!(set.remove(&2), true);
-    /// assert_eq!(set.remove(&2), false);
-    /// ```
-    fn remove(&mut self, value: &T) -> bool;
-}
-
-pub trait MutableSeq<T>: Mutable {
-    /// Appends an element to the back of a collection.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1i, 2);
-    /// vec.push(3);
-    /// assert_eq!(vec, vec!(1, 2, 3));
-    /// ```
-    fn push(&mut self, t: T);
-
-    /// Removes the last element from a collection and returns it, or `None` if
-    /// it is empty.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1i, 2, 3);
-    /// assert_eq!(vec.pop(), Some(3));
-    /// assert_eq!(vec, vec!(1, 2));
-    /// ```
-    fn pop(&mut self) -> Option<T>;
-}
-
-/// A double-ended sequence that allows querying, insertion and deletion at both
-/// ends.
-///
-/// # Example
-///
-/// With a `Deque` we can simulate a queue efficiently:
-///
-/// ```
-/// use std::collections::{RingBuf, Deque};
-///
-/// let mut queue = RingBuf::new();
-/// queue.push(1i);
-/// queue.push(2i);
-/// queue.push(3i);
-///
-/// // Will print 1, 2, 3
-/// while !queue.is_empty() {
-///     let x = queue.pop_front().unwrap();
-///     println!("{}", x);
-/// }
-/// ```
-///
-/// We can also simulate a stack:
-///
-/// ```
-/// use std::collections::{RingBuf, Deque};
-///
-/// let mut stack = RingBuf::new();
-/// stack.push_front(1i);
-/// stack.push_front(2i);
-/// stack.push_front(3i);
-///
-/// // Will print 3, 2, 1
-/// while !stack.is_empty() {
-///     let x = stack.pop_front().unwrap();
-///     println!("{}", x);
-/// }
-/// ```
-///
-/// And of course we can mix and match:
-///
-/// ```
-/// use std::collections::{DList, Deque};
-///
-/// let mut deque = DList::new();
-///
-/// // Init deque with 1, 2, 3, 4
-/// deque.push_front(2i);
-/// deque.push_front(1i);
-/// deque.push(3i);
-/// deque.push(4i);
-///
-/// // Will print (1, 4) and (2, 3)
-/// while !deque.is_empty() {
-///     let f = deque.pop_front().unwrap();
-///     let b = deque.pop().unwrap();
-///     println!("{}", (f, b));
-/// }
-/// ```
-pub trait Deque<T> : MutableSeq<T> {
-    /// Provides a reference to the front element, or `None` if the sequence is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::{RingBuf, Deque};
-    ///
-    /// let mut d = RingBuf::new();
-    /// assert_eq!(d.front(), None);
-    ///
-    /// d.push(1i);
-    /// d.push(2i);
-    /// assert_eq!(d.front(), Some(&1i));
-    /// ```
-    fn front<'a>(&'a self) -> Option<&'a T>;
-
-    /// Provides a mutable reference to the front element, or `None` if the
-    /// sequence is empty.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::{RingBuf, Deque};
-    ///
-    /// let mut d = RingBuf::new();
-    /// assert_eq!(d.front_mut(), None);
-    ///
-    /// d.push(1i);
-    /// d.push(2i);
-    /// match d.front_mut() {
-    ///     Some(x) => *x = 9i,
-    ///     None => (),
-    /// }
-    /// assert_eq!(d.front(), Some(&9i));
-    /// ```
-    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T>;
-
-    /// Provides a reference to the back element, or `None` if the sequence is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::{DList, Deque};
-    ///
-    /// let mut d = DList::new();
-    /// assert_eq!(d.back(), None);
-    ///
-    /// d.push(1i);
-    /// d.push(2i);
-    /// assert_eq!(d.back(), Some(&2i));
-    /// ```
-    fn back<'a>(&'a self) -> Option<&'a T>;
-
-    /// Provides a mutable reference to the back element, or `None` if the
-    /// sequence is empty.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::{DList, Deque};
-    ///
-    /// let mut d = DList::new();
-    /// assert_eq!(d.back(), None);
-    ///
-    /// d.push(1i);
-    /// d.push(2i);
-    /// match d.back_mut() {
-    ///     Some(x) => *x = 9i,
-    ///     None => (),
-    /// }
-    /// assert_eq!(d.back(), Some(&9i));
-    /// ```
-    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T>;
-
-    /// Inserts an element first in the sequence.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::{DList, Deque};
-    ///
-    /// let mut d = DList::new();
-    /// d.push_front(1i);
-    /// d.push_front(2i);
-    /// assert_eq!(d.front(), Some(&2i));
-    /// ```
-    fn push_front(&mut self, elt: T);
-
-    /// Removes the first element and returns it, or `None` if the sequence is
-    /// empty.
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// use std::collections::{RingBuf, Deque};
-    ///
-    /// let mut d = RingBuf::new();
-    /// d.push(1i);
-    /// d.push(2i);
-    ///
-    /// assert_eq!(d.pop_front(), Some(1i));
-    /// assert_eq!(d.pop_front(), Some(2i));
-    /// assert_eq!(d.pop_front(), None);
-    /// ```
-    fn pop_front(&mut self) -> Option<T>;
-}
+#[cfg(test)] mod bench;
 
 // FIXME(#14344) this shouldn't be necessary
 #[doc(hidden)]
@@ -532,8 +79,4 @@ mod std {
     pub use core::clone;    // deriving(Clone)
     pub use core::cmp;      // deriving(Eq, Ord, etc.)
     pub use hash;           // deriving(Hash)
-
-    pub mod collections {
-        pub use MutableSeq;
-    }
 }
diff --git a/src/libcollections/priority_queue.rs b/src/libcollections/priority_queue.rs
index 65fd8ce4f54d9..885b5c99c4501 100644
--- a/src/libcollections/priority_queue.rs
+++ b/src/libcollections/priority_queue.rs
@@ -159,7 +159,6 @@ use core::default::Default;
 use core::mem::{zeroed, replace, swap};
 use core::ptr;
 
-use {Mutable, MutableSeq};
 use slice;
 use vec::Vec;
 
@@ -171,16 +170,6 @@ pub struct PriorityQueue<T> {
     data: Vec<T>,
 }
 
-impl<T: Ord> Collection for PriorityQueue<T> {
-    /// Returns the length of the queue.
-    fn len(&self) -> uint { self.data.len() }
-}
-
-impl<T: Ord> Mutable for PriorityQueue<T> {
-    /// Drops all items from the queue.
-    fn clear(&mut self) { self.data.truncate(0) }
-}
-
 impl<T: Ord> Default for PriorityQueue<T> {
     #[inline]
     fn default() -> PriorityQueue<T> { PriorityQueue::new() }
@@ -504,6 +493,15 @@ impl<T: Ord> PriorityQueue<T> {
         let len = self.len();
         self.siftdown_range(pos, len);
     }
+
+    /// Returns the length of the queue.
+    pub fn len(&self) -> uint { self.data.len() }
+
+    /// Returns true if the queue contains no elements
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Drops all items from the queue.
+    pub fn clear(&mut self) { self.data.truncate(0) }
 }
 
 /// `PriorityQueue` iterator.
@@ -545,7 +543,6 @@ mod tests {
 
     use priority_queue::PriorityQueue;
     use vec::Vec;
-    use MutableSeq;
 
     #[test]
     fn test_iterator() {
diff --git a/src/libcollections/ringbuf.rs b/src/libcollections/ringbuf.rs
index 81e4361ec3949..3c4c3fce61d77 100644
--- a/src/libcollections/ringbuf.rs
+++ b/src/libcollections/ringbuf.rs
@@ -22,7 +22,6 @@ use core::iter;
 use core::slice;
 use std::hash::{Writer, Hash};
 
-use {Deque, Mutable, MutableSeq};
 use vec::Vec;
 
 static INITIAL_CAPACITY: uint = 8u; // 2^3
@@ -36,86 +35,6 @@ pub struct RingBuf<T> {
     elts: Vec<Option<T>>
 }
 
-impl<T> Collection for RingBuf<T> {
-    /// Returns the number of elements in the `RingBuf`.
-    fn len(&self) -> uint { self.nelts }
-}
-
-impl<T> Mutable for RingBuf<T> {
-    /// Clears the `RingBuf`, removing all values.
-    fn clear(&mut self) {
-        for x in self.elts.iter_mut() { *x = None }
-        self.nelts = 0;
-        self.lo = 0;
-    }
-}
-
-impl<T> Deque<T> for RingBuf<T> {
-    /// Returns a reference to the first element in the `RingBuf`.
-    fn front<'a>(&'a self) -> Option<&'a T> {
-        if self.nelts > 0 { Some(&self[0]) } else { None }
-    }
-
-    /// Returns a mutable reference to the first element in the `RingBuf`.
-    fn front_mut<'a>(&'a mut self) -> Option<&'a mut T> {
-        if self.nelts > 0 { Some(&mut self[0]) } else { None }
-    }
-
-    /// Returns a reference to the last element in the `RingBuf`.
-    fn back<'a>(&'a self) -> Option<&'a T> {
-        if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None }
-    }
-
-    /// Returns a mutable reference to the last element in the `RingBuf`.
-    fn back_mut<'a>(&'a mut self) -> Option<&'a mut T> {
-        let nelts = self.nelts;
-        if nelts > 0 { Some(&mut self[nelts - 1]) } else { None }
-    }
-
-    /// Removes and returns the first element in the `RingBuf`, or `None` if it
-    /// is empty.
-    fn pop_front(&mut self) -> Option<T> {
-        let result = self.elts[self.lo].take();
-        if result.is_some() {
-            self.lo = (self.lo + 1u) % self.elts.len();
-            self.nelts -= 1u;
-        }
-        result
-    }
-
-    /// Prepends an element to the `RingBuf`.
-    fn push_front(&mut self, t: T) {
-        if self.nelts == self.elts.len() {
-            grow(self.nelts, &mut self.lo, &mut self.elts);
-        }
-        if self.lo == 0u {
-            self.lo = self.elts.len() - 1u;
-        } else { self.lo -= 1u; }
-        self.elts[self.lo] = Some(t);
-        self.nelts += 1u;
-    }
-}
-
-impl<T> MutableSeq<T> for RingBuf<T> {
-    fn push(&mut self, t: T) {
-        if self.nelts == self.elts.len() {
-            grow(self.nelts, &mut self.lo, &mut self.elts);
-        }
-        let hi = self.raw_index(self.nelts);
-        self.elts[hi] = Some(t);
-        self.nelts += 1u;
-    }
-    fn pop(&mut self) -> Option<T> {
-        if self.nelts > 0 {
-            self.nelts -= 1;
-            let hi = self.raw_index(self.nelts);
-            self.elts[hi].take()
-        } else {
-            None
-        }
-    }
-}
-
 impl<T> Default for RingBuf<T> {
     #[inline]
     fn default() -> RingBuf<T> { RingBuf::new() }
@@ -151,7 +70,7 @@ impl<T> RingBuf<T> {
     /// assert_eq!(buf[1], 7);
     /// ```
     #[deprecated = "use indexing instead: `buf[index] = value`"]
-    pub fn get_mut<'a>(&'a mut self, i: uint) -> &'a mut T {
+    pub fn get_mut(&mut self, i: uint) -> &mut T {
         &mut self[i]
     }
 
@@ -219,7 +138,7 @@ impl<T> RingBuf<T> {
     /// let b: &[_] = &[&5, &3, &4];
     /// assert_eq!(buf.iter().collect::<Vec<&int>>().as_slice(), b);
     /// ```
-    pub fn iter<'a>(&'a self) -> Items<'a, T> {
+    pub fn iter(&self) -> Items<T> {
         Items{index: 0, rindex: self.nelts, lo: self.lo, elts: self.elts.as_slice()}
     }
 
@@ -240,7 +159,7 @@ impl<T> RingBuf<T> {
     /// let b: &[_] = &[&mut 3, &mut 1, &mut 2];
     /// assert_eq!(buf.iter_mut().collect::<Vec<&mut int>>()[], b);
     /// ```
-    pub fn iter_mut<'a>(&'a mut self) -> MutItems<'a, T> {
+    pub fn iter_mut(&mut self) -> MutItems<T> {
         let start_index = raw_index(self.lo, self.elts.len(), 0);
         let end_index = raw_index(self.lo, self.elts.len(), self.nelts);
 
@@ -268,6 +187,230 @@ impl<T> RingBuf<T> {
             }
         }
     }
+
+    /// Returns the number of elements in the `RingBuf`.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut v = RingBuf::new();
+    /// assert_eq!(v.len(), 0);
+    /// v.push(1i);
+    /// assert_eq!(v.len(), 1);
+    /// ```
+    pub fn len(&self) -> uint { self.nelts }
+
+    /// Returns true if the buffer contains no elements
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut v = RingBuf::new();
+    /// assert!(v.is_empty());
+    /// v.push_front(1i);
+    /// assert!(!v.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the buffer, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut v = RingBuf::new();
+    /// v.push(1i);
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    pub fn clear(&mut self) {
+        for x in self.elts.iter_mut() { *x = None }
+        self.nelts = 0;
+        self.lo = 0;
+    }
+
+    /// Provides a reference to the front element, or `None` if the sequence is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut d = RingBuf::new();
+    /// assert_eq!(d.front(), None);
+    ///
+    /// d.push(1i);
+    /// d.push(2i);
+    /// assert_eq!(d.front(), Some(&1i));
+    /// ```
+    pub fn front(&self) -> Option<&T> {
+        if self.nelts > 0 { Some(&self[0]) } else { None }
+    }
+
+    /// Provides a mutable reference to the front element, or `None` if the
+    /// sequence is empty.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut d = RingBuf::new();
+    /// assert_eq!(d.front_mut(), None);
+    ///
+    /// d.push(1i);
+    /// d.push(2i);
+    /// match d.front_mut() {
+    ///     Some(x) => *x = 9i,
+    ///     None => (),
+    /// }
+    /// assert_eq!(d.front(), Some(&9i));
+    /// ```
+    pub fn front_mut(&mut self) -> Option<&mut T> {
+        if self.nelts > 0 { Some(&mut self[0]) } else { None }
+    }
+
+    /// Provides a reference to the back element, or `None` if the sequence is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut d = RingBuf::new();
+    /// assert_eq!(d.back(), None);
+    ///
+    /// d.push(1i);
+    /// d.push(2i);
+    /// assert_eq!(d.back(), Some(&2i));
+    /// ```
+    pub fn back(&self) -> Option<&T> {
+        if self.nelts > 0 { Some(&self[self.nelts - 1]) } else { None }
+    }
+
+    /// Provides a mutable reference to the back element, or `None` if the
+    /// sequence is empty.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut d = RingBuf::new();
+    /// assert_eq!(d.back(), None);
+    ///
+    /// d.push(1i);
+    /// d.push(2i);
+    /// match d.back_mut() {
+    ///     Some(x) => *x = 9i,
+    ///     None => (),
+    /// }
+    /// assert_eq!(d.back(), Some(&9i));
+    /// ```
+    pub fn back_mut(&mut self) -> Option<&mut T> {
+        let nelts = self.nelts;
+        if nelts > 0 { Some(&mut self[nelts - 1]) } else { None }
+    }
+
+    /// Removes the first element and returns it, or `None` if the sequence is
+    /// empty.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut d = RingBuf::new();
+    /// d.push(1i);
+    /// d.push(2i);
+    ///
+    /// assert_eq!(d.pop_front(), Some(1i));
+    /// assert_eq!(d.pop_front(), Some(2i));
+    /// assert_eq!(d.pop_front(), None);
+    /// ```
+    pub fn pop_front(&mut self) -> Option<T> {
+        let result = self.elts[self.lo].take();
+        if result.is_some() {
+            self.lo = (self.lo + 1u) % self.elts.len();
+            self.nelts -= 1u;
+        }
+        result
+    }
+
+    /// Inserts an element first in the sequence.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut d = RingBuf::new();
+    /// d.push_front(1i);
+    /// d.push_front(2i);
+    /// assert_eq!(d.front(), Some(&2i));
+    /// ```
+    pub fn push_front(&mut self, t: T) {
+        if self.nelts == self.elts.len() {
+            grow(self.nelts, &mut self.lo, &mut self.elts);
+        }
+        if self.lo == 0u {
+            self.lo = self.elts.len() - 1u;
+        } else { self.lo -= 1u; }
+        self.elts[self.lo] = Some(t);
+        self.nelts += 1u;
+    }
+
+    /// Appends an element to the back of a buffer
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut buf = RingBuf::new();
+    /// buf.push(1i);
+    /// buf.push(3);
+    /// assert_eq!(3, *buf.back().unwrap());
+    /// ```
+    pub fn push(&mut self, t: T) {
+        if self.nelts == self.elts.len() {
+            grow(self.nelts, &mut self.lo, &mut self.elts);
+        }
+        let hi = self.raw_index(self.nelts);
+        self.elts[hi] = Some(t);
+        self.nelts += 1u;
+    }
+
+    /// Removes the last element from a buffer and returns it, or `None` if
+    /// it is empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// use std::collections::RingBuf;
+    ///
+    /// let mut buf = RingBuf::new();
+    /// assert_eq!(buf.pop(), None);
+    /// buf.push(1i);
+    /// buf.push(3);
+    /// assert_eq!(buf.pop(), Some(3));
+    /// ```
+    pub fn pop(&mut self) -> Option<T> {
+        if self.nelts > 0 {
+            self.nelts -= 1;
+            let hi = self.raw_index(self.nelts);
+            self.elts[hi].take()
+        } else {
+            None
+        }
+    }
 }
 
 /// `RingBuf` iterator.
@@ -513,7 +656,6 @@ mod tests {
     use test::Bencher;
     use test;
 
-    use {Deque, Mutable, MutableSeq};
     use super::RingBuf;
     use vec::Vec;
 
diff --git a/src/libcollections/slice.rs b/src/libcollections/slice.rs
index a552e4caa2d21..107dc3e5c28b7 100644
--- a/src/libcollections/slice.rs
+++ b/src/libcollections/slice.rs
@@ -92,12 +92,11 @@ use core::cmp;
 use core::kinds::Sized;
 use core::mem::size_of;
 use core::mem;
-use core::prelude::{Clone, Collection, Greater, Iterator, Less, None, Option};
+use core::prelude::{Clone, Greater, Iterator, Less, None, Option};
 use core::prelude::{Ord, Ordering, RawPtr, Some, range};
 use core::ptr;
 use core::iter::{range_step, MultiplicativeIterator};
 
-use MutableSeq;
 use vec::Vec;
 
 pub use core::slice::{Chunks, AsSlice, ImmutableSlice, ImmutablePartialEqSlice};
@@ -762,7 +761,6 @@ mod tests {
     use std::rt;
     use slice::*;
 
-    use {Mutable, MutableSeq};
     use vec::Vec;
 
     fn square(n: uint) -> uint { n * n }
@@ -2175,7 +2173,6 @@ mod bench {
     use test::Bencher;
 
     use vec::Vec;
-    use MutableSeq;
 
     #[bench]
     fn iterator(b: &mut Bencher) {
diff --git a/src/libcollections/smallintmap.rs b/src/libcollections/smallintmap.rs
index 9e6485103e192..b2e018743da7d 100644
--- a/src/libcollections/smallintmap.rs
+++ b/src/libcollections/smallintmap.rs
@@ -21,7 +21,6 @@ use core::iter;
 use core::iter::{Enumerate, FilterMap};
 use core::mem::replace;
 
-use {Mutable, Map, MutableMap, MutableSeq};
 use {vec, slice};
 use vec::Vec;
 use hash;
@@ -65,90 +64,6 @@ pub struct SmallIntMap<T> {
     v: Vec<Option<T>>,
 }
 
-impl<V> Collection for SmallIntMap<V> {
-    /// Returns the number of elements in the map.
-    fn len(&self) -> uint {
-        self.v.iter().filter(|elt| elt.is_some()).count()
-    }
-
-    /// Returns`true` if there are no elements in the map.
-    fn is_empty(&self) -> bool {
-        self.v.iter().all(|elt| elt.is_none())
-    }
-}
-
-impl<V> Mutable for SmallIntMap<V> {
-    /// Clears the map, removing all key-value pairs.
-    fn clear(&mut self) { self.v.clear() }
-}
-
-impl<V> Map<uint, V> for SmallIntMap<V> {
-    /// Returns a reference to the value corresponding to the key.
-    fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
-        if *key < self.v.len() {
-            match self.v[*key] {
-              Some(ref value) => Some(value),
-              None => None
-            }
-        } else {
-            None
-        }
-    }
-}
-
-impl<V> MutableMap<uint, V> for SmallIntMap<V> {
-    /// Returns a mutable reference to the value corresponding to the key.
-    fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> {
-        if *key < self.v.len() {
-            match *self.v.index_mut(key) {
-              Some(ref mut value) => Some(value),
-              None => None
-            }
-        } else {
-            None
-        }
-    }
-
-    /// Inserts a key-value pair into the map. An existing value for a
-    /// key is replaced by the new value. Returns `true` if the key did
-    /// not already exist in the map.
-    fn insert(&mut self, key: uint, value: V) -> bool {
-        let exists = self.contains_key(&key);
-        let len = self.v.len();
-        if len <= key {
-            self.v.grow_fn(key - len + 1, |_| None);
-        }
-        self.v[key] = Some(value);
-        !exists
-    }
-
-    /// Removes a key-value pair from the map. Returns `true` if the key
-    /// was present in the map.
-    fn remove(&mut self, key: &uint) -> bool {
-        self.pop(key).is_some()
-    }
-
-    /// Inserts a key-value pair into the map. If the key already had a value
-    /// present in the map, that value is returned. Otherwise `None` is returned.
-    fn swap(&mut self, key: uint, value: V) -> Option<V> {
-        match self.find_mut(&key) {
-            Some(loc) => { return Some(replace(loc, value)); }
-            None => ()
-        }
-        self.insert(key, value);
-        return None;
-    }
-
-    /// Removes a key from the map, returning the value at the key if the key
-    /// was previously in the map.
-    fn pop(&mut self, key: &uint) -> Option<V> {
-        if *key >= self.v.len() {
-            return None;
-        }
-        self.v[*key].take()
-    }
-}
-
 impl<V> Default for SmallIntMap<V> {
     #[inline]
     fn default() -> SmallIntMap<V> { SmallIntMap::new() }
@@ -295,6 +210,204 @@ impl<V> SmallIntMap<V> {
             v.map(|v| (i, v))
         })
     }
+
+    /// Return the number of elements in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut a = SmallIntMap::new();
+    /// assert_eq!(a.len(), 0);
+    /// a.insert(1, "a");
+    /// assert_eq!(a.len(), 1);
+    /// ```
+    pub fn len(&self) -> uint {
+        self.v.iter().filter(|elt| elt.is_some()).count()
+    }
+
+    /// Return true if the map contains no elements.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut a = SmallIntMap::new();
+    /// assert!(a.is_empty());
+    /// a.insert(1, "a");
+    /// assert!(!a.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool {
+        self.v.iter().all(|elt| elt.is_none())
+    }
+
+    /// Clears the map, removing all key-value pairs.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut a = SmallIntMap::new();
+    /// a.insert(1, "a");
+    /// a.clear();
+    /// assert!(a.is_empty());
+    /// ```
+    pub fn clear(&mut self) { self.v.clear() }
+
+    /// Returns a reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut map = SmallIntMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.find(&1), Some(&"a"));
+    /// assert_eq!(map.find(&2), None);
+    /// ```
+    pub fn find<'a>(&'a self, key: &uint) -> Option<&'a V> {
+        if *key < self.v.len() {
+            match self.v[*key] {
+              Some(ref value) => Some(value),
+              None => None
+            }
+        } else {
+            None
+        }
+    }
+
+    /// Returns true if the map contains a value for the specified key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut map = SmallIntMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.contains_key(&1), true);
+    /// assert_eq!(map.contains_key(&2), false);
+    /// ```
+    #[inline]
+    pub fn contains_key(&self, key: &uint) -> bool {
+        self.find(key).is_some()
+    }
+
+    /// Returns a mutable reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut map = SmallIntMap::new();
+    /// map.insert(1, "a");
+    /// match map.find_mut(&1) {
+    ///     Some(x) => *x = "b",
+    ///     None => (),
+    /// }
+    /// assert_eq!(map[1], "b");
+    /// ```
+    pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut V> {
+        if *key < self.v.len() {
+            match *(&mut self.v[*key]) {
+              Some(ref mut value) => Some(value),
+              None => None
+            }
+        } else {
+            None
+        }
+    }
+
+    /// Inserts a key-value pair into the map. An existing value for a
+    /// key is replaced by the new value. Returns `true` if the key did
+    /// not already exist in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut map = SmallIntMap::new();
+    /// assert_eq!(map.insert(2, "value"), true);
+    /// assert_eq!(map.insert(2, "value2"), false);
+    /// assert_eq!(map[2], "value2");
+    /// ```
+    pub fn insert(&mut self, key: uint, value: V) -> bool {
+        let exists = self.contains_key(&key);
+        let len = self.v.len();
+        if len <= key {
+            self.v.grow_fn(key - len + 1, |_| None);
+        }
+        self.v[key] = Some(value);
+        !exists
+    }
+
+    /// Removes a key-value pair from the map. Returns `true` if the key
+    /// was present in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut map = SmallIntMap::new();
+    /// assert_eq!(map.remove(&1), false);
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove(&1), true);
+    /// ```
+    pub fn remove(&mut self, key: &uint) -> bool {
+        self.pop(key).is_some()
+    }
+
+    /// Inserts a key-value pair from the map. If the key already had a value
+    /// present in the map, that value is returned. Otherwise, `None` is returned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut map = SmallIntMap::new();
+    /// assert_eq!(map.swap(37, "a"), None);
+    /// assert_eq!(map.is_empty(), false);
+    ///
+    /// map.insert(37, "b");
+    /// assert_eq!(map.swap(37, "c"), Some("b"));
+    /// assert_eq!(map[37], "c");
+    /// ```
+    pub fn swap(&mut self, key: uint, value: V) -> Option<V> {
+        match self.find_mut(&key) {
+            Some(loc) => { return Some(replace(loc, value)); }
+            None => ()
+        }
+        self.insert(key, value);
+        return None;
+    }
+
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::SmallIntMap;
+    ///
+    /// let mut map = SmallIntMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.pop(&1), Some("a"));
+    /// assert_eq!(map.pop(&1), None);
+    /// ```
+    pub fn pop(&mut self, key: &uint) -> Option<V> {
+        if *key >= self.v.len() {
+            return None;
+        }
+        self.v[*key].take()
+    }
 }
 
 impl<V:Clone> SmallIntMap<V> {
@@ -499,7 +612,6 @@ mod test_map {
     use vec::Vec;
     use hash;
 
-    use {Map, MutableMap, Mutable, MutableSeq};
     use super::SmallIntMap;
 
     #[test]
@@ -869,57 +981,72 @@ mod bench {
     extern crate test;
     use self::test::Bencher;
     use super::SmallIntMap;
-    use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
+    use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
 
-    // Find seq
     #[bench]
     pub fn insert_rand_100(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        insert_rand_n(100, &mut m, b);
+        insert_rand_n(100, &mut m, b,
+                      |m, i| { m.insert(i, 1); },
+                      |m, i| { m.remove(&i); });
     }
 
     #[bench]
     pub fn insert_rand_10_000(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        insert_rand_n(10_000, &mut m, b);
+        insert_rand_n(10_000, &mut m, b,
+                      |m, i| { m.insert(i, 1); },
+                      |m, i| { m.remove(&i); });
     }
 
     // Insert seq
     #[bench]
     pub fn insert_seq_100(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        insert_seq_n(100, &mut m, b);
+        insert_seq_n(100, &mut m, b,
+                     |m, i| { m.insert(i, 1); },
+                     |m, i| { m.remove(&i); });
     }
 
     #[bench]
     pub fn insert_seq_10_000(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        insert_seq_n(10_000, &mut m, b);
+        insert_seq_n(10_000, &mut m, b,
+                     |m, i| { m.insert(i, 1); },
+                     |m, i| { m.remove(&i); });
     }
 
     // Find rand
     #[bench]
     pub fn find_rand_100(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        find_rand_n(100, &mut m, b);
+        find_rand_n(100, &mut m, b,
+                    |m, i| { m.insert(i, 1); },
+                    |m, i| { m.find(&i); });
     }
 
     #[bench]
     pub fn find_rand_10_000(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        find_rand_n(10_000, &mut m, b);
+        find_rand_n(10_000, &mut m, b,
+                    |m, i| { m.insert(i, 1); },
+                    |m, i| { m.find(&i); });
     }
 
     // Find seq
     #[bench]
     pub fn find_seq_100(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        find_seq_n(100, &mut m, b);
+        find_seq_n(100, &mut m, b,
+                   |m, i| { m.insert(i, 1); },
+                   |m, i| { m.find(&i); });
     }
 
     #[bench]
     pub fn find_seq_10_000(b: &mut Bencher) {
         let mut m : SmallIntMap<uint> = SmallIntMap::new();
-        find_seq_n(10_000, &mut m, b);
+        find_seq_n(10_000, &mut m, b,
+                   |m, i| { m.insert(i, 1); },
+                   |m, i| { m.find(&i); });
     }
 }
diff --git a/src/libcollections/str.rs b/src/libcollections/str.rs
index 86a640d1aeb9b..297ba71d252d7 100644
--- a/src/libcollections/str.rs
+++ b/src/libcollections/str.rs
@@ -59,12 +59,11 @@ use core::fmt;
 use core::cmp;
 use core::iter::AdditiveIterator;
 use core::kinds::Sized;
-use core::prelude::{Char, Clone, Collection, Eq, Equiv, ImmutableSlice};
+use core::prelude::{Char, Clone, Eq, Equiv, ImmutableSlice};
 use core::prelude::{Iterator, MutableSlice, None, Option, Ord, Ordering};
 use core::prelude::{PartialEq, PartialOrd, Result, AsSlice, Some, Tuple2};
 use core::prelude::{range};
 
-use {Deque, MutableSeq};
 use hash;
 use ringbuf::RingBuf;
 use string::String;
@@ -464,6 +463,14 @@ impl<'a> MaybeOwned<'a> {
             Owned(_) => false
         }
     }
+
+    /// Return the number of bytes in this string.
+    #[inline]
+    pub fn len(&self) -> uint { self.as_slice().len() }
+
+    /// Returns true if the string contains no bytes
+    #[inline]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 /// Trait for moving into a `MaybeOwned`.
@@ -561,11 +568,6 @@ impl<'a> StrAllocating for MaybeOwned<'a> {
     }
 }
 
-impl<'a> Collection for MaybeOwned<'a> {
-    #[inline]
-    fn len(&self) -> uint { self.as_slice().len() }
-}
-
 impl<'a> Clone for MaybeOwned<'a> {
     #[inline]
     fn clone(&self) -> MaybeOwned<'a> {
@@ -782,7 +784,6 @@ mod tests {
     use std::option::{Some, None};
     use std::ptr::RawPtr;
     use std::iter::{Iterator, DoubleEndedIterator};
-    use {Collection, MutableSeq};
 
     use super::*;
     use std::slice::{AsSlice, ImmutableSlice};
@@ -2142,14 +2143,16 @@ mod tests {
 
     #[test]
     fn test_str_container() {
-        fn sum_len<S: Collection>(v: &[S]) -> uint {
+        fn sum_len(v: &[&str]) -> uint {
             v.iter().map(|x| x.len()).sum()
         }
 
         let s = String::from_str("01234");
         assert_eq!(5, sum_len(["012", "", "34"]));
-        assert_eq!(5, sum_len([String::from_str("01"), String::from_str("2"),
-                               String::from_str("34"), String::from_str("")]));
+        assert_eq!(5, sum_len([String::from_str("01").as_slice(),
+                               String::from_str("2").as_slice(),
+                               String::from_str("34").as_slice(),
+                               String::from_str("").as_slice()]));
         assert_eq!(5, sum_len([s.as_slice()]));
     }
 
@@ -2232,7 +2235,8 @@ mod bench {
     use test::black_box;
     use super::*;
     use std::iter::{Iterator, DoubleEndedIterator};
-    use std::collections::Collection;
+    use std::str::StrSlice;
+    use std::slice::ImmutableSlice;
 
     #[bench]
     fn char_iterator(b: &mut Bencher) {
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 507cfbf191c4a..b3c83ba55598b 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -22,7 +22,6 @@ use core::ops;
 // FIXME: ICE's abound if you import the `Slice` type while importing `Slice` trait
 use core::raw::Slice as RawSlice;
 
-use {Mutable, MutableSeq};
 use hash;
 use slice::CloneableVector;
 use str;
@@ -626,22 +625,43 @@ impl String {
     pub unsafe fn as_mut_vec<'a>(&'a mut self) -> &'a mut Vec<u8> {
         &mut self.vec
     }
-}
 
-#[experimental = "collection traits will probably be removed"]
-impl Collection for String {
+    /// Return the number of bytes in this string.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let a = "foo".to_string();
+    /// assert_eq!(a.len(), 3);
+    /// ```
     #[inline]
     #[stable]
-    fn len(&self) -> uint {
-        self.vec.len()
-    }
-}
+    pub fn len(&self) -> uint { self.vec.len() }
 
-#[experimental = "collection traits will probably be removed"]
-impl Mutable for String {
+    /// Returns true if the string contains no bytes
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let mut v = String::new();
+    /// assert!(v.is_empty());
+    /// v.push('a');
+    /// assert!(!v.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Truncates the string, returning it to 0 length.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let mut s = "foo".to_string();
+    /// s.clear();
+    /// assert!(s.is_empty());
+    /// ```
     #[inline]
     #[stable]
-    fn clear(&mut self) {
+    pub fn clear(&mut self) {
         self.vec.clear()
     }
 }
@@ -830,7 +850,6 @@ mod tests {
     use std::prelude::*;
     use test::Bencher;
 
-    use {Mutable, MutableSeq};
     use str;
     use str::{Str, StrSlice, Owned};
     use super::{as_string, String};
diff --git a/src/libcollections/treemap.rs b/src/libcollections/treemap.rs
index ea4d541aab94a..7e6efcb3d1266 100644
--- a/src/libcollections/treemap.rs
+++ b/src/libcollections/treemap.rs
@@ -44,7 +44,6 @@ use core::mem::{replace, swap};
 use core::ptr;
 use std::hash::{Writer, Hash};
 
-use {Mutable, Set, MutableSet, MutableMap, Map, MutableSeq};
 use vec::Vec;
 
 /// This is implemented as an AA tree, which is a simplified variation of
@@ -206,45 +205,6 @@ impl<K: Ord + Show, V: Show> Show for TreeMap<K, V> {
     }
 }
 
-impl<K: Ord, V> Collection for TreeMap<K, V> {
-    fn len(&self) -> uint { self.length }
-}
-
-impl<K: Ord, V> Mutable for TreeMap<K, V> {
-    fn clear(&mut self) {
-        self.root = None;
-        self.length = 0
-    }
-}
-
-impl<K: Ord, V> Map<K, V> for TreeMap<K, V> {
-    // See comments on tree_find_with
-    #[inline]
-    fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
-        tree_find_with(&self.root, |k2| key.cmp(k2))
-    }
-}
-
-impl<K: Ord, V> MutableMap<K, V> for TreeMap<K, V> {
-    // See comments on tree_find_with_mut
-    #[inline]
-    fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
-        tree_find_with_mut(&mut self.root, |x| key.cmp(x))
-    }
-
-    fn swap(&mut self, key: K, value: V) -> Option<V> {
-        let ret = insert(&mut self.root, key, value);
-        if ret.is_none() { self.length += 1 }
-        ret
-    }
-
-    fn pop(&mut self, key: &K) -> Option<V> {
-        let ret = remove(&mut self.root, key);
-        if ret.is_some() { self.length -= 1 }
-        ret
-    }
-}
-
 impl<K: Ord, V> Default for TreeMap<K,V> {
     #[inline]
     fn default() -> TreeMap<K, V> { TreeMap::new() }
@@ -444,6 +404,184 @@ impl<K: Ord, V> TreeMap<K, V> {
             remaining: length
         }
     }
+
+    /// Return the number of elements in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut a = TreeMap::new();
+    /// assert_eq!(a.len(), 0);
+    /// a.insert(1u, "a");
+    /// assert_eq!(a.len(), 1);
+    /// ```
+    pub fn len(&self) -> uint { self.length }
+
+    /// Return true if the map contains no elements.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut a = TreeMap::new();
+    /// assert!(a.is_empty());
+    /// a.insert(1u, "a");
+    /// assert!(!a.is_empty());
+    /// ```
+    #[inline]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the map, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut a = TreeMap::new();
+    /// a.insert(1u, "a");
+    /// a.clear();
+    /// assert!(a.is_empty());
+    /// ```
+    pub fn clear(&mut self) {
+        self.root = None;
+        self.length = 0
+    }
+
+    /// Returns a reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut map = TreeMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.find(&1), Some(&"a"));
+    /// assert_eq!(map.find(&2), None);
+    /// ```
+    #[inline]
+    pub fn find<'a>(&'a self, key: &K) -> Option<&'a V> {
+        tree_find_with(&self.root, |k2| key.cmp(k2))
+    }
+
+    /// Returns true if the map contains a value for the specified key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut map = TreeMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.contains_key(&1), true);
+    /// assert_eq!(map.contains_key(&2), false);
+    /// ```
+    #[inline]
+    pub fn contains_key(&self, key: &K) -> bool {
+        self.find(key).is_some()
+    }
+
+    /// Returns a mutable reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut map = TreeMap::new();
+    /// map.insert(1u, "a");
+    /// match map.find_mut(&1) {
+    ///     Some(x) => *x = "b",
+    ///     None => (),
+    /// }
+    /// assert_eq!(map[1], "b");
+    /// ```
+    #[inline]
+    pub fn find_mut<'a>(&'a mut self, key: &K) -> Option<&'a mut V> {
+        tree_find_with_mut(&mut self.root, |x| key.cmp(x))
+    }
+
+    /// Inserts a key-value pair into the map. An existing value for a
+    /// key is replaced by the new value. Returns `true` if the key did
+    /// not already exist in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut map = TreeMap::new();
+    /// assert_eq!(map.insert(2u, "value"), true);
+    /// assert_eq!(map.insert(2, "value2"), false);
+    /// assert_eq!(map[2], "value2");
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, key: K, value: V) -> bool {
+        self.swap(key, value).is_none()
+    }
+
+    /// Removes a key-value pair from the map. Returns `true` if the key
+    /// was present in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut map = TreeMap::new();
+    /// assert_eq!(map.remove(&1u), false);
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove(&1), true);
+    /// ```
+    #[inline]
+    pub fn remove(&mut self, key: &K) -> bool {
+        self.pop(key).is_some()
+    }
+
+    /// Inserts a key-value pair from the map. If the key already had a value
+    /// present in the map, that value is returned. Otherwise, `None` is returned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut map = TreeMap::new();
+    /// assert_eq!(map.swap(37u, "a"), None);
+    /// assert_eq!(map.is_empty(), false);
+    ///
+    /// map.insert(37, "b");
+    /// assert_eq!(map.swap(37, "c"), Some("b"));
+    /// assert_eq!(map[37], "c");
+    /// ```
+    pub fn swap(&mut self, key: K, value: V) -> Option<V> {
+        let ret = insert(&mut self.root, key, value);
+        if ret.is_none() { self.length += 1 }
+        ret
+    }
+
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeMap;
+    ///
+    /// let mut map = TreeMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.pop(&1), Some("a"));
+    /// assert_eq!(map.pop(&1), None);
+    /// ```
+    pub fn pop(&mut self, key: &K) -> Option<V> {
+        let ret = remove(&mut self.root, key);
+        if ret.is_some() { self.length -= 1 }
+        ret
+    }
 }
 
 impl<K, V> TreeMap<K, V> {
@@ -1062,59 +1200,6 @@ impl<T: Ord + Show> Show for TreeSet<T> {
     }
 }
 
-impl<T: Ord> Collection for TreeSet<T> {
-    #[inline]
-    fn len(&self) -> uint { self.map.len() }
-}
-
-impl<T: Ord> Mutable for TreeSet<T> {
-    #[inline]
-    fn clear(&mut self) { self.map.clear() }
-}
-
-impl<T: Ord> Set<T> for TreeSet<T> {
-    #[inline]
-    fn contains(&self, value: &T) -> bool {
-        self.map.contains_key(value)
-    }
-
-    fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
-        self.intersection(other).next().is_none()
-    }
-
-    fn is_subset(&self, other: &TreeSet<T>) -> bool {
-        let mut x = self.iter();
-        let mut y = other.iter();
-        let mut a = x.next();
-        let mut b = y.next();
-        while a.is_some() {
-            if b.is_none() {
-                return false;
-            }
-
-            let a1 = a.unwrap();
-            let b1 = b.unwrap();
-
-            match b1.cmp(a1) {
-                Less => (),
-                Greater => return false,
-                Equal => a = x.next(),
-            }
-
-            b = y.next();
-        }
-        true
-    }
-}
-
-impl<T: Ord> MutableSet<T> for TreeSet<T> {
-    #[inline]
-    fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
-
-    #[inline]
-    fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
-}
-
 impl<T: Ord> Default for TreeSet<T> {
     #[inline]
     fn default() -> TreeSet<T> { TreeSet::new() }
@@ -1320,6 +1405,184 @@ impl<T: Ord> TreeSet<T> {
     pub fn union<'a>(&'a self, other: &'a TreeSet<T>) -> UnionItems<'a, T> {
         UnionItems{a: self.iter().peekable(), b: other.iter().peekable()}
     }
+
+    /// Return the number of elements in the set
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let mut v = TreeSet::new();
+    /// assert_eq!(v.len(), 0);
+    /// v.insert(1i);
+    /// assert_eq!(v.len(), 1);
+    /// ```
+    #[inline]
+    pub fn len(&self) -> uint { self.map.len() }
+
+    /// Returns true if the set contains no elements
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let mut v = TreeSet::new();
+    /// assert!(v.is_empty());
+    /// v.insert(1i);
+    /// assert!(!v.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the set, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let mut v = TreeSet::new();
+    /// v.insert(1i);
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    #[inline]
+    pub fn clear(&mut self) { self.map.clear() }
+
+    /// Returns `true` if the set contains a value.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let set: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+    /// assert_eq!(set.contains(&1), true);
+    /// assert_eq!(set.contains(&4), false);
+    /// ```
+    #[inline]
+    pub fn contains(&self, value: &T) -> bool {
+        self.map.contains_key(value)
+    }
+
+    /// Returns `true` if the set has no elements in common with `other`.
+    /// This is equivalent to checking for an empty intersection.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let a: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+    /// let mut b: TreeSet<int> = TreeSet::new();
+    ///
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(4);
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(1);
+    /// assert_eq!(a.is_disjoint(&b), false);
+    /// ```
+    pub fn is_disjoint(&self, other: &TreeSet<T>) -> bool {
+        self.intersection(other).next().is_none()
+    }
+
+    /// Returns `true` if the set is a subset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let sup: TreeSet<int> = [1i, 2, 3].iter().map(|&x| x).collect();
+    /// let mut set: TreeSet<int> = TreeSet::new();
+    ///
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(2);
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(4);
+    /// assert_eq!(set.is_subset(&sup), false);
+    /// ```
+    pub fn is_subset(&self, other: &TreeSet<T>) -> bool {
+        let mut x = self.iter();
+        let mut y = other.iter();
+        let mut a = x.next();
+        let mut b = y.next();
+        while a.is_some() {
+            if b.is_none() {
+                return false;
+            }
+
+            let a1 = a.unwrap();
+            let b1 = b.unwrap();
+
+            match b1.cmp(a1) {
+                Less => (),
+                Greater => return false,
+                Equal => a = x.next(),
+            }
+
+            b = y.next();
+        }
+        true
+    }
+
+    /// Returns `true` if the set is a superset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TreeSet;
+    ///
+    /// let sub: TreeSet<int> = [1i, 2].iter().map(|&x| x).collect();
+    /// let mut set: TreeSet<int> = TreeSet::new();
+    ///
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(0);
+    /// set.insert(1);
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(2);
+    /// assert_eq!(set.is_superset(&sub), true);
+    /// ```
+    pub fn is_superset(&self, other: &TreeSet<T>) -> bool {
+        other.is_subset(self)
+    }
+
+    /// Adds a value to the set. Returns `true` if the value was not already
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut set = BTreeSet::new();
+    ///
+    /// assert_eq!(set.insert(2i), true);
+    /// assert_eq!(set.insert(2i), false);
+    /// assert_eq!(set.len(), 1);
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
+
+    /// Removes a value from the set. Returns `true` if the value was
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::BTreeSet;
+    ///
+    /// let mut set = BTreeSet::new();
+    ///
+    /// set.insert(2i);
+    /// assert_eq!(set.remove(&2), true);
+    /// assert_eq!(set.remove(&2), false);
+    /// ```
+    #[inline]
+    pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
 }
 
 /// A lazy forward iterator over a set.
@@ -1676,7 +1939,6 @@ mod test_treemap {
     use std::rand::Rng;
     use std::rand;
 
-    use {Map, MutableMap, Mutable, MutableSeq};
     use super::{TreeMap, TreeNode};
 
     #[test]
@@ -2195,59 +2457,73 @@ mod bench {
     use test::{Bencher, black_box};
 
     use super::TreeMap;
-    use MutableMap;
-    use deque::bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
+    use bench::{insert_rand_n, insert_seq_n, find_rand_n, find_seq_n};
 
-    // Find seq
     #[bench]
     pub fn insert_rand_100(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        insert_rand_n(100, &mut m, b);
+        insert_rand_n(100, &mut m, b,
+                      |m, i| { m.insert(i, 1); },
+                      |m, i| { m.remove(&i); });
     }
 
     #[bench]
     pub fn insert_rand_10_000(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        insert_rand_n(10_000, &mut m, b);
+        insert_rand_n(10_000, &mut m, b,
+                      |m, i| { m.insert(i, 1); },
+                      |m, i| { m.remove(&i); });
     }
 
     // Insert seq
     #[bench]
     pub fn insert_seq_100(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        insert_seq_n(100, &mut m, b);
+        insert_seq_n(100, &mut m, b,
+                     |m, i| { m.insert(i, 1); },
+                     |m, i| { m.remove(&i); });
     }
 
     #[bench]
     pub fn insert_seq_10_000(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        insert_seq_n(10_000, &mut m, b);
+        insert_seq_n(10_000, &mut m, b,
+                     |m, i| { m.insert(i, 1); },
+                     |m, i| { m.remove(&i); });
     }
 
     // Find rand
     #[bench]
     pub fn find_rand_100(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        find_rand_n(100, &mut m, b);
+        find_rand_n(100, &mut m, b,
+                    |m, i| { m.insert(i, 1); },
+                    |m, i| { m.find(&i); });
     }
 
     #[bench]
     pub fn find_rand_10_000(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        find_rand_n(10_000, &mut m, b);
+        find_rand_n(10_000, &mut m, b,
+                    |m, i| { m.insert(i, 1); },
+                    |m, i| { m.find(&i); });
     }
 
     // Find seq
     #[bench]
     pub fn find_seq_100(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        find_seq_n(100, &mut m, b);
+        find_seq_n(100, &mut m, b,
+                   |m, i| { m.insert(i, 1); },
+                   |m, i| { m.find(&i); });
     }
 
     #[bench]
     pub fn find_seq_10_000(b: &mut Bencher) {
         let mut m : TreeMap<uint,uint> = TreeMap::new();
-        find_seq_n(10_000, &mut m, b);
+        find_seq_n(10_000, &mut m, b,
+                   |m, i| { m.insert(i, 1); },
+                   |m, i| { m.find(&i); });
     }
 
     fn bench_iter(b: &mut Bencher, size: uint) {
@@ -2286,7 +2562,6 @@ mod test_set {
     use std::prelude::*;
     use std::hash;
 
-    use {Set, MutableSet, Mutable, MutableMap, MutableSeq};
     use super::{TreeMap, TreeSet};
 
     #[test]
diff --git a/src/libcollections/trie.rs b/src/libcollections/trie.rs
index 8c18a6488ba50..7a8cc5df55a27 100644
--- a/src/libcollections/trie.rs
+++ b/src/libcollections/trie.rs
@@ -29,7 +29,6 @@ use core::uint;
 use core::iter;
 use std::hash::{Writer, Hash};
 
-use {Mutable, Map, MutableMap, Set, MutableSet};
 use slice::{Items, MutItems};
 use slice;
 
@@ -126,72 +125,6 @@ impl<T: Show> Show for TrieMap<T> {
     }
 }
 
-impl<T> Collection for TrieMap<T> {
-    /// Returns the number of elements in the map.
-    #[inline]
-    fn len(&self) -> uint { self.length }
-}
-
-impl<T> Mutable for TrieMap<T> {
-    /// Clears the map, removing all values.
-    #[inline]
-    fn clear(&mut self) {
-        self.root = TrieNode::new();
-        self.length = 0;
-    }
-}
-
-impl<T> Map<uint, T> for TrieMap<T> {
-    /// Returns a reference to the value corresponding to the key.
-    #[inline]
-    fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
-        let mut node: &'a TrieNode<T> = &self.root;
-        let mut idx = 0;
-        loop {
-            match node.children[chunk(*key, idx)] {
-              Internal(ref x) => node = &**x,
-              External(stored, ref value) => {
-                if stored == *key {
-                    return Some(value)
-                } else {
-                    return None
-                }
-              }
-              Nothing => return None
-            }
-            idx += 1;
-        }
-    }
-}
-
-impl<T> MutableMap<uint, T> for TrieMap<T> {
-    /// Returns a mutable reference to the value corresponding to the key.
-    #[inline]
-    fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
-        find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
-    }
-
-    /// Inserts a key-value pair from the map. If the key already had a value
-    /// present in the map, that value is returned. Otherwise, `None` is returned.
-    fn swap(&mut self, key: uint, value: T) -> Option<T> {
-        let ret = insert(&mut self.root.count,
-                         &mut self.root.children[chunk(key, 0)],
-                         key, value, 1);
-        if ret.is_none() { self.length += 1 }
-        ret
-    }
-
-    /// Removes a key from the map, returning the value at the key if the key
-    /// was previously in the map.
-    fn pop(&mut self, key: &uint) -> Option<T> {
-        let ret = remove(&mut self.root.count,
-                         &mut self.root.children[chunk(*key, 0)],
-                         *key, 1);
-        if ret.is_some() { self.length -= 1 }
-        ret
-    }
-}
-
 impl<T> Default for TrieMap<T> {
     #[inline]
     fn default() -> TrieMap<T> { TrieMap::new() }
@@ -294,6 +227,205 @@ impl<T> TrieMap<T> {
 
         iter
     }
+
+    /// Return the number of elements in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut a = TrieMap::new();
+    /// assert_eq!(a.len(), 0);
+    /// a.insert(1, "a");
+    /// assert_eq!(a.len(), 1);
+    /// ```
+    #[inline]
+    pub fn len(&self) -> uint { self.length }
+
+    /// Return true if the map contains no elements.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut a = TrieMap::new();
+    /// assert!(a.is_empty());
+    /// a.insert(1, "a");
+    /// assert!(!a.is_empty());
+    /// ```
+    #[inline]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the map, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut a = TrieMap::new();
+    /// a.insert(1, "a");
+    /// a.clear();
+    /// assert!(a.is_empty());
+    /// ```
+    #[inline]
+    pub fn clear(&mut self) {
+        self.root = TrieNode::new();
+        self.length = 0;
+    }
+
+    /// Returns a reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut map = TrieMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.find(&1), Some(&"a"));
+    /// assert_eq!(map.find(&2), None);
+    /// ```
+    #[inline]
+    pub fn find<'a>(&'a self, key: &uint) -> Option<&'a T> {
+        let mut node: &'a TrieNode<T> = &self.root;
+        let mut idx = 0;
+        loop {
+            match node.children[chunk(*key, idx)] {
+              Internal(ref x) => node = &**x,
+              External(stored, ref value) => {
+                if stored == *key {
+                    return Some(value)
+                } else {
+                    return None
+                }
+              }
+              Nothing => return None
+            }
+            idx += 1;
+        }
+    }
+
+    /// Returns true if the map contains a value for the specified key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut map = TrieMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.contains_key(&1), true);
+    /// assert_eq!(map.contains_key(&2), false);
+    /// ```
+    #[inline]
+    pub fn contains_key(&self, key: &uint) -> bool {
+        self.find(key).is_some()
+    }
+
+    /// Returns a mutable reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut map = TrieMap::new();
+    /// map.insert(1, "a");
+    /// match map.find_mut(&1) {
+    ///     Some(x) => *x = "b",
+    ///     None => (),
+    /// }
+    /// assert_eq!(map[1], "b");
+    /// ```
+    #[inline]
+    pub fn find_mut<'a>(&'a mut self, key: &uint) -> Option<&'a mut T> {
+        find_mut(&mut self.root.children[chunk(*key, 0)], *key, 1)
+    }
+
+    /// Inserts a key-value pair into the map. An existing value for a
+    /// key is replaced by the new value. Returns `true` if the key did
+    /// not already exist in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut map = TrieMap::new();
+    /// assert_eq!(map.insert(2, "value"), true);
+    /// assert_eq!(map.insert(2, "value2"), false);
+    /// assert_eq!(map[2], "value2");
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, key: uint, value: T) -> bool {
+        self.swap(key, value).is_none()
+    }
+
+    /// Removes a key-value pair from the map. Returns `true` if the key
+    /// was present in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut map = TrieMap::new();
+    /// assert_eq!(map.remove(&1), false);
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove(&1), true);
+    /// ```
+    #[inline]
+    pub fn remove(&mut self, key: &uint) -> bool {
+        self.pop(key).is_some()
+    }
+
+    /// Inserts a key-value pair from the map. If the key already had a value
+    /// present in the map, that value is returned. Otherwise, `None` is returned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut map = TrieMap::new();
+    /// assert_eq!(map.swap(37, "a"), None);
+    /// assert_eq!(map.is_empty(), false);
+    ///
+    /// map.insert(37, "b");
+    /// assert_eq!(map.swap(37, "c"), Some("b"));
+    /// assert_eq!(map[37], "c");
+    /// ```
+    pub fn swap(&mut self, key: uint, value: T) -> Option<T> {
+        let ret = insert(&mut self.root.count,
+                         &mut self.root.children[chunk(key, 0)],
+                         key, value, 1);
+        if ret.is_none() { self.length += 1 }
+        ret
+    }
+
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieMap;
+    ///
+    /// let mut map = TrieMap::new();
+    /// map.insert(1, "a");
+    /// assert_eq!(map.pop(&1), Some("a"));
+    /// assert_eq!(map.pop(&1), None);
+    /// ```
+    pub fn pop(&mut self, key: &uint) -> Option<T> {
+        let ret = remove(&mut self.root.count,
+                         &mut self.root.children[chunk(*key, 0)],
+                         *key, 1);
+        if ret.is_some() { self.length -= 1 }
+        ret
+    }
 }
 
 // FIXME #5846 we want to be able to choose between &x and &mut x
@@ -569,52 +701,6 @@ impl Show for TrieSet {
     }
 }
 
-impl Collection for TrieSet {
-    /// Returns the number of elements in the set.
-    #[inline]
-    fn len(&self) -> uint { self.map.len() }
-}
-
-impl Mutable for TrieSet {
-    /// Clears the set, removing all values.
-    #[inline]
-    fn clear(&mut self) { self.map.clear() }
-}
-
-impl Set<uint> for TrieSet {
-    #[inline]
-    fn contains(&self, value: &uint) -> bool {
-        self.map.contains_key(value)
-    }
-
-    #[inline]
-    fn is_disjoint(&self, other: &TrieSet) -> bool {
-        self.iter().all(|v| !other.contains(&v))
-    }
-
-    #[inline]
-    fn is_subset(&self, other: &TrieSet) -> bool {
-        self.iter().all(|v| other.contains(&v))
-    }
-
-    #[inline]
-    fn is_superset(&self, other: &TrieSet) -> bool {
-        other.is_subset(self)
-    }
-}
-
-impl MutableSet<uint> for TrieSet {
-    #[inline]
-    fn insert(&mut self, value: uint) -> bool {
-        self.map.insert(value, ())
-    }
-
-    #[inline]
-    fn remove(&mut self, value: &uint) -> bool {
-        self.map.remove(value)
-    }
-}
-
 impl Default for TrieSet {
     #[inline]
     fn default() -> TrieSet { TrieSet::new() }
@@ -714,6 +800,171 @@ impl TrieSet {
     pub fn upper_bound<'a>(&'a self, val: uint) -> SetItems<'a> {
         SetItems{iter: self.map.upper_bound(val)}
     }
+
+    /// Return the number of elements in the set
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let mut v = TrieSet::new();
+    /// assert_eq!(v.len(), 0);
+    /// v.insert(1);
+    /// assert_eq!(v.len(), 1);
+    /// ```
+    #[inline]
+    pub fn len(&self) -> uint { self.map.len() }
+
+    /// Returns true if the set contains no elements
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let mut v = TrieSet::new();
+    /// assert!(v.is_empty());
+    /// v.insert(1);
+    /// assert!(!v.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the set, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let mut v = TrieSet::new();
+    /// v.insert(1);
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    #[inline]
+    pub fn clear(&mut self) { self.map.clear() }
+
+    /// Returns `true` if the set contains a value.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let set: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
+    /// assert_eq!(set.contains(&1), true);
+    /// assert_eq!(set.contains(&4), false);
+    /// ```
+    #[inline]
+    pub fn contains(&self, value: &uint) -> bool {
+        self.map.contains_key(value)
+    }
+
+    /// Returns `true` if the set has no elements in common with `other`.
+    /// This is equivalent to checking for an empty intersection.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let a: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let mut b: TrieSet = TrieSet::new();
+    ///
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(4);
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(1);
+    /// assert_eq!(a.is_disjoint(&b), false);
+    /// ```
+    #[inline]
+    pub fn is_disjoint(&self, other: &TrieSet) -> bool {
+        self.iter().all(|v| !other.contains(&v))
+    }
+
+    /// Returns `true` if the set is a subset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let sup: TrieSet = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let mut set: TrieSet = TrieSet::new();
+    ///
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(2);
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(4);
+    /// assert_eq!(set.is_subset(&sup), false);
+    /// ```
+    #[inline]
+    pub fn is_subset(&self, other: &TrieSet) -> bool {
+        self.iter().all(|v| other.contains(&v))
+    }
+
+    /// Returns `true` if the set is a superset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let sub: TrieSet = [1, 2].iter().map(|&x| x).collect();
+    /// let mut set: TrieSet = TrieSet::new();
+    ///
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(0);
+    /// set.insert(1);
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(2);
+    /// assert_eq!(set.is_superset(&sub), true);
+    /// ```
+    #[inline]
+    pub fn is_superset(&self, other: &TrieSet) -> bool {
+        other.is_subset(self)
+    }
+
+    /// Adds a value to the set. Returns `true` if the value was not already
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let mut set = TrieSet::new();
+    ///
+    /// assert_eq!(set.insert(2), true);
+    /// assert_eq!(set.insert(2), false);
+    /// assert_eq!(set.len(), 1);
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, value: uint) -> bool {
+        self.map.insert(value, ())
+    }
+
+    /// Removes a value from the set. Returns `true` if the value was
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::TrieSet;
+    ///
+    /// let mut set = TrieSet::new();
+    ///
+    /// set.insert(2);
+    /// assert_eq!(set.remove(&2), true);
+    /// assert_eq!(set.remove(&2), false);
+    /// ```
+    #[inline]
+    pub fn remove(&mut self, value: &uint) -> bool {
+        self.map.remove(value)
+    }
 }
 
 impl FromIterator<uint> for TrieSet {
@@ -1026,7 +1277,6 @@ mod test_map {
     use std::uint;
     use std::hash;
 
-    use {MutableMap, Map, MutableSeq};
     use super::{TrieMap, TrieNode, Internal, External, Nothing};
 
     fn check_integrity<T>(trie: &TrieNode<T>) {
@@ -1442,7 +1692,6 @@ mod bench_map {
     use std::rand::{weak_rng, Rng};
     use test::{Bencher, black_box};
 
-    use MutableMap;
     use super::TrieMap;
 
     fn bench_iter(b: &mut Bencher, size: uint) {
@@ -1559,7 +1808,6 @@ mod test_set {
     use std::prelude::*;
     use std::uint;
 
-    use {MutableSet, Set, MutableSeq};
     use super::TrieSet;
 
     #[test]
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index b190093bafcb3..d7ec3836eb264 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -27,7 +27,6 @@ use core::ptr;
 use core::raw::Slice as RawSlice;
 use core::uint;
 
-use {Mutable, MutableSeq};
 use slice::{CloneableVector};
 
 /// An owned, growable vector.
@@ -530,15 +529,6 @@ impl<T: Ord> Ord for Vec<T> {
     }
 }
 
-#[experimental = "waiting on Collection stability"]
-impl<T> Collection for Vec<T> {
-    #[inline]
-    #[stable]
-    fn len(&self) -> uint {
-        self.len
-    }
-}
-
 // FIXME: #13996: need a way to mark the return value as `noalias`
 #[inline(never)]
 unsafe fn alloc_or_realloc<T>(ptr: *mut T, old_size: uint, size: uint) -> *mut T {
@@ -969,15 +959,107 @@ impl<T> Vec<T> {
             self.push(f(i));
         }
     }
-}
 
-#[experimental = "waiting on Mutable stability"]
-impl<T> Mutable for Vec<T> {
+    /// Appends an element to the back of a collection.
+    ///
+    /// # Failure
+    ///
+    /// Fails if the number of elements in the vector overflows a `uint`.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec!(1i, 2);
+    /// vec.push(3);
+    /// assert_eq!(vec, vec!(1, 2, 3));
+    /// ```
+    #[inline]
+    #[stable]
+    pub fn push(&mut self, value: T) {
+        if mem::size_of::<T>() == 0 {
+            // zero-size types consume no memory, so we can't rely on the address space running out
+            self.len = self.len.checked_add(&1).expect("length overflow");
+            unsafe { mem::forget(value); }
+            return
+        }
+        if self.len == self.cap {
+            let old_size = self.cap * mem::size_of::<T>();
+            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
+            if old_size > size { panic!("capacity overflow") }
+            unsafe {
+                self.ptr = alloc_or_realloc(self.ptr, old_size, size);
+            }
+            self.cap = max(self.cap, 2) * 2;
+        }
+
+        unsafe {
+            let end = (self.ptr as *const T).offset(self.len as int) as *mut T;
+            ptr::write(&mut *end, value);
+            self.len += 1;
+        }
+    }
+
+    /// Removes the last element from a vector and returns it, or `None` if
+    /// it is empty.
+    ///
+    /// # Example
+    ///
+    /// ```rust
+    /// let mut vec = vec![1i, 2, 3];
+    /// assert_eq!(vec.pop(), Some(3));
+    /// assert_eq!(vec, vec![1, 2]);
+    /// ```
     #[inline]
     #[stable]
-    fn clear(&mut self) {
+    pub fn pop(&mut self) -> Option<T> {
+        if self.len == 0 {
+            None
+        } else {
+            unsafe {
+                self.len -= 1;
+                Some(ptr::read(self.as_slice().unsafe_get(self.len())))
+            }
+        }
+    }
+
+    /// Clears the vector, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let mut v = vec![1i, 2, 3];
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    #[inline]
+    #[stable]
+    pub fn clear(&mut self) {
         self.truncate(0)
     }
+
+    /// Return the number of elements in the vector
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let a = vec![1i, 2, 3];
+    /// assert_eq!(a.len(), 3);
+    /// ```
+    #[inline]
+    #[stable]
+    pub fn len(&self) -> uint { self.len }
+
+    /// Returns true if the vector contains no elements
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let mut v = Vec::new();
+    /// assert!(v.is_empty());
+    /// v.push(1i);
+    /// assert!(!v.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl<T: PartialEq> Vec<T> {
@@ -1141,61 +1223,6 @@ impl<T:fmt::Show> fmt::Show for Vec<T> {
     }
 }
 
-#[experimental = "waiting on MutableSeq stability"]
-impl<T> MutableSeq<T> for Vec<T> {
-    /// Appends an element to the back of a collection.
-    ///
-    /// # Failure
-    ///
-    /// Fails if the number of elements in the vector overflows a `uint`.
-    ///
-    /// # Example
-    ///
-    /// ```rust
-    /// let mut vec = vec!(1i, 2);
-    /// vec.push(3);
-    /// assert_eq!(vec, vec!(1, 2, 3));
-    /// ```
-    #[inline]
-    #[stable]
-    fn push(&mut self, value: T) {
-        if mem::size_of::<T>() == 0 {
-            // zero-size types consume no memory, so we can't rely on the address space running out
-            self.len = self.len.checked_add(&1).expect("length overflow");
-            unsafe { mem::forget(value); }
-            return
-        }
-        if self.len == self.cap {
-            let old_size = self.cap * mem::size_of::<T>();
-            let size = max(old_size, 2 * mem::size_of::<T>()) * 2;
-            if old_size > size { panic!("capacity overflow") }
-            unsafe {
-                self.ptr = alloc_or_realloc(self.ptr, old_size, size);
-            }
-            self.cap = max(self.cap, 2) * 2;
-        }
-
-        unsafe {
-            let end = (self.ptr as *const T).offset(self.len as int) as *mut T;
-            ptr::write(&mut *end, value);
-            self.len += 1;
-        }
-    }
-
-    #[inline]
-    #[stable]
-    fn pop(&mut self) -> Option<T> {
-        if self.len == 0 {
-            None
-        } else {
-            unsafe {
-                self.len -= 1;
-                Some(ptr::read(self.as_slice().unsafe_get(self.len())))
-            }
-        }
-    }
-}
-
 /// An iterator that moves out of a vector.
 pub struct MoveItems<T> {
     allocation: *mut T, // the block of memory allocated for the vector
@@ -1636,8 +1663,6 @@ mod tests {
     use test::Bencher;
     use super::{as_vec, unzip, raw, Vec};
 
-    use MutableSeq;
-
     struct DropCounter<'a> {
         count: &'a mut int
     }
diff --git a/src/libcore/char.rs b/src/libcore/char.rs
index 5d9553cbbbd57..3b9f8f58a2054 100644
--- a/src/libcore/char.rs
+++ b/src/libcore/char.rs
@@ -18,7 +18,7 @@
 use mem::transmute;
 use option::{None, Option, Some};
 use iter::range_step;
-use collections::Collection;
+use slice::ImmutableSlice;
 
 // UTF-8 ranges and tags for encoding characters
 static TAG_CONT: u8    = 0b1000_0000u8;
diff --git a/src/libcore/collections.rs b/src/libcore/collections.rs
deleted file mode 100644
index 7d87e03c13410..0000000000000
--- a/src/libcore/collections.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-// Copyright 2013 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.
-
-//! Traits for generic collections
-
-/// A trait to represent the abstract idea of a container. The only concrete
-/// knowledge known is the number of elements contained within.
-pub trait Collection {
-    /// Return the number of elements in the container
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// let a = [1i, 2, 3];
-    /// assert_eq!(a.len(), 3);
-    /// ```
-    fn len(&self) -> uint;
-
-    /// Return true if the container contains no elements
-    ///
-    /// # Example
-    ///
-    /// ```
-    /// let s = String::new();
-    /// assert!(s.is_empty());
-    /// ```
-    #[inline]
-    fn is_empty(&self) -> bool {
-        self.len() == 0
-    }
-}
diff --git a/src/libcore/fmt/float.rs b/src/libcore/fmt/float.rs
index b8a91a912ba3c..f51d3948757c7 100644
--- a/src/libcore/fmt/float.rs
+++ b/src/libcore/fmt/float.rs
@@ -11,14 +11,12 @@
 #![allow(missing_docs)]
 
 use char;
-use collections::Collection;
 use fmt;
 use iter::{range, DoubleEndedIterator};
 use num::{Float, FPNaN, FPInfinite, ToPrimitive, Primitive};
 use num::{Zero, One, cast};
 use result::Ok;
-use slice::MutableSlice;
-use slice;
+use slice::{mod, ImmutableSlice, MutableSlice};
 use str::StrSlice;
 
 /// A flag that specifies whether to use exponential (scientific) notation.
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 5000b020985e5..74b39a7058c0a 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -14,7 +14,6 @@
 
 use any;
 use cell::{Cell, Ref, RefMut};
-use collections::Collection;
 use iter::{Iterator, range};
 use kinds::{Copy, Sized};
 use mem;
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 568528f6ae29e..190e1ecea5921 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -14,11 +14,10 @@
 
 #![allow(unsigned_negation)]
 
-use collections::Collection;
 use fmt;
 use iter::DoubleEndedIterator;
 use num::{Int, cast, zero};
-use slice::{MutableSlice};
+use slice::{ImmutableSlice, MutableSlice};
 
 /// A type that represents a specific radix
 #[doc(hidden)]
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index a7be23e53e074..7c5c54c6d8abc 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -102,7 +102,6 @@ pub mod ops;
 pub mod cmp;
 pub mod clone;
 pub mod default;
-pub mod collections;
 
 /* Core types and methods on primitives */
 
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude.rs
index 680f91945d103..64917fb2541b9 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude.rs
@@ -50,7 +50,6 @@ pub use char::Char;
 pub use clone::Clone;
 pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 pub use cmp::{Ordering, Less, Equal, Greater, Equiv};
-pub use collections::Collection;
 pub use iter::{FromIterator, Extendable};
 pub use iter::{Iterator, DoubleEndedIterator, RandomAccessIterator, CloneableIterator};
 pub use iter::{OrdIterator, MutableDoubleEndedIterator, ExactSize};
diff --git a/src/libcore/slice.rs b/src/libcore/slice.rs
index aadf540afbe20..362463f2dcd26 100644
--- a/src/libcore/slice.rs
+++ b/src/libcore/slice.rs
@@ -36,7 +36,6 @@
 
 use mem::transmute;
 use clone::Clone;
-use collections::Collection;
 use cmp::{PartialEq, PartialOrd, Eq, Ord, Ordering, Less, Equal, Greater, Equiv};
 use cmp;
 use default::Default;
@@ -234,6 +233,29 @@ pub trait ImmutableSlice<T> for Sized? {
     /// ```
     #[unstable = "waiting on unboxed closures"]
     fn binary_search(&self, f: |&T| -> Ordering) -> BinarySearchResult;
+
+    /// Return the number of elements in the slice
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let a = [1i, 2, 3];
+    /// assert_eq!(a.len(), 3);
+    /// ```
+    #[experimental = "not triaged yet"]
+    fn len(&self) -> uint;
+
+    /// Returns true if the slice has a length of 0
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// let a = [1i, 2, 3];
+    /// assert!(!a.is_empty());
+    /// ```
+    #[inline]
+    #[experimental = "not triaged yet"]
+    fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 #[unstable]
@@ -372,6 +394,9 @@ impl<T> ImmutableSlice<T> for [T] {
         }
         return NotFound(base);
     }
+
+    #[inline]
+    fn len(&self) -> uint { self.repr().len }
 }
 
 
@@ -886,24 +911,6 @@ impl<'a,T> AsSlice<T> for &'a [T] {
     fn as_slice<'a>(&'a self) -> &'a [T] { *self }
 }
 
-#[experimental = "trait is experimental"]
-impl<'a, T> Collection for &'a [T] {
-    /// Returns the length of a slice.
-    #[inline]
-    fn len(&self) -> uint {
-        self.repr().len
-    }
-}
-
-#[experimental = "trait is experimental"]
-impl<'a, T> Collection for &'a mut [T] {
-    /// Returns the length of a slice.
-    #[inline]
-    fn len(&self) -> uint {
-        self.repr().len
-    }
-}
-
 #[unstable = "waiting for DST"]
 impl<'a, T> Default for &'a [T] {
     fn default() -> &'a [T] { &[] }
@@ -1508,7 +1515,6 @@ pub mod raw {
 /// Operations on `[u8]`.
 #[experimental = "needs review"]
 pub mod bytes {
-    use collections::Collection;
     use kinds::Sized;
     use ptr;
     use slice::{ImmutableSlice, MutableSlice};
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 433a3ce1109ad..27886a378cdf8 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -22,7 +22,6 @@ use char::Char;
 use clone::Clone;
 use cmp;
 use cmp::{PartialEq, Eq};
-use collections::Collection;
 use default::Default;
 use iter::{Map, Iterator};
 use iter::{DoubleEndedIterator, ExactSize};
@@ -1057,7 +1056,6 @@ const TAG_CONT_U8: u8 = 0b1000_0000u8;
 /// Unsafe operations
 pub mod raw {
     use mem;
-    use collections::Collection;
     use ptr::RawPtr;
     use raw::Slice;
     use slice::{ImmutableSlice};
@@ -1121,7 +1119,6 @@ Section: Trait implementations
 #[allow(missing_docs)]
 pub mod traits {
     use cmp::{Ord, Ordering, Less, Equal, Greater, PartialEq, PartialOrd, Equiv, Eq};
-    use collections::Collection;
     use iter::Iterator;
     use option::{Option, Some};
     use ops;
@@ -1199,13 +1196,6 @@ impl<'a> Str for &'a str {
     fn as_slice<'a>(&'a self) -> &'a str { *self }
 }
 
-impl<'a> Collection for &'a str {
-    #[inline]
-    fn len(&self) -> uint {
-        self.repr().len
-    }
-}
-
 /// Methods for string slices
 pub trait StrSlice for Sized? {
     /// Returns true if one string contains another
@@ -1827,6 +1817,28 @@ pub trait StrSlice for Sized? {
 
     /// Return an iterator of `u16` over the string encoded as UTF-16.
     fn utf16_units<'a>(&'a self) -> Utf16CodeUnits<'a>;
+
+    /// Return the number of bytes in this string
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// assert_eq!("foo".len(), 3);
+    /// assert_eq!("ƒoo".len(), 4);
+    /// ```
+    #[experimental = "not triaged yet"]
+    fn len(&self) -> uint;
+
+    /// Returns true if this slice contains no bytes
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// assert!("".is_empty());
+    /// ```
+    #[inline]
+    #[experimental = "not triaged yet"]
+    fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 #[inline(never)]
@@ -2179,6 +2191,9 @@ impl StrSlice for str {
     fn utf16_units(&self) -> Utf16CodeUnits {
         Utf16CodeUnits{ chars: self.chars(), extra: 0}
     }
+
+    #[inline]
+    fn len(&self) -> uint { self.repr().len }
 }
 
 impl<'a> Default for &'a str {
diff --git a/src/libgraphviz/maybe_owned_vec.rs b/src/libgraphviz/maybe_owned_vec.rs
index a4d794d1f99fb..d465d1407513b 100644
--- a/src/libgraphviz/maybe_owned_vec.rs
+++ b/src/libgraphviz/maybe_owned_vec.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::collections::Collection;
 use std::default::Default;
 use std::fmt;
 use std::iter::FromIterator;
@@ -62,6 +61,10 @@ impl<'a,T> MaybeOwnedVector<'a,T> {
             &Borrowed(ref v) => v.iter(),
         }
     }
+
+    pub fn len(&self) -> uint { self.as_slice().len() }
+
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl<'a, T: PartialEq> PartialEq for MaybeOwnedVector<'a, T> {
@@ -145,12 +148,6 @@ impl<'a, T> Default for MaybeOwnedVector<'a, T> {
     }
 }
 
-impl<'a, T> Collection for MaybeOwnedVector<'a, T> {
-    fn len(&self) -> uint {
-        self.as_slice().len()
-    }
-}
-
 impl<'a> BytesContainer for MaybeOwnedVector<'a, u8> {
     fn container_as_bytes<'a>(&'a self) -> &'a [u8] {
         self.as_slice()
diff --git a/src/libregex/re.rs b/src/libregex/re.rs
index d352739f853e9..130e120b588d4 100644
--- a/src/libregex/re.rs
+++ b/src/libregex/re.rs
@@ -772,14 +772,14 @@ impl<'t> Captures<'t> {
         let re = Regex::new(r"\$\$").unwrap();
         re.replace_all(text.as_slice(), NoExpand("$"))
     }
-}
 
-impl<'t> Collection for Captures<'t> {
     /// Returns the number of captured groups.
     #[inline]
-    fn len(&self) -> uint {
-        self.locs.len() / 2
-    }
+    pub fn len(&self) -> uint { self.locs.len() / 2 }
+
+    /// Returns if there are no captured groups.
+    #[inline]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 /// An iterator over capture groups for a particular match of a regular
diff --git a/src/librlibc/lib.rs b/src/librlibc/lib.rs
index ca7ce2a8b7153..dd88eb3251b63 100644
--- a/src/librlibc/lib.rs
+++ b/src/librlibc/lib.rs
@@ -108,7 +108,6 @@ pub unsafe extern "C" fn memcmp(s1: *const u8, s2: *const u8, n: uint) -> i32 {
 
 #[cfg(test)]
 mod test {
-    use core::collections::Collection;
     use core::str::StrSlice;
     use core::slice::{MutableSlice, ImmutableSlice};
 
diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs
index 98d02dfb8d7a8..7dbddd3f5df33 100644
--- a/src/librustc/middle/trans/adt.rs
+++ b/src/librustc/middle/trans/adt.rs
@@ -45,7 +45,6 @@
 
 #![allow(unsigned_negation)]
 
-use std::collections::Map;
 use std::num::Int;
 use std::rc::Rc;
 
diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs
index ed38f6f871d79..cf807cb22bc2a 100644
--- a/src/librustc/util/common.rs
+++ b/src/librustc/util/common.rs
@@ -184,8 +184,8 @@ pub fn can_reach<S,H:Hasher<S>,T:Eq+Clone+Hash<S>>(
 /// }
 /// ```
 #[inline(always)]
-pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
-    cache: &RefCell<M>,
+pub fn memoized<T: Clone + Hash<S> + Eq, U: Clone, S, H: Hasher<S>>(
+    cache: &RefCell<HashMap<T, U, H>>,
     arg: T,
     f: |T| -> U
 ) -> U {
@@ -193,8 +193,8 @@ pub fn memoized<T: Clone, U: Clone, M: MutableMap<T, U>>(
 }
 
 #[inline(always)]
-pub fn memoized_with_key<T, K, U: Clone, M: MutableMap<K, U>>(
-    cache: &RefCell<M>,
+pub fn memoized_with_key<T, K: Hash<S> + Eq, U: Clone, S, H: Hasher<S>>(
+    cache: &RefCell<HashMap<K, U, H>>,
     arg: T,
     f: |T| -> U,
     k: |&T| -> K
diff --git a/src/librustrt/at_exit_imp.rs b/src/librustrt/at_exit_imp.rs
index c54afb241aebb..ce27decb136c0 100644
--- a/src/librustrt/at_exit_imp.rs
+++ b/src/librustrt/at_exit_imp.rs
@@ -15,7 +15,6 @@
 use core::prelude::*;
 
 use alloc::boxed::Box;
-use collections::MutableSeq;
 use collections::vec::Vec;
 use core::atomic;
 use core::mem;
diff --git a/src/librustrt/c_str.rs b/src/librustrt/c_str.rs
index ddb4df4fdc538..676f36e546858 100644
--- a/src/librustrt/c_str.rs
+++ b/src/librustrt/c_str.rs
@@ -76,7 +76,7 @@ use collections::hash;
 use core::fmt;
 use core::kinds::marker;
 use core::mem;
-use core::prelude::{Clone, Collection, Drop, Eq, ImmutableSlice, Iterator};
+use core::prelude::{Clone, Drop, Eq, ImmutableSlice, Iterator};
 use core::prelude::{MutableSlice, None, Option, Ordering, PartialEq};
 use core::prelude::{PartialOrd, RawPtr, Some, StrSlice, range};
 use core::ptr;
@@ -259,6 +259,16 @@ impl CString {
         self.buf
     }
 
+    /// Return the number of bytes in the CString (not including the NUL
+    /// terminator).
+    #[inline]
+    pub fn len(&self) -> uint {
+        unsafe { libc::strlen(self.buf) as uint }
+    }
+
+    /// Returns if there are no bytes in this string
+    #[inline]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl Drop for CString {
@@ -271,14 +281,6 @@ impl Drop for CString {
     }
 }
 
-impl Collection for CString {
-    /// Return the number of bytes in the CString (not including the NUL terminator).
-    #[inline]
-    fn len(&self) -> uint {
-        unsafe { libc::strlen(self.buf) as uint }
-    }
-}
-
 impl fmt::Show for CString {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         String::from_utf8_lossy(self.as_bytes_no_nul()).fmt(f)
diff --git a/src/librustrt/local_data.rs b/src/librustrt/local_data.rs
index 14275d070f0c9..796f9af659630 100644
--- a/src/librustrt/local_data.rs
+++ b/src/librustrt/local_data.rs
@@ -42,7 +42,6 @@ use core::prelude::*;
 
 use alloc::heap;
 use collections::treemap::TreeMap;
-use collections::MutableMap;
 use core::cmp;
 use core::kinds::marker;
 use core::mem;
@@ -261,8 +260,6 @@ impl<T: 'static> KeyValue<T> {
     /// assert_eq!(*key.get().unwrap(), 3);
     /// ```
     pub fn get(&'static self) -> Option<Ref<T>> {
-        use collections::Map;
-
         let map = match unsafe { get_local_map() } {
             Some(map) => map,
             None => return None,
diff --git a/src/libstd/ascii.rs b/src/libstd/ascii.rs
index 31f37a8a1bbda..6b64959a8436b 100644
--- a/src/libstd/ascii.rs
+++ b/src/libstd/ascii.rs
@@ -14,7 +14,6 @@
 
 #![experimental]
 
-use collections::Collection;
 use core::kinds::Sized;
 use fmt;
 use iter::Iterator;
diff --git a/src/libstd/c_vec.rs b/src/libstd/c_vec.rs
index bb7de168898f0..fd605bb2b5cc2 100644
--- a/src/libstd/c_vec.rs
+++ b/src/libstd/c_vec.rs
@@ -35,7 +35,6 @@
 
 #![experimental]
 
-use collections::Collection;
 use kinds::Send;
 use mem;
 use ops::Drop;
@@ -143,6 +142,12 @@ impl<T> CVec<T> {
         self.dtor = None;
         self.base
     }
+
+    /// Returns the number of items in this vector.
+    pub fn len(&self) -> uint { self.len }
+
+    /// Returns whether this vector is empty.
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 impl<T> AsSlice<T> for CVec<T> {
@@ -154,10 +159,6 @@ impl<T> AsSlice<T> for CVec<T> {
     }
 }
 
-impl<T> Collection for CVec<T> {
-    fn len(&self) -> uint { self.len }
-}
-
 #[cfg(test)]
 mod tests {
     use prelude::*;
diff --git a/src/libstd/collections/hashmap/map.rs b/src/libstd/collections/hashmap/map.rs
index cb47c28f8bef2..1dd150badaac9 100644
--- a/src/libstd/collections/hashmap/map.rs
+++ b/src/libstd/collections/hashmap/map.rs
@@ -12,7 +12,6 @@
 
 use clone::Clone;
 use cmp::{max, Eq, Equiv, PartialEq};
-use collections::{Collection, Mutable, MutableSet, Map, MutableMap};
 use default::Default;
 use fmt::{mod, Show};
 use hash::{Hash, Hasher, RandomSipHasher};
@@ -470,86 +469,6 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
     }
 }
 
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Collection for HashMap<K, V, H> {
-    /// Return the number of elements in the map.
-    fn len(&self) -> uint { self.table.size() }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Mutable for HashMap<K, V, H> {
-    /// Clear the map, removing all key-value pairs. Keeps the allocated memory
-    /// for reuse.
-    fn clear(&mut self) {
-        // Prevent reallocations from happening from now on. Makes it possible
-        // for the map to be reused but has a downside: reserves permanently.
-        self.resize_policy.reserve(self.table.size());
-
-        let cap = self.table.capacity();
-        let mut buckets = Bucket::first(&mut self.table);
-
-        while buckets.index() != cap {
-            buckets = match buckets.peek() {
-                Empty(b)  => b.next(),
-                Full(full) => {
-                    let (b, _, _) = full.take();
-                    b.next()
-                }
-            };
-        }
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> Map<K, V> for HashMap<K, V, H> {
-    fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
-        self.search(k).map(|bucket| {
-            let (_, v) = bucket.into_refs();
-            v
-        })
-    }
-
-    fn contains_key(&self, k: &K) -> bool {
-        self.search(k).is_some()
-    }
-}
-
-impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> MutableMap<K, V> for HashMap<K, V, H> {
-    fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
-        match self.search_mut(k) {
-            Some(bucket) => {
-                let (_, v) = bucket.into_mut_refs();
-                Some(v)
-            }
-            _ => None
-        }
-    }
-
-    fn swap(&mut self, k: K, v: V) -> Option<V> {
-        let hash = self.make_hash(&k);
-        let potential_new_size = self.table.size() + 1;
-        self.make_some_room(potential_new_size);
-
-        let mut retval = None;
-        self.insert_or_replace_with(hash, k, v, |_, val_ref, val| {
-            retval = Some(replace(val_ref, val));
-        });
-        retval
-    }
-
-
-    fn pop(&mut self, k: &K) -> Option<V> {
-        if self.table.size() == 0 {
-            return None
-        }
-
-        let potential_new_size = self.table.size() - 1;
-        self.make_some_room(potential_new_size);
-
-        self.search_mut(k).map(|bucket| {
-            let (_k, val) = pop_internal(bucket);
-            val
-        })
-    }
-}
-
 impl<K: Hash + Eq, V> HashMap<K, V, RandomSipHasher> {
     /// Create an empty HashMap.
     ///
@@ -1063,6 +982,219 @@ impl<K: Eq + Hash<S>, V, S, H: Hasher<S>> HashMap<K, V, H> {
         let hash = self.make_hash(&key);
         search_entry_hashed(&mut self.table, hash, key)
     }
+
+    /// Return the number of elements in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// assert_eq!(a.len(), 0);
+    /// a.insert(1u, "a");
+    /// assert_eq!(a.len(), 1);
+    /// ```
+    pub fn len(&self) -> uint { self.table.size() }
+
+    /// Return true if the map contains no elements.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// assert!(a.is_empty());
+    /// a.insert(1u, "a");
+    /// assert!(!a.is_empty());
+    /// ```
+    #[inline]
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clears the map, removing all key-value pairs. Keeps the allocated memory
+    /// for reuse.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut a = HashMap::new();
+    /// a.insert(1u, "a");
+    /// a.clear();
+    /// assert!(a.is_empty());
+    /// ```
+    pub fn clear(&mut self) {
+        // Prevent reallocations from happening from now on. Makes it possible
+        // for the map to be reused but has a downside: reserves permanently.
+        self.resize_policy.reserve(self.table.size());
+
+        let cap = self.table.capacity();
+        let mut buckets = Bucket::first(&mut self.table);
+
+        while buckets.index() != cap {
+            buckets = match buckets.peek() {
+                Empty(b)  => b.next(),
+                Full(full) => {
+                    let (b, _, _) = full.take();
+                    b.next()
+                }
+            };
+        }
+    }
+
+    /// Returns a reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.find(&1), Some(&"a"));
+    /// assert_eq!(map.find(&2), None);
+    /// ```
+    pub fn find<'a>(&'a self, k: &K) -> Option<&'a V> {
+        self.search(k).map(|bucket| {
+            let (_, v) = bucket.into_refs();
+            v
+        })
+    }
+
+    /// Returns true if the map contains a value for the specified key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.contains_key(&1), true);
+    /// assert_eq!(map.contains_key(&2), false);
+    /// ```
+    pub fn contains_key(&self, k: &K) -> bool {
+        self.search(k).is_some()
+    }
+
+    /// Returns a mutable reference to the value corresponding to the key.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1u, "a");
+    /// match map.find_mut(&1) {
+    ///     Some(x) => *x = "b",
+    ///     None => (),
+    /// }
+    /// assert_eq!(map[1], "b");
+    /// ```
+    pub fn find_mut<'a>(&'a mut self, k: &K) -> Option<&'a mut V> {
+        match self.search_mut(k) {
+            Some(bucket) => {
+                let (_, v) = bucket.into_mut_refs();
+                Some(v)
+            }
+            _ => None
+        }
+    }
+
+    /// Inserts a key-value pair into the map. An existing value for a
+    /// key is replaced by the new value. Returns `true` if the key did
+    /// not already exist in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// assert_eq!(map.insert(2u, "value"), true);
+    /// assert_eq!(map.insert(2, "value2"), false);
+    /// assert_eq!(map[2], "value2");
+    /// ```
+    #[inline]
+    pub fn insert(&mut self, key: K, value: V) -> bool {
+        self.swap(key, value).is_none()
+    }
+
+    /// Removes a key-value pair from the map. Returns `true` if the key
+    /// was present in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// assert_eq!(map.remove(&1u), false);
+    /// map.insert(1, "a");
+    /// assert_eq!(map.remove(&1), true);
+    /// ```
+    #[inline]
+    pub fn remove(&mut self, key: &K) -> bool {
+        self.pop(key).is_some()
+    }
+
+    /// Inserts a key-value pair from the map. If the key already had a value
+    /// present in the map, that value is returned. Otherwise, `None` is returned.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// assert_eq!(map.swap(37u, "a"), None);
+    /// assert_eq!(map.is_empty(), false);
+    ///
+    /// map.insert(37, "b");
+    /// assert_eq!(map.swap(37, "c"), Some("b"));
+    /// assert_eq!(map[37], "c");
+    /// ```
+    pub fn swap(&mut self, k: K, v: V) -> Option<V> {
+        let hash = self.make_hash(&k);
+        let potential_new_size = self.table.size() + 1;
+        self.make_some_room(potential_new_size);
+
+        let mut retval = None;
+        self.insert_or_replace_with(hash, k, v, |_, val_ref, val| {
+            retval = Some(replace(val_ref, val));
+        });
+        retval
+    }
+
+    /// Removes a key from the map, returning the value at the key if the key
+    /// was previously in the map.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashMap;
+    ///
+    /// let mut map = HashMap::new();
+    /// map.insert(1u, "a");
+    /// assert_eq!(map.pop(&1), Some("a"));
+    /// assert_eq!(map.pop(&1), None);
+    /// ```
+    pub fn pop(&mut self, k: &K) -> Option<V> {
+        if self.table.size() == 0 {
+            return None
+        }
+
+        let potential_new_size = self.table.size() - 1;
+        self.make_some_room(potential_new_size);
+
+        self.search_mut(k).map(|bucket| {
+            let (_k, val) = pop_internal(bucket);
+            val
+        })
+    }
 }
 
 fn search_entry_hashed<'a, K: Eq, V>(table: &'a mut RawTable<K,V>, hash: SafeHash, k: K)
diff --git a/src/libstd/collections/hashmap/set.rs b/src/libstd/collections/hashmap/set.rs
index ca954679c1c9d..957f10b4be8fd 100644
--- a/src/libstd/collections/hashmap/set.rs
+++ b/src/libstd/collections/hashmap/set.rs
@@ -12,7 +12,6 @@
 
 use clone::Clone;
 use cmp::{Eq, Equiv, PartialEq};
-use collections::{Collection, Mutable, Set, MutableSet, Map, MutableMap};
 use default::Default;
 use fmt::Show;
 use fmt;
@@ -375,44 +374,170 @@ impl<T: Eq + Hash<S>, S, H: Hasher<S>> HashSet<T, H> {
         -> Chain<SetItems<'a, T>, SetAlgebraItems<'a, T, H>> {
         self.iter().chain(other.difference(self))
     }
-}
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
-    fn eq(&self, other: &HashSet<T, H>) -> bool {
-        if self.len() != other.len() { return false; }
-
-        self.iter().all(|key| other.contains(key))
-    }
-}
-
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
+    /// Return the number of elements in the set
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut v = HashSet::new();
+    /// assert_eq!(v.len(), 0);
+    /// v.insert(1u);
+    /// assert_eq!(v.len(), 1);
+    /// ```
+    pub fn len(&self) -> uint { self.map.len() }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Collection for HashSet<T, H> {
-    fn len(&self) -> uint { self.map.len() }
-}
+    /// Returns true if the set contains no elements
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut v = HashSet::new();
+    /// assert!(v.is_empty());
+    /// v.insert(1u);
+    /// assert!(!v.is_empty());
+    /// ```
+    pub fn is_empty(&self) -> bool { self.map.len() == 0 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Mutable for HashSet<T, H> {
-    fn clear(&mut self) { self.map.clear() }
-}
+    /// Clears the set, removing all values.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut v = HashSet::new();
+    /// v.insert(1u);
+    /// v.clear();
+    /// assert!(v.is_empty());
+    /// ```
+    pub fn clear(&mut self) { self.map.clear() }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> Set<T> for HashSet<T, H> {
-    fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
+    /// Returns `true` if the set contains a value.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let set: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
+    /// assert_eq!(set.contains(&1), true);
+    /// assert_eq!(set.contains(&4), false);
+    /// ```
+    pub fn contains(&self, value: &T) -> bool { self.map.contains_key(value) }
 
-    fn is_disjoint(&self, other: &HashSet<T, H>) -> bool {
+    /// Returns `true` if the set has no elements in common with `other`.
+    /// This is equivalent to checking for an empty intersection.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let a: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let mut b: HashSet<uint> = HashSet::new();
+    ///
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(4);
+    /// assert_eq!(a.is_disjoint(&b), true);
+    /// b.insert(1);
+    /// assert_eq!(a.is_disjoint(&b), false);
+    /// ```
+    pub fn is_disjoint(&self, other: &HashSet<T, H>) -> bool {
         self.iter().all(|v| !other.contains(v))
     }
 
-    fn is_subset(&self, other: &HashSet<T, H>) -> bool {
+    /// Returns `true` if the set is a subset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let sup: HashSet<uint> = [1, 2, 3].iter().map(|&x| x).collect();
+    /// let mut set: HashSet<uint> = HashSet::new();
+    ///
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(2);
+    /// assert_eq!(set.is_subset(&sup), true);
+    /// set.insert(4);
+    /// assert_eq!(set.is_subset(&sup), false);
+    /// ```
+    pub fn is_subset(&self, other: &HashSet<T, H>) -> bool {
         self.iter().all(|v| other.contains(v))
     }
+
+    /// Returns `true` if the set is a superset of another.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let sub: HashSet<uint> = [1, 2].iter().map(|&x| x).collect();
+    /// let mut set: HashSet<uint> = HashSet::new();
+    ///
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(0);
+    /// set.insert(1);
+    /// assert_eq!(set.is_superset(&sub), false);
+    ///
+    /// set.insert(2);
+    /// assert_eq!(set.is_superset(&sub), true);
+    /// ```
+    #[inline]
+    pub fn is_superset(&self, other: &HashSet<T, H>) -> bool {
+        other.is_subset(self)
+    }
+
+    /// Adds a value to the set. Returns `true` if the value was not already
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// assert_eq!(set.insert(2u), true);
+    /// assert_eq!(set.insert(2), false);
+    /// assert_eq!(set.len(), 1);
+    /// ```
+    pub fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
+
+    /// Removes a value from the set. Returns `true` if the value was
+    /// present in the set.
+    ///
+    /// # Example
+    ///
+    /// ```
+    /// use std::collections::HashSet;
+    ///
+    /// let mut set = HashSet::new();
+    ///
+    /// set.insert(2u);
+    /// assert_eq!(set.remove(&2), true);
+    /// assert_eq!(set.remove(&2), false);
+    /// ```
+    pub fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
 }
 
-impl<T: Eq + Hash<S>, S, H: Hasher<S>> MutableSet<T> for HashSet<T, H> {
-    fn insert(&mut self, value: T) -> bool { self.map.insert(value, ()) }
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> PartialEq for HashSet<T, H> {
+    fn eq(&self, other: &HashSet<T, H>) -> bool {
+        if self.len() != other.len() { return false; }
 
-    fn remove(&mut self, value: &T) -> bool { self.map.remove(value) }
+        self.iter().all(|key| other.contains(key))
+    }
 }
 
+impl<T: Eq + Hash<S>, S, H: Hasher<S>> Eq for HashSet<T, H> {}
+
 impl<T: Eq + Hash<S> + fmt::Show, S, H: Hasher<S>> fmt::Show for HashSet<T, H> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         try!(write!(f, "{{"));
@@ -470,7 +595,6 @@ mod test_set {
 
     use super::HashSet;
     use slice::ImmutablePartialEqSlice;
-    use collections::Collection;
 
     #[test]
     fn test_disjoint() {
diff --git a/src/libstd/collections/lru_cache.rs b/src/libstd/collections/lru_cache.rs
index 5408e50f2bda3..93e649f9355dd 100644
--- a/src/libstd/collections/lru_cache.rs
+++ b/src/libstd/collections/lru_cache.rs
@@ -38,7 +38,7 @@
 //! ```
 
 use cmp::{PartialEq, Eq};
-use collections::{HashMap, Collection, Mutable, MutableMap};
+use collections::HashMap;
 use fmt;
 use hash::Hash;
 use iter::{range, Iterator};
@@ -288,6 +288,15 @@ impl<K: Hash + Eq, V> LruCache<K, V> {
             (*(*node).next).prev = node;
         }
     }
+
+    /// Return the number of key-value pairs in the cache.
+    pub fn len(&self) -> uint { self.map.len() }
+
+    /// Returns whether the cache is currently empty.
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
+
+    /// Clear the cache of all key-value pairs.
+    pub fn clear(&mut self) { self.map.clear(); }
 }
 
 impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
@@ -311,20 +320,6 @@ impl<A: fmt::Show + Hash + Eq, B: fmt::Show> fmt::Show for LruCache<A, B> {
     }
 }
 
-impl<K: Hash + Eq, V> Collection for LruCache<K, V> {
-    /// Return the number of key-value pairs in the cache.
-    fn len(&self) -> uint {
-        self.map.len()
-    }
-}
-
-impl<K: Hash + Eq, V> Mutable for LruCache<K, V> {
-    /// Clear the cache of all key-value pairs.
-    fn clear(&mut self) {
-        self.map.clear();
-    }
-}
-
 #[unsafe_destructor]
 impl<K, V> Drop for LruCache<K, V> {
     fn drop(&mut self) {
diff --git a/src/libstd/collections/mod.rs b/src/libstd/collections/mod.rs
index c227aa65b48f2..be9e22ee9d14c 100644
--- a/src/libstd/collections/mod.rs
+++ b/src/libstd/collections/mod.rs
@@ -328,8 +328,6 @@
 
 #![experimental]
 
-pub use core_collections::{Collection, Mutable, Map, MutableMap};
-pub use core_collections::{Set, MutableSet, Deque, MutableSeq};
 pub use core_collections::{Bitv, BitvSet, BTreeMap, BTreeSet, DList, EnumSet};
 pub use core_collections::{PriorityQueue, RingBuf, SmallIntMap};
 pub use core_collections::{TreeMap, TreeSet, TrieMap, TrieSet};
diff --git a/src/libstd/dynamic_lib.rs b/src/libstd/dynamic_lib.rs
index ec6eef07c9541..4c133fc739739 100644
--- a/src/libstd/dynamic_lib.rs
+++ b/src/libstd/dynamic_lib.rs
@@ -20,7 +20,6 @@ A simple wrapper over the platform's dynamic library facilities
 #![allow(missing_docs)]
 
 use clone::Clone;
-use collections::MutableSeq;
 use c_str::ToCStr;
 use iter::Iterator;
 use mem;
@@ -280,7 +279,6 @@ pub mod dl {
 #[cfg(target_os = "windows")]
 pub mod dl {
     use c_str::ToCStr;
-    use collections::MutableSeq;
     use iter::Iterator;
     use libc;
     use os;
diff --git a/src/libstd/io/buffered.rs b/src/libstd/io/buffered.rs
index a01787c286bb9..49c688da31cbf 100644
--- a/src/libstd/io/buffered.rs
+++ b/src/libstd/io/buffered.rs
@@ -13,7 +13,6 @@
 //! Buffering wrappers for I/O traits
 
 use cmp;
-use collections::Collection;
 use io::{Reader, Writer, Stream, Buffer, DEFAULT_BUF_SIZE, IoResult};
 use iter::ExactSize;
 use ops::Drop;
diff --git a/src/libstd/io/comm_adapters.rs b/src/libstd/io/comm_adapters.rs
index 91f3f38f89dcb..c925208c3eee7 100644
--- a/src/libstd/io/comm_adapters.rs
+++ b/src/libstd/io/comm_adapters.rs
@@ -10,7 +10,6 @@
 
 use clone::Clone;
 use cmp;
-use collections::Collection;
 use comm::{Sender, Receiver};
 use io;
 use option::{None, Some};
diff --git a/src/libstd/io/extensions.rs b/src/libstd/io/extensions.rs
index 06ed183e93679..6d0b8ebc3d9c4 100644
--- a/src/libstd/io/extensions.rs
+++ b/src/libstd/io/extensions.rs
@@ -15,7 +15,6 @@
 // FIXME: Not sure how this should be structured
 // FIXME: Iteration should probably be considered separately
 
-use collections::{Collection, MutableSeq};
 use io::{IoError, IoResult, Reader};
 use io;
 use iter::Iterator;
@@ -502,7 +501,6 @@ mod test {
 mod bench {
     extern crate test;
 
-    use collections::Collection;
     use prelude::*;
     use self::test::Bencher;
 
diff --git a/src/libstd/io/fs.rs b/src/libstd/io/fs.rs
index f193ce8cffacb..c8524676a6dd4 100644
--- a/src/libstd/io/fs.rs
+++ b/src/libstd/io/fs.rs
@@ -54,7 +54,6 @@ fs::unlink(&path);
 
 use c_str::ToCStr;
 use clone::Clone;
-use collections::{Collection, MutableSeq};
 use io::standard_error;
 use io::{FilePermission, Write, UnstableFileStat, Open, FileAccess, FileMode};
 use io::{IoResult, IoError, FileStat, SeekStyle, Seek, Writer, Reader};
diff --git a/src/libstd/io/mem.rs b/src/libstd/io/mem.rs
index 2f6dd7e47955f..6010436581764 100644
--- a/src/libstd/io/mem.rs
+++ b/src/libstd/io/mem.rs
@@ -13,13 +13,11 @@
 //! Readers and Writers for in-memory buffers
 
 use cmp::min;
-use collections::Collection;
 use option::None;
 use result::{Err, Ok};
 use io;
 use io::{Reader, Writer, Seek, Buffer, IoError, SeekStyle, IoResult};
-use slice;
-use slice::AsSlice;
+use slice::{mod, AsSlice, ImmutableSlice};
 use vec::Vec;
 
 const BUF_CAPACITY: uint = 128;
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 6d6c0c0dd758b..c6f237ff1da34 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -222,7 +222,6 @@ responding to errors that may occur while attempting to read the numbers.
 #![deny(unused_must_use)]
 
 use char::Char;
-use collections::Collection;
 use default::Default;
 use fmt;
 use int;
diff --git a/src/libstd/io/net/ip.rs b/src/libstd/io/net/ip.rs
index e93af7446990a..f4f3be13f6675 100644
--- a/src/libstd/io/net/ip.rs
+++ b/src/libstd/io/net/ip.rs
@@ -15,13 +15,12 @@
 
 #![allow(missing_docs)]
 
-use collections::Collection;
 use fmt;
 use from_str::FromStr;
 use iter::Iterator;
 use option::{Option, None, Some};
 use str::StrSlice;
-use slice::{MutableCloneableSlice, MutableSlice};
+use slice::{MutableCloneableSlice, MutableSlice, ImmutableSlice};
 
 pub type Port = u16;
 
diff --git a/src/libstd/num/strconv.rs b/src/libstd/num/strconv.rs
index 3b17f0bc79fa7..30ecf2284df76 100644
--- a/src/libstd/num/strconv.rs
+++ b/src/libstd/num/strconv.rs
@@ -14,7 +14,6 @@
 
 use char;
 use clone::Clone;
-use collections::{Collection, MutableSeq};
 use num::{NumCast, Zero, One, cast, Int};
 use num::{Float, FPNaN, FPInfinite, ToPrimitive};
 use num;
diff --git a/src/libstd/os.rs b/src/libstd/os.rs
index d4e6251cebeb0..5b3c872d2b726 100644
--- a/src/libstd/os.rs
+++ b/src/libstd/os.rs
@@ -32,7 +32,6 @@
 #![allow(non_snake_case)]
 
 use clone::Clone;
-use collections::{Collection, MutableSeq};
 use fmt;
 use io::{IoResult, IoError};
 use iter::Iterator;
diff --git a/src/libstd/path/mod.rs b/src/libstd/path/mod.rs
index 6a1229902464e..62105c0d90ea7 100644
--- a/src/libstd/path/mod.rs
+++ b/src/libstd/path/mod.rs
@@ -67,7 +67,6 @@ println!("path exists: {}", path.exists());
 
 #![experimental]
 
-use collections::{Collection, MutableSeq};
 use c_str::CString;
 use clone::Clone;
 use fmt;
diff --git a/src/libstd/path/posix.rs b/src/libstd/path/posix.rs
index 0d7a467b313f2..596dbfc7e6399 100644
--- a/src/libstd/path/posix.rs
+++ b/src/libstd/path/posix.rs
@@ -13,7 +13,6 @@
 use c_str::{CString, ToCStr};
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use collections::{Collection, MutableSeq};
 use from_str::FromStr;
 use hash;
 use io::Writer;
diff --git a/src/libstd/path/windows.rs b/src/libstd/path/windows.rs
index 1ddc027a07eab..de85748da5e90 100644
--- a/src/libstd/path/windows.rs
+++ b/src/libstd/path/windows.rs
@@ -16,7 +16,6 @@ use ascii::AsciiCast;
 use c_str::{CString, ToCStr};
 use clone::Clone;
 use cmp::{PartialEq, Eq, PartialOrd, Ord, Ordering};
-use collections::{Collection, MutableSeq};
 use from_str::FromStr;
 use hash;
 use io::Writer;
diff --git a/src/libstd/prelude.rs b/src/libstd/prelude.rs
index 48be404b0d02a..b2ff29c0f7eef 100644
--- a/src/libstd/prelude.rs
+++ b/src/libstd/prelude.rs
@@ -65,8 +65,6 @@
 #[doc(no_inline)] pub use clone::Clone;
 #[doc(no_inline)] pub use cmp::{PartialEq, PartialOrd, Eq, Ord};
 #[doc(no_inline)] pub use cmp::{Ordering, Less, Equal, Greater, Equiv};
-#[doc(no_inline)] pub use collections::{Collection, Mutable, Map, MutableMap, MutableSeq};
-#[doc(no_inline)] pub use collections::{Set, MutableSet};
 #[doc(no_inline)] pub use iter::{FromIterator, Extendable, ExactSize};
 #[doc(no_inline)] pub use iter::{Iterator, DoubleEndedIterator};
 #[doc(no_inline)] pub use iter::{RandomAccessIterator, CloneableIterator};
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index bf5bdc8a308e3..ba1061cfc21fd 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -62,7 +62,6 @@ mod imp {
 mod imp {
     extern crate libc;
 
-    use collections::Collection;
     use io::{IoResult};
     use kinds::marker;
     use mem;
@@ -70,7 +69,7 @@ mod imp {
     use rand::Rng;
     use result::{Ok};
     use self::libc::{c_int, size_t};
-    use slice::MutableSlice;
+    use slice::{ImmutableSlice, MutableSlice};
 
     /// A random number generator that retrieves randomness straight from
     /// the operating system. Platform sources:
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
index 4f2205312373c..c1bb6970f7150 100644
--- a/src/libstd/rand/reader.rs
+++ b/src/libstd/rand/reader.rs
@@ -10,10 +10,10 @@
 
 //! A wrapper around any Reader to treat it as an RNG.
 
-use collections::Collection;
 use io::Reader;
 use rand::Rng;
 use result::{Ok, Err};
+use slice::ImmutableSlice;
 
 /// An RNG that reads random bytes straight from a `Reader`. This will
 /// work best with an infinite reader, but this is not required.
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 5bd3927727574..5d7aa0509c5d8 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -12,7 +12,6 @@
 
 #![allow(non_camel_case_types)]
 
-use collections::Collection;
 use from_str::from_str;
 use io::{IoResult, Writer};
 use iter::Iterator;
@@ -390,7 +389,6 @@ mod imp {
 
     #[cfg(not(any(target_os = "macos", target_os = "ios")))]
     fn print(w: &mut Writer, idx: int, addr: *mut libc::c_void) -> IoResult<()> {
-        use collections::Collection;
         use iter::Iterator;
         use os;
         use path::GenericPath;
@@ -659,7 +657,6 @@ mod imp {
 #[allow(dead_code, non_snake_case)]
 mod imp {
     use c_str::CString;
-    use core_collections::Collection;
     use intrinsics;
     use io::{IoResult, Writer};
     use libc;
diff --git a/src/libsync/deque.rs b/src/libsync/deque.rs
index 31889a36dd7ab..11b8b974dcf79 100644
--- a/src/libsync/deque.rs
+++ b/src/libsync/deque.rs
@@ -55,7 +55,7 @@ use core::prelude::*;
 use alloc::arc::Arc;
 use alloc::heap::{allocate, deallocate};
 use alloc::boxed::Box;
-use collections::{Vec, MutableSeq};
+use collections::Vec;
 use core::kinds::marker;
 use core::mem::{forget, min_align_of, size_of, transmute};
 use core::ptr;
diff --git a/src/libsync/raw.rs b/src/libsync/raw.rs
index 1410091b924ba..facf204983b42 100644
--- a/src/libsync/raw.rs
+++ b/src/libsync/raw.rs
@@ -22,7 +22,7 @@ use core::finally::Finally;
 use core::kinds::marker;
 use core::mem;
 use core::cell::UnsafeCell;
-use collections::{Vec, MutableSeq};
+use collections::Vec;
 
 use mutex;
 use comm::{Receiver, Sender, channel};
diff --git a/src/libsyntax/owned_slice.rs b/src/libsyntax/owned_slice.rs
index 4f09b34557c74..f622e2d611276 100644
--- a/src/libsyntax/owned_slice.rs
+++ b/src/libsyntax/owned_slice.rs
@@ -112,6 +112,10 @@ impl<T> OwnedSlice<T> {
     pub fn map<U>(&self, f: |&T| -> U) -> OwnedSlice<U> {
         self.iter().map(f).collect()
     }
+
+    pub fn len(&self) -> uint { self.len }
+
+    pub fn is_empty(&self) -> bool { self.len == 0 }
 }
 
 impl<T> Default for OwnedSlice<T> {
@@ -140,10 +144,6 @@ impl<T: PartialEq> PartialEq for OwnedSlice<T> {
 
 impl<T: Eq> Eq for OwnedSlice<T> {}
 
-impl<T> Collection for OwnedSlice<T> {
-    fn len(&self) -> uint { self.len }
-}
-
 impl<T> FromIterator<T> for OwnedSlice<T> {
     fn from_iter<I: Iterator<T>>(mut iter: I) -> OwnedSlice<T> {
         OwnedSlice::from_vec(iter.collect())
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index 422c2d5c75bd7..56ee6c7b9158c 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -25,16 +25,6 @@ enum SmallVectorRepr<T> {
     Many(Vec<T>),
 }
 
-impl<T> Collection for SmallVector<T> {
-    fn len(&self) -> uint {
-        match self.repr {
-            Zero => 0,
-            One(..) => 1,
-            Many(ref vals) => vals.len()
-        }
-    }
-}
-
 impl<T> FromIterator<T> for SmallVector<T> {
     fn from_iter<I: Iterator<T>>(iter: I) -> SmallVector<T> {
         let mut v = SmallVector::zero();
@@ -131,6 +121,16 @@ impl<T> SmallVector<T> {
         };
         MoveItems { repr: repr }
     }
+
+    pub fn len(&self) -> uint {
+        match self.repr {
+            Zero => 0,
+            One(..) => 1,
+            Many(ref vals) => vals.len()
+        }
+    }
+
+    pub fn is_empty(&self) -> bool { self.len() == 0 }
 }
 
 pub struct MoveItems<T> {
diff --git a/src/libunicode/u_str.rs b/src/libunicode/u_str.rs
index e4148440252af..4bad631798fb2 100644
--- a/src/libunicode/u_str.rs
+++ b/src/libunicode/u_str.rs
@@ -19,7 +19,7 @@
 
 use core::clone::Clone;
 use core::cmp;
-use core::collections::Collection;
+use core::slice::ImmutableSlice;
 use core::iter::{Filter, AdditiveIterator, Iterator, DoubleEndedIterator};
 use core::kinds::Sized;
 use core::option::{Option, None, Some};
diff --git a/src/test/bench/core-map.rs b/src/test/bench/core-map.rs
index f68ace395aaa5..3933a33446d63 100644
--- a/src/test/bench/core-map.rs
+++ b/src/test/bench/core-map.rs
@@ -22,7 +22,29 @@ fn timed(label: &str, f: ||) {
     println!("  {}: {}", label, end - start);
 }
 
-fn ascending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
+trait MutableMap {
+    fn insert(&mut self, k: uint, v: uint);
+    fn remove(&mut self, k: &uint) -> bool;
+    fn find(&self, k: &uint) -> Option<&uint>;
+}
+
+impl MutableMap for TreeMap<uint, uint> {
+    fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); }
+    fn remove(&mut self, k: &uint) -> bool { self.remove(k) }
+    fn find(&self, k: &uint) -> Option<&uint> { self.find(k) }
+}
+impl MutableMap for HashMap<uint, uint> {
+    fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); }
+    fn remove(&mut self, k: &uint) -> bool { self.remove(k) }
+    fn find(&self, k: &uint) -> Option<&uint> { self.find(k) }
+}
+impl MutableMap for TrieMap<uint> {
+    fn insert(&mut self, k: uint, v: uint) { self.insert(k, v); }
+    fn remove(&mut self, k: &uint) -> bool { self.remove(k) }
+    fn find(&self, k: &uint) -> Option<&uint> { self.find(k) }
+}
+
+fn ascending<M: MutableMap>(map: &mut M, n_keys: uint) {
     println!(" Ascending integers:");
 
     timed("insert", || {
@@ -44,7 +66,7 @@ fn ascending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
     });
 }
 
-fn descending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
+fn descending<M: MutableMap>(map: &mut M, n_keys: uint) {
     println!(" Descending integers:");
 
     timed("insert", || {
@@ -66,7 +88,7 @@ fn descending<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint) {
     });
 }
 
-fn vector<M: MutableMap<uint, uint>>(map: &mut M, n_keys: uint, dist: &[uint]) {
+fn vector<M: MutableMap>(map: &mut M, n_keys: uint, dist: &[uint]) {
     timed("insert", || {
         for i in range(0u, n_keys) {
             map.insert(dist[i], i + 1);
diff --git a/src/test/bench/core-set.rs b/src/test/bench/core-set.rs
index 7f85bc1d700af..4833467922b76 100644
--- a/src/test/bench/core-set.rs
+++ b/src/test/bench/core-set.rs
@@ -16,6 +16,7 @@ extern crate time;
 
 use std::collections::bitv::BitvSet;
 use std::collections::TreeSet;
+use std::hash::Hash;
 use std::collections::HashSet;
 use std::os;
 use std::uint;
@@ -37,6 +38,28 @@ fn timed(result: &mut f64, op: ||) {
     *result = (end - start);
 }
 
+trait MutableSet<T> {
+    fn insert(&mut self, k: T);
+    fn remove(&mut self, k: &T) -> bool;
+    fn contains(&self, k: &T) -> bool;
+}
+
+impl<T: Hash + Eq> MutableSet<T> for HashSet<T> {
+    fn insert(&mut self, k: T) { self.insert(k); }
+    fn remove(&mut self, k: &T) -> bool { self.remove(k) }
+    fn contains(&self, k: &T) -> bool { self.contains(k) }
+}
+impl<T: Ord> MutableSet<T> for TreeSet<T> {
+    fn insert(&mut self, k: T) { self.insert(k); }
+    fn remove(&mut self, k: &T) -> bool { self.remove(k) }
+    fn contains(&self, k: &T) -> bool { self.contains(k) }
+}
+impl MutableSet<uint> for BitvSet {
+    fn insert(&mut self, k: uint) { self.insert(k); }
+    fn remove(&mut self, k: &uint) -> bool { self.remove(k) }
+    fn contains(&self, k: &uint) -> bool { self.contains(k) }
+}
+
 impl Results {
     pub fn bench_int<T:MutableSet<uint>,
                      R: rand::Rng>(
diff --git a/src/test/compile-fail/issue-16562.rs b/src/test/compile-fail/issue-16562.rs
index 2207e10add451..3c784c3b770e4 100644
--- a/src/test/compile-fail/issue-16562.rs
+++ b/src/test/compile-fail/issue-16562.rs
@@ -15,6 +15,8 @@ struct Col<D, C> {
     col: C,
 }
 
+trait Collection { fn len(&self) -> uint; }
+
 impl<T, M: MatrixShape> Collection for Col<M, uint> {
 //~^ ERROR unable to infer enough type information
     fn len(&self) -> uint {
diff --git a/src/test/compile-fail/issue-16747.rs b/src/test/compile-fail/issue-16747.rs
index 012dc01ca97a8..134f58951bab2 100644
--- a/src/test/compile-fail/issue-16747.rs
+++ b/src/test/compile-fail/issue-16747.rs
@@ -12,6 +12,8 @@ trait ListItem<'a> {
     fn list_name() -> &'a str;
 }
 
+trait Collection { fn len(&self) -> uint; }
+
 struct List<'a, T: ListItem<'a>> {
 //~^ ERROR the parameter type `T` may not live long enough; consider adding an explicit lifetime bo
 //~^^ NOTE ...so that the reference type `&'a [T]` does not outlive the data it points at
diff --git a/src/test/compile-fail/map-types.rs b/src/test/compile-fail/map-types.rs
index 6f032c5b1f089..80818e06f8b23 100644
--- a/src/test/compile-fail/map-types.rs
+++ b/src/test/compile-fail/map-types.rs
@@ -12,11 +12,15 @@ extern crate collections;
 
 use std::collections::HashMap;
 
+trait Map<K, V> {}
+
+impl<K, V> Map<K, V> for HashMap<K, V> {}
+
 // Test that trait types printed in error msgs include the type arguments.
 
 fn main() {
     let x: Box<HashMap<int, int>> = box HashMap::new();
     let x: Box<Map<int, int>> = x;
     let y: Box<Map<uint, int>> = box x;
-    //~^ ERROR the trait `collections::Map<uint, int>` is not implemented
+    //~^ ERROR the trait `Map<uint,int>` is not implemented
 }
diff --git a/src/test/run-pass/class-impl-very-parameterized-trait.rs b/src/test/run-pass/class-impl-very-parameterized-trait.rs
index aab06c0339be2..b5892c3f12305 100644
--- a/src/test/run-pass/class-impl-very-parameterized-trait.rs
+++ b/src/test/run-pass/class-impl-very-parameterized-trait.rs
@@ -46,18 +46,9 @@ impl<T> cat<T> {
             return false;
         }
     }
-}
-
-impl<T> Collection for cat<T> {
     fn len(&self) -> uint { self.meows as uint }
     fn is_empty(&self) -> bool { self.meows == 0 }
-}
-
-impl<T> Mutable for cat<T> {
     fn clear(&mut self) {}
-}
-
-impl<T> Map<int, T> for cat<T> {
     fn contains_key(&self, k: &int) -> bool { *k <= self.meows }
 
     fn find(&self, k: &int) -> Option<&T> {
@@ -67,9 +58,6 @@ impl<T> Map<int, T> for cat<T> {
             None
         }
     }
-}
-
-impl<T> MutableMap<int, T> for cat<T> {
     fn insert(&mut self, k: int, _: T) -> bool {
         self.meows += k;
         true
diff --git a/src/test/run-pass/issue-2383.rs b/src/test/run-pass/issue-2383.rs
index 9a00868cc1259..39995db5a2f54 100644
--- a/src/test/run-pass/issue-2383.rs
+++ b/src/test/run-pass/issue-2383.rs
@@ -11,7 +11,6 @@
 
 extern crate collections;
 use std::collections::RingBuf;
-use std::collections::Deque;
 
 pub fn main() {
     let mut q = RingBuf::new();
diff --git a/src/test/run-pass/send_str_hashmap.rs b/src/test/run-pass/send_str_hashmap.rs
index 8b041ed3a3e76..e586799d122d7 100644
--- a/src/test/run-pass/send_str_hashmap.rs
+++ b/src/test/run-pass/send_str_hashmap.rs
@@ -10,7 +10,6 @@
 
 extern crate collections;
 
-use std::collections::{Map, MutableMap};
 use std::str::{SendStr, Owned, Slice};
 use std::collections::HashMap;
 use std::option::Some;
diff --git a/src/test/run-pass/send_str_treemap.rs b/src/test/run-pass/send_str_treemap.rs
index c6b872efa030c..f73ab8f52d7ed 100644
--- a/src/test/run-pass/send_str_treemap.rs
+++ b/src/test/run-pass/send_str_treemap.rs
@@ -10,7 +10,6 @@
 
 extern crate collections;
 
-use std::collections::{ Map, MutableMap};
 use std::str::{SendStr, Owned, Slice};
 use std::to_string::ToString;
 use self::collections::TreeMap;