about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2018-05-17 16:44:38 +0000
committerbors <bors@rust-lang.org>2018-05-17 16:44:38 +0000
commit90463a6bdcd18c60e18a1cc810fc6453b96f7d54 (patch)
tree73a99c27209c97d623333dabb38158550c0cd6c0 /src
parentdbd10f81758381339f98994b8d31814cf5e98707 (diff)
parenta22af69c8f5b3838a8822b9e6dbe2199cfb8f297 (diff)
downloadrust-90463a6bdcd18c60e18a1cc810fc6453b96f7d54.tar.gz
rust-90463a6bdcd18c60e18a1cc810fc6453b96f7d54.zip
Auto merge of #50629 - Mark-Simulacrum:stage-step, r=alexcrichton
Switch to bootstrapping from 1.27

It's possible the Float trait could be removed from core, but I couldn't tell whether it was intended to be removed or not. @SimonSapin may be able to comment more here; we can presumably also do that in a follow up PR as this one is already quite large.
Diffstat (limited to 'src')
-rw-r--r--src/bootstrap/builder.rs9
-rw-r--r--src/bootstrap/channel.rs2
-rw-r--r--src/bootstrap/compile.rs2
-rw-r--r--src/bootstrap/tool.rs2
-rw-r--r--src/liballoc/Cargo.toml2
-rw-r--r--src/liballoc/alloc.rs47
-rw-r--r--src/liballoc/lib.rs10
-rw-r--r--src/liballoc/slice.rs13
-rw-r--r--src/liballoc/str.rs7
-rw-r--r--src/liballoc/vec.rs3
-rw-r--r--src/liballoc_jemalloc/lib.rs7
-rw-r--r--src/liballoc_system/lib.rs27
-rw-r--r--src/libarena/lib.rs1
-rw-r--r--src/libcore/Cargo.toml2
-rw-r--r--src/libcore/clone.rs1
-rw-r--r--src/libcore/internal_macros.rs14
-rw-r--r--src/libcore/lib.rs19
-rw-r--r--src/libcore/marker.rs1
-rw-r--r--src/libcore/num/f32.rs4
-rw-r--r--src/libcore/num/f64.rs4
-rw-r--r--src/libcore/num/mod.rs2
-rw-r--r--src/libcore/ops/range.rs10
-rw-r--r--src/libcore/prelude/v1.rs10
-rw-r--r--src/libcore/slice/mod.rs987
-rw-r--r--src/libcore/str/mod.rs590
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/num/uint_macros.rs1
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc_mir/borrow_check/nll/mod.rs4
-rw-r--r--src/librustc_mir/lib.rs13
-rw-r--r--src/librustc_mir/util/pretty.rs8
-rw-r--r--src/librustc_typeck/lib.rs2
-rw-r--r--src/librustdoc/lib.rs2
-rw-r--r--src/libstd/alloc.rs61
-rw-r--r--src/libstd/f32.rs12
-rw-r--r--src/libstd/f64.rs12
-rw-r--r--src/libstd/lib.rs9
-rw-r--r--src/libsyntax_ext/asm.rs21
-rw-r--r--src/libsyntax_ext/lib.rs3
-rw-r--r--src/rtstartup/rsbegin.rs31
-rw-r--r--src/rustc/Cargo.toml2
-rw-r--r--src/stage0.txt2
-rw-r--r--src/tools/rustdoc/Cargo.toml2
43 files changed, 442 insertions, 1521 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index cc1e66332a3..8a17a8b091b 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -584,11 +584,10 @@ impl<'a> Builder<'a> {
             cargo.env("RUST_CHECK", "1");
         }
 
-        // If we were invoked from `make` then that's already got a jobserver
-        // set up for us so no need to tell Cargo about jobs all over again.
-        if env::var_os("MAKEFLAGS").is_none() && env::var_os("MFLAGS").is_none() {
-             cargo.arg("-j").arg(self.jobs().to_string());
-        }
+        cargo.arg("-j").arg(self.jobs().to_string());
+        // Remove make-related flags to ensure Cargo can correctly set things up
+        cargo.env_remove("MAKEFLAGS");
+        cargo.env_remove("MFLAGS");
 
         // FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005
         // Force cargo to output binaries with disambiguating hashes in the name
diff --git a/src/bootstrap/channel.rs b/src/bootstrap/channel.rs
index 3453933a965..a2495f68c1f 100644
--- a/src/bootstrap/channel.rs
+++ b/src/bootstrap/channel.rs
@@ -24,7 +24,7 @@ use Build;
 use config::Config;
 
 // The version number
