diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 46b6a5722ea..1e592397014 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -71,7 +71,8 @@
 
 use boxed::Box;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::atomic;
 use core::atomic::Ordering::{Relaxed, Release, Acquire, SeqCst};
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 9420a88bade..ab1a5ba9019 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -53,7 +53,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use heap;
 use raw_vec::RawVec;
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 0e9b01e5c23..6d251cae41d 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -75,7 +75,6 @@
 #![feature(coerce_unsized)]
 #![feature(core)]
 #![feature(core_intrinsics)]
-#![feature(core_prelude)]
 #![feature(core_slice_ext)]
 #![feature(custom_attribute)]
 #![feature(fundamental)]
@@ -93,17 +92,17 @@
 #![feature(unsize)]
 #![feature(core_slice_ext)]
 #![feature(core_str_ext)]
+#![cfg_attr(stage0, feature(core, core_prelude))]
 
 #![cfg_attr(test, feature(test, alloc, rustc_private, box_raw))]
 #![cfg_attr(all(not(feature = "external_funcs"), not(feature = "external_crate")),
             feature(libc))]
 
-#[macro_use]
-extern crate core;
-
 #[cfg(all(not(feature = "external_funcs"), not(feature = "external_crate")))]
 extern crate libc;
 
+#[cfg(stage0)] #[macro_use] extern crate core;
+
 // Allow testing this library
 
 #[cfg(test)] #[macro_use] extern crate std;
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index e4e3b3b209c..05fd36e8e7f 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -150,7 +150,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 #[cfg(not(test))]
 use boxed::Box;
diff --git a/src/libcollections/binary_heap.rs b/src/libcollections/binary_heap.rs
index ddf61918947..65a252aea49 100644
--- a/src/libcollections/binary_heap.rs
+++ b/src/libcollections/binary_heap.rs
@@ -151,7 +151,8 @@
 #![allow(missing_docs)]
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::iter::{FromIterator};
 use core::mem::swap;
diff --git a/src/libcollections/bit.rs b/src/libcollections/bit.rs
index 30f23e073f6..af33181c5d0 100644
--- a/src/libcollections/bit.rs
+++ b/src/libcollections/bit.rs
@@ -86,7 +86,8 @@
 //! println!("There are {} primes below {}", num_primes, max_prime);
 //! ```
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp::Ordering;
 use core::cmp;
diff --git a/src/libcollections/btree/map.rs b/src/libcollections/btree/map.rs
index a5a0d864572..9fa54c6ca2f 100644
--- a/src/libcollections/btree/map.rs
+++ b/src/libcollections/btree/map.rs
@@ -17,7 +17,8 @@
 
 use self::Entry::*;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp::Ordering;
 use core::fmt::Debug;
@@ -530,7 +531,8 @@ enum Continuation<A, B> {
 /// to nodes. By using this module much better safety guarantees can be made, and more search
 /// boilerplate gets cut out.
 mod stack {
-    use core::prelude::*;
+    #[cfg(stage0)]
+    use core::prelude::v1::*;
     use core::marker;
     use core::mem;
     use core::ops::{Deref, DerefMut};
diff --git a/src/libcollections/btree/node.rs b/src/libcollections/btree/node.rs
index 4d76a986700..b9cd73470b6 100644
--- a/src/libcollections/btree/node.rs
+++ b/src/libcollections/btree/node.rs
@@ -16,7 +16,8 @@ pub use self::SearchResult::*;
 pub use self::ForceResult::*;
 pub use self::TraversalItem::*;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp::Ordering::{Greater, Less, Equal};
 use core::intrinsics::arith_offset;
diff --git a/src/libcollections/btree/set.rs b/src/libcollections/btree/set.rs
index 596312e509e..b9430b2d003 100644
--- a/src/libcollections/btree/set.rs
+++ b/src/libcollections/btree/set.rs
@@ -11,7 +11,8 @@
 // This is pretty much entirely stolen from TreeSet, since BTreeMap has an identical interface
 // to TreeMap
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp::Ordering::{self, Less, Greater, Equal};
 use core::fmt::Debug;
diff --git a/src/libcollections/enum_set.rs b/src/libcollections/enum_set.rs
index e90e6c065a2..e74726baf11 100644
--- a/src/libcollections/enum_set.rs
+++ b/src/libcollections/enum_set.rs
@@ -17,7 +17,9 @@
             reason = "matches collection reform specification, \
                       waiting for dust to settle")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use core::marker;
 use core::fmt;
 use core::iter::{FromIterator};
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index ee7d2c4d23b..5fb28d67974 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -33,9 +33,7 @@
 #![feature(alloc)]
 #![feature(box_patterns)]
 #![feature(box_syntax)]
-#![feature(core)]
 #![feature(core_intrinsics)]
-#![feature(core_prelude)]
 #![feature(core_slice_ext)]
 #![feature(core_str_ext)]
 #![feature(heap_api)]
@@ -62,12 +60,12 @@
 #![feature(utf8_error)]
 #![cfg_attr(test, feature(rand, test))]
 #![cfg_attr(not(test), feature(str_words))]
+#![cfg_attr(stage0, feature(core, core_prelude))]
 
 #![feature(no_std)]
 #![no_std]
 
-#[macro_use]
-extern crate core;
+#[cfg(stage0)] #[macro_use] extern crate core;
 
 extern crate rustc_unicode;
 extern crate alloc;
diff --git a/src/libcollections/linked_list.rs b/src/libcollections/linked_list.rs
index 32d6b3b95a4..697cfea197c 100644
--- a/src/libcollections/linked_list.rs
+++ b/src/libcollections/linked_list.rs
@@ -21,7 +21,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use alloc::boxed::Box;
 use core::cmp::Ordering;
diff --git a/src/libcollections/string.rs b/src/libcollections/string.rs
index 0b441b42cdc..b323ab03ec6 100644
--- a/src/libcollections/string.rs
+++ b/src/libcollections/string.rs
@@ -12,7 +12,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::fmt;
 use core::hash;
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index 96ad00597f8..9a29f6f9b82 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -58,7 +58,9 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use alloc::raw_vec::RawVec;
 use alloc::boxed::Box;
 use alloc::heap::EMPTY;
diff --git a/src/libcollections/vec_deque.rs b/src/libcollections/vec_deque.rs
index c6d0d946ab0..b55436c7057 100644
--- a/src/libcollections/vec_deque.rs
+++ b/src/libcollections/vec_deque.rs
@@ -18,7 +18,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp::Ordering;
 use core::fmt;
diff --git a/src/libcollections/vec_map.rs b/src/libcollections/vec_map.rs
index a2d378a0faf..8be80a67ce7 100644
--- a/src/libcollections/vec_map.rs
+++ b/src/libcollections/vec_map.rs
@@ -20,7 +20,8 @@
 
 use self::Entry::*;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp::{max, Ordering};
 use core::fmt;
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index 22f0215f0ad..39a067c1608 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use prelude::*;
+use prelude::v1::*;
 use fmt::{self, Write, FlagV1};
 
 struct PadAdapter<'a, 'b: 'a> {
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 02b23c6c7e7..668e2ecf1c6 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -12,7 +12,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::*;
+use prelude::v1::*;
 
 use cell::{Cell, RefCell, Ref, RefMut, BorrowState};
 use marker::PhantomData;
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index 7cacc6af575..bffbb789f22 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -12,7 +12,7 @@
 
 // FIXME: #6220 Implement floating point formatting
 
-use prelude::*;
+use prelude::v1::*;
 
 use fmt;
 use num::Zero;
diff --git a/src/libcore/hash/mod.rs b/src/libcore/hash/mod.rs
index e35f380d06f..34bc3b835a1 100644
--- a/src/libcore/hash/mod.rs
+++ b/src/libcore/hash/mod.rs
@@ -62,7 +62,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::*;
+use prelude::v1::*;
 
 use mem;
 
@@ -183,7 +183,7 @@ pub fn hash<T: Hash, H: Hasher + Default>(value: &T) -> u64 {
 //////////////////////////////////////////////////////////////////////////////
 
 mod impls {
-    use prelude::*;
+    use prelude::v1::*;
 
     use slice;
     use super::*;
diff --git a/src/libcore/hash/sip.rs b/src/libcore/hash/sip.rs
index 93bdadff549..4dcd513a0d2 100644
--- a/src/libcore/hash/sip.rs
+++ b/src/libcore/hash/sip.rs
@@ -10,8 +10,9 @@
 
 //! An implementation of SipHash 2-4.
 
+use prelude::v1::*;
+
 use ptr;
-use prelude::*;
 use super::Hasher;
 
 /// An implementation of SipHash 2-4.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 238644c4a26..56fb4c71a6a 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -60,8 +60,10 @@
        html_playground_url = "http://play.rust-lang.org/")]
 #![doc(test(no_crate_inject))]
 
-#![feature(no_std)]
-#![no_std]
+#![cfg_attr(stage0, feature(no_std))]
+#![cfg_attr(stage0, no_std)]
+#![cfg_attr(not(stage0), feature(no_core))]
+#![cfg_attr(not(stage0), no_core)]
 #![allow(raw_pointer_derive)]
 #![deny(missing_docs)]
 
@@ -168,6 +170,7 @@ mod tuple;
 // compiling the core library when it's compiling this library, so it expands
 // all references to `::core::$foo`
 #[doc(hidden)]
+#[cfg(stage0)]
 mod core {
     pub use intrinsics;     // derive(PartialOrd)
     pub use fmt;            // format_args!
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 6b4424093b4..d0e6d4fa49c 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -15,7 +15,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::*;
+use prelude::v1::*;
 
 use intrinsics;
 use mem;
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index fa7aa2ab5ce..bf7da04f995 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -15,7 +15,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use prelude::*;
+use prelude::v1::*;
 
 use intrinsics;
 use mem;
diff --git a/src/libcore/num/flt2dec/bignum.rs b/src/libcore/num/flt2dec/bignum.rs
index 4f373c16f7c..1e39c53f9e0 100644
--- a/src/libcore/num/flt2dec/bignum.rs
+++ b/src/libcore/num/flt2dec/bignum.rs
@@ -21,7 +21,8 @@
 
 #![macro_use]
 
-use prelude::*;
+use prelude::v1::*;
+
 use mem;
 use intrinsics;
 
@@ -351,7 +352,7 @@ define_bignum!(Big32x36: type=Digit32, n=36);
 // this one is used for testing only.
 #[doc(hidden)]
 pub mod tests {
-    use prelude::*;
+    use prelude::v1::*;
     define_bignum!(Big8x3: type=u8, n=3);
 }
 
diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs
index f98bc11a315..a292ffa2e9d 100644
--- a/src/libcore/num/flt2dec/decoder.rs
+++ b/src/libcore/num/flt2dec/decoder.rs
@@ -10,7 +10,7 @@
 
 //! Decodes a floating-point value into individual parts and error ranges.
 
-use prelude::*;
+use prelude::v1::*;
 
 use {f32, f64};
 use num::{Float, FpCategory};
diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs
index f3a7e8f09a9..40fa2a5563d 100644
--- a/src/libcore/num/flt2dec/mod.rs
+++ b/src/libcore/num/flt2dec/mod.rs
@@ -129,7 +129,7 @@ functions.
 #![unstable(feature = "flt2dec",
             reason = "internal routines only exposed for testing")]
 
-use prelude::*;
+use prelude::v1::*;
 use i16;
 use num::Float;
 use slice::bytes;
diff --git a/src/libcore/num/flt2dec/strategy/dragon.rs b/src/libcore/num/flt2dec/strategy/dragon.rs
index a1137789371..b03286ddd0d 100644
--- a/src/libcore/num/flt2dec/strategy/dragon.rs
+++ b/src/libcore/num/flt2dec/strategy/dragon.rs
@@ -15,7 +15,8 @@ Almost direct (but slightly optimized) Rust translation of Figure 3 of [1].
     quickly and accurately. SIGPLAN Not. 31, 5 (May. 1996), 108-116.
 */
 
-use prelude::*;
+use prelude::v1::*;
+
 use num::Float;
 use cmp::Ordering;
 
diff --git a/src/libcore/num/flt2dec/strategy/grisu.rs b/src/libcore/num/flt2dec/strategy/grisu.rs
index 54d3c92eca4..390920a354c 100644
--- a/src/libcore/num/flt2dec/strategy/grisu.rs
+++ b/src/libcore/num/flt2dec/strategy/grisu.rs
@@ -16,7 +16,8 @@ Rust adaptation of Grisu3 algorithm described in [1]. It uses about
     accurately with integers. SIGPLAN Not. 45, 6 (June 2010), 233-243.
 */
 