-pub const CFG_RELEASE_NUM: &str = "1.27.0";
+pub const CFG_RELEASE_NUM: &str = "1.28.0";
 
 pub struct GitInfo {
     inner: Option<Info>,
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 8e0227f8fe1..231ed9d40d2 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -972,7 +972,7 @@ impl Step for Assemble {
 
         // Link the compiler binary itself into place
         let out_dir = builder.cargo_out(build_compiler, Mode::Librustc, host);
-        let rustc = out_dir.join(exe("rustc", &*host));
+        let rustc = out_dir.join(exe("rustc_binary", &*host));
         let bindir = sysroot.join("bin");
         t!(fs::create_dir_all(&bindir));
         let compiler = builder.rustc(target_compiler);
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 4b6e266f1e5..29f37b36e2a 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -431,7 +431,7 @@ impl Step for Rustdoc {
         // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
         // rustdoc a different name.
         let tool_rustdoc = builder.cargo_out(build_compiler, Mode::Tool, target)
-            .join(exe("rustdoc-tool-binary", &target_compiler.host));
+            .join(exe("rustdoc_tool_binary", &target_compiler.host));
 
         // don't create a stage0-sysroot/bin directory.
         if target_compiler.stage > 0 {
diff --git a/src/liballoc/Cargo.toml b/src/liballoc/Cargo.toml
index 6383bd1e941..ada21e04b30 100644
--- a/src/liballoc/Cargo.toml
+++ b/src/liballoc/Cargo.toml
@@ -2,6 +2,8 @@
 authors = ["The Rust Project Developers"]
 name = "alloc"
 version = "0.0.0"
+autotests = false
+autobenches = false
 
 [lib]
 name = "alloc"
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index 09d16b26520..79607b06f94 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -22,28 +22,6 @@ use core::usize;
 #[doc(inline)]
 pub use core::alloc::*;
 
-#[cfg(stage0)]
-extern "Rust" {
-    #[allocator]
-    #[rustc_allocator_nounwind]
-    fn __rust_alloc(size: usize, align: usize, err: *mut u8) -> *mut u8;
-    #[cold]
-    #[rustc_allocator_nounwind]
-    fn __rust_oom(err: *const u8) -> !;
-    #[rustc_allocator_nounwind]
-    fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
-    #[rustc_allocator_nounwind]
-    fn __rust_realloc(ptr: *mut u8,
-                      old_size: usize,
-                      old_align: usize,
-                      new_size: usize,
-                      new_align: usize,
-                      err: *mut u8) -> *mut u8;
-    #[rustc_allocator_nounwind]
-    fn __rust_alloc_zeroed(size: usize, align: usize, err: *mut u8) -> *mut u8;
-}
-
-#[cfg(not(stage0))]
 extern "Rust" {
     #[allocator]
     #[rustc_allocator_nounwind]
@@ -74,10 +52,7 @@ pub const Heap: Global = Global;
 unsafe impl GlobalAlloc for Global {
     #[inline]
     unsafe fn alloc(&self, layout: Layout) -> *mut Opaque {
-        #[cfg(not(stage0))]
         let ptr = __rust_alloc(layout.size(), layout.align());
-        #[cfg(stage0)]
-        let ptr = __rust_alloc(layout.size(), layout.align(), &mut 0);
         ptr as *mut Opaque
     }
 
@@ -88,20 +63,13 @@ unsafe impl GlobalAlloc for Global {
 
     #[inline]
     unsafe fn realloc(&self, ptr: *mut Opaque, layout: Layout, new_size: usize) -> *mut Opaque {
-        #[cfg(not(stage0))]
         let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(), new_size);
-        #[cfg(stage0)]
-        let ptr = __rust_realloc(ptr as *mut u8, layout.size(), layout.align(),
-                                 new_size, layout.align(), &mut 0);
         ptr as *mut Opaque
     }
 
     #[inline]
     unsafe fn alloc_zeroed(&self, layout: Layout) -> *mut Opaque {
-        #[cfg(not(stage0))]
         let ptr = __rust_alloc_zeroed(layout.size(), layout.align());
-        #[cfg(stage0)]
-        let ptr = __rust_alloc_zeroed(layout.size(), layout.align(), &mut 0);
         ptr as *mut Opaque
     }
 }
@@ -152,14 +120,7 @@ unsafe fn exchange_malloc(size: usize, align: usize) -> *mut u8 {
     }
 }
 
-#[cfg(stage0)]
-#[lang = "box_free"]
-#[inline]
-unsafe fn old_box_free<T: ?Sized>(ptr: *mut T) {
-    box_free(Unique::new_unchecked(ptr))
-}
-
-#[cfg_attr(not(any(test, stage0)), lang = "box_free")]
+#[cfg_attr(not(test), lang = "box_free")]
 #[inline]
 pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
     let ptr = ptr.as_ptr();
@@ -172,12 +133,6 @@ pub(crate) unsafe fn box_free<T: ?Sized>(ptr: Unique<T>) {
     }
 }
 
-#[cfg(stage0)]
-pub fn oom() -> ! {
-    unsafe { ::core::intrinsics::abort() }
-}
-
-#[cfg(not(stage0))]
 pub fn oom() -> ! {
     extern {
         #[lang = "oom"]
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index f7dd9d4f010..91de3ad0c39 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -75,7 +75,6 @@
 #![deny(missing_debug_implementations)]
 
 #![cfg_attr(test, allow(deprecated))] // rand
-#![cfg_attr(all(not(test), stage0), feature(float_internals))]
 #![cfg_attr(not(test), feature(exact_size_is_empty))]
 #![cfg_attr(not(test), feature(generator_trait))]
 #![cfg_attr(test, feature(rand, test))]
@@ -90,13 +89,10 @@
 #![feature(collections_range)]
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
-#![cfg_attr(stage0, feature(core_slice_ext))]
-#![cfg_attr(stage0, feature(core_str_ext))]
 #![feature(custom_attribute)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
 #![feature(fmt_internals)]
-#![cfg_attr(stage0, feature(fn_must_use))]
 #![feature(from_ref)]
 #![feature(fundamental)]
 #![feature(lang_items)]
@@ -122,7 +118,6 @@
 #![feature(exact_chunks)]
 #![feature(pointer_methods)]
 #![feature(inclusive_range_methods)]
-#![cfg_attr(stage0, feature(generic_param_attrs))]
 #![feature(rustc_const_unstable)]
 #![feature(const_vec_new)]
 
@@ -157,15 +152,10 @@ pub mod alloc;
 #[unstable(feature = "allocator_api", issue = "32838")]
 #[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")]
 /// Use the `alloc` module instead.
-#[cfg(not(stage0))]
 pub mod heap {
     pub use alloc::*;
 }
 
-#[unstable(feature = "allocator_api", issue = "32838")]
-#[rustc_deprecated(since = "1.27.0", reason = "module renamed to `alloc`")]
-#[cfg(stage0)]
-pub mod heap;
 
 // Primitive types using the heaps above
 
diff --git a/src/liballoc/slice.rs b/src/liballoc/slice.rs
index 6caf12aa7eb..4427ac004f9 100644
--- a/src/liballoc/slice.rs
+++ b/src/liballoc/slice.rs
@@ -101,7 +101,6 @@ use core::cmp::Ordering::{self, Less};
 use core::mem::size_of;
 use core::mem;
 use core::ptr;
-#[cfg(stage0)] use core::slice::SliceExt;
 use core::{u8, u16, u32};
 
 use borrow::{Borrow, BorrowMut, ToOwned};
@@ -171,13 +170,9 @@ mod hack {
     }
 }
 
-#[cfg_attr(stage0, lang = "slice")]
-#[cfg_attr(not(stage0), lang = "slice_alloc")]
+#[lang = "slice_alloc"]
 #[cfg(not(test))]
 impl<T> [T] {
-    #[cfg(stage0)]
-    slice_core_methods!();
-
     /// Sorts the slice.
     ///
     /// This sort is stable (i.e. does not reorder equal elements) and `O(n log n)` worst-case.
@@ -467,8 +462,7 @@ impl<T> [T] {
     }
 }
 
-#[cfg_attr(stage0, lang = "slice_u8")]
-#[cfg_attr(not(stage0), lang = "slice_u8_alloc")]
+#[lang = "slice_u8_alloc"]
 #[cfg(not(test))]
 impl [u8] {
     /// Returns a vector containing a copy of this slice where each byte
@@ -504,9 +498,6 @@ impl [u8] {
         me.make_ascii_lowercase();
         me
     }
-
-    #[cfg(stage0)]
-    slice_u8_core_methods!();
 }
 
 ////////////////////////////////////////////////////////////////////////////////
diff --git a/src/liballoc/str.rs b/src/liballoc/str.rs
index 42efdea74b1..c10c0a69433 100644
--- a/src/liballoc/str.rs
+++ b/src/liballoc/str.rs
@@ -40,7 +40,6 @@
 
 use core::fmt;
 use core::str as core_str;
-#[cfg(stage0)] use core::str::StrExt;
 use core::str::pattern::Pattern;
 use core::str::pattern::{Searcher, ReverseSearcher, DoubleEndedSearcher};
 use core::mem;
@@ -158,13 +157,9 @@ impl ToOwned for str {
 }
 
 /// Methods for string slices.
-#[cfg_attr(stage0, lang = "str")]
-#[cfg_attr(not(stage0), lang = "str_alloc")]
+#[lang = "str_alloc"]
 #[cfg(not(test))]
 impl str {
-    #[cfg(stage0)]
-    str_core_methods!();
-
     /// Converts a `Box<str>` into a `Box<[u8]>` without copying or allocating.
     ///
     /// # Examples
diff --git a/src/liballoc/vec.rs b/src/liballoc/vec.rs
index d30f8cd0fca..bf89b377b7e 100644
--- a/src/liballoc/vec.rs
+++ b/src/liballoc/vec.rs
@@ -73,9 +73,6 @@ use core::intrinsics::{arith_offset, assume};
 use core::iter::{FromIterator, FusedIterator, TrustedLen};
 use core::marker::PhantomData;
 use core::mem;
-#[cfg(not(test))]
-#[cfg(stage0)]
-use core::num::Float;
 use core::ops::Bound::{Excluded, Included, Unbounded};
 use core::ops::{Index, IndexMut, RangeBounds};
 use core::ops;
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
index 4b8755877de..ce856eccd83 100644
--- a/src/liballoc_jemalloc/lib.rs
+++ b/src/liballoc_jemalloc/lib.rs
@@ -97,13 +97,6 @@ mod contents {
         ptr
     }
 
-    #[cfg(stage0)]
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_oom() -> ! {
-        ::core::intrinsics::abort();
-    }
-
     #[no_mangle]
     #[rustc_std_internal_symbol]
     pub unsafe extern fn __rde_dealloc(ptr: *mut u8,
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs
index 7376ac0f15d..9490b54e675 100644
--- a/src/liballoc_system/lib.rs
+++ b/src/liballoc_system/lib.rs
@@ -73,33 +73,6 @@ unsafe impl Alloc for System {
     }
 }
 
-#[cfg(stage0)]
-#[unstable(feature = "allocator_api", issue = "32838")]
-unsafe impl<'a> Alloc for &'a System {
-    #[inline]
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
-        NonNull::new(GlobalAlloc::alloc(*self, layout)).ok_or(AllocErr)
-    }
-
-    #[inline]
-    unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<NonNull<Opaque>, AllocErr> {
-        NonNull::new(GlobalAlloc::alloc_zeroed(*self, layout)).ok_or(AllocErr)
-    }
-
-    #[inline]
-    unsafe fn dealloc(&mut self, ptr: NonNull<Opaque>, layout: Layout) {
-        GlobalAlloc::dealloc(*self, ptr.as_ptr(), layout)
-    }
-
-    #[inline]
-    unsafe fn realloc(&mut self,
-                      ptr: NonNull<Opaque>,
-                      layout: Layout,
-                      new_size: usize) -> Result<NonNull<Opaque>, AllocErr> {
-        NonNull::new(GlobalAlloc::realloc(*self, ptr.as_ptr(), layout, new_size)).ok_or(AllocErr)
-    }
-}
-
 #[cfg(any(windows, unix, target_os = "cloudabi", target_os = "redox"))]
 mod realloc_fallback {
     use core::alloc::{GlobalAlloc, Opaque, Layout};
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index c79e0e14e3d..f7143a4f981 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -26,7 +26,6 @@
 #![feature(alloc)]
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
-#![cfg_attr(stage0, feature(generic_param_attrs))]
 #![cfg_attr(test, feature(test))]
 
 #![allow(deprecated)]
diff --git a/src/libcore/Cargo.toml b/src/libcore/Cargo.toml
index 24529f7a9d8..321ed892ea9 100644
--- a/src/libcore/Cargo.toml
+++ b/src/libcore/Cargo.toml
@@ -2,6 +2,8 @@
 authors = ["The Rust Project Developers"]
 name = "core"
 version = "0.0.0"
+autotests = false
+autobenches = false
 
 [lib]
 name = "core"
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index f79f7351698..3b15ba2b4ab 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -153,7 +153,6 @@ pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: ::marker::PhantomData<T
 ///
 /// Implementations that cannot be described in Rust
 /// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
-#[cfg(not(stage0))]
 mod impls {
 
     use super::Clone;
diff --git a/src/libcore/internal_macros.rs b/src/libcore/internal_macros.rs
index 58eef649287..db75f9bf210 100644
--- a/src/libcore/internal_macros.rs
+++ b/src/libcore/internal_macros.rs
@@ -86,17 +86,3 @@ macro_rules! forward_ref_op_assign {
         }
     }
 }
-
-#[cfg(stage0)]
-macro_rules! public_in_stage0 {
-    ( { $(#[$attr:meta])* } $($Item: tt)*) => {
-        $(#[$attr])* pub $($Item)*
-    }
-}
-
-#[cfg(not(stage0))]
-macro_rules! public_in_stage0 {
-    ( { $(#[$attr:meta])* } $($Item: tt)*) => {
-        $(#[$attr])* pub(crate) $($Item)*
-    }
-}
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 06fbfcecba8..77b5488084d 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -112,18 +112,13 @@
 #![feature(unwind_attributes)]
 #![feature(doc_alias)]
 #![feature(inclusive_range_methods)]
-
-#![cfg_attr(not(stage0), feature(mmx_target_feature))]
-#![cfg_attr(not(stage0), feature(tbm_target_feature))]
-#![cfg_attr(not(stage0), feature(sse4a_target_feature))]
-#![cfg_attr(not(stage0), feature(arm_target_feature))]
-#![cfg_attr(not(stage0), feature(powerpc_target_feature))]
-#![cfg_attr(not(stage0), feature(mips_target_feature))]
-#![cfg_attr(not(stage0), feature(aarch64_target_feature))]
-
-#![cfg_attr(stage0, feature(target_feature))]
-#![cfg_attr(stage0, feature(cfg_target_feature))]
-#![cfg_attr(stage0, feature(fn_must_use))]
+#![feature(mmx_target_feature)]
+#![feature(tbm_target_feature)]
+#![feature(sse4a_target_feature)]
+#![feature(arm_target_feature)]
+#![feature(powerpc_target_feature)]
+#![feature(mips_target_feature)]
+#![feature(aarch64_target_feature)]
 
 #[prelude_import]
 #[allow(unused)]
diff --git a/src/libcore/marker.rs b/src/libcore/marker.rs
index db5f50a99ca..6c8ee0eda11 100644
--- a/src/libcore/marker.rs
+++ b/src/libcore/marker.rs
@@ -611,7 +611,6 @@ pub unsafe auto trait Unpin {}
 ///
 /// Implementations that cannot be described in Rust
 /// are implemented in `SelectionContext::copy_clone_conditions()` in librustc.
-#[cfg(not(stage0))]
 mod copy_impls {
 
     use super::Copy;
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 4a7dc13f0f2..718dd42a615 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -19,7 +19,7 @@
 
 use mem;
 use num::Float;
-#[cfg(not(stage0))] use num::FpCategory;
+use num::FpCategory;
 use num::FpCategory as Fp;
 
 /// The radix or base of the internal representation of `f32`.
@@ -277,7 +277,6 @@ impl Float for f32 {
 
 // FIXME: remove (inline) this macro and the Float trait
 // when updating to a bootstrap compiler that has the new lang items.
-#[cfg_attr(stage0, macro_export)]
 #[unstable(feature = "core_float", issue = "32110")]
 macro_rules! f32_core_methods { () => {
     /// Returns `true` if this value is `NaN` and false otherwise.
@@ -553,7 +552,6 @@ macro_rules! f32_core_methods { () => {
 
 #[lang = "f32"]
 #[cfg(not(test))]
-#[cfg(not(stage0))]
 impl f32 {
     f32_core_methods!();
 }
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 801de5e87bd..f128c55c78a 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -19,7 +19,7 @@
 
 use mem;
 use num::Float;
-#[cfg(not(stage0))] use num::FpCategory;
+use num::FpCategory;
 use num::FpCategory as Fp;
 
 /// The radix or base of the internal representation of `f64`.
@@ -276,7 +276,6 @@ impl Float for f64 {
 
 // FIXME: remove (inline) this macro and the Float trait
 // when updating to a bootstrap compiler that has the new lang items.
-#[cfg_attr(stage0, macro_export)]
 #[unstable(feature = "core_float", issue = "32110")]
 macro_rules! f64_core_methods { () => {
     /// Returns `true` if this value is `NaN` and false otherwise.
@@ -562,7 +561,6 @@ macro_rules! f64_core_methods { () => {
 
 #[lang = "f64"]
 #[cfg(not(test))]
-#[cfg(not(stage0))]
 impl f64 {
     f64_core_methods!();
 }
diff --git a/src/libcore/num/mod.rs b/src/libcore/num/mod.rs
index 6df8ca98ba9..58d45b107f1 100644
--- a/src/libcore/num/mod.rs
+++ b/src/libcore/num/mod.rs
@@ -422,7 +422,6 @@ $EndFeature, "
         /// assert_eq!(m, -22016);
         /// ```
         #[unstable(feature = "reverse_bits", issue = "48763")]
-        #[cfg(not(stage0))]
         #[inline]
         pub fn reverse_bits(self) -> Self {
             (self as $UnsignedT).reverse_bits() as Self
@@ -2194,7 +2193,6 @@ assert_eq!(n.trailing_zeros(), 3);", $EndFeature, "
         /// assert_eq!(m, 43520);
         /// ```
         #[unstable(feature = "reverse_bits", issue = "48763")]
-        #[cfg(not(stage0))]
         #[inline]
         pub fn reverse_bits(self) -> Self {
             unsafe { intrinsics::bitreverse(self as $ActualT) as Self }
diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs
index 697e6a3efde..1f84631ada3 100644
--- a/src/libcore/ops/range.rs
+++ b/src/libcore/ops/range.rs
@@ -335,18 +335,8 @@ pub struct RangeInclusive<Idx> {
     // but it is known that LLVM is not able to optimize loops following that RFC.
     // Consider adding an extra `bool` field to indicate emptiness of the range.
     // See #45222 for performance test cases.
-    #[cfg(not(stage0))]
     pub(crate) start: Idx,
-    #[cfg(not(stage0))]
     pub(crate) end: Idx,
-    /// The lower bound of the range (inclusive).
-    #[cfg(stage0)]
-    #[unstable(feature = "inclusive_range_fields", issue = "49022")]
-    pub start: Idx,
-    /// The upper bound of the range (inclusive).
-    #[cfg(stage0)]
-    #[unstable(feature = "inclusive_range_fields", issue = "49022")]
-    pub end: Idx,
 }
 
 impl<Idx> RangeInclusive<Idx> {
diff --git a/src/libcore/prelude/v1.rs b/src/libcore/prelude/v1.rs
index 8212648f2d8..45f629a6442 100644
--- a/src/libcore/prelude/v1.rs
+++ b/src/libcore/prelude/v1.rs
@@ -54,13 +54,3 @@ pub use option::Option::{self, Some, None};
 #[stable(feature = "core_prelude", since = "1.4.0")]
 #[doc(no_inline)]
 pub use result::Result::{self, Ok, Err};
-
-// Re-exported extension traits for primitive types
-#[stable(feature = "core_prelude", since = "1.4.0")]
-#[doc(no_inline)]
-#[cfg(stage0)]
-pub use slice::SliceExt;
-#[stable(feature = "core_prelude", since = "1.4.0")]
-#[doc(no_inline)]
-#[cfg(stage0)]
-pub use str::StrExt;
diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs
index 93ebc23ac0b..82891b691dc 100644
--- a/src/libcore/slice/mod.rs
+++ b/src/libcore/slice/mod.rs
@@ -68,181 +68,6 @@ struct Repr<T> {
 // Extension traits
 //
 
-public_in_stage0! {
-{
-/// Extension methods for slices.
-#[unstable(feature = "core_slice_ext",
-           reason = "stable interface provided by `impl [T]` in later crates",
-           issue = "32110")]
-#[allow(missing_docs)] // documented elsewhere
-}
-trait SliceExt {
-    type Item;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_at(&self, mid: usize) -> (&[Self::Item], &[Self::Item]);
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn iter(&self) -> Iter<Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split<P>(&self, pred: P) -> Split<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "slice_rsplit", since = "1.27.0")]
-    fn rsplit<P>(&self, pred: P) -> RSplit<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn splitn<P>(&self, n: usize, pred: P) -> SplitN<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rsplitn<P>(&self,  n: usize, pred: P) -> RSplitN<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn windows(&self, size: usize) -> Windows<Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn chunks(&self, size: usize) -> Chunks<Self::Item>;
-
-    #[unstable(feature = "exact_chunks", issue = "47115")]
-    fn exact_chunks(&self, size: usize) -> ExactChunks<Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn get<I>(&self, index: I) -> Option<&I::Output>
-        where I: SliceIndex<Self>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn first(&self) -> Option<&Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_first(&self) -> Option<(&Self::Item, &[Self::Item])>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_last(&self) -> Option<(&Self::Item, &[Self::Item])>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn last(&self) -> Option<&Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
-        where I: SliceIndex<Self>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn as_ptr(&self) -> *const Self::Item;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn binary_search(&self, x: &Self::Item) -> Result<usize, usize>
-        where Self::Item: Ord;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
-        where F: FnMut(&'a Self::Item) -> Ordering;
-
-    #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
-    fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
-        where F: FnMut(&'a Self::Item) -> B,
-              B: Ord;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn len(&self) -> usize;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn is_empty(&self) -> bool { self.len() == 0 }
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
-        where I: SliceIndex<Self>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn iter_mut(&mut self) -> IterMut<Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn first_mut(&mut self) -> Option<&mut Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_first_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_last_mut(&mut self) -> Option<(&mut Self::Item, &mut [Self::Item])>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn last_mut(&mut self) -> Option<&mut Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_mut<P>(&mut self, pred: P) -> SplitMut<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "slice_rsplit", since = "1.27.0")]
-    fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rsplitn_mut<P>(&mut self,  n: usize, pred: P) -> RSplitNMut<Self::Item, P>
-        where P: FnMut(&Self::Item) -> bool;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<Self::Item>;
-
-    #[unstable(feature = "exact_chunks", issue = "47115")]
-    fn exact_chunks_mut(&mut self, size: usize) -> ExactChunksMut<Self::Item>;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn swap(&mut self, a: usize, b: usize);
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_at_mut(&mut self, mid: usize) -> (&mut [Self::Item], &mut [Self::Item]);
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn reverse(&mut self);
-
-    #[stable(feature = "core", since = "1.6.0")]
-    unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
-        where I: SliceIndex<Self>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn as_mut_ptr(&mut self) -> *mut Self::Item;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn contains(&self, x: &Self::Item) -> bool where Self::Item: PartialEq;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn starts_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn ends_with(&self, needle: &[Self::Item]) -> bool where Self::Item: PartialEq;
-
-    #[stable(feature = "slice_rotate", since = "1.26.0")]
-    fn rotate_left(&mut self, mid: usize);
-
-    #[stable(feature = "slice_rotate", since = "1.26.0")]
-    fn rotate_right(&mut self, k: usize);
-
-    #[stable(feature = "clone_from_slice", since = "1.7.0")]
-    fn clone_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Clone;
-
-    #[stable(feature = "copy_from_slice", since = "1.9.0")]
-    fn copy_from_slice(&mut self, src: &[Self::Item]) where Self::Item: Copy;
-
-    #[stable(feature = "swap_with_slice", since = "1.27.0")]
-    fn swap_with_slice(&mut self, src: &mut [Self::Item]);
-
-    #[stable(feature = "sort_unstable", since = "1.20.0")]
-    fn sort_unstable(&mut self)
-        where Self::Item: Ord;
-
-    #[stable(feature = "sort_unstable", since = "1.20.0")]
-    fn sort_unstable_by<F>(&mut self, compare: F)
-        where F: FnMut(&Self::Item, &Self::Item) -> Ordering;
-
-    #[stable(feature = "sort_unstable", since = "1.20.0")]
-    fn sort_unstable_by_key<B, F>(&mut self, f: F)
-        where F: FnMut(&Self::Item) -> B,
-              B: Ord;
-}}
-
 // Use macros to be generic over const/mut
 macro_rules! slice_offset {
     ($ptr:expr, $by:expr) => {{
@@ -281,488 +106,9 @@ macro_rules! make_ref_mut {
     }};
 }
 
-#[unstable(feature = "core_slice_ext",
-           reason = "stable interface provided by `impl [T]` in later crates",
-           issue = "32110")]
-impl<T> SliceExt for [T] {
-    type Item = T;
-
-    #[inline]
-    fn split_at(&self, mid: usize) -> (&[T], &[T]) {
-        (&self[..mid], &self[mid..])
-    }
-
-    #[inline]
-    fn iter(&self) -> Iter<T> {
-        unsafe {
-            let p = if mem::size_of::<T>() == 0 {
-                1 as *const _
-            } else {
-                let p = self.as_ptr();
-                assume(!p.is_null());
-                p
-            };
-
-            Iter {
-                ptr: p,
-                end: slice_offset!(p, self.len() as isize),
-                _marker: marker::PhantomData
-            }
-        }
-    }
-
-    #[inline]
-    fn split<P>(&self, pred: P) -> Split<T, P>
-        where P: FnMut(&T) -> bool
-    {
-        Split {
-            v: self,
-            pred,
-            finished: false
-        }
-    }
-
-    #[inline]
-    fn rsplit<P>(&self, pred: P) -> RSplit<T, P>
-        where P: FnMut(&T) -> bool
-    {
-        RSplit { inner: self.split(pred) }
-    }
-
-    #[inline]
-    fn splitn<P>(&self, n: usize, pred: P) -> SplitN<T, P>
-        where P: FnMut(&T) -> bool
-    {
-        SplitN {
-            inner: GenericSplitN {
-                iter: self.split(pred),
-                count: n
-            }
-        }
-    }
-
-    #[inline]
-    fn rsplitn<P>(&self, n: usize, pred: P) -> RSplitN<T, P>
-        where P: FnMut(&T) -> bool
-    {
-        RSplitN {
-            inner: GenericSplitN {
-                iter: self.rsplit(pred),
-                count: n
-            }
-        }
-    }
-
-    #[inline]
-    fn windows(&self, size: usize) -> Windows<T> {
-        assert!(size != 0);
-        Windows { v: self, size: size }
-    }
-
-    #[inline]
-    fn chunks(&self, chunk_size: usize) -> Chunks<T> {
-        assert!(chunk_size != 0);
-        Chunks { v: self, chunk_size: chunk_size }
-    }
-
-    #[inline]
-    fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
-        assert!(chunk_size != 0);
-        let rem = self.len() % chunk_size;
-        let len = self.len() - rem;
-        ExactChunks { v: &self[..len], chunk_size: chunk_size}
-    }
-
-    #[inline]
-    fn get<I>(&self, index: I) -> Option<&I::Output>
-        where I: SliceIndex<[T]>
-    {
-        index.get(self)
-    }
-
-    #[inline]
-    fn first(&self) -> Option<&T> {
-        if self.is_empty() { None } else { Some(&self[0]) }
-    }
-
-    #[inline]
-    fn split_first(&self) -> Option<(&T, &[T])> {
-        if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
-    }
-
-    #[inline]
-    fn split_last(&self) -> Option<(&T, &[T])> {
-        let len = self.len();
-        if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
-    }
-
-    #[inline]
-    fn last(&self) -> Option<&T> {
-        if self.is_empty() { None } else { Some(&self[self.len() - 1]) }
-    }
-
-    #[inline]
-    unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
-        where I: SliceIndex<[T]>
-    {
-        index.get_unchecked(self)
-    }
-
-    #[inline]
-    fn as_ptr(&self) -> *const T {
-        self as *const [T] as *const T
-    }
-
-    fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
-        where F: FnMut(&'a T) -> Ordering
-    {
-        let s = self;
-        let mut size = s.len();
-        if size == 0 {
-            return Err(0);
-        }
-        let mut base = 0usize;
-        while size > 1 {
-            let half = size / 2;
-            let mid = base + half;
-            // mid is always in [0, size), that means mid is >= 0 and < size.
-            // mid >= 0: by definition
-            // mid < size: mid = size / 2 + size / 4 + size / 8 ...
-            let cmp = f(unsafe { s.get_unchecked(mid) });
-            base = if cmp == Greater { base } else { mid };
-            size -= half;
-        }
-        // base is always in [0, size) because base <= mid.
-        let cmp = f(unsafe { s.get_unchecked(base) });
-        if cmp == Equal { Ok(base) } else { Err(base + (cmp == Less) as usize) }
-    }
-
-    #[inline]
-    fn len(&self) -> usize {
-        unsafe {
-            mem::transmute::<&[T], Repr<T>>(self).len
-        }
-    }
-
-    #[inline]
-    fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
-        where I: SliceIndex<[T]>
-    {
-        index.get_mut(self)
-    }
-
-    #[inline]
-    fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
-        let len = self.len();
-        let ptr = self.as_mut_ptr();
-
-        unsafe {
-            assert!(mid <= len);
-
-            (from_raw_parts_mut(ptr, mid),
-             from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
-        }
-    }
-
-    #[inline]
-    fn iter_mut(&mut self) -> IterMut<T> {
-        unsafe {
-            let p = if mem::size_of::<T>() == 0 {
-                1 as *mut _
-            } else {
-                let p = self.as_mut_ptr();
-                assume(!p.is_null());
-                p
-            };
-
-            IterMut {
-                ptr: p,
-                end: slice_offset!(p, self.len() as isize),
-                _marker: marker::PhantomData
-            }
-        }
-    }
-
-    #[inline]
-    fn last_mut(&mut self) -> Option<&mut T> {
-        let len = self.len();
-        if len == 0 { return None; }
-        Some(&mut self[len - 1])
-    }
-
-    #[inline]
-    fn first_mut(&mut self) -> Option<&mut T> {
-        if self.is_empty() { None } else { Some(&mut self[0]) }
-    }
-
-    #[inline]
-    fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
-        if self.is_empty() { None } else {
-            let split = self.split_at_mut(1);
-            Some((&mut split.0[0], split.1))
-        }
-    }
-
-    #[inline]
-    fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
-        let len = self.len();
-        if len == 0 { None } else {
-            let split = self.split_at_mut(len - 1);
-            Some((&mut split.1[0], split.0))
-        }
-    }
-
-    #[inline]
-    fn split_mut<P>(&mut self, pred: P) -> SplitMut<T, P>
-        where P: FnMut(&T) -> bool
-    {
-        SplitMut { v: self, pred: pred, finished: false }
-    }
-
-    #[inline]
-    fn rsplit_mut<P>(&mut self, pred: P) -> RSplitMut<T, P>
-        where P: FnMut(&T) -> bool
-    {
-        RSplitMut { inner: self.split_mut(pred) }
-    }
-
-    #[inline]
-    fn splitn_mut<P>(&mut self, n: usize, pred: P) -> SplitNMut<T, P>
-        where P: FnMut(&T) -> bool
-    {
-        SplitNMut {
-            inner: GenericSplitN {
-                iter: self.split_mut(pred),
-                count: n
-            }
-        }
-    }
-
-    #[inline]
-    fn rsplitn_mut<P>(&mut self, n: usize, pred: P) -> RSplitNMut<T, P> where
-        P: FnMut(&T) -> bool,
-    {
-        RSplitNMut {
-            inner: GenericSplitN {
-                iter: self.rsplit_mut(pred),
-                count: n
-            }
-        }
-    }
-
-    #[inline]
-    fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
-        assert!(chunk_size != 0);
-        ChunksMut { v: self, chunk_size: chunk_size }
-    }
-
-    #[inline]
-    fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
-        assert!(chunk_size != 0);
-        let rem = self.len() % chunk_size;
-        let len = self.len() - rem;
-        ExactChunksMut { v: &mut self[..len], chunk_size: chunk_size}
-    }
-
-    #[inline]
-    fn swap(&mut self, a: usize, b: usize) {
-        unsafe {
-            // Can't take two mutable loans from one vector, so instead just cast
-            // them to their raw pointers to do the swap
-            let pa: *mut T = &mut self[a];
-            let pb: *mut T = &mut self[b];
-            ptr::swap(pa, pb);
-        }
-    }
-
-    fn reverse(&mut self) {
-        let mut i: usize = 0;
-        let ln = self.len();
-
-        // For very small types, all the individual reads in the normal
-        // path perform poorly.  We can do better, given efficient unaligned
-        // load/store, by loading a larger chunk and reversing a register.
-
-        // Ideally LLVM would do this for us, as it knows better than we do
-        // whether unaligned reads are efficient (since that changes between
-        // different ARM versions, for example) and what the best chunk size
-        // would be.  Unfortunately, as of LLVM 4.0 (2017-05) it only unrolls
-        // the loop, so we need to do this ourselves.  (Hypothesis: reverse
-        // is troublesome because the sides can be aligned differently --
-        // will be, when the length is odd -- so there's no way of emitting
-        // pre- and postludes to use fully-aligned SIMD in the middle.)
-
-        let fast_unaligned =
-            cfg!(any(target_arch = "x86", target_arch = "x86_64"));
-
-        if fast_unaligned && mem::size_of::<T>() == 1 {
-            // Use the llvm.bswap intrinsic to reverse u8s in a usize
-            let chunk = mem::size_of::<usize>();
-            while i + chunk - 1 < ln / 2 {
-                unsafe {
-                    let pa: *mut T = self.get_unchecked_mut(i);
-                    let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
-                    let va = ptr::read_unaligned(pa as *mut usize);
-                    let vb = ptr::read_unaligned(pb as *mut usize);
-                    ptr::write_unaligned(pa as *mut usize, vb.swap_bytes());
-                    ptr::write_unaligned(pb as *mut usize, va.swap_bytes());
-                }
-                i += chunk;
-            }
-        }
-
-        if fast_unaligned && mem::size_of::<T>() == 2 {
-            // Use rotate-by-16 to reverse u16s in a u32
-            let chunk = mem::size_of::<u32>() / 2;
-            while i + chunk - 1 < ln / 2 {
-                unsafe {
-                    let pa: *mut T = self.get_unchecked_mut(i);
-                    let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
-                    let va = ptr::read_unaligned(pa as *mut u32);
-                    let vb = ptr::read_unaligned(pb as *mut u32);
-                    ptr::write_unaligned(pa as *mut u32, vb.rotate_left(16));
-                    ptr::write_unaligned(pb as *mut u32, va.rotate_left(16));
-                }
-                i += chunk;
-            }
-        }
-
-        while i < ln / 2 {
-            // Unsafe swap to avoid the bounds check in safe swap.
-            unsafe {
-                let pa: *mut T = self.get_unchecked_mut(i);
-                let pb: *mut T = self.get_unchecked_mut(ln - i - 1);
-                ptr::swap(pa, pb);
-            }
-            i += 1;
-        }
-    }
-
-    #[inline]
-    unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
-        where I: SliceIndex<[T]>
-    {
-        index.get_unchecked_mut(self)
-    }
-
-    #[inline]
-    fn as_mut_ptr(&mut self) -> *mut T {
-        self as *mut [T] as *mut T
-    }
-
-    #[inline]
-    fn contains(&self, x: &T) -> bool where T: PartialEq {
-        x.slice_contains(self)
-    }
-
-    #[inline]
-    fn starts_with(&self, needle: &[T]) -> bool where T: PartialEq {
-        let n = needle.len();
-        self.len() >= n && needle == &self[..n]
-    }
-
-    #[inline]
-    fn ends_with(&self, needle: &[T]) -> bool where T: PartialEq {
-        let (m, n) = (self.len(), needle.len());
-        m >= n && needle == &self[m-n..]
-    }
-
-    fn binary_search(&self, x: &T) -> Result<usize, usize>
-        where T: Ord
-    {
-        self.binary_search_by(|p| p.cmp(x))
-    }
-
-    fn rotate_left(&mut self, mid: usize) {
-        assert!(mid <= self.len());
-        let k = self.len() - mid;
-
-        unsafe {
-            let p = self.as_mut_ptr();
-            rotate::ptr_rotate(mid, p.offset(mid as isize), k);
-        }
-    }
-
-    fn rotate_right(&mut self, k: usize) {
-        assert!(k <= self.len());
-        let mid = self.len() - k;
-
-        unsafe {
-            let p = self.as_mut_ptr();
-            rotate::ptr_rotate(mid, p.offset(mid as isize), k);
-        }
-    }
-
-    #[inline]
-    fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
-        assert!(self.len() == src.len(),
-                "destination and source slices have different lengths");
-        // NOTE: We need to explicitly slice them to the same length
-        // for bounds checking to be elided, and the optimizer will
-        // generate memcpy for simple cases (for example T = u8).
-        let len = self.len();
-        let src = &src[..len];
-        for i in 0..len {
-            self[i].clone_from(&src[i]);
-        }
-    }
-
-    #[inline]
-    fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
-        assert!(self.len() == src.len(),
-                "destination and source slices have different lengths");
-        unsafe {
-            ptr::copy_nonoverlapping(
-                src.as_ptr(), self.as_mut_ptr(), self.len());
-        }
-    }
-
-    #[inline]
-    fn swap_with_slice(&mut self, src: &mut [T]) {
-        assert!(self.len() == src.len(),
-                "destination and source slices have different lengths");
-        unsafe {
-            ptr::swap_nonoverlapping(
-                self.as_mut_ptr(), src.as_mut_ptr(), self.len());
-        }
-    }
-
-    #[inline]
-    fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
-        where F: FnMut(&'a Self::Item) -> B,
-              B: Ord
-    {
-        self.binary_search_by(|k| f(k).cmp(b))
-    }
-
-    #[inline]
-    fn sort_unstable(&mut self)
-        where Self::Item: Ord
-    {
-        sort::quicksort(self, |a, b| a.lt(b));
-    }
-
-    #[inline]
-    fn sort_unstable_by<F>(&mut self, mut compare: F)
-        where F: FnMut(&Self::Item, &Self::Item) -> Ordering
-    {
-        sort::quicksort(self, |a, b| compare(a, b) == Ordering::Less);
-    }
-
-    #[inline]
-    fn sort_unstable_by_key<B, F>(&mut self, mut f: F)
-        where F: FnMut(&Self::Item) -> B,
-              B: Ord
-    {
-        sort::quicksort(self, |a, b| f(a).lt(&f(b)));
-    }
-}
-
-// FIXME: remove (inline) this macro and the SliceExt trait
-// when updating to a bootstrap compiler that has the new lang items.
-#[cfg_attr(stage0, macro_export)]
-#[unstable(feature = "core_slice_ext", issue = "32110")]
-macro_rules! slice_core_methods { () => {
+#[lang = "slice"]
+#[cfg(not(test))]
+impl<T> [T] {
     /// Returns the number of elements in the slice.
     ///
     /// # Examples
@@ -774,7 +120,9 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn len(&self) -> usize {
-        SliceExt::len(self)
+        unsafe {
+            mem::transmute::<&[T], Repr<T>>(self).len
+        }
     }
 
     /// Returns `true` if the slice has a length of 0.
@@ -788,7 +136,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn is_empty(&self) -> bool {
-        SliceExt::is_empty(self)
+        self.len() == 0
     }
 
     /// Returns the first element of the slice, or `None` if it is empty.
@@ -805,7 +153,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn first(&self) -> Option<&T> {
-        SliceExt::first(self)
+        if self.is_empty() { None } else { Some(&self[0]) }
     }
 
     /// Returns a mutable pointer to the first element of the slice, or `None` if it is empty.
@@ -823,7 +171,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn first_mut(&mut self) -> Option<&mut T> {
-        SliceExt::first_mut(self)
+        if self.is_empty() { None } else { Some(&mut self[0]) }
     }
 
     /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
@@ -841,7 +189,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_first(&self) -> Option<(&T, &[T])> {
-        SliceExt::split_first(self)
+        if self.is_empty() { None } else { Some((&self[0], &self[1..])) }
     }
 
     /// Returns the first and all the rest of the elements of the slice, or `None` if it is empty.
@@ -861,7 +209,10 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
-        SliceExt::split_first_mut(self)
+        if self.is_empty() { None } else {
+            let split = self.split_at_mut(1);
+            Some((&mut split.0[0], split.1))
+        }
     }
 
     /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
@@ -879,7 +230,8 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_last(&self) -> Option<(&T, &[T])> {
-        SliceExt::split_last(self)
+        let len = self.len();
+        if len == 0 { None } else { Some((&self[len - 1], &self[..(len - 1)])) }
     }
 
     /// Returns the last and all the rest of the elements of the slice, or `None` if it is empty.
@@ -899,7 +251,12 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "slice_splits", since = "1.5.0")]
     #[inline]
     pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
-        SliceExt::split_last_mut(self)
+        let len = self.len();
+        if len == 0 { None } else {
+            let split = self.split_at_mut(len - 1);
+            Some((&mut split.1[0], split.0))
+        }
+
     }
 
     /// Returns the last element of the slice, or `None` if it is empty.
@@ -916,7 +273,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn last(&self) -> Option<&T> {
-        SliceExt::last(self)
+        if self.is_empty() { None } else { Some(&self[self.len() - 1]) }
     }
 
     /// Returns a mutable pointer to the last item in the slice.
@@ -934,7 +291,9 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn last_mut(&mut self) -> Option<&mut T> {
-        SliceExt::last_mut(self)
+        let len = self.len();
+        if len == 0 { return None; }
+        Some(&mut self[len - 1])
     }
 
     /// Returns a reference to an element or subslice depending on the type of
@@ -959,7 +318,7 @@ macro_rules! slice_core_methods { () => {
     pub fn get<I>(&self, index: I) -> Option<&I::Output>
         where I: SliceIndex<Self>
     {
-        SliceExt::get(self, index)
+        index.get(self)
     }
 
     /// Returns a mutable reference to an element or subslice depending on the
@@ -982,7 +341,7 @@ macro_rules! slice_core_methods { () => {
     pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
         where I: SliceIndex<Self>
     {
-        SliceExt::get_mut(self, index)
+        index.get_mut(self)
     }
 
     /// Returns a reference to an element or subslice, without doing bounds
@@ -1007,7 +366,7 @@ macro_rules! slice_core_methods { () => {
     pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
         where I: SliceIndex<Self>
     {
-        SliceExt::get_unchecked(self, index)
+        index.get_unchecked(self)
     }
 
     /// Returns a mutable reference to an element or subslice, without doing
@@ -1034,7 +393,7 @@ macro_rules! slice_core_methods { () => {
     pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
         where I: SliceIndex<Self>
     {
-        SliceExt::get_unchecked_mut(self, index)
+        index.get_unchecked_mut(self)
     }
 
     /// Returns a raw pointer to the slice's buffer.
@@ -1060,7 +419,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn as_ptr(&self) -> *const T {
-        SliceExt::as_ptr(self)
+        self as *const [T] as *const T
     }
 
     /// Returns an unsafe mutable pointer to the slice's buffer.
@@ -1087,7 +446,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn as_mut_ptr(&mut self) -> *mut T {
-        SliceExt::as_mut_ptr(self)
+        self as *mut [T] as *mut T
     }
 
     /// Swaps two elements in the slice.
@@ -1111,7 +470,13 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn swap(&mut self, a: usize, b: usize) {
-        SliceExt::swap(self, a, b)
+        unsafe {
+            // Can't take two mutable loans from one vector, so instead just cast
+            // them to their raw pointers to do the swap
+            let pa: *mut T = &mut self[a];
+            let pb: *mut T = &mut self[b];
+            ptr::swap(pa, pb);
+        }
     }
 
     /// Reverses the order of elements in the slice, in place.
@@ -1126,7 +491,66 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn reverse(&mut self) {
-        SliceExt::reverse(self)
+        let mut i: usize = 0;
+        let ln = self.len();
+
+        // For very small types, all the individual reads in the normal
+        // path perform poorly.  We can do better, given efficient unaligned
+        // load/store, by loading a larger chunk and reversing a register.
+
+        // Ideally LLVM would do this for us, as it knows better than we do
+        // whether unaligned reads are efficient (since that changes between
+        // different ARM versions, for example) and what the best chunk size
+        // would be.  Unfortunately, as of LLVM 4.0 (2017-05) it only unrolls
+        // the loop, so we need to do this ourselves.  (Hypothesis: reverse
+        // is troublesome because the sides can be aligned differently --
+        // will be, when the length is odd -- so there's no way of emitting
+        // pre- and postludes to use fully-aligned SIMD in the middle.)
+
+        let fast_unaligned =
+            cfg!(any(target_arch = "x86", target_arch = "x86_64"));
+
+        if fast_unaligned && mem::size_of::<T>() == 1 {
+            // Use the llvm.bswap intrinsic to reverse u8s in a usize
+            let chunk = mem::size_of::<usize>();
+            while i + chunk - 1 < ln / 2 {
+                unsafe {
+                    let pa: *mut T = self.get_unchecked_mut(i);
+                    let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
+                    let va = ptr::read_unaligned(pa as *mut usize);
+                    let vb = ptr::read_unaligned(pb as *mut usize);
+                    ptr::write_unaligned(pa as *mut usize, vb.swap_bytes());
+                    ptr::write_unaligned(pb as *mut usize, va.swap_bytes());
+                }
+                i += chunk;
+            }
+        }
+
+        if fast_unaligned && mem::size_of::<T>() == 2 {
+            // Use rotate-by-16 to reverse u16s in a u32
+            let chunk = mem::size_of::<u32>() / 2;
+            while i + chunk - 1 < ln / 2 {
+                unsafe {
+                    let pa: *mut T = self.get_unchecked_mut(i);
+                    let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
+                    let va = ptr::read_unaligned(pa as *mut u32);
+                    let vb = ptr::read_unaligned(pb as *mut u32);
+                    ptr::write_unaligned(pa as *mut u32, vb.rotate_left(16));
+                    ptr::write_unaligned(pb as *mut u32, va.rotate_left(16));
+                }
+                i += chunk;
+            }
+        }
+
+        while i < ln / 2 {
+            // Unsafe swap to avoid the bounds check in safe swap.
+            unsafe {
+                let pa: *mut T = self.get_unchecked_mut(i);
+                let pb: *mut T = self.get_unchecked_mut(ln - i - 1);
+                ptr::swap(pa, pb);
+            }
+            i += 1;
+        }
     }
 
     /// Returns an iterator over the slice.
@@ -1145,7 +569,21 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn iter(&self) -> Iter<T> {
-        SliceExt::iter(self)
+        unsafe {
+            let p = if mem::size_of::<T>() == 0 {
+                1 as *const _
+            } else {
+                let p = self.as_ptr();
+                assume(!p.is_null());
+                p
+            };
+
+            Iter {
+                ptr: p,
+                end: slice_offset!(p, self.len() as isize),
+                _marker: marker::PhantomData
+            }
+        }
     }
 
     /// Returns an iterator that allows modifying each value.
@@ -1162,7 +600,21 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn iter_mut(&mut self) -> IterMut<T> {
-        SliceExt::iter_mut(self)
+        unsafe {
+            let p = if mem::size_of::<T>() == 0 {
+                1 as *mut _
+            } else {
+                let p = self.as_mut_ptr();
+                assume(!p.is_null());
+                p
+            };
+
+            IterMut {
+                ptr: p,
+                end: slice_offset!(p, self.len() as isize),
+                _marker: marker::PhantomData
+            }
+        }
     }
 
     /// Returns an iterator over all contiguous windows of length
@@ -1194,7 +646,8 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn windows(&self, size: usize) -> Windows<T> {
-        SliceExt::windows(self, size)
+        assert!(size != 0);
+        Windows { v: self, size: size }
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a
@@ -1224,7 +677,8 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn chunks(&self, chunk_size: usize) -> Chunks<T> {
-        SliceExt::chunks(self, chunk_size)
+        assert!(chunk_size != 0);
+        Chunks { v: self, chunk_size: chunk_size }
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a
@@ -1256,7 +710,10 @@ macro_rules! slice_core_methods { () => {
     #[unstable(feature = "exact_chunks", issue = "47115")]
     #[inline]
     pub fn exact_chunks(&self, chunk_size: usize) -> ExactChunks<T> {
-        SliceExt::exact_chunks(self, chunk_size)
+        assert!(chunk_size != 0);
+        let rem = self.len() % chunk_size;
+        let len = self.len() - rem;
+        ExactChunks { v: &self[..len], chunk_size: chunk_size}
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
@@ -1290,7 +747,8 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<T> {
-        SliceExt::chunks_mut(self, chunk_size)
+        assert!(chunk_size != 0);
+        ChunksMut { v: self, chunk_size: chunk_size }
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time.
@@ -1328,7 +786,10 @@ macro_rules! slice_core_methods { () => {
     #[unstable(feature = "exact_chunks", issue = "47115")]
     #[inline]
     pub fn exact_chunks_mut(&mut self, chunk_size: usize) -> ExactChunksMut<T> {
-        SliceExt::exact_chunks_mut(self, chunk_size)
+        assert!(chunk_size != 0);
+        let rem = self.len() % chunk_size;
+        let len = self.len() - rem;
+        ExactChunksMut { v: &mut self[..len], chunk_size: chunk_size}
     }
 
     /// Divides one slice into two at an index.
@@ -1367,7 +828,7 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn split_at(&self, mid: usize) -> (&[T], &[T]) {
-        SliceExt::split_at(self, mid)
+        (&self[..mid], &self[mid..])
     }
 
     /// Divides one mutable slice into two at an index.
@@ -1397,7 +858,15 @@ macro_rules! slice_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn split_at_mut(&mut self, mid: usize) -> (&mut [T], &mut [T]) {
-        SliceExt::split_at_mut(self, mid)
+        let len = self.len();
+        let ptr = self.as_mut_ptr();
+
+        unsafe {
+            assert!(mid <= len);
+
+            (from_raw_parts_mut(ptr, mid),
+             from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
+        }
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1445,7 +914,11 @@ macro_rules! slice_core_methods { () => {
     pub fn split<F>(&self, pred: F) -> Split<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::split(self, pred)
+        Split {
+            v: self,
+            pred,
+            finished: false
+        }
     }
 
     /// Returns an iterator over mutable subslices separated by elements that
@@ -1466,7 +939,7 @@ macro_rules! slice_core_methods { () => {
     pub fn split_mut<F>(&mut self, pred: F) -> SplitMut<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::split_mut(self, pred)
+        SplitMut { v: self, pred: pred, finished: false }
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1501,7 +974,7 @@ macro_rules! slice_core_methods { () => {
     pub fn rsplit<F>(&self, pred: F) -> RSplit<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::rsplit(self, pred)
+        RSplit { inner: self.split(pred) }
     }
 
     /// Returns an iterator over mutable subslices separated by elements that
@@ -1526,7 +999,7 @@ macro_rules! slice_core_methods { () => {
     pub fn rsplit_mut<F>(&mut self, pred: F) -> RSplitMut<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::rsplit_mut(self, pred)
+        RSplitMut { inner: self.split_mut(pred) }
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1553,7 +1026,12 @@ macro_rules! slice_core_methods { () => {
     pub fn splitn<F>(&self, n: usize, pred: F) -> SplitN<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::splitn(self, n, pred)
+        SplitN {
+            inner: GenericSplitN {
+                iter: self.split(pred),
+                count: n
+            }
+        }
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1578,7 +1056,12 @@ macro_rules! slice_core_methods { () => {
     pub fn splitn_mut<F>(&mut self, n: usize, pred: F) -> SplitNMut<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::splitn_mut(self, n, pred)
+        SplitNMut {
+            inner: GenericSplitN {
+                iter: self.split_mut(pred),
+                count: n
+            }
+        }
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1606,7 +1089,12 @@ macro_rules! slice_core_methods { () => {
     pub fn rsplitn<F>(&self, n: usize, pred: F) -> RSplitN<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::rsplitn(self, n, pred)
+        RSplitN {
+            inner: GenericSplitN {
+                iter: self.rsplit(pred),
+                count: n
+            }
+        }
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1632,7 +1120,12 @@ macro_rules! slice_core_methods { () => {
     pub fn rsplitn_mut<F>(&mut self, n: usize, pred: F) -> RSplitNMut<T, F>
         where F: FnMut(&T) -> bool
     {
-        SliceExt::rsplitn_mut(self, n, pred)
+        RSplitNMut {
+            inner: GenericSplitN {
+                iter: self.rsplit_mut(pred),
+                count: n
+            }
+        }
     }
 
     /// Returns `true` if the slice contains an element with the given value.
@@ -1648,7 +1141,7 @@ macro_rules! slice_core_methods { () => {
     pub fn contains(&self, x: &T) -> bool
         where T: PartialEq
     {
-        SliceExt::contains(self, x)
+        x.slice_contains(self)
     }
 
     /// Returns `true` if `needle` is a prefix of the slice.
@@ -1675,7 +1168,8 @@ macro_rules! slice_core_methods { () => {
     pub fn starts_with(&self, needle: &[T]) -> bool
         where T: PartialEq
     {
-        SliceExt::starts_with(self, needle)
+        let n = needle.len();
+        self.len() >= n && needle == &self[..n]
     }
 
     /// Returns `true` if `needle` is a suffix of the slice.
@@ -1702,7 +1196,8 @@ macro_rules! slice_core_methods { () => {
     pub fn ends_with(&self, needle: &[T]) -> bool
         where T: PartialEq
     {
-        SliceExt::ends_with(self, needle)
+        let (m, n) = (self.len(), needle.len());
+        m >= n && needle == &self[m-n..]
     }
 
     /// Binary searches this sorted slice for a given element.
@@ -1731,7 +1226,7 @@ macro_rules! slice_core_methods { () => {
     pub fn binary_search(&self, x: &T) -> Result<usize, usize>
         where T: Ord
     {
-        SliceExt::binary_search(self, x)
+        self.binary_search_by(|p| p.cmp(x))
     }
 
     /// Binary searches this sorted slice with a comparator function.
@@ -1767,10 +1262,29 @@ macro_rules! slice_core_methods { () => {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn binary_search_by<'a, F>(&'a self, f: F) -> Result<usize, usize>
+    pub fn binary_search_by<'a, F>(&'a self, mut f: F) -> Result<usize, usize>
         where F: FnMut(&'a T) -> Ordering
     {
-        SliceExt::binary_search_by(self, f)
+        let s = self;
+        let mut size = s.len();
+        if size == 0 {
+            return Err(0);
+        }
+        let mut base = 0usize;
+        while size > 1 {
+            let half = size / 2;
+            let mid = base + half;
+            // mid is always in [0, size), that means mid is >= 0 and < size.
+            // mid >= 0: by definition
+            // mid < size: mid = size / 2 + size / 4 + size / 8 ...
+            let cmp = f(unsafe { s.get_unchecked(mid) });
+            base = if cmp == Greater { base } else { mid };
+            size -= half;
+        }
+        // base is always in [0, size) because base <= mid.
+        let cmp = f(unsafe { s.get_unchecked(base) });
+        if cmp == Equal { Ok(base) } else { Err(base + (cmp == Less) as usize) }
+
     }
 
     /// Binary searches this sorted slice with a key extraction function.
@@ -1805,11 +1319,11 @@ macro_rules! slice_core_methods { () => {
     /// ```
     #[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
     #[inline]
-    pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, f: F) -> Result<usize, usize>
+    pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
         where F: FnMut(&'a T) -> B,
               B: Ord
     {
-        SliceExt::binary_search_by_key(self, b, f)
+        self.binary_search_by(|k| f(k).cmp(b))
     }
 
     /// Sorts the slice, but may not preserve the order of equal elements.
@@ -1843,7 +1357,7 @@ macro_rules! slice_core_methods { () => {
     pub fn sort_unstable(&mut self)
         where T: Ord
     {
-        SliceExt::sort_unstable(self);
+        sort::quicksort(self, |a, b| a.lt(b));
     }
 
     /// Sorts the slice with a comparator function, but may not preserve the order of equal
@@ -1878,10 +1392,10 @@ macro_rules! slice_core_methods { () => {
     /// [pdqsort]: https://github.com/orlp/pdqsort
     #[stable(feature = "sort_unstable", since = "1.20.0")]
     #[inline]
-    pub fn sort_unstable_by<F>(&mut self, compare: F)
+    pub fn sort_unstable_by<F>(&mut self, mut compare: F)
         where F: FnMut(&T, &T) -> Ordering
     {
-        SliceExt::sort_unstable_by(self, compare);
+        sort::quicksort(self, |a, b| compare(a, b) == Ordering::Less);
     }
 
     /// Sorts the slice with a key extraction function, but may not preserve the order of equal
@@ -1910,10 +1424,10 @@ macro_rules! slice_core_methods { () => {
     /// [pdqsort]: https://github.com/orlp/pdqsort
     #[stable(feature = "sort_unstable", since = "1.20.0")]
     #[inline]
-    pub fn sort_unstable_by_key<K, F>(&mut self, f: F)
+    pub fn sort_unstable_by_key<K, F>(&mut self, mut f: F)
         where F: FnMut(&T) -> K, K: Ord
     {
-        SliceExt::sort_unstable_by_key(self, f);
+        sort::quicksort(self, |a, b| f(a).lt(&f(b)));
     }
 
     /// Rotates the slice in-place such that the first `mid` elements of the
@@ -1948,7 +1462,13 @@ macro_rules! slice_core_methods { () => {
    /// ```
     #[stable(feature = "slice_rotate", since = "1.26.0")]
     pub fn rotate_left(&mut self, mid: usize) {
-        SliceExt::rotate_left(self, mid);
+        assert!(mid <= self.len());
+        let k = self.len() - mid;
+
+        unsafe {
+            let p = self.as_mut_ptr();
+            rotate::ptr_rotate(mid, p.offset(mid as isize), k);
+        }
     }
 
     /// Rotates the slice in-place such that the first `self.len() - k`
@@ -1983,7 +1503,13 @@ macro_rules! slice_core_methods { () => {
     /// ```
     #[stable(feature = "slice_rotate", since = "1.26.0")]
     pub fn rotate_right(&mut self, k: usize) {
-        SliceExt::rotate_right(self, k);
+        assert!(k <= self.len());
+        let mid = self.len() - k;
+
+        unsafe {
+            let p = self.as_mut_ptr();
+            rotate::ptr_rotate(mid, p.offset(mid as isize), k);
+        }
     }
 
     /// Copies the elements from `src` into `self`.
@@ -2040,7 +1566,17 @@ macro_rules! slice_core_methods { () => {
     /// [`split_at_mut`]: #method.split_at_mut
     #[stable(feature = "clone_from_slice", since = "1.7.0")]
     pub fn clone_from_slice(&mut self, src: &[T]) where T: Clone {
-        SliceExt::clone_from_slice(self, src)
+        assert!(self.len() == src.len(),
+                "destination and source slices have different lengths");
+        // NOTE: We need to explicitly slice them to the same length
+        // for bounds checking to be elided, and the optimizer will
+        // generate memcpy for simple cases (for example T = u8).
+        let len = self.len();
+        let src = &src[..len];
+        for i in 0..len {
+            self[i].clone_from(&src[i]);
+        }
+
     }
 
     /// Copies all elements from `src` into `self`, using a memcpy.
@@ -2096,7 +1632,12 @@ macro_rules! slice_core_methods { () => {
     /// [`split_at_mut`]: #method.split_at_mut
     #[stable(feature = "copy_from_slice", since = "1.9.0")]
     pub fn copy_from_slice(&mut self, src: &[T]) where T: Copy {
-        SliceExt::copy_from_slice(self, src)
+        assert!(self.len() == src.len(),
+                "destination and source slices have different lengths");
+        unsafe {
+            ptr::copy_nonoverlapping(
+                src.as_ptr(), self.as_mut_ptr(), self.len());
+        }
     }
 
     /// Swaps all elements in `self` with those in `other`.
@@ -2148,22 +1689,18 @@ macro_rules! slice_core_methods { () => {
     /// [`split_at_mut`]: #method.split_at_mut
     #[stable(feature = "swap_with_slice", since = "1.27.0")]
     pub fn swap_with_slice(&mut self, other: &mut [T]) {
-        SliceExt::swap_with_slice(self, other)
+        assert!(self.len() == other.len(),
+                "destination and source slices have different lengths");
+        unsafe {
+            ptr::swap_nonoverlapping(
+                self.as_mut_ptr(), other.as_mut_ptr(), self.len());
+        }
     }
-}}
-
-#[lang = "slice"]
-#[cfg(not(test))]
-#[cfg(not(stage0))]
-impl<T> [T] {
-    slice_core_methods!();
 }
 
-// FIXME: remove (inline) this macro
-// when updating to a bootstrap compiler that has the new lang items.
-#[cfg_attr(stage0, macro_export)]
-#[unstable(feature = "core_slice_ext", issue = "32110")]
-macro_rules! slice_u8_core_methods { () => {
+#[lang = "slice_u8"]
+#[cfg(not(test))]
+impl [u8] {
     /// Checks if all bytes in this slice are within the ASCII range.
     #[stable(feature = "ascii_methods_on_intrinsics", since = "1.23.0")]
     #[inline]
@@ -2217,13 +1754,7 @@ macro_rules! slice_u8_core_methods { () => {
             byte.make_ascii_lowercase();
         }
     }
-}}
 
-#[lang = "slice_u8"]
-#[cfg(not(test))]
-#[cfg(not(stage0))]
-impl [u8] {
-    slice_u8_core_methods!();
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index df7b2f25a86..82bead0ab46 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -2097,119 +2097,7 @@ mod traits {
             (..self.end+1).index_mut(slice)
         }
     }
-
-}
-
-public_in_stage0! {
-{
-/// Methods for string slices
-#[allow(missing_docs)]
-#[doc(hidden)]
-#[unstable(feature = "core_str_ext",
-           reason = "stable interface provided by `impl str` in later crates",
-           issue = "32110")]
 }
-trait StrExt {
-    // NB there are no docs here are they're all located on the StrExt trait in
-    // liballoc, not here.
-
-    #[stable(feature = "core", since = "1.6.0")]
-    fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn chars(&self) -> Chars;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn bytes(&self) -> Bytes;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn char_indices(&self) -> CharIndices;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
-        where P::Searcher: ReverseSearcher<'a>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
-        where P::Searcher: ReverseSearcher<'a>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
-        where P::Searcher: ReverseSearcher<'a>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
-        where P::Searcher: ReverseSearcher<'a>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
-        where P::Searcher: ReverseSearcher<'a>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn lines(&self) -> Lines;
-    #[stable(feature = "core", since = "1.6.0")]
-    #[rustc_deprecated(since = "1.6.0", reason = "use lines() instead now")]
-    #[allow(deprecated)]
-    fn lines_any(&self) -> LinesAny;
-    #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output>;
-    #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output>;
-    #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output;
-    #[stable(feature = "str_checked_slicing", since = "1.20.0")]
-    unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output;
-    #[stable(feature = "core", since = "1.6.0")]
-    unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str;
-    #[stable(feature = "core", since = "1.6.0")]
-    unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
-        where P::Searcher: ReverseSearcher<'a>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: DoubleEndedSearcher<'a>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: ReverseSearcher<'a>;
-    #[stable(feature = "is_char_boundary", since = "1.9.0")]
-    fn is_char_boundary(&self, index: usize) -> bool;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn as_bytes(&self) -> &[u8];
-    #[stable(feature = "str_mut_extras", since = "1.20.0")]
-    unsafe fn as_bytes_mut(&mut self) -> &mut [u8];
-    #[stable(feature = "core", since = "1.6.0")]
-    fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
-        where P::Searcher: ReverseSearcher<'a>;
-    fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_at(&self, mid: usize) -> (&str, &str);
-    #[stable(feature = "core", since = "1.6.0")]
-    fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str);
-    #[stable(feature = "core", since = "1.6.0")]
-    fn as_ptr(&self) -> *const u8;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn len(&self) -> usize;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn is_empty(&self) -> bool;
-    #[stable(feature = "core", since = "1.6.0")]
-    fn parse<T: FromStr>(&self) -> Result<T, T::Err>;
-    #[stable(feature = "split_whitespace", since = "1.1.0")]
-    fn split_whitespace<'a>(&'a self) -> SplitWhitespace<'a>;
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim(&self) -> &str;
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim_left(&self) -> &str;
-    #[stable(feature = "rust1", since = "1.0.0")]
-    fn trim_right(&self) -> &str;
-}}
 
 // truncate `&str` to length at most equal to `max`
 // return `true` if it were truncated, and the new str.
@@ -2255,307 +2143,9 @@ fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
            index, ch, char_range, s_trunc, ellipsis);
 }
 
-#[stable(feature = "core", since = "1.6.0")]
-impl StrExt for str {
-    #[inline]
-    fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
-        pat.is_contained_in(self)
-    }
-
-    #[inline]
-    fn chars(&self) -> Chars {
-        Chars{iter: self.as_bytes().iter()}
-    }
-
-    #[inline]
-    fn bytes(&self) -> Bytes {
-        Bytes(self.as_bytes().iter().cloned())
-    }
-
-    #[inline]
-    fn char_indices(&self) -> CharIndices {
-        CharIndices { front_offset: 0, iter: self.chars() }
-    }
-
-    #[inline]
-    fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
-        Split(SplitInternal {
-            start: 0,
-            end: self.len(),
-            matcher: pat.into_searcher(self),
-            allow_trailing_empty: true,
-            finished: false,
-        })
-    }
-
-    #[inline]
-    fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        RSplit(self.split(pat).0)
-    }
-
-    #[inline]
-    fn splitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> SplitN<'a, P> {
-        SplitN(SplitNInternal {
-            iter: self.split(pat).0,
-            count,
-        })
-    }
-
-    #[inline]
-    fn rsplitn<'a, P: Pattern<'a>>(&'a self, count: usize, pat: P) -> RSplitN<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        RSplitN(self.splitn(count, pat).0)
-    }
-
-    #[inline]
-    fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
-        SplitTerminator(SplitInternal {
-            allow_trailing_empty: false,
-            ..self.split(pat).0
-        })
-    }
-
-    #[inline]
-    fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        RSplitTerminator(self.split_terminator(pat).0)
-    }
-
-    #[inline]
-    fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
-        Matches(MatchesInternal(pat.into_searcher(self)))
-    }
-
-    #[inline]
-    fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        RMatches(self.matches(pat).0)
-    }
-
-    #[inline]
-    fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
-        MatchIndices(MatchIndicesInternal(pat.into_searcher(self)))
-    }
-
-    #[inline]
-    fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        RMatchIndices(self.match_indices(pat).0)
-    }
-    #[inline]
-    fn lines(&self) -> Lines {
-        Lines(self.split_terminator('\n').map(LinesAnyMap))
-    }
-
-    #[inline]
-    #[allow(deprecated)]
-    fn lines_any(&self) -> LinesAny {
-        LinesAny(self.lines())
-    }
-
-    #[inline]
-    fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
-        i.get(self)
-    }
-
-    #[inline]
-    fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
-        i.get_mut(self)
-    }
-
-    #[inline]
-    unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
-        i.get_unchecked(self)
-    }
-
-    #[inline]
-    unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
-        i.get_unchecked_mut(self)
-    }
-
-    #[inline]
-    unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
-        (begin..end).get_unchecked(self)
-    }
-
-    #[inline]
-    unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
-        (begin..end).get_unchecked_mut(self)
-    }
-
-    #[inline]
-    fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
-        pat.is_prefix_of(self)
-    }
-
-    #[inline]
-    fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        pat.is_suffix_of(self)
-    }
-
-    #[inline]
-    fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: DoubleEndedSearcher<'a>
-    {
-        let mut i = 0;
-        let mut j = 0;
-        let mut matcher = pat.into_searcher(self);
-        if let Some((a, b)) = matcher.next_reject() {
-            i = a;
-            j = b; // Remember earliest known match, correct it below if
-                   // last match is different
-        }
-        if let Some((_, b)) = matcher.next_reject_back() {
-            j = b;
-        }
-        unsafe {
-            // Searcher is known to return valid indices
-            self.slice_unchecked(i, j)
-        }
-    }
-
-    #[inline]
-    fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
-        let mut i = self.len();
-        let mut matcher = pat.into_searcher(self);
-        if let Some((a, _)) = matcher.next_reject() {
-            i = a;
-        }
-        unsafe {
-            // Searcher is known to return valid indices
-            self.slice_unchecked(i, self.len())
-        }
-    }
-
-    #[inline]
-    fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        let mut j = 0;
-        let mut matcher = pat.into_searcher(self);
-        if let Some((_, b)) = matcher.next_reject_back() {
-            j = b;
-        }
-        unsafe {
-            // Searcher is known to return valid indices
-            self.slice_unchecked(0, j)
-        }
-    }
-
-    #[inline]
-    fn is_char_boundary(&self, index: usize) -> bool {
-        // 0 and len are always ok.
-        // Test for 0 explicitly so that it can optimize out the check
-        // easily and skip reading string data for that case.
-        if index == 0 || index == self.len() { return true; }
-        match self.as_bytes().get(index) {
-            None => false,
-            // This is bit magic equivalent to: b < 128 || b >= 192
-            Some(&b) => (b as i8) >= -0x40,
-        }
-    }
-
-    #[inline]
-    fn as_bytes(&self) -> &[u8] {
-        unsafe { &*(self as *const str as *const [u8]) }
-    }
-
-    #[inline]
-    unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
-        &mut *(self as *mut str as *mut [u8])
-    }
-
-    fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
-        pat.into_searcher(self).next_match().map(|(i, _)| i)
-    }
-
-    fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
-        where P::Searcher: ReverseSearcher<'a>
-    {
-        pat.into_searcher(self).next_match_back().map(|(i, _)| i)
-    }
-
-    fn find_str<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
-        self.find(pat)
-    }
-
-    #[inline]
-    fn split_at(&self, mid: usize) -> (&str, &str) {
-        // is_char_boundary checks that the index is in [0, .len()]
-        if self.is_char_boundary(mid) {
-            unsafe {
-                (self.slice_unchecked(0, mid),
-                 self.slice_unchecked(mid, self.len()))
-            }
-        } else {
-            slice_error_fail(self, 0, mid)
-        }
-    }
-
-    fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
-        // is_char_boundary checks that the index is in [0, .len()]
-        if self.is_char_boundary(mid) {
-            let len = self.len();
-            let ptr = self.as_ptr() as *mut u8;
-            unsafe {
-                (from_raw_parts_mut(ptr, mid),
-                 from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
-            }
-        } else {
-            slice_error_fail(self, 0, mid)
-        }
-    }
-
-    #[inline]
-    fn as_ptr(&self) -> *const u8 {
-        self as *const str as *const u8
-    }
-
-    #[inline]
-    fn len(&self) -> usize {
-        self.as_bytes().len()
-    }
-
-    #[inline]
-    fn is_empty(&self) -> bool { self.len() == 0 }
-
-    #[inline]
-    fn parse<T: FromStr>(&self) -> Result<T, T::Err> { FromStr::from_str(self) }
-
-    #[inline]
-    fn split_whitespace(&self) -> SplitWhitespace {
-        SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
-    }
-
-    #[inline]
-    fn trim(&self) -> &str {
-        self.trim_matches(|c: char| c.is_whitespace())
-    }
-
-    #[inline]
-    fn trim_left(&self) -> &str {
-        self.trim_left_matches(|c: char| c.is_whitespace())
-    }
-
-    #[inline]
-    fn trim_right(&self) -> &str {
-        self.trim_right_matches(|c: char| c.is_whitespace())
-    }
-}
-
-// FIXME: remove (inline) this macro and the SliceExt trait
-// when updating to a bootstrap compiler that has the new lang items.
-#[cfg_attr(stage0, macro_export)]
-#[unstable(feature = "core_str_ext", issue = "32110")]
-macro_rules! str_core_methods { () => {
+#[lang = "str"]
+#[cfg(not(test))]
+impl str {
     /// Returns the length of `self`.
     ///
     /// This length is in bytes, not [`char`]s or graphemes. In other words,
@@ -2577,7 +2167,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn len(&self) -> usize {
-        StrExt::len(self)
+        self.as_bytes().len()
     }
 
     /// Returns `true` if `self` has a length of zero bytes.
@@ -2596,7 +2186,7 @@ macro_rules! str_core_methods { () => {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn is_empty(&self) -> bool {
-        StrExt::is_empty(self)
+        self.len() == 0
     }
 
     /// Checks that `index`-th byte lies at the start and/or end of a
@@ -2626,7 +2216,15 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "is_char_boundary", since = "1.9.0")]
     #[inline]
     pub fn is_char_boundary(&self, index: usize) -> bool {
-        StrExt::is_char_boundary(self, index)
+        // 0 and len are always ok.
+        // Test for 0 explicitly so that it can optimize out the check
+        // easily and skip reading string data for that case.
+        if index == 0 || index == self.len() { return true; }
+        match self.as_bytes().get(index) {
+            None => false,
+            // This is bit magic equivalent to: b < 128 || b >= 192
+            Some(&b) => (b as i8) >= -0x40,
+        }
     }
 
     /// Converts a string slice to a byte slice. To convert the byte slice back
@@ -2645,7 +2243,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline(always)]
     pub fn as_bytes(&self) -> &[u8] {
-        StrExt::as_bytes(self)
+        unsafe { &*(self as *const str as *const [u8]) }
     }
 
     /// Converts a mutable string slice to a mutable byte slice. To convert the
@@ -2684,7 +2282,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_mut_extras", since = "1.20.0")]
     #[inline(always)]
     pub unsafe fn as_bytes_mut(&mut self) -> &mut [u8] {
-        StrExt::as_bytes_mut(self)
+        &mut *(self as *mut str as *mut [u8])
     }
 
     /// Converts a string slice to a raw pointer.
@@ -2706,7 +2304,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn as_ptr(&self) -> *const u8 {
-        StrExt::as_ptr(self)
+        self as *const str as *const u8
     }
 
     /// Returns a subslice of `str`.
@@ -2733,7 +2331,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
     #[inline]
     pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
-        StrExt::get(self, i)
+        i.get(self)
     }
 
     /// Returns a mutable subslice of `str`.
@@ -2767,7 +2365,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
     #[inline]
     pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
-        StrExt::get_mut(self, i)
+        i.get_mut(self)
     }
 
     /// Returns a unchecked subslice of `str`.
@@ -2799,7 +2397,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
     #[inline]
     pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
-        StrExt::get_unchecked(self, i)
+        i.get_unchecked(self)
     }
 
     /// Returns a mutable, unchecked subslice of `str`.
@@ -2831,7 +2429,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_checked_slicing", since = "1.20.0")]
     #[inline]
     pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
-        StrExt::get_unchecked_mut(self, i)
+        i.get_unchecked_mut(self)
     }
 
     /// Creates a string slice from another string slice, bypassing safety
@@ -2880,7 +2478,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub unsafe fn slice_unchecked(&self, begin: usize, end: usize) -> &str {
-        StrExt::slice_unchecked(self, begin, end)
+        (begin..end).get_unchecked(self)
     }
 
     /// Creates a string slice from another string slice, bypassing safety
@@ -2910,7 +2508,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_slice_mut", since = "1.5.0")]
     #[inline]
     pub unsafe fn slice_mut_unchecked(&mut self, begin: usize, end: usize) -> &mut str {
-        StrExt::slice_mut_unchecked(self, begin, end)
+        (begin..end).get_unchecked_mut(self)
     }
 
     /// Divide one string slice into two at an index.
@@ -2946,7 +2544,15 @@ macro_rules! str_core_methods { () => {
     #[inline]
     #[stable(feature = "str_split_at", since = "1.4.0")]
     pub fn split_at(&self, mid: usize) -> (&str, &str) {
-        StrExt::split_at(self, mid)
+        // is_char_boundary checks that the index is in [0, .len()]
+        if self.is_char_boundary(mid) {
+            unsafe {
+                (self.slice_unchecked(0, mid),
+                 self.slice_unchecked(mid, self.len()))
+            }
+        } else {
+            slice_error_fail(self, 0, mid)
+        }
     }
 
     /// Divide one mutable string slice into two at an index.
@@ -2983,7 +2589,17 @@ macro_rules! str_core_methods { () => {
     #[inline]
     #[stable(feature = "str_split_at", since = "1.4.0")]
     pub fn split_at_mut(&mut self, mid: usize) -> (&mut str, &mut str) {
-        StrExt::split_at_mut(self, mid)
+        // is_char_boundary checks that the index is in [0, .len()]
+        if self.is_char_boundary(mid) {
+            let len = self.len();
+            let ptr = self.as_ptr() as *mut u8;
+            unsafe {
+                (from_raw_parts_mut(ptr, mid),
+                 from_raw_parts_mut(ptr.offset(mid as isize), len - mid))
+            }
+        } else {
+            slice_error_fail(self, 0, mid)
+        }
     }
 
     /// Returns an iterator over the [`char`]s of a string slice.
@@ -3035,8 +2651,9 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn chars(&self) -> Chars {
-        StrExt::chars(self)
+        Chars{iter: self.as_bytes().iter()}
     }
+
     /// Returns an iterator over the [`char`]s of a string slice, and their
     /// positions.
     ///
@@ -3091,7 +2708,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn char_indices(&self) -> CharIndices {
-        StrExt::char_indices(self)
+        CharIndices { front_offset: 0, iter: self.chars() }
     }
 
     /// An iterator over the bytes of a string slice.
@@ -3116,7 +2733,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn bytes(&self) -> Bytes {
-        StrExt::bytes(self)
+        Bytes(self.as_bytes().iter().cloned())
     }
 
     /// Split a string slice by whitespace.
@@ -3156,7 +2773,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "split_whitespace", since = "1.1.0")]
     #[inline]
     pub fn split_whitespace(&self) -> SplitWhitespace {
-        StrExt::split_whitespace(self)
+        SplitWhitespace { inner: self.split(IsWhitespace).filter(IsNotEmpty) }
     }
 
     /// An iterator over the lines of a string, as string slices.
@@ -3198,7 +2815,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn lines(&self) -> Lines {
-        StrExt::lines(self)
+        Lines(self.split_terminator('\n').map(LinesAnyMap))
     }
 
     /// An iterator over the lines of a string.
@@ -3207,7 +2824,7 @@ macro_rules! str_core_methods { () => {
     #[inline]
     #[allow(deprecated)]
     pub fn lines_any(&self) -> LinesAny {
-        StrExt::lines_any(self)
+        LinesAny(self.lines())
     }
 
     /// Returns an iterator of `u16` over the string encoded as UTF-16.
@@ -3226,7 +2843,7 @@ macro_rules! str_core_methods { () => {
     /// ```
     #[stable(feature = "encode_utf16", since = "1.8.0")]
     pub fn encode_utf16(&self) -> EncodeUtf16 {
-        EncodeUtf16::new(self)
+        EncodeUtf16 { chars: self.chars(), extra: 0 }
     }
 
     /// Returns `true` if the given pattern matches a sub-slice of
@@ -3247,7 +2864,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn contains<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
-        StrExt::contains(self, pat)
+        pat.is_contained_in(self)
     }
 
     /// Returns `true` if the given pattern matches a prefix of this
@@ -3267,7 +2884,7 @@ macro_rules! str_core_methods { () => {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn starts_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool {
-        StrExt::starts_with(self, pat)
+        pat.is_prefix_of(self)
     }
 
     /// Returns `true` if the given pattern matches a suffix of this
@@ -3289,7 +2906,7 @@ macro_rules! str_core_methods { () => {
     pub fn ends_with<'a, P: Pattern<'a>>(&'a self, pat: P) -> bool
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::ends_with(self, pat)
+        pat.is_suffix_of(self)
     }
 
     /// Returns the byte index of the first character of this string slice that
@@ -3337,7 +2954,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn find<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize> {
-        StrExt::find(self, pat)
+        pat.into_searcher(self).next_match().map(|(i, _)| i)
     }
 
     /// Returns the byte index of the last character of this string slice that
@@ -3384,7 +3001,7 @@ macro_rules! str_core_methods { () => {
     pub fn rfind<'a, P: Pattern<'a>>(&'a self, pat: P) -> Option<usize>
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::rfind(self, pat)
+        pat.into_searcher(self).next_match_back().map(|(i, _)| i)
     }
 
     /// An iterator over substrings of this string slice, separated by
@@ -3496,7 +3113,13 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn split<'a, P: Pattern<'a>>(&'a self, pat: P) -> Split<'a, P> {
-        StrExt::split(self, pat)
+        Split(SplitInternal {
+            start: 0,
+            end: self.len(),
+            matcher: pat.into_searcher(self),
+            allow_trailing_empty: true,
+            finished: false,
+        })
     }
 
     /// An iterator over substrings of the given string slice, separated by
@@ -3548,7 +3171,7 @@ macro_rules! str_core_methods { () => {
     pub fn rsplit<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplit<'a, P>
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::rsplit(self, pat)
+        RSplit(self.split(pat).0)
     }
 
     /// An iterator over substrings of the given string slice, separated by
@@ -3593,7 +3216,10 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn split_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> SplitTerminator<'a, P> {
-        StrExt::split_terminator(self, pat)
+        SplitTerminator(SplitInternal {
+            allow_trailing_empty: false,
+            ..self.split(pat).0
+        })
     }
 
     /// An iterator over substrings of `self`, separated by characters
@@ -3639,7 +3265,7 @@ macro_rules! str_core_methods { () => {
     pub fn rsplit_terminator<'a, P: Pattern<'a>>(&'a self, pat: P) -> RSplitTerminator<'a, P>
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::rsplit_terminator(self, pat)
+        RSplitTerminator(self.split_terminator(pat).0)
     }
 
     /// An iterator over substrings of the given string slice, separated by a
@@ -3690,7 +3316,10 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn splitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> SplitN<'a, P> {
-        StrExt::splitn(self, n, pat)
+        SplitN(SplitNInternal {
+            iter: self.split(pat).0,
+            count: n,
+        })
     }
 
     /// An iterator over substrings of this string slice, separated by a
@@ -3740,7 +3369,7 @@ macro_rules! str_core_methods { () => {
     pub fn rsplitn<'a, P: Pattern<'a>>(&'a self, n: usize, pat: P) -> RSplitN<'a, P>
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::rsplitn(self, n, pat)
+        RSplitN(self.splitn(n, pat).0)
     }
 
     /// An iterator over the disjoint matches of a pattern within the given string
@@ -3779,7 +3408,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_matches", since = "1.2.0")]
     #[inline]
     pub fn matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> Matches<'a, P> {
-        StrExt::matches(self, pat)
+        Matches(MatchesInternal(pat.into_searcher(self)))
     }
 
     /// An iterator over the disjoint matches of a pattern within this string slice,
@@ -3818,7 +3447,7 @@ macro_rules! str_core_methods { () => {
     pub fn rmatches<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatches<'a, P>
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::rmatches(self, pat)
+        RMatches(self.matches(pat).0)
     }
 
     /// An iterator over the disjoint matches of a pattern within this string
@@ -3862,7 +3491,7 @@ macro_rules! str_core_methods { () => {
     #[stable(feature = "str_match_indices", since = "1.5.0")]
     #[inline]
     pub fn match_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> MatchIndices<'a, P> {
-        StrExt::match_indices(self, pat)
+        MatchIndices(MatchIndicesInternal(pat.into_searcher(self)))
     }
 
     /// An iterator over the disjoint matches of a pattern within `self`,
@@ -3907,7 +3536,7 @@ macro_rules! str_core_methods { () => {
     pub fn rmatch_indices<'a, P: Pattern<'a>>(&'a self, pat: P) -> RMatchIndices<'a, P>
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::rmatch_indices(self, pat)
+        RMatchIndices(self.match_indices(pat).0)
     }
 
     /// Returns a string slice with leading and trailing whitespace removed.
@@ -3926,7 +3555,7 @@ macro_rules! str_core_methods { () => {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn trim(&self) -> &str {
-        StrExt::trim(self)
+        self.trim_matches(|c: char| c.is_whitespace())
     }
 
     /// Returns a string slice with leading whitespace removed.
@@ -3962,7 +3591,7 @@ macro_rules! str_core_methods { () => {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn trim_left(&self) -> &str {
-        StrExt::trim_left(self)
+        self.trim_left_matches(|c: char| c.is_whitespace())
     }
 
     /// Returns a string slice with trailing whitespace removed.
@@ -3998,7 +3627,7 @@ macro_rules! str_core_methods { () => {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn trim_right(&self) -> &str {
-        StrExt::trim_right(self)
+        self.trim_right_matches(|c: char| c.is_whitespace())
     }
 
     /// Returns a string slice with all prefixes and suffixes that match a
@@ -4030,7 +3659,21 @@ macro_rules! str_core_methods { () => {
     pub fn trim_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
         where P::Searcher: DoubleEndedSearcher<'a>
     {
-        StrExt::trim_matches(self, pat)
+        let mut i = 0;
+        let mut j = 0;
+        let mut matcher = pat.into_searcher(self);
+        if let Some((a, b)) = matcher.next_reject() {
+            i = a;
+            j = b; // Remember earliest known match, correct it below if
+                   // last match is different
+        }
+        if let Some((_, b)) = matcher.next_reject_back() {
+            j = b;
+        }
+        unsafe {
+            // Searcher is known to return valid indices
+            self.slice_unchecked(i, j)
+        }
     }
 
     /// Returns a string slice with all prefixes that match a pattern
@@ -4061,7 +3704,15 @@ macro_rules! str_core_methods { () => {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn trim_left_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str {
-        StrExt::trim_left_matches(self, pat)
+        let mut i = self.len();
+        let mut matcher = pat.into_searcher(self);
+        if let Some((a, _)) = matcher.next_reject() {
+            i = a;
+        }
+        unsafe {
+            // Searcher is known to return valid indices
+            self.slice_unchecked(i, self.len())
+        }
     }
 
     /// Returns a string slice with all suffixes that match a pattern
@@ -4100,7 +3751,15 @@ macro_rules! str_core_methods { () => {
     pub fn trim_right_matches<'a, P: Pattern<'a>>(&'a self, pat: P) -> &'a str
         where P::Searcher: ReverseSearcher<'a>
     {
-        StrExt::trim_right_matches(self, pat)
+        let mut j = 0;
+        let mut matcher = pat.into_searcher(self);
+        if let Some((_, b)) = matcher.next_reject_back() {
+            j = b;
+        }
+        unsafe {
+            // Searcher is known to return valid indices
+            self.slice_unchecked(0, j)
+        }
     }
 
     /// Parses this string slice into another type.
@@ -4150,7 +3809,7 @@ macro_rules! str_core_methods { () => {
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn parse<F: FromStr>(&self) -> Result<F, F::Err> {
-        StrExt::parse(self)
+        FromStr::from_str(self)
     }
 
     /// Checks if all characters in this string are within the ASCII range.
@@ -4220,16 +3879,8 @@ macro_rules! str_core_methods { () => {
         let me = unsafe { self.as_bytes_mut() };
         me.make_ascii_lowercase()
     }
-}}
-
-#[lang = "str"]
-#[cfg(not(test))]
-#[cfg(not(stage0))]
-impl str {
-    str_core_methods!();
 }
 
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl AsRef<[u8]> for str {
     #[inline]
@@ -4332,17 +3983,6 @@ pub struct EncodeUtf16<'a> {
     extra: u16,
 }
 
-// FIXME: remove (inline) this method
-// when updating to a bootstrap compiler that has the new lang items.
-// For grepping purpose: #[cfg(stage0)]
-impl<'a> EncodeUtf16<'a> {
-    #[unstable(feature = "core_str_ext", issue = "32110")]
-    #[doc(hidden)]
-    pub fn new(s: &'a str) -> Self {
-        EncodeUtf16 { chars: s.chars(), extra: 0 }
-    }
-}
-
 #[stable(feature = "collection_debug", since = "1.17.0")]
 impl<'a> fmt::Debug for EncodeUtf16<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index 7fb4b503c01..8c481338945 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -41,7 +41,6 @@
 #![feature(try_from)]
 #![feature(try_trait)]
 #![feature(exact_chunks)]
-#![cfg_attr(stage0, feature(atomic_nand))]
 #![feature(reverse_bits)]
 #![feature(inclusive_range_methods)]
 #![feature(iterator_find_map)]
diff --git a/src/libcore/tests/num/uint_macros.rs b/src/libcore/tests/num/uint_macros.rs
index 257f6ea20d4..ca6906f7310 100644
--- a/src/libcore/tests/num/uint_macros.rs
+++ b/src/libcore/tests/num/uint_macros.rs
@@ -98,7 +98,6 @@ mod tests {
     }
 
     #[test]
-    #[cfg(not(stage0))]
     fn test_reverse_bits() {
         assert_eq!(A.reverse_bits().reverse_bits(), A);
         assert_eq!(B.reverse_bits().reverse_bits(), B);
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index ac6ff6831ad..bbd684982fa 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -46,7 +46,6 @@
 #![feature(core_intrinsics)]
 #![feature(drain_filter)]
 #![feature(entry_or_default)]
-#![cfg_attr(stage0, feature(dyn_trait))]
 #![feature(from_ref)]
 #![feature(fs_read_write)]
 #![feature(iterator_find_map)]
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 0b1729294d8..a162ef36a60 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -240,11 +240,11 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
     });
 
     // Also dump the inference graph constraints as a graphviz file.
-    let _: io::Result<()> = do_catch! {{
+    let _: io::Result<()> = do catch {
         let mut file =
             pretty::create_dump_file(infcx.tcx, "regioncx.dot", None, "nll", &0, source)?;
         regioncx.dump_graphviz(&mut file)?;
-    }};
+    };
 }
 
 fn dump_annotation<'a, 'gcx, 'tcx>(
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index ecced1b8168..d9b6c406e20 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -24,7 +24,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(const_fn)]
 #![feature(core_intrinsics)]
 #![feature(decl_macro)]
-#![cfg_attr(stage0, feature(dyn_trait))]
 #![feature(fs_read_write)]
 #![feature(macro_vis_matcher)]
 #![feature(exhaustive_patterns)]
@@ -34,7 +33,7 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 #![feature(crate_visibility_modifier)]
 #![feature(never_type)]
 #![feature(specialization)]
-#![cfg_attr(stage0, feature(try_trait))]
+#![feature(try_trait)]
 
 extern crate arena;
 #[macro_use]
@@ -54,16 +53,6 @@ extern crate log_settings;
 extern crate rustc_apfloat;
 extern crate byteorder;
 
-#[cfg(stage0)]
-macro_rules! do_catch {
-  ($t:expr) => { (|| ::std::ops::Try::from_ok($t) )() }
-}
-
-#[cfg(not(stage0))]
-macro_rules! do_catch {
-  ($t:expr) => { do catch { $t } }
-}
-
 mod diagnostics;
 
 mod borrow_check;
diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs
index 9d74ad0830f..9e1ce9b2851 100644
--- a/src/librustc_mir/util/pretty.rs
+++ b/src/librustc_mir/util/pretty.rs
@@ -137,7 +137,7 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
 ) where
     F: FnMut(PassWhere, &mut dyn Write) -> io::Result<()>,
 {
-    let _: io::Result<()> = do_catch! {{
+    let _: io::Result<()> = do catch {
         let mut file = create_dump_file(tcx, "mir", pass_num, pass_name, disambiguator, source)?;
         writeln!(file, "// MIR for `{}`", node_path)?;
         writeln!(file, "// source = {:?}", source)?;
@@ -150,14 +150,14 @@ fn dump_matched_mir_node<'a, 'gcx, 'tcx, F>(
         extra_data(PassWhere::BeforeCFG, &mut file)?;
         write_mir_fn(tcx, source, mir, &mut extra_data, &mut file)?;
         extra_data(PassWhere::AfterCFG, &mut file)?;
-    }};
+    };
 
     if tcx.sess.opts.debugging_opts.dump_mir_graphviz {
-        let _: io::Result<()> = do_catch! {{
+        let _: io::Result<()> = do catch {
             let mut file =
                 create_dump_file(tcx, "dot", pass_num, pass_name, disambiguator, source)?;
             write_mir_fn_graphviz(tcx, source.def_id, mir, &mut file)?;
-        }};
+        };
     }
 }
 
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 350b53a406b..ef79517d06a 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -71,8 +71,6 @@ This API is completely unstable and subject to change.
 
 #![allow(non_camel_case_types)]
 
-#![cfg_attr(stage0, feature(dyn_trait))]
-
 #![feature(box_patterns)]
 #![feature(box_syntax)]
 #![feature(crate_visibility_modifier)]
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 3ce95c78a90..1b713a446a0 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -13,8 +13,6 @@
        html_root_url = "https://doc.rust-lang.org/nightly/",
        html_playground_url = "https://play.rust-lang.org/")]
 
-#![cfg_attr(stage0, feature(dyn_trait))]
-
 #![feature(ascii_ctype)]
 #![feature(rustc_private)]
 #![feature(box_patterns)]
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index a8578404467..78d3d6d5e60 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -17,7 +17,6 @@
 #[doc(inline)] pub use alloc_system::System;
 #[doc(inline)] pub use core::alloc::*;
 
-#[cfg(not(stage0))]
 #[cfg(not(test))]
 #[doc(hidden)]
 #[lang = "oom"]
@@ -43,13 +42,6 @@ pub mod __default_lib_allocator {
         System.alloc(layout) as *mut u8
     }
 
-    #[cfg(stage0)]
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rdl_oom() -> ! {
-        super::oom()
-    }
-
     #[no_mangle]
     #[rustc_std_internal_symbol]
     pub unsafe extern fn __rdl_dealloc(ptr: *mut u8,
@@ -74,57 +66,4 @@ pub mod __default_lib_allocator {
         let layout = Layout::from_size_align_unchecked(size, align);
         System.alloc_zeroed(layout) as *mut u8
     }
-
-    #[cfg(stage0)]
-    pub mod stage0 {
-        #[no_mangle]
-        #[rustc_std_internal_symbol]
-        pub unsafe extern fn __rdl_usable_size(_layout: *const u8,
-                                               _min: *mut usize,
-                                               _max: *mut usize) {
-            unimplemented!()
-        }
-
-        #[no_mangle]
-        #[rustc_std_internal_symbol]
-        pub unsafe extern fn __rdl_alloc_excess(_size: usize,
-                                                _align: usize,
-                                                _excess: *mut usize,
-                                                _err: *mut u8) -> *mut u8 {
-            unimplemented!()
-        }
-
-        #[no_mangle]
-        #[rustc_std_internal_symbol]
-        pub unsafe extern fn __rdl_realloc_excess(_ptr: *mut u8,
-                                                  _old_size: usize,
-                                                  _old_align: usize,
-                                                  _new_size: usize,
-                                                  _new_align: usize,
-                                                  _excess: *mut usize,
-                                                  _err: *mut u8) -> *mut u8 {
-            unimplemented!()
-        }
-
-        #[no_mangle]
-        #[rustc_std_internal_symbol]
-        pub unsafe extern fn __rdl_grow_in_place(_ptr: *mut u8,
-                                                 _old_size: usize,
-                                                 _old_align: usize,
-                                                 _new_size: usize,
-                                                 _new_align: usize) -> u8 {
-            unimplemented!()
-        }
-
-        #[no_mangle]
-        #[rustc_std_internal_symbol]
-        pub unsafe extern fn __rdl_shrink_in_place(_ptr: *mut u8,
-                                                   _old_size: usize,
-                                                   _old_align: usize,
-                                                   _new_size: usize,
-                                                   _new_align: usize) -> u8 {
-            unimplemented!()
-        }
-
-    }
 }
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 7314d32b020..ae30321f46d 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -19,14 +19,8 @@
 #![allow(missing_docs)]
 
 #[cfg(not(test))]
-#[cfg(stage0)]
-use core::num::Float;
-#[cfg(not(test))]
 use intrinsics;
 #[cfg(not(test))]
-#[cfg(stage0)]
-use num::FpCategory;
-#[cfg(not(test))]
 use sys::cmath;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -41,12 +35,8 @@ pub use core::f32::{MIN, MIN_POSITIVE, MAX};
 pub use core::f32::consts;
 
 #[cfg(not(test))]
-#[cfg_attr(stage0, lang = "f32")]
-#[cfg_attr(not(stage0), lang = "f32_runtime")]
+#[lang = "f32_runtime"]
 impl f32 {
-    #[cfg(stage0)]
-    f32_core_methods!();
-
     /// Returns the largest integer less than or equal to a number.
     ///
     /// # Examples
diff --git a/src/libstd/f64.rs b/src/libstd/f64.rs
index 75edba8979f..7950d434b77 100644
--- a/src/libstd/f64.rs
+++ b/src/libstd/f64.rs
@@ -19,14 +19,8 @@
 #![allow(missing_docs)]
 
 #[cfg(not(test))]
-#[cfg(stage0)]
-use core::num::Float;
-#[cfg(not(test))]
 use intrinsics;
 #[cfg(not(test))]
-#[cfg(stage0)]
-use num::FpCategory;
-#[cfg(not(test))]
 use sys::cmath;
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -41,12 +35,8 @@ pub use core::f64::{MIN, MIN_POSITIVE, MAX};
 pub use core::f64::consts;
 
 #[cfg(not(test))]
-#[cfg_attr(stage0, lang = "f64")]
-#[cfg_attr(not(stage0), lang = "f64_runtime")]
+#[lang = "f64_runtime"]
 impl f64 {
-    #[cfg(stage0)]
-    f64_core_methods!();
-
     /// Returns the largest integer less than or equal to a number.
     ///
     /// # Examples
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 9cdc6a21622..f7d06852f27 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -252,7 +252,6 @@
 #![feature(collections_range)]
 #![feature(compiler_builtins_lib)]
 #![feature(const_fn)]
-#![cfg_attr(stage0, feature(core_float))]
 #![feature(core_intrinsics)]
 #![feature(dropck_eyepatch)]
 #![feature(exact_size_is_empty)]
@@ -260,10 +259,8 @@
 #![feature(fs_read_write)]
 #![feature(fixed_size_array)]
 #![feature(float_from_str_radix)]
-#![cfg_attr(stage0, feature(float_internals))]
 #![feature(fn_traits)]
 #![feature(fnbox)]
-#![cfg_attr(stage0, feature(generic_param_attrs))]
 #![feature(hashmap_internals)]
 #![feature(heap_api)]
 #![feature(int_error_internals)]
@@ -319,6 +316,7 @@
 #![cfg_attr(test, feature(update_panic_count))]
 #![cfg_attr(windows, feature(used))]
 #![feature(doc_alias)]
+#![feature(float_internals)]
 
 #![default_lib_allocator]
 
@@ -364,11 +362,6 @@ extern crate libc;
 #[allow(unused_extern_crates)]
 extern crate unwind;
 
-// compiler-rt intrinsics
-#[doc(masked)]
-#[cfg(stage0)]
-extern crate compiler_builtins;
-
 // During testing, this crate is not actually the "real" std library, but rather
 // it links to the real std library, which was compiled from this same source
 // code. So any lang items std defines are conditionally excluded (or else they
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 369c5b1ff60..dd8f79d20ab 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -45,17 +45,6 @@ impl State {
     }
 }
 
-macro_rules! span_err_if_not_stage0 {
-    ($cx:expr, $sp:expr, $code:ident, $text:tt) => {
-        #[cfg(not(stage0))] {
-            span_err!($cx, $sp, $code, $text)
-        }
-        #[cfg(stage0)] {
-            $cx.span_err($sp, $text)
-        }
-    }
-}
-
 const OPTIONS: &'static [&'static str] = &["volatile", "alignstack", "intel"];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
@@ -100,7 +89,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                 if asm_str_style.is_some() {
                     // If we already have a string with instructions,
                     // ending up in Asm state again is an error.
-                    span_err_if_not_stage0!(cx, sp, E0660, "malformed inline assembly");
+                    span_err!(cx, sp, E0660, "malformed inline assembly");
                     return DummyResult::expr(sp);
                 }
                 // Nested parser, stop before the first colon (see above).
@@ -153,7 +142,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                             Some(Symbol::intern(&format!("={}", ch.as_str())))
                         }
                         _ => {
-                            span_err_if_not_stage0!(cx, span, E0661,
+                            span_err!(cx, span, E0661,
                                                     "output operand constraint lacks '=' or '+'");
                             None
                         }
@@ -179,10 +168,10 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                     let (constraint, _str_style) = panictry!(p.parse_str());
 
                     if constraint.as_str().starts_with("=") {
-                        span_err_if_not_stage0!(cx, p.prev_span, E0662,
+                        span_err!(cx, p.prev_span, E0662,
                                                 "input operand constraint contains '='");
                     } else if constraint.as_str().starts_with("+") {
-                        span_err_if_not_stage0!(cx, p.prev_span, E0663,
+                        span_err!(cx, p.prev_span, E0663,
                                                 "input operand constraint contains '+'");
                     }
 
@@ -205,7 +194,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                     if OPTIONS.iter().any(|&opt| s == opt) {
                         cx.span_warn(p.prev_span, "expected a clobber, found an option");
                     } else if s.as_str().starts_with("{") || s.as_str().ends_with("}") {
-                        span_err_if_not_stage0!(cx, p.prev_span, E0664,
+                        span_err!(cx, p.prev_span, E0664,
                                                 "clobber should not be surrounded by braces");
                     }
 
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index b6721dd28f3..e100ef29225 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -18,7 +18,7 @@
 #![feature(decl_macro)]
 #![feature(str_escape)]
 
-#![cfg_attr(not(stage0), feature(rustc_diagnostic_macros))]
+#![feature(rustc_diagnostic_macros)]
 
 extern crate fmt_macros;
 #[macro_use]
@@ -29,7 +29,6 @@ extern crate rustc_data_structures;
 extern crate rustc_errors as errors;
 extern crate rustc_target;
 
-#[cfg(not(stage0))]
 mod diagnostics;
 
 mod assert;
diff --git a/src/rtstartup/rsbegin.rs b/src/rtstartup/rsbegin.rs
index 7d5581bb774..8ff401164c1 100644
--- a/src/rtstartup/rsbegin.rs
+++ b/src/rtstartup/rsbegin.rs
@@ -23,7 +23,7 @@
 // of other runtime components (registered via yet another special image section).
 
 #![feature(no_core, lang_items, optin_builtin_traits)]
-#![crate_type="rlib"]
+#![crate_type = "rlib"]
 #![no_core]
 #![allow(non_camel_case_types)]
 
@@ -43,7 +43,7 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     drop_in_place(to_drop);
 }
 
-#[cfg(all(target_os="windows", target_arch = "x86", target_env="gnu"))]
+#[cfg(all(target_os = "windows", target_arch = "x86", target_env = "gnu"))]
 pub mod eh_frames {
     #[no_mangle]
     #[link_section = ".eh_frame"]
@@ -54,6 +54,21 @@ pub mod eh_frames {
     // This is defined as `struct object` in $GCC/libgcc/unwind-dw2-fde.h.
     static mut OBJ: [isize; 6] = [0; 6];
 
+    macro_rules! impl_copy {
+        ($($t:ty)*) => {
+            $(
+                impl ::Copy for $t {}
+            )*
+        }
+    }
+
+    impl_copy! {
+        usize u8 u16 u32 u64 u128
+        isize i8 i16 i32 i64 i128
+        f32 f64
+        bool char
+    }
+
     // Unwind info registration/deregistration routines.
     // See the docs of `unwind` module in libstd.
     extern "C" {
@@ -63,14 +78,18 @@ pub mod eh_frames {
 
     unsafe fn init() {
         // register unwind info on module startup
-        rust_eh_register_frames(&__EH_FRAME_BEGIN__ as *const u8,
-                                &mut OBJ as *mut _ as *mut u8);
+        rust_eh_register_frames(
+            &__EH_FRAME_BEGIN__ as *const u8,
+            &mut OBJ as *mut _ as *mut u8,
+        );
     }
 
     unsafe fn uninit() {
         // unregister on shutdown
-        rust_eh_unregister_frames(&__EH_FRAME_BEGIN__ as *const u8,
-                                  &mut OBJ as *mut _ as *mut u8);
+        rust_eh_unregister_frames(
+            &__EH_FRAME_BEGIN__ as *const u8,
+            &mut OBJ as *mut _ as *mut u8,
+        );
     }
 
     // MSVC-specific init/uninit routine registration
diff --git a/src/rustc/Cargo.toml b/src/rustc/Cargo.toml
index 9986e0b512a..9ccd37a6a45 100644
--- a/src/rustc/Cargo.toml
+++ b/src/rustc/Cargo.toml
@@ -4,7 +4,7 @@ name = "rustc-main"
 version = "0.0.0"
 
 [[bin]]
-name = "rustc"
+name = "rustc_binary"
 path = "rustc.rs"
 
 [dependencies]
diff --git a/src/stage0.txt b/src/stage0.txt
index a5ad2b315a1..435cfd2f6db 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.x.0` for Cargo where they were released on `date`.
 
-date: 2018-04-24
+date: 2018-05-10
 rustc: beta
 cargo: beta
 
diff --git a/src/tools/rustdoc/Cargo.toml b/src/tools/rustdoc/Cargo.toml
index 344f617ef95..d3881500441 100644
--- a/src/tools/rustdoc/Cargo.toml
+++ b/src/tools/rustdoc/Cargo.toml
@@ -7,7 +7,7 @@ authors = ["The Rust Project Developers"]
 # the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool"
 # rustdoc a different name.
 [[bin]]
-name = "rustdoc-tool-binary"
+name = "rustdoc_tool_binary"
 path = "main.rs"
 
 [dependencies]