-use prelude::*;
+use prelude::v1::*;
+
 use num::Float;
 
 use num::flt2dec::{Decoded, MAX_SIG_DIGITS, round_up};
diff --git a/src/libcore/prelude/mod.rs b/src/libcore/prelude/mod.rs
new file mode 100644
index 00000000000..b6c93615378
--- /dev/null
+++ b/src/libcore/prelude/mod.rs
@@ -0,0 +1,13 @@
+// Copyright 2015 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.
+
+//! The libcore prelude
+
+pub mod v1;
diff --git a/src/libcore/prelude.rs b/src/libcore/prelude/v1.rs
similarity index 75%
rename from src/libcore/prelude.rs
rename to src/libcore/prelude/v1.rs
index ac153d64ab2..50dc9b7e043 100644
--- a/src/libcore/prelude.rs
+++ b/src/libcore/prelude/v1.rs
@@ -11,18 +11,8 @@
 //! The core prelude
 //!
 //! This module is intended for users of libcore which do not link to libstd as
-//! well. This module is not imported by default, but using the entire contents
-//! of this module will provide all of the useful traits and types in libcore
-//! that one would expect from the standard library as well.
-//!
-//! There is no method to automatically inject this prelude, and this prelude is
-//! a subset of the standard library's prelude.
-//!
-//! # Example
-//!
-//! ```ignore
-//! use core::prelude::*;
-//! ```
+//! well. This module is imported by default when `#![no_std]` is used in the
+//! same manner as the standard library's prelude.
 
 #![unstable(feature = "core_prelude",
             reason = "the libcore prelude has not been scrutinized and \
diff --git a/src/libcore/str/pattern.rs b/src/libcore/str/pattern.rs
index 2b3fc39fc8b..10ef689ba5d 100644
--- a/src/libcore/str/pattern.rs
+++ b/src/libcore/str/pattern.rs
@@ -16,7 +16,8 @@
 #![unstable(feature = "pattern",
             reason = "API not fully fleshed out and ready to be stabilized")]
 
-use prelude::*;
+use prelude::v1::*;
+
 use cmp;
 use usize;
 
diff --git a/src/liblibc/lib.rs b/src/liblibc/lib.rs
index 8bd57a8cb1f..d895a3e62a3 100644
--- a/src/liblibc/lib.rs
+++ b/src/liblibc/lib.rs
@@ -14,7 +14,8 @@
 #![crate_type = "rlib"]
 #![cfg_attr(not(feature = "cargo-build"), unstable(feature = "libc",
                                                    reason = "use `libc` from crates.io"))]
-#![cfg_attr(not(feature = "cargo-build"), feature(staged_api, core, no_std))]
+#![cfg_attr(not(feature = "cargo-build"), feature(staged_api, no_std))]
+#![cfg_attr(all(not(feature = "cargo-build"), stage0), feature(core))]
 #![cfg_attr(not(feature = "cargo-build"), staged_api)]
 #![cfg_attr(not(feature = "cargo-build"), no_std)]
 #![doc(html_logo_url = "http://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
@@ -78,7 +79,7 @@
 #![allow(bad_style, raw_pointer_derive)]
 #![cfg_attr(target_os = "nacl", allow(unused_imports))]
 #[cfg(feature = "cargo-build")] extern crate std as core;
-#[cfg(not(feature = "cargo-build"))] extern crate core;
+#[cfg(all(stage0, not(feature = "cargo-build")))] extern crate core;
 
 #[cfg(test)] extern crate std;
 #[cfg(test)] extern crate test;
diff --git a/src/librand/chacha.rs b/src/librand/chacha.rs
index da360978369..51000ed166b 100644
--- a/src/librand/chacha.rs
+++ b/src/librand/chacha.rs
@@ -10,7 +10,9 @@
 
 //! The ChaCha random number generator.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use {Rng, SeedableRng, Rand};
 
 const KEY_WORDS    : usize =  8; // 8 words for the 256-bit key
diff --git a/src/librand/distributions/mod.rs b/src/librand/distributions/mod.rs
index 4ea81b8e619..6f003b8b9ad 100644
--- a/src/librand/distributions/mod.rs
+++ b/src/librand/distributions/mod.rs
@@ -17,7 +17,9 @@
 //! internally. The `IndependentSample` trait is for generating values
 //! that do not need to record state.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use core::num::Float;
 use core::marker::PhantomData;
 
diff --git a/src/librand/distributions/range.rs b/src/librand/distributions/range.rs
index dce114d1fc2..52a5219a380 100644
--- a/src/librand/distributions/range.rs
+++ b/src/librand/distributions/range.rs
@@ -12,7 +12,8 @@
 
 // this is surprisingly complicated to be both generic & correct
 
-use core::prelude::PartialOrd;
+#[cfg(stage0)]
+use core::prelude::v1::PartialOrd;
 
 use Rng;
 use distributions::{Sample, IndependentSample};
diff --git a/src/librand/isaac.rs b/src/librand/isaac.rs
index 1b2210c89ed..6827d9c6f13 100644
--- a/src/librand/isaac.rs
+++ b/src/librand/isaac.rs
@@ -12,7 +12,9 @@
 
 #![allow(non_camel_case_types)]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use core::slice;
 use core::iter::repeat;
 use core::num::Wrapping as w;
diff --git a/src/librand/lib.rs b/src/librand/lib.rs
index 2f76aa53f83..ace2c2fc21d 100644
--- a/src/librand/lib.rs
+++ b/src/librand/lib.rs
@@ -28,26 +28,26 @@
 #![staged_api]
 #![unstable(feature = "rand",
             reason = "use `rand` from crates.io")]
-#![feature(core)]
 #![feature(core_float)]
-#![feature(core_prelude)]
 #![feature(core_slice_ext)]
 #![feature(no_std)]
 #![feature(num_bits_bytes)]
 #![feature(staged_api)]
 #![feature(step_by)]
+#![cfg_attr(stage0, feature(core, core_prelude))]
 
 #![cfg_attr(test, feature(test, rand, rustc_private, iter_order))]
 
 #![allow(deprecated)]
 
-#[macro_use]
-extern crate core;
+#[cfg(stage0)] #[macro_use] extern crate core;
 
 #[cfg(test)] #[macro_use] extern crate std;
 #[cfg(test)] #[macro_use] extern crate log;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use core::marker::PhantomData;
 
 pub use isaac::{IsaacRng, Isaac64Rng};
diff --git a/src/librand/rand_impls.rs b/src/librand/rand_impls.rs
index 2f37451ecbb..3db98cfe2f4 100644
--- a/src/librand/rand_impls.rs
+++ b/src/librand/rand_impls.rs
@@ -10,7 +10,9 @@
 
 //! The implementations of `Rand` for the built-in types.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use core::char;
 use core::isize;
 use core::usize;
diff --git a/src/librand/reseeding.rs b/src/librand/reseeding.rs
index 73ff51da290..6fe7dd09854 100644
--- a/src/librand/reseeding.rs
+++ b/src/librand/reseeding.rs
@@ -11,7 +11,8 @@
 //! A wrapper around another RNG that reseeds it after it
 //! generates a certain number of random bytes.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use {Rng, SeedableRng};
 
diff --git a/src/librustc_bitflags/lib.rs b/src/librustc_bitflags/lib.rs
index c4573bd9060..59baa638bfe 100644
--- a/src/librustc_bitflags/lib.rs
+++ b/src/librustc_bitflags/lib.rs
@@ -290,13 +290,6 @@ macro_rules! bitflags {
     };
 }
 
-// This is a no_std crate. So the test code's invocation of #[derive] etc, via
-// bitflags!, will use names from the underlying crates.
-#[cfg(test)]
-mod core {
-    pub use std::{fmt, hash, clone, cmp, marker, option};
-}
-
 #[cfg(test)]
 #[allow(non_upper_case_globals)]
 mod tests {
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index a9efd13a998..7d50395aca3 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -46,7 +46,7 @@ struct RH<'a> {
     sub: &'a [RH<'a>]
 }
 
-const EMPTY_SOURCE_STR: &'static str = "#![feature(no_std)] #![no_std]";
+const EMPTY_SOURCE_STR: &'static str = "#![feature(no_core)] #![no_core]";
 
 struct ExpectErrorEmitter {
     messages: Vec<String>
diff --git a/src/librustc_unicode/lib.rs b/src/librustc_unicode/lib.rs
index b420444d1f5..3a69430d078 100644
--- a/src/librustc_unicode/lib.rs
+++ b/src/librustc_unicode/lib.rs
@@ -33,17 +33,16 @@
        test(no_crate_inject))]
 #![no_std]
 
-#![feature(core)]
 #![feature(core_char_ext)]
-#![feature(core_prelude)]
 #![feature(core_slice_ext)]
 #![feature(core_str_ext)]
 #![feature(iter_arith)]
 #![feature(lang_items)]
 #![feature(no_std)]
 #![feature(staged_api)]
+#![cfg_attr(stage0, feature(core, core_prelude))]
 
-extern crate core;
+#[cfg(stage0)] extern crate core;
 
 mod normalize;
 mod tables;
diff --git a/src/librustc_unicode/u_str.rs b/src/librustc_unicode/u_str.rs
index e329785d271..95214fe2db3 100644
--- a/src/librustc_unicode/u_str.rs
+++ b/src/librustc_unicode/u_str.rs
@@ -14,7 +14,8 @@
 //! unicode parts of the CharExt trait.
 
 use self::GraphemeState::*;
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::char;
 use core::cmp;
diff --git a/src/libstd/ffi/os_str.rs b/src/libstd/ffi/os_str.rs
index 97bf33335b0..47b8230e430 100644
--- a/src/libstd/ffi/os_str.rs
+++ b/src/libstd/ffi/os_str.rs
@@ -32,7 +32,8 @@
 #![unstable(feature = "os_str",
             reason = "recently added as part of path/io reform")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use borrow::{Borrow, Cow, ToOwned};
 use ffi::CString;
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index a879c2ebd73..62490bb9d08 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -17,7 +17,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use fmt;
 use ffi::OsString;
diff --git a/src/libstd/io/cursor.rs b/src/libstd/io/cursor.rs
index 980ec51c926..8033d77ff6a 100644
--- a/src/libstd/io/cursor.rs
+++ b/src/libstd/io/cursor.rs
@@ -292,7 +292,8 @@ impl Write for Cursor<Vec<u8>> {
 
 #[cfg(test)]
 mod tests {
-    use core::prelude::*;
+    #[cfg(stage0)]
+    use core::prelude::v1::*;
 
     use io::prelude::*;
     use io::{Cursor, SeekFrom};
diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs
index 67bc45d3b62..864870a5905 100644
--- a/src/libstd/io/impls.rs
+++ b/src/libstd/io/impls.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use boxed::Box;
 use cmp;
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 6e651464c74..38e4b0d03e7 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -10,6 +10,7 @@
 
 #![allow(missing_copy_implementations)]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use io::{self, Read, Write, ErrorKind, BufRead};
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 2e796004aab..7baa7558e52 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -213,7 +213,6 @@
 #![feature(core)]
 #![feature(core_float)]
 #![feature(core_intrinsics)]
-#![feature(core_prelude)]
 #![feature(core_simd)]
 #![feature(drain)]
 #![feature(fnbox)]
@@ -250,6 +249,7 @@
 #![cfg_attr(test, feature(float_from_str_radix, range_inclusive, float_extras, hash_default))]
 #![cfg_attr(test, feature(test, rustc_private, float_consts))]
 #![cfg_attr(target_env = "msvc", feature(link_args))]
+#![cfg_attr(stage0, feature(core, core_prelude))]
 
 // Don't link to std. We are std.
 #![no_std]
@@ -257,13 +257,17 @@
 #![allow(trivial_casts)]
 #![deny(missing_docs)]
 
+#[cfg(stage0)] #[macro_use] extern crate core;
+
 #[cfg(test)] extern crate test;
 #[cfg(test)] #[macro_use] extern crate log;
 
-#[macro_use]
+// We want to reexport a few macros from core but libcore has already been
+// imported by the compiler (via our #[no_std] attribute) In this case we just
+// add a new crate name so we can attach the reexports to it.
 #[macro_reexport(assert, assert_eq, debug_assert, debug_assert_eq,
     unreachable, unimplemented, write, writeln)]
-extern crate core;
+extern crate core as __core;
 
 #[macro_use]
 #[macro_reexport(vec, format)]
@@ -410,11 +414,3 @@ pub mod __rand {
 // the rustdoc documentation for primitive types. Using `include!`
 // because rustdoc only looks for these modules at the crate level.
 include!("primitive_docs.rs");
-
-// The expansion of --test has a few references to `::std::$foo` so this module
-// is necessary to get things to compile.
-#[cfg(test)]
-mod std {
-    pub use option;
-    pub use realstd::env;
-}
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index 8212b8888d3..290aa6e2fda 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -11,6 +11,7 @@
 #![unstable(feature = "udp", reason = "remaining functions have not been \
                                        scrutinized enough to be stabilized")]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use fmt;
diff --git a/src/libstd/num/f32.rs b/src/libstd/num/f32.rs
index 73d6639cf00..64da75e94db 100644
--- a/src/libstd/num/f32.rs
+++ b/src/libstd/num/f32.rs
@@ -15,6 +15,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use core::num;
diff --git a/src/libstd/num/f64.rs b/src/libstd/num/f64.rs
index 3911d276b0f..fcba821522e 100644
--- a/src/libstd/num/f64.rs
+++ b/src/libstd/num/f64.rs
@@ -15,6 +15,7 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 #![allow(missing_docs)]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use core::num;
diff --git a/src/libstd/num/mod.rs b/src/libstd/num/mod.rs
index 9a52a0214e9..db7fd463e07 100644
--- a/src/libstd/num/mod.rs
+++ b/src/libstd/num/mod.rs
@@ -43,7 +43,8 @@ pub fn test_num<T>(ten: T, two: T) where
 
 #[cfg(test)]
 mod tests {
-    use core::prelude::*;
+    #[cfg(stage0)]
+    use core::prelude::v1::*;
     use super::*;
     use i8;
     use i16;
diff --git a/src/libstd/path.rs b/src/libstd/path.rs
index f5f8508e9aa..4a4db61c3b9 100644
--- a/src/libstd/path.rs
+++ b/src/libstd/path.rs
@@ -98,7 +98,8 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use ascii::*;
 use borrow::{Borrow, IntoCow, ToOwned, Cow};
@@ -134,7 +135,8 @@ use self::platform::{is_sep_byte, is_verbatim_sep, MAIN_SEP_STR, parse_prefix};
 #[cfg(unix)]
 mod platform {
     use super::Prefix;
-    use core::prelude::*;
+    #[cfg(stage0)]
+    use core::prelude::v1::*;
     use ffi::OsStr;
 
     #[inline]
@@ -157,7 +159,8 @@ mod platform {
 
 #[cfg(windows)]
 mod platform {
-    use core::prelude::*;
+    #[cfg(stage0)]
+    use core::prelude::v1::*;
     use ascii::*;
 
     use super::{os_str_as_u8_slice, u8_slice_as_os_str, Prefix};
@@ -1747,7 +1750,8 @@ impl AsRef<Path> for PathBuf {
 #[cfg(test)]
 mod tests {
     use super::*;
-    use core::prelude::*;
+    #[cfg(stage0)]
+    use core::prelude::v1::*;
     use string::{ToString, String};
     use vec::Vec;
 
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 74a66558627..be921d9aef0 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -815,7 +815,7 @@ mod tests {
     #[cfg(target_os="android")]
     #[test]
     fn test_inherit_env() {
-        use std::env;
+        use env;
 
         let mut result = env_cmd().output().unwrap();
         let output = String::from_utf8(result.stdout).unwrap();
diff --git a/src/libstd/rand/mod.rs b/src/libstd/rand/mod.rs
index b806afc5951..df9cd98084b 100644
--- a/src/libstd/rand/mod.rs
+++ b/src/libstd/rand/mod.rs
@@ -57,6 +57,7 @@
 
 #![unstable(feature = "rand")]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use cell::RefCell;
diff --git a/src/libstd/rand/os.rs b/src/libstd/rand/os.rs
index 3f75c8bca83..9ae9455848e 100644
--- a/src/libstd/rand/os.rs
+++ b/src/libstd/rand/os.rs
@@ -15,7 +15,7 @@ pub use self::imp::OsRng;
 
 #[cfg(all(unix, not(target_os = "ios")))]
 mod imp {
-    use prelude::v1::*;
+    #[cfg(stage0)] use prelude::v1::*;
     use self::OsRngInner::*;
 
     use fs::File;
@@ -251,6 +251,7 @@ mod imp {
 
 #[cfg(windows)]
 mod imp {
+    #[cfg(stage0)]
     use prelude::v1::*;
 
     use io;
diff --git a/src/libstd/rand/reader.rs b/src/libstd/rand/reader.rs
index d19bc5b617f..665f423c3f1 100644
--- a/src/libstd/rand/reader.rs
+++ b/src/libstd/rand/reader.rs
@@ -12,7 +12,7 @@
 
 #![allow(dead_code)]
 
-use prelude::v1::*;
+#[cfg(stage0)] use prelude::v1::*;
 use io::prelude::*;
 use rand::Rng;
 
diff --git a/src/libstd/rt/args.rs b/src/libstd/rt/args.rs
index 52697f00264..e77a2bbd0b9 100644
--- a/src/libstd/rt/args.rs
+++ b/src/libstd/rt/args.rs
@@ -19,7 +19,8 @@
 //!
 //! FIXME #7756: Would be nice for this to not exist.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 use vec::Vec;
 
 /// One-time global initialization.
@@ -140,7 +141,8 @@ mod imp {
           target_os = "ios",
           target_os = "windows"))]
 mod imp {
-    use core::prelude::*;
+    #[cfg(stage0)]
+    use core::prelude::v1::*;
     use vec::Vec;
 
     pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
diff --git a/src/libstd/rt/backtrace.rs b/src/libstd/rt/backtrace.rs
index 2eadf36a6b4..18d93cba8bc 100644
--- a/src/libstd/rt/backtrace.rs
+++ b/src/libstd/rt/backtrace.rs
@@ -12,6 +12,7 @@
 
 #![allow(non_camel_case_types)]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use env;
diff --git a/src/libstd/sync/future.rs b/src/libstd/sync/future.rs
index b87a2756829..d0314da19d3 100644
--- a/src/libstd/sync/future.rs
+++ b/src/libstd/sync/future.rs
@@ -39,7 +39,8 @@
                         outside in crates.io first")]
 #![allow(deprecated)]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 use core::mem::replace;
 
 use boxed::Box;
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index d80d858e7a9..954edefcc45 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -265,6 +265,7 @@
 // And now that you've seen all the races that I found and attempted to fix,
 // here's the code for you to find some more!
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use sync::Arc;
diff --git a/src/libstd/sync/mpsc/mpsc_queue.rs b/src/libstd/sync/mpsc/mpsc_queue.rs
index d6d173e5e7e..f45032d327f 100644
--- a/src/libstd/sync/mpsc/mpsc_queue.rs
+++ b/src/libstd/sync/mpsc/mpsc_queue.rs
@@ -40,7 +40,8 @@
 
 pub use self::PopResult::*;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use alloc::boxed::Box;
 use core::ptr;
diff --git a/src/libstd/sync/mpsc/oneshot.rs b/src/libstd/sync/mpsc/oneshot.rs
index 7e9c017617d..b84cb3b5472 100644
--- a/src/libstd/sync/mpsc/oneshot.rs
+++ b/src/libstd/sync/mpsc/oneshot.rs
@@ -37,7 +37,8 @@ pub use self::UpgradeResult::*;
 pub use self::SelectionResult::*;
 use self::MyUpgrade::*;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use sync::mpsc::Receiver;
 use sync::mpsc::blocking::{self, SignalToken};
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
index ee1516342ad..1d31ac165f6 100644
--- a/src/libstd/sync/mpsc/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -57,7 +57,8 @@
                       but no guarantees beyond this are being made")]
 
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cell::{Cell, UnsafeCell};
 use core::marker;
diff --git a/src/libstd/sync/mpsc/shared.rs b/src/libstd/sync/mpsc/shared.rs
index 41c79dd52c8..8c019395d30 100644
--- a/src/libstd/sync/mpsc/shared.rs
+++ b/src/libstd/sync/mpsc/shared.rs
@@ -20,7 +20,8 @@
 
 pub use self::Failure::*;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp;
 use core::isize;
diff --git a/src/libstd/sync/mpsc/spsc_queue.rs b/src/libstd/sync/mpsc/spsc_queue.rs
index 3cf75de5a46..5c0db521007 100644
--- a/src/libstd/sync/mpsc/spsc_queue.rs
+++ b/src/libstd/sync/mpsc/spsc_queue.rs
@@ -33,7 +33,8 @@
 //! concurrently between two threads. This data structure is safe to use and
 //! enforces the semantics that there is one pusher and one popper.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use alloc::boxed::Box;
 use core::ptr;
diff --git a/src/libstd/sync/mpsc/stream.rs b/src/libstd/sync/mpsc/stream.rs
index 404814b4cd4..a9514da4698 100644
--- a/src/libstd/sync/mpsc/stream.rs
+++ b/src/libstd/sync/mpsc/stream.rs
@@ -22,7 +22,8 @@ pub use self::UpgradeResult::*;
 pub use self::SelectionResult::*;
 use self::Message::*;
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::cmp;
 use core::isize;
diff --git a/src/libstd/sync/mpsc/sync.rs b/src/libstd/sync/mpsc/sync.rs
index 904eab1fd7e..7c9298fff2a 100644
--- a/src/libstd/sync/mpsc/sync.rs
+++ b/src/libstd/sync/mpsc/sync.rs
@@ -33,7 +33,8 @@
 /// of a synchronous channel. There are a few branches for the unbuffered case,
 /// but they're mostly just relevant to blocking senders.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 pub use self::Failure::*;
 use self::Blocker::*;
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 0bda6a975a2..53191e14bec 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -13,6 +13,7 @@
 //! This primitive is meant to be used to run one-time initialization. An
 //! example use case would be for initializing an FFI library.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use isize;
diff --git a/src/libstd/sys/common/backtrace.rs b/src/libstd/sys/common/backtrace.rs
index 00932712a07..17953d0af4e 100644
--- a/src/libstd/sys/common/backtrace.rs
+++ b/src/libstd/sys/common/backtrace.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 use io::prelude::*;
 
diff --git a/src/libstd/sys/common/mod.rs b/src/libstd/sys/common/mod.rs
index 69c54f98917..b205b6df4cb 100644
--- a/src/libstd/sys/common/mod.rs
+++ b/src/libstd/sys/common/mod.rs
@@ -10,6 +10,7 @@
 
 #![allow(missing_docs)]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 pub mod backtrace;
diff --git a/src/libstd/sys/common/poison.rs b/src/libstd/sys/common/poison.rs
index 065b1d6c9ac..196fe37d456 100644
--- a/src/libstd/sys/common/poison.rs
+++ b/src/libstd/sys/common/poison.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use cell::Cell;
diff --git a/src/libstd/sys/common/thread_info.rs b/src/libstd/sys/common/thread_info.rs
index bb47c946e49..fb4e0ec70e0 100644
--- a/src/libstd/sys/common/thread_info.rs
+++ b/src/libstd/sys/common/thread_info.rs
@@ -10,7 +10,8 @@
 
 #![allow(dead_code)] // stack_guard isn't used right now on all platforms
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use cell::RefCell;
 use string::String;
diff --git a/src/libstd/sys/common/thread_local.rs b/src/libstd/sys/common/thread_local.rs
index 3b2cb00d8c4..2269a053874 100644
--- a/src/libstd/sys/common/thread_local.rs
+++ b/src/libstd/sys/common/thread_local.rs
@@ -58,6 +58,7 @@
 #![unstable(feature = "thread_local_internals")]
 #![allow(dead_code)] // sys isn't exported yet
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use sync::atomic::{self, AtomicUsize, Ordering};
diff --git a/src/libstd/sys/common/wtf8.rs b/src/libstd/sys/common/wtf8.rs
index 3d5d1f5e0eb..0a5f4563dea 100644
--- a/src/libstd/sys/common/wtf8.rs
+++ b/src/libstd/sys/common/wtf8.rs
@@ -25,7 +25,8 @@
 // unix (it's mostly used on windows), so don't worry about dead code here.
 #![allow(dead_code)]
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use core::char::{encode_utf8_raw, encode_utf16_raw};
 use core::str::next_code_point;
diff --git a/src/libstd/sys/unix/backtrace.rs b/src/libstd/sys/unix/backtrace.rs
index ed6421f3670..ae8bfb07aaf 100644
--- a/src/libstd/sys/unix/backtrace.rs
+++ b/src/libstd/sys/unix/backtrace.rs
@@ -83,6 +83,7 @@
 /// to symbols. This is a bit of a hokey implementation as-is, but it works for
 /// all unix platforms we support right now, so it at least gets the job done.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 use io::prelude::*;
 
diff --git a/src/libstd/sys/unix/condvar.rs b/src/libstd/sys/unix/condvar.rs
index beecb445e8d..9dd8df7524d 100644
--- a/src/libstd/sys/unix/condvar.rs
+++ b/src/libstd/sys/unix/condvar.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use cell::UnsafeCell;
diff --git a/src/libstd/sys/unix/ext/fs.rs b/src/libstd/sys/unix/ext/fs.rs
index 4ee790b0161..dca7f6e829f 100644
--- a/src/libstd/sys/unix/ext/fs.rs
+++ b/src/libstd/sys/unix/ext/fs.rs
@@ -12,6 +12,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use fs::{self, Permissions, OpenOptions};
diff --git a/src/libstd/sys/unix/ext/process.rs b/src/libstd/sys/unix/ext/process.rs
index 06c5261bb42..e984c577935 100644
--- a/src/libstd/sys/unix/ext/process.rs
+++ b/src/libstd/sys/unix/ext/process.rs
@@ -14,6 +14,7 @@
 
 use os::unix::raw::{uid_t, gid_t};
 use os::unix::io::{FromRawFd, RawFd, AsRawFd, IntoRawFd};
+#[cfg(stage0)]
 use prelude::v1::*;
 use process;
 use sys;
diff --git a/src/libstd/sys/unix/fd.rs b/src/libstd/sys/unix/fd.rs
index 026380027d2..bdbe120f79d 100644
--- a/src/libstd/sys/unix/fd.rs
+++ b/src/libstd/sys/unix/fd.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use io;
 use libc::{self, c_int, size_t, c_void};
diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs
index 0c99a30f107..ddab24b133f 100644
--- a/src/libstd/sys/unix/fs.rs
+++ b/src/libstd/sys/unix/fs.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 use io::prelude::*;
 use os::unix::prelude::*;
 
diff --git a/src/libstd/sys/unix/mod.rs b/src/libstd/sys/unix/mod.rs
index 6fd20b940bb..85dc8752443 100644
--- a/src/libstd/sys/unix/mod.rs
+++ b/src/libstd/sys/unix/mod.rs
@@ -11,6 +11,7 @@
 #![allow(missing_docs)]
 #![allow(non_camel_case_types)]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use io::{self, ErrorKind};
diff --git a/src/libstd/sys/unix/mutex.rs b/src/libstd/sys/unix/mutex.rs
index 6eed403dfc0..a6132b37a66 100644
--- a/src/libstd/sys/unix/mutex.rs
+++ b/src/libstd/sys/unix/mutex.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use cell::UnsafeCell;
diff --git a/src/libstd/sys/unix/os_str.rs b/src/libstd/sys/unix/os_str.rs
index 69d876a48a4..e21d88676e7 100644
--- a/src/libstd/sys/unix/os_str.rs
+++ b/src/libstd/sys/unix/os_str.rs
@@ -11,7 +11,8 @@
 /// The underlying OsString/OsStr implementation on Unix systems: just
 /// a `Vec<u8>`/`[u8]`.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use borrow::Cow;
 use fmt::{self, Debug};
diff --git a/src/libstd/sys/unix/pipe.rs b/src/libstd/sys/unix/pipe.rs
index 140f0c042ba..2abd74bea1b 100644
--- a/src/libstd/sys/unix/pipe.rs
+++ b/src/libstd/sys/unix/pipe.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use sys::fd::FileDesc;
diff --git a/src/libstd/sys/unix/rwlock.rs b/src/libstd/sys/unix/rwlock.rs
index ee687f350f0..50b4907e6ca 100644
--- a/src/libstd/sys/unix/rwlock.rs
+++ b/src/libstd/sys/unix/rwlock.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use libc;
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 62689c39255..ed4e50735a6 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -8,8 +8,10 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
+use core::prelude::v1::*;
+
 use libc;
-use core::prelude::*;
 use self::imp::{make_handler, drop_handler};
 
 pub use self::imp::{init, cleanup};
diff --git a/src/libstd/sys/unix/stdio.rs b/src/libstd/sys/unix/stdio.rs
index fce52f8f92b..8542c660c26 100644
--- a/src/libstd/sys/unix/stdio.rs
+++ b/src/libstd/sys/unix/stdio.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use io;
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 6be61f06926..67ecd4d9229 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -166,6 +166,7 @@ impl Drop for Thread {
           not(target_os = "netbsd"),
           not(target_os = "openbsd")))]
 pub mod guard {
+    #[cfg(stage0)]
     use prelude::v1::*;
 
     pub unsafe fn current() -> Option<usize> { None }
diff --git a/src/libstd/sys/unix/thread_local.rs b/src/libstd/sys/unix/thread_local.rs
index 7238adfcc56..5626446b31c 100644
--- a/src/libstd/sys/unix/thread_local.rs
+++ b/src/libstd/sys/unix/thread_local.rs
@@ -10,6 +10,7 @@
 
 #![allow(dead_code)] // sys isn't exported yet
 
+#[cfg(stage0)]
 use prelude::v1::*;
 use libc::c_int;
 
diff --git a/src/libstd/sys/windows/backtrace.rs b/src/libstd/sys/windows/backtrace.rs
index 3f595762fc7..d84513c5f95 100644
--- a/src/libstd/sys/windows/backtrace.rs
+++ b/src/libstd/sys/windows/backtrace.rs
@@ -24,6 +24,7 @@
 
 #![allow(dead_code)]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 use io::prelude::*;
 
diff --git a/src/libstd/sys/windows/condvar.rs b/src/libstd/sys/windows/condvar.rs
index 04d62200e9b..f3edcfd420c 100644
--- a/src/libstd/sys/windows/condvar.rs
+++ b/src/libstd/sys/windows/condvar.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use cell::UnsafeCell;
diff --git a/src/libstd/sys/windows/ext/fs.rs b/src/libstd/sys/windows/ext/fs.rs
index f629e983ce5..e15d1f0ec15 100644
--- a/src/libstd/sys/windows/ext/fs.rs
+++ b/src/libstd/sys/windows/ext/fs.rs
@@ -12,6 +12,7 @@
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use fs::{OpenOptions, Metadata};
diff --git a/src/libstd/sys/windows/fs.rs b/src/libstd/sys/windows/fs.rs
index 4ce6d53cf12..8d81d6576ff 100644
--- a/src/libstd/sys/windows/fs.rs
+++ b/src/libstd/sys/windows/fs.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 use io::prelude::*;
 use os::windows::prelude::*;
 
diff --git a/src/libstd/sys/windows/handle.rs b/src/libstd/sys/windows/handle.rs
index a566c5eff32..91fe131c251 100644
--- a/src/libstd/sys/windows/handle.rs
+++ b/src/libstd/sys/windows/handle.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use io::ErrorKind;
diff --git a/src/libstd/sys/windows/net.rs b/src/libstd/sys/windows/net.rs
index d58355ed1fe..f2aca8d1a6e 100644
--- a/src/libstd/sys/windows/net.rs
+++ b/src/libstd/sys/windows/net.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use io;
diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs
index a7ece66e0f1..4044c429d49 100644
--- a/src/libstd/sys/windows/pipe.rs
+++ b/src/libstd/sys/windows/pipe.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use io;
diff --git a/src/libstd/sys/windows/rwlock.rs b/src/libstd/sys/windows/rwlock.rs
index 25865286db0..010ffe76fba 100644
--- a/src/libstd/sys/windows/rwlock.rs
+++ b/src/libstd/sys/windows/rwlock.rs
@@ -8,6 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use cell::UnsafeCell;
diff --git a/src/libstd/sys/windows/stack_overflow.rs b/src/libstd/sys/windows/stack_overflow.rs
index 491b53c4ed9..bc8ee6619f1 100644
--- a/src/libstd/sys/windows/stack_overflow.rs
+++ b/src/libstd/sys/windows/stack_overflow.rs
@@ -8,7 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::prelude::*;
+#[cfg(stage0)]
+use core::prelude::v1::*;
 
 use libc::types::os::arch::extra::{LPVOID, DWORD, LONG};
 use libc;
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index 42805c2ac52..15df5d756be 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -86,6 +86,7 @@ impl Thread {
 }
 
 pub mod guard {
+    #[cfg(stage0)]
     use prelude::v1::*;
 
     pub unsafe fn current() -> Option<usize> { None }
diff --git a/src/libstd/thread/local.rs b/src/libstd/thread/local.rs
index 9a6d68acb9f..0615033736e 100644
--- a/src/libstd/thread/local.rs
+++ b/src/libstd/thread/local.rs
@@ -12,6 +12,7 @@
 
 #![unstable(feature = "thread_local_internals")]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use cell::UnsafeCell;
@@ -271,6 +272,7 @@ impl<T: 'static> LocalKey<T> {
           not(no_elf_tls)))]
 #[doc(hidden)]
 mod imp {
+    #[cfg(stage0)]
     use prelude::v1::*;
 
     use cell::{Cell, UnsafeCell};
@@ -327,6 +329,7 @@ mod imp {
     // Due to rust-lang/rust#18804, make sure this is not generic!
     #[cfg(target_os = "linux")]
     unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern fn(*mut u8)) {
+        use prelude::v1::*;
         use mem;
         use libc;
         use sys_common::thread_local as os;
diff --git a/src/libstd/thread/scoped_tls.rs b/src/libstd/thread/scoped_tls.rs
index cf2c5db8277..1ea33a01791 100644
--- a/src/libstd/thread/scoped_tls.rs
+++ b/src/libstd/thread/scoped_tls.rs
@@ -42,6 +42,7 @@
 
 #![unstable(feature = "thread_local_internals")]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 #[doc(hidden)]
@@ -249,6 +250,7 @@ mod imp {
           no_elf_tls))]
 #[doc(hidden)]
 mod imp {
+    #[cfg(stage0)]
     use prelude::v1::*;
 
     use cell::Cell;
@@ -278,6 +280,7 @@ mod imp {
 #[cfg(test)]
 mod tests {
     use cell::Cell;
+    #[cfg(stage0)]
     use prelude::v1::*;
 
     scoped_thread_local!(static FOO: u32);
diff --git a/src/libstd/time/duration.rs b/src/libstd/time/duration.rs
index 8001df29d1f..28eaed40da8 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libstd/time/duration.rs
@@ -12,6 +12,7 @@
 
 #![unstable(feature = "duration", reason = "recently added API per RFC 1040")]
 
+#[cfg(stage0)]
 use prelude::v1::*;
 
 use fmt;
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 409ae86db35..b2cff3ed53c 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -611,7 +611,7 @@ pub struct ExtCtxt<'a> {
     pub cfg: ast::CrateConfig,
     pub backtrace: ExpnId,
     pub ecfg: expand::ExpansionConfig<'a>,
-    pub use_std: bool,
+    pub crate_root: Option<&'static str>,
 
     pub mod_path: Vec<ast::Ident> ,
     pub exported_macros: Vec<ast::MacroDef>,
@@ -630,7 +630,7 @@ impl<'a> ExtCtxt<'a> {
             backtrace: NO_EXPANSION,
             mod_path: Vec::new(),
             ecfg: ecfg,
-            use_std: true,
+            crate_root: None,
             exported_macros: Vec::new(),
             syntax_env: env,
             recursion_count: 0,
@@ -805,8 +805,13 @@ impl<'a> ExtCtxt<'a> {
     pub fn ident_of(&self, st: &str) -> ast::Ident {
         str_to_ident(st)
     }
-    pub fn ident_of_std(&self, st: &str) -> ast::Ident {
-        self.ident_of(if self.use_std { "std" } else { st })
+    pub fn std_path(&self, components: &[&str]) -> Vec<ast::Ident> {
+        let mut v = Vec::new();
+        if let Some(s) = self.crate_root {
+            v.push(self.ident_of(s));
+        }
+        v.extend(components.iter().map(|s| self.ident_of(s)));
+        return v
     }
     pub fn name_of(&self, st: &str) -> ast::Name {
         token::intern(st)
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index b91c54ae972..2061165abd2 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -437,11 +437,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.ty_path(
             self.path_all(DUMMY_SP,
                           true,
-                          vec!(
-                              self.ident_of_std("core"),
-                              self.ident_of("option"),
-                              self.ident_of("Option")
-                          ),
+                          self.std_path(&["option", "Option"]),
                           Vec::new(),
                           vec!( ty ),
                           Vec::new()))
@@ -713,11 +709,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         self.expr(sp, ast::ExprVec(exprs))
     }
     fn expr_vec_ng(&self, sp: Span) -> P<ast::Expr> {
-        self.expr_call_global(sp,
-                              vec!(self.ident_of_std("collections"),
-                                   self.ident_of("vec"),
-                                   self.ident_of("Vec"),
-                                   self.ident_of("new")),
+        self.expr_call_global(sp, self.std_path(&["vec", "Vec", "new"]),
                               Vec::new())
     }
     fn expr_vec_slice(&self, sp: Span, exprs: Vec<P<ast::Expr>>) -> P<ast::Expr> {
@@ -733,20 +725,13 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
 
 
     fn expr_some(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let some = vec!(
-            self.ident_of_std("core"),
-            self.ident_of("option"),
-            self.ident_of("Option"),
-            self.ident_of("Some"));
+        let some = self.std_path(&["option", "Option", "Some"]);
         self.expr_call_global(sp, some, vec!(expr))
     }
 
     fn expr_none(&self, sp: Span) -> P<ast::Expr> {
-        let none = self.path_global(sp, vec!(
-            self.ident_of_std("core"),
-            self.ident_of("option"),
-            self.ident_of("Option"),
-            self.ident_of("None")));
+        let none = self.std_path(&["option", "Option", "None"]);
+        let none = self.path_global(sp, none);
         self.expr_path(none)
     }
 
@@ -769,10 +754,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         let expr_file_line_ptr = self.expr_addr_of(span, expr_file_line_tuple);
         self.expr_call_global(
             span,
-            vec!(
-                self.ident_of_std("core"),
-                self.ident_of("rt"),
-                self.ident_of("begin_unwind")),
+            self.std_path(&["rt", "begin_unwind"]),
             vec!(
                 self.expr_str(span, msg),
                 expr_file_line_ptr))
@@ -785,37 +767,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn expr_ok(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let ok = vec!(
-            self.ident_of_std("core"),
-            self.ident_of("result"),
-            self.ident_of("Result"),
-            self.ident_of("Ok"));
+        let ok = self.std_path(&["result", "Result", "Ok"]);
         self.expr_call_global(sp, ok, vec!(expr))
     }
 
     fn expr_err(&self, sp: Span, expr: P<ast::Expr>) -> P<ast::Expr> {
-        let err = vec!(
-            self.ident_of_std("core"),
-            self.ident_of("result"),
-            self.ident_of("Result"),
-            self.ident_of("Err"));
+        let err = self.std_path(&["result", "Result", "Err"]);
         self.expr_call_global(sp, err, vec!(expr))
     }
 
     fn expr_try(&self, sp: Span, head: P<ast::Expr>) -> P<ast::Expr> {
-        let ok = vec![
-            self.ident_of_std("core"),
-            self.ident_of("result"),
-            self.ident_of("Result"),
-            self.ident_of("Ok")
-        ];
+        let ok = self.std_path(&["result", "Result", "Ok"]);
         let ok_path = self.path_global(sp, ok);
-        let err = vec![
-            self.ident_of_std("core"),
-            self.ident_of("result"),
-            self.ident_of("Result"),
-            self.ident_of("Err")
-        ];
+        let err = self.std_path(&["result", "Result", "Err"]);
         let err_path = self.path_global(sp, err);
 
         let binding_variable = self.ident_of("__try_var");
@@ -876,41 +840,25 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
     }
 
     fn pat_some(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = vec!(
-            self.ident_of_std("core"),
-            self.ident_of("option"),
-            self.ident_of("Option"),
-            self.ident_of("Some"));
+        let some = self.std_path(&["option", "Option", "Some"]);
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!(pat))
     }
 
     fn pat_none(&self, span: Span) -> P<ast::Pat> {
-        let some = vec!(
-            self.ident_of_std("core"),
-            self.ident_of("option"),
-            self.ident_of("Option"),
-            self.ident_of("None"));
+        let some = self.std_path(&["option", "Option", "None"]);
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!())
     }
 
     fn pat_ok(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = vec!(
-            self.ident_of_std("core"),
-            self.ident_of("result"),
-            self.ident_of("Result"),
-            self.ident_of("Ok"));
+        let some = self.std_path(&["result", "Result", "Ok"]);
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!(pat))
     }
 
     fn pat_err(&self, span: Span, pat: P<ast::Pat>) -> P<ast::Pat> {
-        let some = vec!(
-            self.ident_of_std("core"),
-            self.ident_of("result"),
-            self.ident_of("Result"),
-            self.ident_of("Err"));
+        let some = self.std_path(&["result", "Result", "Err"]);
         let path = self.path_global(span, some);
         self.pat_enum(span, path, vec!(pat))
     }
diff --git a/src/libsyntax/ext/deriving/bounds.rs b/src/libsyntax/ext/deriving/bounds.rs
index 689a4e96aec..71b6184390a 100644
--- a/src/libsyntax/ext/deriving/bounds.rs
+++ b/src/libsyntax/ext/deriving/bounds.rs
@@ -29,11 +29,10 @@ pub fn expand_deriving_copy(cx: &mut ExtCtxt,
                             item: &Annotatable,
                             push: &mut FnMut(Annotatable))
 {
-    let path = Path::new(vec![
-        if cx.use_std { "std" } else { "core" },
-        "marker",
-        "Copy",
-    ]);
+    let mut v = cx.crate_root.map(|s| vec![s]).unwrap_or(Vec::new());
+    v.push("marker");
+    v.push("Copy");
+    let path = Path::new(v);
 
     let trait_def = TraitDef {
         span: span,
diff --git a/src/libsyntax/ext/deriving/clone.rs b/src/libsyntax/ext/deriving/clone.rs
index a9c05339894..9261c0162c7 100644
--- a/src/libsyntax/ext/deriving/clone.rs
+++ b/src/libsyntax/ext/deriving/clone.rs
@@ -57,12 +57,7 @@ fn cs_clone(
     substr: &Substructure) -> P<Expr> {
     let ctor_path;
     let all_fields;
-    let fn_path = vec![
-        cx.ident_of_std("core"),
-        cx.ident_of("clone"),
-        cx.ident_of("Clone"),
-        cx.ident_of("clone"),
-    ];
+    let fn_path = cx.std_path(&["clone", "Clone", "clone"]);
     let subcall = |field: &FieldInfo| {
         let args = vec![cx.expr_addr_of(field.span, field.self_.clone())];
 
diff --git a/src/libsyntax/ext/deriving/cmp/ord.rs b/src/libsyntax/ext/deriving/cmp/ord.rs
index d605e0286f5..815448ac610 100644
--- a/src/libsyntax/ext/deriving/cmp/ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/ord.rs
@@ -65,17 +65,9 @@ pub fn cs_cmp(cx: &mut ExtCtxt, span: Span,
               substr: &Substructure) -> P<Expr> {
     let test_id = cx.ident_of("__test");
     let equals_path = cx.path_global(span,
-                                     vec!(cx.ident_of_std("core"),
-                                          cx.ident_of("cmp"),
-                                          cx.ident_of("Ordering"),
-                                          cx.ident_of("Equal")));
+                                     cx.std_path(&["cmp", "Ordering", "Equal"]));
 
-    let cmp_path = vec![
-        cx.ident_of_std("core"),
-        cx.ident_of("cmp"),
-        cx.ident_of("Ord"),
-        cx.ident_of("cmp"),
-    ];
+    let cmp_path = cx.std_path(&["cmp", "Ord", "cmp"]);
 
     /*
     Builds:
diff --git a/src/libsyntax/ext/deriving/cmp/partial_ord.rs b/src/libsyntax/ext/deriving/cmp/partial_ord.rs
index 4eb95343a49..a11e9f473a4 100644
--- a/src/libsyntax/ext/deriving/cmp/partial_ord.rs
+++ b/src/libsyntax/ext/deriving/cmp/partial_ord.rs
@@ -108,19 +108,11 @@ pub fn cs_partial_cmp(cx: &mut ExtCtxt, span: Span,
               substr: &Substructure) -> P<Expr> {
     let test_id = cx.ident_of("__test");
     let ordering = cx.path_global(span,
-                                  vec!(cx.ident_of_std("core"),
-                                       cx.ident_of("cmp"),
-                                       cx.ident_of("Ordering"),
-                                       cx.ident_of("Equal")));
+                                  cx.std_path(&["cmp", "Ordering", "Equal"]));
     let ordering = cx.expr_path(ordering);
     let equals_expr = cx.expr_some(span, ordering);
 
-    let partial_cmp_path = vec![
-        cx.ident_of_std("core"),
-        cx.ident_of("cmp"),
-        cx.ident_of("PartialOrd"),
-        cx.ident_of("partial_cmp"),
-    ];
+    let partial_cmp_path = cx.std_path(&["cmp", "PartialOrd", "partial_cmp"]);
 
     /*
     Builds:
diff --git a/src/libsyntax/ext/deriving/decodable.rs b/src/libsyntax/ext/deriving/decodable.rs
index 085d9d60937..99fac991e7f 100644
--- a/src/libsyntax/ext/deriving/decodable.rs
+++ b/src/libsyntax/ext/deriving/decodable.rs
@@ -46,10 +46,11 @@ fn expand_deriving_decodable_imp(cx: &mut ExtCtxt,
                                  push: &mut FnMut(Annotatable),
                                  krate: &'static str)
 {
-    if !cx.use_std {
+    if cx.crate_root != Some("std") {
         // FIXME(#21880): lift this requirement.
-        cx.span_err(span, "this trait cannot be derived with #![no_std]");
-        return;
+        cx.span_err(span, "this trait cannot be derived with #![no_std] \
+                           or #![no_core]");
+        return
     }
 
     let trait_def = TraitDef {
diff --git a/src/libsyntax/ext/deriving/default.rs b/src/libsyntax/ext/deriving/default.rs
index ab22b710700..3f4e9da0ed5 100644
--- a/src/libsyntax/ext/deriving/default.rs
+++ b/src/libsyntax/ext/deriving/default.rs
@@ -51,12 +51,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt,
 }
 
 fn default_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure) -> P<Expr> {
-    let default_ident = vec!(
-        cx.ident_of_std("core"),
-        cx.ident_of("default"),
-        cx.ident_of("Default"),
-        cx.ident_of("default")
-    );
+    let default_ident = cx.std_path(&["default", "Default", "default"]);
     let default_call = |span| cx.expr_call_global(span, default_ident.clone(), Vec::new());
 
     return match *substr.fields {
diff --git a/src/libsyntax/ext/deriving/encodable.rs b/src/libsyntax/ext/deriving/encodable.rs
index ae4d337b9f6..3c77effe5f5 100644
--- a/src/libsyntax/ext/deriving/encodable.rs
+++ b/src/libsyntax/ext/deriving/encodable.rs
@@ -122,9 +122,10 @@ fn expand_deriving_encodable_imp(cx: &mut ExtCtxt,
                                  push: &mut FnMut(Annotatable),
                                  krate: &'static str)
 {
-    if !cx.use_std {
+    if cx.crate_root != Some("std") {
         // FIXME(#21880): lift this requirement.
-        cx.span_err(span, "this trait cannot be derived with #![no_std]");
+        cx.span_err(span, "this trait cannot be derived with #![no_std] \
+                           or #![no_core]");
         return;
     }
 
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index 8f9e0279b29..1f4860b7ec1 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -1252,9 +1252,7 @@ impl<'a> MethodDef<'a> {
 
             let mut first_ident = None;
             for (&ident, self_arg) in vi_idents.iter().zip(&self_args) {
-                let path = vec![cx.ident_of_std("core"),
-                                cx.ident_of("intrinsics"),
-                                cx.ident_of("discriminant_value")];
+                let path = cx.std_path(&["intrinsics", "discriminant_value"]);
                 let call = cx.expr_call_global(
                     sp, path, vec![cx.expr_addr_of(sp, self_arg.clone())]);
                 let variant_value = cx.expr_block(P(ast::Block {
@@ -1289,9 +1287,7 @@ impl<'a> MethodDef<'a> {
             //Since we know that all the arguments will match if we reach the match expression we
             //add the unreachable intrinsics as the result of the catch all which should help llvm
             //in optimizing it
-            let path = vec![cx.ident_of_std("core"),
-                            cx.ident_of("intrinsics"),
-                            cx.ident_of("unreachable")];
+            let path = cx.std_path(&["intrinsics", "unreachable"]);
             let call = cx.expr_call_global(
                 sp, path, vec![]);
             let unreachable = cx.expr_block(P(ast::Block {
diff --git a/src/libsyntax/ext/deriving/hash.rs b/src/libsyntax/ext/deriving/hash.rs
index cdb378a34d4..97c50ed1eea 100644
--- a/src/libsyntax/ext/deriving/hash.rs
+++ b/src/libsyntax/ext/deriving/hash.rs
@@ -63,12 +63,7 @@ fn hash_substructure(cx: &mut ExtCtxt, trait_span: Span, substr: &Substructure)
     };
     let call_hash = |span, thing_expr| {
         let hash_path = {
-            let strs = vec![
-                cx.ident_of_std("core"),
-                cx.ident_of("hash"),
-                cx.ident_of("Hash"),
-                cx.ident_of("hash"),
-            ];
+            let strs = cx.std_path(&["hash", "Hash", "hash"]);
 
             cx.expr_path(cx.path_global(span, strs))
         };
diff --git a/src/libsyntax/ext/deriving/mod.rs b/src/libsyntax/ext/deriving/mod.rs
index 344515b875f..36deaf488e1 100644
--- a/src/libsyntax/ext/deriving/mod.rs
+++ b/src/libsyntax/ext/deriving/mod.rs
@@ -40,13 +40,13 @@ macro_rules! path_local {
 }
 
 macro_rules! pathvec_std {
-    ($cx:expr, $first:ident :: $($rest:ident)::+) => (
-        if $cx.use_std {
-            pathvec!(std :: $($rest)::+)
-        } else {
-            pathvec!($first :: $($rest)::+)
+    ($cx:expr, $first:ident :: $($rest:ident)::+) => ({
+        let mut v = pathvec!($($rest)::+);
+        if let Some(s) = $cx.crate_root {
+            v.insert(0, s);
         }
-    )
+        v
+    })
 }
 
 macro_rules! path_std {
diff --git a/src/libsyntax/ext/env.rs b/src/libsyntax/ext/env.rs
index 2ca74644b3b..d85071e78af 100644
--- a/src/libsyntax/ext/env.rs
+++ b/src/libsyntax/ext/env.rs
@@ -34,10 +34,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
       Err(..) => {
           cx.expr_path(cx.path_all(sp,
                                    true,
-                                   vec!(cx.ident_of_std("core"),
-                                        cx.ident_of("option"),
-                                        cx.ident_of("Option"),
-                                        cx.ident_of("None")),
+                                   cx.std_path(&["option", "Option", "None"]),
                                    Vec::new(),
                                    vec!(cx.ty_rptr(sp,
                                                    cx.ty_ident(sp,
@@ -50,10 +47,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[ast::TokenT
       }
       Ok(s) => {
           cx.expr_call_global(sp,
-                              vec!(cx.ident_of_std("core"),
-                                   cx.ident_of("option"),
-                                   cx.ident_of("Option"),
-                                   cx.ident_of("Some")),
+                              cx.std_path(&["option", "Option", "Some"]),
                               vec!(cx.expr_str(sp,
                                                token::intern_and_get_ident(
                                           &s[..]))))
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 6e49b190f7c..66b3768a476 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -38,8 +38,7 @@ use std_inject;
 fn mk_core_path(fld: &mut MacroExpander,
                 span: Span,
                 suffix: &[&'static str]) -> ast::Path {
-    let mut idents = vec![fld.cx.ident_of_std("core")];
-    for s in suffix.iter() { idents.push(fld.cx.ident_of(*s)); }
+    let idents = fld.cx.std_path(suffix);
     fld.cx.path_global(span, idents)
 }
 
@@ -417,12 +416,7 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             // `match ::std::iter::Iterator::next(&mut iter) { ... }`
             let match_expr = {
                 let next_path = {
-                    let strs = vec![
-                        fld.cx.ident_of_std("core"),
-                        fld.cx.ident_of("iter"),
-                        fld.cx.ident_of("Iterator"),
-                        fld.cx.ident_of("next"),
-                    ];
+                    let strs = fld.cx.std_path(&["iter", "Iterator", "next"]);
 
                     fld.cx.path_global(span, strs)
                 };
@@ -450,12 +444,8 @@ pub fn expand_expr(e: P<ast::Expr>, fld: &mut MacroExpander) -> P<ast::Expr> {
             // `match ::std::iter::IntoIterator::into_iter(<head>) { ... }`
             let into_iter_expr = {
                 let into_iter_path = {
-                    let strs = vec![
-                        fld.cx.ident_of_std("core"),
-                        fld.cx.ident_of("iter"),
-                        fld.cx.ident_of("IntoIterator"),
-                        fld.cx.ident_of("into_iter"),
-                    ];
+                    let strs = fld.cx.std_path(&["iter", "IntoIterator",
+                                                 "into_iter"]);
 
                     fld.cx.path_global(span, strs)
                 };
@@ -1665,7 +1655,13 @@ pub fn expand_crate<'feat>(parse_sess: &parse::ParseSess,
                            user_exts: Vec<NamedSyntaxExtension>,
                            c: Crate) -> Crate {
     let mut cx = ExtCtxt::new(parse_sess, c.config.clone(), cfg);
-    cx.use_std = std_inject::use_std(&c);
+    if std_inject::no_core(&c) {
+        cx.crate_root = None;
+    } else if std_inject::no_std(&c) {
+        cx.crate_root = Some("core");
+    } else {
+        cx.crate_root = Some("std");
+    }
 
     let mut expander = MacroExpander::new(&mut cx);
 
diff --git a/src/libsyntax/ext/format.rs b/src/libsyntax/ext/format.rs
index 5a2b9c0eea4..cc2f94f05d4 100644
--- a/src/libsyntax/ext/format.rs
+++ b/src/libsyntax/ext/format.rs
@@ -305,8 +305,7 @@ impl<'a, 'b> Context<'a, 'b> {
     }
 
     fn rtpath(ecx: &ExtCtxt, s: &str) -> Vec<ast::Ident> {
-        vec![ecx.ident_of_std("core"), ecx.ident_of("fmt"), ecx.ident_of("rt"),
-             ecx.ident_of("v1"), ecx.ident_of(s)]
+        ecx.std_path(&["fmt", "rt", "v1", s])
     }
 
     fn trans_count(&self, c: parse::Count) -> P<ast::Expr> {
@@ -579,11 +578,8 @@ impl<'a, 'b> Context<'a, 'b> {
             ("new_v1_formatted", vec![pieces, args_slice, fmt])
         };
 
-        self.ecx.expr_call_global(self.macsp, vec!(
-                self.ecx.ident_of_std("core"),
-                self.ecx.ident_of("fmt"),
-                self.ecx.ident_of("Arguments"),
-                self.ecx.ident_of(fn_name)), fn_args)
+        let path = self.ecx.std_path(&["fmt", "Arguments", fn_name]);
+        self.ecx.expr_call_global(self.macsp, path, fn_args)
     }
 
     fn format_arg(ecx: &ExtCtxt, macsp: Span, sp: Span,
@@ -610,24 +606,15 @@ impl<'a, 'b> Context<'a, 'b> {
                 }
             }
             Unsigned => {
-                return ecx.expr_call_global(macsp, vec![
-                        ecx.ident_of_std("core"),
-                        ecx.ident_of("fmt"),
-                        ecx.ident_of("ArgumentV1"),
-                        ecx.ident_of("from_usize")], vec![arg])
+                let path = ecx.std_path(&["fmt", "ArgumentV1", "from_usize"]);
+                return ecx.expr_call_global(macsp, path, vec![arg])
             }
         };
 
-        let format_fn = ecx.path_global(sp, vec![
-                ecx.ident_of_std("core"),
-                ecx.ident_of("fmt"),
-                ecx.ident_of(trait_),
-                ecx.ident_of("fmt")]);
-        ecx.expr_call_global(macsp, vec![
-                ecx.ident_of_std("core"),
-                ecx.ident_of("fmt"),
-                ecx.ident_of("ArgumentV1"),
-                ecx.ident_of("new")], vec![arg, ecx.expr_path(format_fn)])
+        let path = ecx.std_path(&["fmt", trait_, "fmt"]);
+        let format_fn = ecx.path_global(sp, path);
+        let path = ecx.std_path(&["fmt", "ArgumentV1", "new"]);
+        ecx.expr_call_global(macsp, path, vec![arg, ecx.expr_path(format_fn)])
     }
 }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 945e457a77b..4a1b74d89d0 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -122,6 +122,9 @@ const KNOWN_FEATURES: &'static [(&'static str, &'static str, Status)] = &[
     // Allows using #![no_std]
     ("no_std", "1.0.0", Active),
 
+    // Allows using #![no_core]
+    ("no_core", "1.3.0", Active),
+
     // Allows using `box` in patterns; RFC 469
     ("box_patterns", "1.0.0", Active),
 
@@ -226,6 +229,8 @@ pub const KNOWN_ATTRIBUTES: &'static [(&'static str, AttributeType)] = &[
                       and possibly buggy")),
     ("no_std", Gated("no_std",
                      "no_std is experimental")),
+    ("no_core", Gated("no_core",
+                     "no_core is experimental")),
     ("lang", Gated("lang_items",
                      "language items are subject to change")),
     ("linkage", Gated("linkage",
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 6cfe85bc37e..f0973e0ba6e 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -113,7 +113,7 @@ pub fn print_crate<'a>(cm: &'a CodeMap,
                                       out,
                                       ann,
                                       is_expanded);
-    if is_expanded && std_inject::use_std(krate) {
+    if is_expanded && !std_inject::no_std(krate) {
         // We need to print `#![no_std]` (and its feature gate) so that
         // compiling pretty-printed source won't inject libstd again.
         // However we don't want these attributes in the AST because
diff --git a/src/libsyntax/std_inject.rs b/src/libsyntax/std_inject.rs
index 9787f2537c6..d41a8ff140c 100644
--- a/src/libsyntax/std_inject.rs
+++ b/src/libsyntax/std_inject.rs
@@ -41,52 +41,57 @@ fn ignored_span(sess: &ParseSess, sp: Span) -> Span {
 
 pub fn maybe_inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>)
                                -> ast::Crate {
-    if use_std(&krate) {
-        inject_crates_ref(krate, alt_std_name)
-    } else {
+    if no_core(&krate) {
         krate
+    } else {
+        let name = if no_std(&krate) {"core"} else {"std"};
+        let mut fold = CrateInjector {
+            item_name: token::str_to_ident(name),
+            crate_name: token::intern(&alt_std_name.unwrap_or(name.to_string())),
+        };
+        fold.fold_crate(krate)
     }
 }
 
 pub fn maybe_inject_prelude(sess: &ParseSess, krate: ast::Crate) -> ast::Crate {
-    if use_std(&krate) {
+    if no_core(&krate) {
+        krate
+    } else {
+        let name = if no_std(&krate) {"core"} else {"std"};
         let mut fold = PreludeInjector {
-            span: ignored_span(sess, DUMMY_SP)
+            span: ignored_span(sess, DUMMY_SP),
+            crate_identifier: token::str_to_ident(name),
         };
         fold.fold_crate(krate)
-    } else {
-        krate
     }
 }
 
-pub fn use_std(krate: &ast::Crate) -> bool {
-    !attr::contains_name(&krate.attrs, "no_std")
+pub fn no_core(krate: &ast::Crate) -> bool {
+    attr::contains_name(&krate.attrs, "no_core")
+}
+
+pub fn no_std(krate: &ast::Crate) -> bool {
+    attr::contains_name(&krate.attrs, "no_std") || no_core(krate)
 }
 
 fn no_prelude(attrs: &[ast::Attribute]) -> bool {
     attr::contains_name(attrs, "no_implicit_prelude")
 }
 
-struct StandardLibraryInjector {
-    alt_std_name: Option<String>,
+struct CrateInjector {
+    item_name: ast::Ident,
+    crate_name: ast::Name,
 }
 
-impl fold::Folder for StandardLibraryInjector {
+impl fold::Folder for CrateInjector {
     fn fold_crate(&mut self, mut krate: ast::Crate) -> ast::Crate {
-
-        // The name to use in `extern crate name as std;`
-        let actual_crate_name = match self.alt_std_name {
-            Some(ref s) => token::intern(&s),
-            None => token::intern("std"),
-        };
-
         krate.module.items.insert(0, P(ast::Item {
             id: ast::DUMMY_NODE_ID,
-            ident: token::str_to_ident("std"),
+            ident: self.item_name,
             attrs: vec!(
                 attr::mk_attr_outer(attr::mk_attr_id(), attr::mk_word_item(
                         InternedString::new("macro_use")))),
-            node: ast::ItemExternCrate(Some(actual_crate_name)),
+            node: ast::ItemExternCrate(Some(self.crate_name)),
             vis: ast::Inherited,
             span: DUMMY_SP
         }));
@@ -95,15 +100,9 @@ impl fold::Folder for StandardLibraryInjector {
     }
 }
 
-fn inject_crates_ref(krate: ast::Crate, alt_std_name: Option<String>) -> ast::Crate {
-    let mut fold = StandardLibraryInjector {
-        alt_std_name: alt_std_name
-    };
-    fold.fold_crate(krate)
-}
-
 struct PreludeInjector {
-    span: Span
+    span: Span,
+    crate_identifier: ast::Ident,
 }
 
 impl fold::Folder for PreludeInjector {
@@ -134,7 +133,7 @@ impl fold::Folder for PreludeInjector {
             global: false,
             segments: vec![
                 ast::PathSegment {
-                    identifier: token::str_to_ident("std"),
+                    identifier: self.crate_identifier,
                     parameters: ast::PathParameters::none(),
                 },
                 ast::PathSegment {
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index cbc7b38b1ed..ea99291d6c2 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -258,6 +258,7 @@ fn generate_test_harness(sess: &ParseSess,
         config: krate.config.clone(),
         toplevel_reexport: None,
     };
+    cx.ext_cx.crate_root = Some("std");
 
     cx.ext_cx.bt_push(ExpnInfo {
         call_site: DUMMY_SP,
@@ -449,18 +450,11 @@ fn mk_main(cx: &mut TestCtxt) -> P<ast::Item> {
     // test::test_main_static
     let test_main_path = ecx.path(sp, vec![token::str_to_ident("test"),
                                            token::str_to_ident("test_main_static")]);
-    // ::std::env::args
-    let os_args_path = ecx.path_global(sp, vec![token::str_to_ident("std"),
-                                                token::str_to_ident("env"),
-                                                token::str_to_ident("args")]);
-    // ::std::env::args()
-    let os_args_path_expr = ecx.expr_path(os_args_path);
-    let call_os_args = ecx.expr_call(sp, os_args_path_expr, vec![]);
     // test::test_main_static(...)
     let test_main_path_expr = ecx.expr_path(test_main_path);
     let tests_ident_expr = ecx.expr_ident(sp, token::str_to_ident("TESTS"));
     let call_test_main = ecx.expr_call(sp, test_main_path_expr,
-                                       vec![call_os_args, tests_ident_expr]);
+                                       vec![tests_ident_expr]);
     let call_test_main = ecx.stmt_expr(call_test_main);
     // #![main]
     let main_meta = ecx.meta_word(sp, token::intern_and_get_ident("main"));
@@ -633,12 +627,14 @@ fn mk_test_desc_and_fn_rec(cx: &TestCtxt, test: &Test) -> P<ast::Expr> {
     let fail_expr = match test.should_panic {
         ShouldPanic::No => ecx.expr_path(should_panic_path("No")),
         ShouldPanic::Yes(ref msg) => {
-            let path = should_panic_path("Yes");
-            let arg = match *msg {
-                Some(ref msg) => ecx.expr_some(span, ecx.expr_str(span, msg.clone())),
-                None => ecx.expr_none(span),
-            };
-            ecx.expr_call(span, ecx.expr_path(path), vec![arg])
+            match *msg {
+                Some(ref msg) => {
+                    let msg = ecx.expr_str(span, msg.clone());
+                    let path = should_panic_path("YesWithMessage");
+                    ecx.expr_call(span, ecx.expr_path(path), vec![msg])
+                }
+                None => ecx.expr_path(should_panic_path("Yes")),
+            }
         }
     };
 
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 194b6c8e3e2..7777ea51f82 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -197,7 +197,8 @@ pub struct Bencher {
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ShouldPanic {
     No,
-    Yes(Option<&'static str>)
+    Yes,
+    YesWithMessage(&'static str)
 }
 
 // The definition of a single test. A test runner will run a list of
@@ -262,8 +263,8 @@ pub fn test_main(args: &[String], tests: Vec<TestDescAndFn> ) {
 // a Vec<TestDescAndFn> is used in order to effect ownership-transfer
 // semantics into parallel test runners, which in turn requires a Vec<>
 // rather than a &[].
-pub fn test_main_static(args: env::Args, tests: &[TestDescAndFn]) {
-    let args = args.collect::<Vec<_>>();
+pub fn test_main_static(tests: &[TestDescAndFn]) {
+    let args = env::args().collect::<Vec<_>>();
     let owned_tests = tests.iter().map(|t| {
         match t.testfn {
             StaticTestFn(f) => TestDescAndFn { testfn: StaticTestFn(f), desc: t.desc.clone() },
@@ -1027,8 +1028,8 @@ pub fn run_test(opts: &TestOpts,
 fn calc_result(desc: &TestDesc, task_result: Result<(), Box<Any+Send>>) -> TestResult {
     match (&desc.should_panic, task_result) {
         (&ShouldPanic::No, Ok(())) |
-        (&ShouldPanic::Yes(None), Err(_)) => TrOk,
-        (&ShouldPanic::Yes(Some(msg)), Err(ref err))
+        (&ShouldPanic::Yes, Err(_)) => TrOk,
+        (&ShouldPanic::YesWithMessage(msg), Err(ref err))
             if err.downcast_ref::<String>()
                 .map(|e| &**e)
                 .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e))
@@ -1276,7 +1277,7 @@ mod tests {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_panic: ShouldPanic::Yes(None)
+                should_panic: ShouldPanic::Yes,
             },
             testfn: DynTestFn(Box::new(move|| f())),
         };
@@ -1293,7 +1294,7 @@ mod tests {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_panic: ShouldPanic::Yes(Some("error message"))
+                should_panic: ShouldPanic::YesWithMessage("error message"),
             },
             testfn: DynTestFn(Box::new(move|| f())),
         };
@@ -1310,7 +1311,7 @@ mod tests {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_panic: ShouldPanic::Yes(Some("foobar"))
+                should_panic: ShouldPanic::YesWithMessage("foobar"),
             },
             testfn: DynTestFn(Box::new(move|| f())),
         };
@@ -1327,7 +1328,7 @@ mod tests {
             desc: TestDesc {
                 name: StaticTestName("whatever"),
                 ignore: false,
-                should_panic: ShouldPanic::Yes(None)
+                should_panic: ShouldPanic::Yes,
             },
             testfn: DynTestFn(Box::new(move|| f())),
         };
diff --git a/src/test/auxiliary/weak-lang-items.rs b/src/test/auxiliary/weak-lang-items.rs
index ceffae79677..7342652fb96 100644
--- a/src/test/auxiliary/weak-lang-items.rs
+++ b/src/test/auxiliary/weak-lang-items.rs
@@ -13,13 +13,10 @@
 // This aux-file will require the eh_personality function to be codegen'd, but
 // it hasn't been defined just yet. Make sure we don't explode.
 
-#![feature(no_std, core)]
+#![feature(no_std)]
 #![no_std]
 #![crate_type = "rlib"]
 
-#[macro_use]
-extern crate core;
-
 struct A;
 
 impl core::ops::Drop for A {
diff --git a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
index 0e083e47236..4aad828590a 100644
--- a/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
+++ b/src/test/compile-fail/associated-types-ICE-when-projecting-out-of-err.rs
@@ -13,8 +13,8 @@
 
 #![crate_type = "lib"]
 #![feature(lang_items)]
-#![feature(no_std)]
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 
 #[lang="sized"]
 pub trait Sized {
diff --git a/src/test/compile-fail/double-import.rs b/src/test/compile-fail/double-import.rs
index cbf13c0a559..bf4dc894154 100644
--- a/src/test/compile-fail/double-import.rs
+++ b/src/test/compile-fail/double-import.rs
@@ -7,8 +7,8 @@
 // <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(no_std)]
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 
 // This tests that conflicting imports shows both `use` lines
 // when reporting the error.
diff --git a/src/test/compile-fail/issue-19660.rs b/src/test/compile-fail/issue-19660.rs
index 258c63b7428..c4b871a28c5 100644
--- a/src/test/compile-fail/issue-19660.rs
+++ b/src/test/compile-fail/issue-19660.rs
@@ -10,8 +10,8 @@
 
 // error-pattern: requires `copy` lang_item
 
-#![feature(lang_items, start, no_std)]
-#![no_std]
+#![feature(lang_items, start, no_core)]
+#![no_core]
 
 #[lang = "sized"]
 trait Sized { }
diff --git a/src/test/compile-fail/lang-item-missing.rs b/src/test/compile-fail/lang-item-missing.rs
index c7426fc6fc1..ce2fa2548c3 100644
--- a/src/test/compile-fail/lang-item-missing.rs
+++ b/src/test/compile-fail/lang-item-missing.rs
@@ -13,8 +13,8 @@
 
 // error-pattern: requires `sized` lang_item
 
-#![feature(start, no_std)]
-#![no_std]
+#![feature(start, no_core)]
+#![no_core]
 
 #[start]
 fn start(argc: isize, argv: *const *const u8) -> isize {
diff --git a/src/test/compile-fail/lint-dead-code-1.rs b/src/test/compile-fail/lint-dead-code-1.rs
index e91e6efd1cb..9749e596895 100644
--- a/src/test/compile-fail/lint-dead-code-1.rs
+++ b/src/test/compile-fail/lint-dead-code-1.rs
@@ -14,12 +14,9 @@
 #![allow(non_camel_case_types)]
 #![allow(non_upper_case_globals)]
 #![deny(dead_code)]
-#![feature(core)]
 
 #![crate_type="lib"]
 
-extern crate core;
-
 pub use foo2::Bar2;
 
 mod foo {
diff --git a/src/test/compile-fail/no-core-gated.rs b/src/test/compile-fail/no-core-gated.rs
new file mode 100644
index 00000000000..dbaa4177e14
--- /dev/null
+++ b/src/test/compile-fail/no-core-gated.rs
@@ -0,0 +1,13 @@
+// Copyright 2015 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.
+
+#![no_core] //~ ERROR no_core is experimental
+
+fn main() {}
diff --git a/src/test/compile-fail/no-std-inject.rs b/src/test/compile-fail/no-std-inject.rs
new file mode 100644
index 00000000000..a03972410c9
--- /dev/null
+++ b/src/test/compile-fail/no-std-inject.rs
@@ -0,0 +1,17 @@
+// Copyright 2015 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(no_std, core)]
+#![no_std]
+
+extern crate core; //~ ERROR: an external crate named `core` has already
+extern crate std;
+
+fn main() {}
diff --git a/src/test/compile-fail/no_owned_box_lang_item.rs b/src/test/compile-fail/no_owned_box_lang_item.rs
index b2536701375..ae7b00cc91f 100644
--- a/src/test/compile-fail/no_owned_box_lang_item.rs
+++ b/src/test/compile-fail/no_owned_box_lang_item.rs
@@ -15,8 +15,6 @@
 #![no_std]
 #![feature(lang_items, no_std, box_syntax)]
 
-extern crate core;
-
 fn main() {
     let x = box 1i32;
 }
diff --git a/src/test/compile-fail/privacy1.rs b/src/test/compile-fail/privacy1.rs
index f728fdfaf9a..7c8b91741ea 100644
--- a/src/test/compile-fail/privacy1.rs
+++ b/src/test/compile-fail/privacy1.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, start, no_std)]
-#![no_std] // makes debugging this test *a lot* easier (during resolve)
+#![feature(lang_items, start, no_core)]
+#![no_core] // makes debugging this test *a lot* easier (during resolve)
 
 #[lang="sized"]
 pub trait Sized {}
diff --git a/src/test/compile-fail/privacy2.rs b/src/test/compile-fail/privacy2.rs
index 7b4a2a3595b..fd8f8d20b7b 100644
--- a/src/test/compile-fail/privacy2.rs
+++ b/src/test/compile-fail/privacy2.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(start, no_std)]
-#![no_std] // makes debugging this test *a lot* easier (during resolve)
+#![feature(start, no_core)]
+#![no_core] // makes debugging this test *a lot* easier (during resolve)
 
 // Test to make sure that globs don't leak in regular `use` statements.
 
diff --git a/src/test/compile-fail/privacy3.rs b/src/test/compile-fail/privacy3.rs
index 8c9de1fa25c..da6266bc7ee 100644
--- a/src/test/compile-fail/privacy3.rs
+++ b/src/test/compile-fail/privacy3.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(start, no_std)]
-#![no_std] // makes debugging this test *a lot* easier (during resolve)
+#![feature(start, no_core)]
+#![no_core] // makes debugging this test *a lot* easier (during resolve)
 
 // Test to make sure that private items imported through globs remain private
 // when  they're used.
diff --git a/src/test/compile-fail/privacy4.rs b/src/test/compile-fail/privacy4.rs
index bcb46663aa8..8e9998dd597 100644
--- a/src/test/compile-fail/privacy4.rs
+++ b/src/test/compile-fail/privacy4.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, start, no_std)]
-#![no_std] // makes debugging this test *a lot* easier (during resolve)
+#![feature(lang_items, start, no_core)]
+#![no_core] // makes debugging this test *a lot* easier (during resolve)
 
 #[lang = "sized"] pub trait Sized {}
 #[lang="copy"] pub trait Copy {}
diff --git a/src/test/compile-fail/regions-struct-not-wf.rs b/src/test/compile-fail/regions-struct-not-wf.rs
index 3b8312a3019..c22812c3d86 100644
--- a/src/test/compile-fail/regions-struct-not-wf.rs
+++ b/src/test/compile-fail/regions-struct-not-wf.rs
@@ -10,8 +10,6 @@
 
 // Various examples of structs whose fields are not well-formed.
 
-#![feature(no_std)]
-#![no_std]
 #![allow(dead_code)]
 
 struct Ref<'a, T> { //~ ERROR the parameter type `T` may not live long enough
diff --git a/src/test/compile-fail/required-lang-item.rs b/src/test/compile-fail/required-lang-item.rs
index bb80c763a8b..1aa22a1676e 100644
--- a/src/test/compile-fail/required-lang-item.rs
+++ b/src/test/compile-fail/required-lang-item.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, no_std)]
-#![no_std]
+#![feature(lang_items, no_core)]
+#![no_core]
 
 #[lang="sized"] pub trait Sized { }
 
diff --git a/src/test/run-make/alloc-extern-crates/fakealloc.rs b/src/test/run-make/alloc-extern-crates/fakealloc.rs
index 6d30956ab2b..c64b3170ffe 100644
--- a/src/test/run-make/alloc-extern-crates/fakealloc.rs
+++ b/src/test/run-make/alloc-extern-crates/fakealloc.rs
@@ -9,9 +9,8 @@
 // except according to those terms.
 
 #![crate_type = "rlib"]
-#![feature(no_std, core)]
+#![feature(no_std)]
 #![no_std]
-extern crate core;
 
 
 #[inline]
diff --git a/src/test/run-make/mismatching-target-triples/bar.rs b/src/test/run-make/mismatching-target-triples/bar.rs
index 8695ab58e5f..0dc5c0a3a8e 100644
--- a/src/test/run-make/mismatching-target-triples/bar.rs
+++ b/src/test/run-make/mismatching-target-triples/bar.rs
@@ -7,6 +7,7 @@
 // <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(no_std)]
-#![no_std]
+
+#![feature(no_core)]
+#![no_core]
 extern crate foo;
diff --git a/src/test/run-make/mismatching-target-triples/foo.rs b/src/test/run-make/mismatching-target-triples/foo.rs
index afd4f298a97..a2169d0c631 100644
--- a/src/test/run-make/mismatching-target-triples/foo.rs
+++ b/src/test/run-make/mismatching-target-triples/foo.rs
@@ -7,6 +7,7 @@
 // <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(no_std)]
-#![no_std]
+
+#![feature(no_core)]
+#![no_core]
 #![crate_type = "lib"]
diff --git a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs
index 6aff4c9b3d5..c241241e18b 100644
--- a/src/test/run-make/pretty-expanded-hygiene/input.pp.rs
+++ b/src/test/run-make/pretty-expanded-hygiene/input.pp.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 // minimal junk
-#![feature(no_std)]
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 
 
 fn bar /* 62#0 */() { let x /* 59#2 */ = 1; y /* 61#4 */ + x /* 59#5 */ }
diff --git a/src/test/run-make/pretty-expanded-hygiene/input.rs b/src/test/run-make/pretty-expanded-hygiene/input.rs
index a46fa12ac05..56783b56099 100644
--- a/src/test/run-make/pretty-expanded-hygiene/input.rs
+++ b/src/test/run-make/pretty-expanded-hygiene/input.rs
@@ -9,8 +9,8 @@
 // except according to those terms.
 
 // minimal junk
-#![feature(no_std)]
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 
 macro_rules! foo {
     ($x: ident) => { y + $x }
diff --git a/src/test/run-make/simd-ffi/simd.rs b/src/test/run-make/simd-ffi/simd.rs
index 563fe79e537..5576e882371 100644
--- a/src/test/run-make/simd-ffi/simd.rs
+++ b/src/test/run-make/simd-ffi/simd.rs
@@ -12,8 +12,8 @@
 #![crate_type = "lib"]
 // we can compile to a variety of platforms, because we don't need
 // cross-compiled standard libraries.
-#![feature(no_std)]
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 
 #![feature(simd, simd_ffi, link_llvm_intrinsics, lang_items)]
 
@@ -75,8 +75,6 @@ pub trait Sized { }
 #[lang = "copy"]
 pub trait Copy { }
 
-mod core {
-    pub mod marker {
-        pub use Copy;
-    }
+pub mod marker {
+    pub use Copy;
 }
diff --git a/src/test/run-make/target-specs/foo.rs b/src/test/run-make/target-specs/foo.rs
index 9dbae193388..15b56977232 100644
--- a/src/test/run-make/target-specs/foo.rs
+++ b/src/test/run-make/target-specs/foo.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, no_std)]
-#![no_std]
+#![feature(lang_items, no_core)]
+#![no_core]
 
 #[lang="copy"]
 trait Copy { }
diff --git a/src/test/run-make/use-extern-for-plugins/bar.rs b/src/test/run-make/use-extern-for-plugins/bar.rs
index f279893b77b..3e99ed60c62 100644
--- a/src/test/run-make/use-extern-for-plugins/bar.rs
+++ b/src/test/run-make/use-extern-for-plugins/bar.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(no_std)]
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 #![crate_type = "lib"]
 #![crate_name = "a"]
 
diff --git a/src/test/run-make/use-extern-for-plugins/baz.rs b/src/test/run-make/use-extern-for-plugins/baz.rs
index 89d6c6bc58c..3f15d0e6e05 100644
--- a/src/test/run-make/use-extern-for-plugins/baz.rs
+++ b/src/test/run-make/use-extern-for-plugins/baz.rs
@@ -8,8 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(no_std)]
-#![no_std]
+#![feature(no_core)]
+#![no_core]
 #![crate_type = "lib"]
 
 #[macro_use]
diff --git a/src/test/run-pass/derive-no-std.rs b/src/test/run-pass/derive-no-std.rs
index 0234d7b0b63..e7c6b67b820 100644
--- a/src/test/run-pass/derive-no-std.rs
+++ b/src/test/run-pass/derive-no-std.rs
@@ -8,10 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(no_std, core, rand, collections, rustc_private)]
+#![feature(no_std, rand, collections, rustc_private)]
 #![no_std]
 
-extern crate core;
 extern crate rand;
 extern crate serialize as rustc_serialize;
 extern crate collections;
diff --git a/src/test/run-pass/for-loop-no-std.rs b/src/test/run-pass/for-loop-no-std.rs
index a1bd77a74f7..2f327bdebbf 100644
--- a/src/test/run-pass/for-loop-no-std.rs
+++ b/src/test/run-pass/for-loop-no-std.rs
@@ -8,18 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// pretty-expanded FIXME #23616
-
-#![feature(lang_items, start, no_std, core_slice_ext, core, collections)]
+#![feature(lang_items, start, no_std, core_slice_ext, collections)]
 #![no_std]
 
 extern crate std as other;
 
-#[macro_use] extern crate core;
 #[macro_use] extern crate collections;
 
-use core::slice::SliceExt;
-
 #[start]
 fn start(_argc: isize, _argv: *const *const u8) -> isize {
     for _ in [1,2,3].iter() { }
diff --git a/src/test/run-pass/format-no-std.rs b/src/test/run-pass/format-no-std.rs
index 1452cefbd5c..baa159b0e0e 100644
--- a/src/test/run-pass/format-no-std.rs
+++ b/src/test/run-pass/format-no-std.rs
@@ -8,12 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, start, no_std, core, collections)]
+#![feature(lang_items, start, no_std, collections)]
 #![no_std]
 
 extern crate std as other;
 
-#[macro_use] extern crate core;
 #[macro_use] extern crate collections;
 
 use collections::string::ToString;
diff --git a/src/test/run-pass/no-core-1.rs b/src/test/run-pass/no-core-1.rs
new file mode 100644
index 00000000000..7868077fbf2
--- /dev/null
+++ b/src/test/run-pass/no-core-1.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 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(no_core, core)]
+#![no_core]
+
+extern crate std;
+extern crate core;
+
+use std::option::Option::Some;
+
+fn main() {
+    let a = Some("foo");
+    a.unwrap();
+}
diff --git a/src/test/run-pass/no-std-1.rs b/src/test/run-pass/no-std-1.rs
new file mode 100644
index 00000000000..95bf3158e12
--- /dev/null
+++ b/src/test/run-pass/no-std-1.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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(no_std)]
+#![no_std]
+
+extern crate std;
+
+fn main() {
+    let a = Some("foo");
+    a.unwrap();
+}
diff --git a/src/test/run-pass/no-std-2.rs b/src/test/run-pass/no-std-2.rs
new file mode 100644
index 00000000000..043b016bdb9
--- /dev/null
+++ b/src/test/run-pass/no-std-2.rs
@@ -0,0 +1,19 @@
+// Copyright 2015 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(no_std)]
+#![no_std]
+
+extern crate std;
+
+fn main() {
+    let a = core::option::Option::Some("foo");
+    a.unwrap();
+}
diff --git a/src/test/run-pass/no-std-3.rs b/src/test/run-pass/no-std-3.rs
new file mode 100644
index 00000000000..318b29d99cc
--- /dev/null
+++ b/src/test/run-pass/no-std-3.rs
@@ -0,0 +1,26 @@
+// Copyright 2015 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(no_std)]
+#![no_std]
+
+extern crate std;
+
+mod foo {
+    pub fn test() -> Option<i32> {
+        Some(2)
+    }
+}
+
+fn main() {
+    let a = core::option::Option::Some("foo");
+    a.unwrap();
+    foo::test().unwrap();
+}
diff --git a/src/test/run-pass/smallest-hello-world.rs b/src/test/run-pass/smallest-hello-world.rs
index 67affb5ae09..134a962d3dc 100644
--- a/src/test/run-pass/smallest-hello-world.rs
+++ b/src/test/run-pass/smallest-hello-world.rs
@@ -12,8 +12,8 @@
 
 // pretty-expanded FIXME #23616
 
-#![feature(intrinsics, lang_items, start, no_std, libc)]
-#![no_std]
+#![feature(intrinsics, lang_items, start, no_core, libc)]
+#![no_core]
 
 extern crate libc;
 
diff --git a/src/test/run-pass/use.rs b/src/test/run-pass/use.rs
index 40ab4c86c6f..592d17922e1 100644
--- a/src/test/run-pass/use.rs
+++ b/src/test/run-pass/use.rs
@@ -11,8 +11,8 @@
 // pretty-expanded FIXME #23616
 
 #![allow(unused_imports)]
-#![feature(start, no_std)]
-#![no_std]
+#![feature(start, no_core, core)]
+#![no_core]
 
 extern crate std;
 extern crate std as zed;
diff --git a/src/test/run-pass/vec-macro-no-std.rs b/src/test/run-pass/vec-macro-no-std.rs
index cf3a8796d32..ddac0ecc13c 100644
--- a/src/test/run-pass/vec-macro-no-std.rs
+++ b/src/test/run-pass/vec-macro-no-std.rs
@@ -8,13 +8,11 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(lang_items, start, no_std, core, core_slice_ext, libc, collections)]
+#![feature(lang_items, start, no_std, core_slice_ext, libc, collections)]
 #![no_std]
 
 extern crate std as other;
 
-#[macro_use]
-extern crate core;
 extern crate libc;
 
 #[macro_use]
diff --git a/src/test/rustdoc/issue-23511.rs b/src/test/rustdoc/issue-23511.rs
index 6582ca0eba9..1e8d20f74f9 100644
--- a/src/test/rustdoc/issue-23511.rs
+++ b/src/test/rustdoc/issue-23511.rs
@@ -11,8 +11,6 @@
 #![feature(no_std, lang_items, core)]
 #![no_std]
 
-extern crate core;
-
 pub mod str {
     #![doc(primitive = "str")]