Use the GlobalAlloc trait for #[global_allocator]
diff --git a/src/Cargo.lock b/src/Cargo.lock
index e5297d1..2e969f4 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -19,7 +19,6 @@
 name = "alloc_jemalloc"
 version = "0.0.0"
 dependencies = [
- "alloc_system 0.0.0",
  "build_helper 0.1.0",
  "cc 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "compiler_builtins 0.0.0",
diff --git a/src/doc/unstable-book/src/language-features/global-allocator.md b/src/doc/unstable-book/src/language-features/global-allocator.md
index b3e6925..6ce12ba 100644
--- a/src/doc/unstable-book/src/language-features/global-allocator.md
+++ b/src/doc/unstable-book/src/language-features/global-allocator.md
@@ -29,16 +29,16 @@
 ```rust
 #![feature(global_allocator, allocator_api, heap_api)]
 
-use std::heap::{Alloc, System, Layout, AllocErr};
+use std::alloc::{GlobalAlloc, System, Layout, Void};
 
 struct MyAllocator;
 
-unsafe impl<'a> Alloc for &'a MyAllocator {
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
+unsafe impl GlobalAlloc for MyAllocator {
+    unsafe fn alloc(&self, layout: Layout) -> *mut Void {
         System.alloc(layout)
     }
 
-    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
+    unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) {
         System.dealloc(ptr, layout)
     }
 }
diff --git a/src/liballoc/alloc.rs b/src/liballoc/alloc.rs
index b975ff6..73bc78e 100644
--- a/src/liballoc/alloc.rs
+++ b/src/liballoc/alloc.rs
@@ -16,26 +16,19 @@
             issue = "32838")]
 
 use core::intrinsics::{min_align_of_val, size_of_val};
-use core::mem;
 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_usable_size(layout: *const u8,
-                          min: *mut usize,
-                          max: *mut usize);
-    #[rustc_allocator_nounwind]
     fn __rust_realloc(ptr: *mut u8,
                       old_size: usize,
                       old_align: usize,
@@ -44,31 +37,22 @@
                       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]
-    fn __rust_alloc_excess(size: usize,
-                           align: usize,
-                           excess: *mut usize,
-                           err: *mut u8) -> *mut u8;
+    fn __rust_alloc(size: usize, align: usize) -> *mut u8;
     #[rustc_allocator_nounwind]
-    fn __rust_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;
+    fn __rust_dealloc(ptr: *mut u8, size: usize, align: usize);
     #[rustc_allocator_nounwind]
-    fn __rust_grow_in_place(ptr: *mut u8,
-                            old_size: usize,
-                            old_align: usize,
-                            new_size: usize,
-                            new_align: usize) -> u8;
+    fn __rust_realloc(ptr: *mut u8,
+                      old_size: usize,
+                      align: usize,
+                      new_size: usize) -> *mut u8;
     #[rustc_allocator_nounwind]
-    fn __rust_shrink_in_place(ptr: *mut u8,
-                              old_size: usize,
-                              old_align: usize,
-                              new_size: usize,
-                              new_align: usize) -> u8;
+    fn __rust_alloc_zeroed(size: usize, align: usize) -> *mut u8;
 }
 
 #[derive(Copy, Clone, Default, Debug)]
@@ -86,22 +70,15 @@
 unsafe impl Alloc for Global {
     #[inline]
     unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
-        let mut err = AllocErr;
-        let ptr = __rust_alloc(layout.size(),
-                               layout.align(),
-                               &mut err as *mut AllocErr as *mut u8);
-        if ptr.is_null() {
-            Err(AllocErr)
-        } else {
-            Ok(ptr)
-        }
-    }
+        #[cfg(not(stage0))]
+        let ptr = __rust_alloc(layout.size(), layout.align());
+        #[cfg(stage0)]
+        let ptr = __rust_alloc(layout.size(), layout.align(), &mut 0);
 
-    #[inline]
-    #[cold]
-    fn oom(&mut self, err: AllocErr) -> ! {
-        unsafe {
-            __rust_oom(&err as *const AllocErr as *const u8)
+        if !ptr.is_null() {
+            Ok(ptr)
+        } else {
+            Err(AllocErr)
         }
     }
 
@@ -111,125 +88,40 @@
     }
 
     #[inline]
-    fn usable_size(&self, layout: &Layout) -> (usize, usize) {
-        let mut min = 0;
-        let mut max = 0;
-        unsafe {
-            __rust_usable_size(layout as *const Layout as *const u8,
-                               &mut min,
-                               &mut max);
-        }
-        (min, max)
-    }
-
-    #[inline]
     unsafe fn realloc(&mut self,
                       ptr: *mut u8,
                       layout: Layout,
                       new_layout: Layout)
                       -> Result<*mut u8, AllocErr>
     {
-        let mut err = AllocErr;
-        let ptr = __rust_realloc(ptr,
-                                 layout.size(),
-                                 layout.align(),
-                                 new_layout.size(),
-                                 new_layout.align(),
-                                 &mut err as *mut AllocErr as *mut u8);
-        if ptr.is_null() {
-            Err(AllocErr)
+        if layout.align() == new_layout.align() {
+            #[cfg(not(stage0))]
+            let ptr = __rust_realloc(ptr, layout.size(), layout.align(), new_layout.size());
+            #[cfg(stage0)]
+            let ptr = __rust_realloc(ptr, layout.size(), layout.align(),
+                                     new_layout.size(), new_layout.align(), &mut 0);
+
+            if !ptr.is_null() {
+                Ok(ptr)
+            } else {
+                Err(AllocErr)
+            }
         } else {
-            mem::forget(err);
-            Ok(ptr)
+            Err(AllocErr)
         }
     }
 
     #[inline]
     unsafe fn alloc_zeroed(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
-        let mut err = AllocErr;
-        let ptr = __rust_alloc_zeroed(layout.size(),
-                                      layout.align(),
-                                      &mut err as *mut AllocErr as *mut u8);
-        if ptr.is_null() {
-            Err(AllocErr)
-        } else {
+        #[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);
+
+        if !ptr.is_null() {
             Ok(ptr)
-        }
-    }
-
-    #[inline]
-    unsafe fn alloc_excess(&mut self, layout: Layout) -> Result<Excess, AllocErr> {
-        let mut err = AllocErr;
-        let mut size = 0;
-        let ptr = __rust_alloc_excess(layout.size(),
-                                      layout.align(),
-                                      &mut size,
-                                      &mut err as *mut AllocErr as *mut u8);
-        if ptr.is_null() {
+        } else {
             Err(AllocErr)
-        } else {
-            Ok(Excess(ptr, size))
-        }
-    }
-
-    #[inline]
-    unsafe fn realloc_excess(&mut self,
-                             ptr: *mut u8,
-                             layout: Layout,
-                             new_layout: Layout) -> Result<Excess, AllocErr> {
-        let mut err = AllocErr;
-        let mut size = 0;
-        let ptr = __rust_realloc_excess(ptr,
-                                        layout.size(),
-                                        layout.align(),
-                                        new_layout.size(),
-                                        new_layout.align(),
-                                        &mut size,
-                                        &mut err as *mut AllocErr as *mut u8);
-        if ptr.is_null() {
-            Err(AllocErr)
-        } else {
-            Ok(Excess(ptr, size))
-        }
-    }
-
-    #[inline]
-    unsafe fn grow_in_place(&mut self,
-                            ptr: *mut u8,
-                            layout: Layout,
-                            new_layout: Layout)
-                            -> Result<(), CannotReallocInPlace>
-    {
-        debug_assert!(new_layout.size() >= layout.size());
-        debug_assert!(new_layout.align() == layout.align());
-        let ret = __rust_grow_in_place(ptr,
-                                       layout.size(),
-                                       layout.align(),
-                                       new_layout.size(),
-                                       new_layout.align());
-        if ret != 0 {
-            Ok(())
-        } else {
-            Err(CannotReallocInPlace)
-        }
-    }
-
-    #[inline]
-    unsafe fn shrink_in_place(&mut self,
-                              ptr: *mut u8,
-                              layout: Layout,
-                              new_layout: Layout) -> Result<(), CannotReallocInPlace> {
-        debug_assert!(new_layout.size() <= layout.size());
-        debug_assert!(new_layout.align() == layout.align());
-        let ret = __rust_shrink_in_place(ptr,
-                                         layout.size(),
-                                         layout.align(),
-                                         new_layout.size(),
-                                         new_layout.align());
-        if ret != 0 {
-            Ok(())
-        } else {
-            Err(CannotReallocInPlace)
         }
     }
 }
diff --git a/src/liballoc_jemalloc/Cargo.toml b/src/liballoc_jemalloc/Cargo.toml
index 0243517..7986d5d 100644
--- a/src/liballoc_jemalloc/Cargo.toml
+++ b/src/liballoc_jemalloc/Cargo.toml
@@ -12,7 +12,6 @@
 doc = false
 
 [dependencies]
-alloc_system = { path = "../liballoc_system" }
 core = { path = "../libcore" }
 libc = { path = "../rustc/libc_shim" }
 compiler_builtins = { path = "../rustc/compiler_builtins_shim" }
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
index 59a7e87..661d7ab 100644
--- a/src/liballoc_jemalloc/lib.rs
+++ b/src/liballoc_jemalloc/lib.rs
@@ -14,7 +14,6 @@
             reason = "this library is unlikely to be stabilized in its current \
                       form or name",
             issue = "27783")]
-#![feature(alloc_system)]
 #![feature(libc)]
 #![feature(linkage)]
 #![feature(staged_api)]
@@ -23,15 +22,12 @@
 #![cfg_attr(not(dummy_jemalloc), feature(allocator_api))]
 #![rustc_alloc_kind = "exe"]
 
-extern crate alloc_system;
 extern crate libc;
 
 #[cfg(not(dummy_jemalloc))]
 pub use contents::*;
 #[cfg(not(dummy_jemalloc))]
 mod contents {
-    use core::alloc::{Alloc, AllocErr, Layout};
-    use alloc_system::System;
     use libc::{c_int, c_void, size_t};
 
     // Note that the symbols here are prefixed by default on macOS and Windows (we
@@ -52,16 +48,8 @@
         fn rallocx(ptr: *mut c_void, size: size_t, flags: c_int) -> *mut c_void;
         #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
                        target_os = "dragonfly", target_os = "windows", target_env = "musl"),
-                   link_name = "je_xallocx")]
-        fn xallocx(ptr: *mut c_void, size: size_t, extra: size_t, flags: c_int) -> size_t;
-        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                       target_os = "dragonfly", target_os = "windows", target_env = "musl"),
                    link_name = "je_sdallocx")]
         fn sdallocx(ptr: *mut c_void, size: size_t, flags: c_int);
-        #[cfg_attr(any(target_os = "macos", target_os = "android", target_os = "ios",
-                       target_os = "dragonfly", target_os = "windows", target_env = "musl"),
-                   link_name = "je_nallocx")]
-        fn nallocx(size: size_t, flags: c_int) -> size_t;
     }
 
     const MALLOCX_ZERO: c_int = 0x40;
@@ -102,9 +90,7 @@
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_alloc(size: usize,
-                                     align: usize,
-                                     _err: *mut u8) -> *mut u8 {
+    pub unsafe extern fn __rde_alloc(size: usize, align: usize) -> *mut u8 {
         let flags = align_to_flags(align, size);
         let ptr = mallocx(size as size_t, flags) as *mut u8;
         ptr
@@ -112,12 +98,6 @@
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_oom(err: *const u8) -> ! {
-        System.oom((*(err as *const AllocErr)).clone())
-    }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
     pub unsafe extern fn __rde_dealloc(ptr: *mut u8,
                                        size: usize,
                                        align: usize) {
@@ -127,42 +107,18 @@
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_usable_size(layout: *const u8,
-                                           min: *mut usize,
-                                           max: *mut usize) {
-        let layout = &*(layout as *const Layout);
-        let flags = align_to_flags(layout.align(), layout.size());
-        let size = nallocx(layout.size(), flags) as usize;
-        *min = layout.size();
-        if size > 0 {
-            *max = size;
-        } else {
-            *max = layout.size();
-        }
-    }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
     pub unsafe extern fn __rde_realloc(ptr: *mut u8,
                                        _old_size: usize,
-                                       old_align: usize,
-                                       new_size: usize,
-                                       new_align: usize,
-                                       _err: *mut u8) -> *mut u8 {
-        if new_align != old_align {
-            return 0 as *mut u8
-        }
-
-        let flags = align_to_flags(new_align, new_size);
+                                       align: usize,
+                                       new_size: usize) -> *mut u8 {
+        let flags = align_to_flags(align, new_size);
         let ptr = rallocx(ptr as *mut c_void, new_size, flags) as *mut u8;
         ptr
     }
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_alloc_zeroed(size: usize,
-                                            align: usize,
-                                            _err: *mut u8) -> *mut u8 {
+    pub unsafe extern fn __rde_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
         let ptr = if align <= MIN_ALIGN && align <= size {
             calloc(size as size_t, 1) as *mut u8
         } else {
@@ -171,60 +127,4 @@
         };
         ptr
     }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_alloc_excess(size: usize,
-                                            align: usize,
-                                            excess: *mut usize,
-                                            err: *mut u8) -> *mut u8 {
-        let p = __rde_alloc(size, align, err);
-        if !p.is_null() {
-            let flags = align_to_flags(align, size);
-            *excess = nallocx(size, flags) as usize;
-        }
-        return p
-    }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_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 {
-        let p = __rde_realloc(ptr, old_size, old_align, new_size, new_align, err);
-        if !p.is_null() {
-            let flags = align_to_flags(new_align, new_size);
-            *excess = nallocx(new_size, flags) as usize;
-        }
-        p
-    }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_grow_in_place(ptr: *mut u8,
-                                             old_size: usize,
-                                             old_align: usize,
-                                             new_size: usize,
-                                             new_align: usize) -> u8 {
-        __rde_shrink_in_place(ptr, old_size, old_align, new_size, new_align)
-    }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rde_shrink_in_place(ptr: *mut u8,
-                                               _old_size: usize,
-                                               old_align: usize,
-                                               new_size: usize,
-                                               new_align: usize) -> u8 {
-        if old_align == new_align {
-            let flags = align_to_flags(new_align, new_size);
-            (xallocx(ptr as *mut c_void, new_size, 0, flags) == new_size) as u8
-        } else {
-            0
-        }
-    }
 }
diff --git a/src/librustc_allocator/expand.rs b/src/librustc_allocator/expand.rs
index ee38cca..ce41fe1 100644
--- a/src/librustc_allocator/expand.rs
+++ b/src/librustc_allocator/expand.rs
@@ -11,7 +11,7 @@
 use rustc::middle::allocator::AllocatorKind;
 use rustc_errors;
 use syntax::abi::Abi;
-use syntax::ast::{Crate, Attribute, LitKind, StrStyle, ExprKind};
+use syntax::ast::{Crate, Attribute, LitKind, StrStyle};
 use syntax::ast::{Unsafety, Constness, Generics, Mutability, Ty, Mac, Arg};
 use syntax::ast::{self, Ident, Item, ItemKind, TyKind, VisibilityKind, Expr};
 use syntax::attr;
@@ -88,7 +88,7 @@
             span,
             kind: AllocatorKind::Global,
             global: item.ident,
-            alloc: Ident::from_str("alloc"),
+            core: Ident::from_str("core"),
             cx: ExtCtxt::new(self.sess, ecfg, self.resolver),
         };
         let super_path = f.cx.path(f.span, vec![
@@ -96,7 +96,7 @@
             f.global,
         ]);
         let mut items = vec![
-            f.cx.item_extern_crate(f.span, f.alloc),
+            f.cx.item_extern_crate(f.span, f.core),
             f.cx.item_use_simple(
                 f.span,
                 respan(f.span.shrink_to_lo(), VisibilityKind::Inherited),
@@ -126,7 +126,7 @@
     span: Span,
     kind: AllocatorKind,
     global: Ident,
-    alloc: Ident,
+    core: Ident,
     cx: ExtCtxt<'a>,
 }
 
@@ -143,8 +143,7 @@
             self.arg_ty(ty, &mut abi_args, mk)
         }).collect();
         let result = self.call_allocator(method.name, args);
-        let (output_ty, output_expr) =
-            self.ret_ty(&method.output, &mut abi_args, mk, result);
+        let (output_ty, output_expr) = self.ret_ty(&method.output, result);
         let kind = ItemKind::Fn(self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)),
                                 Unsafety::Unsafe,
                                 dummy_spanned(Constness::NotConst),
@@ -159,16 +158,15 @@
 
     fn call_allocator(&self, method: &str, mut args: Vec<P<Expr>>) -> P<Expr> {
         let method = self.cx.path(self.span, vec![
-            self.alloc,
-            Ident::from_str("heap"),
-            Ident::from_str("Alloc"),
+            self.core,
+            Ident::from_str("alloc"),
+            Ident::from_str("GlobalAlloc"),
             Ident::from_str(method),
         ]);
         let method = self.cx.expr_path(method);
         let allocator = self.cx.path_ident(self.span, self.global);
         let allocator = self.cx.expr_path(allocator);
         let allocator = self.cx.expr_addr_of(self.span, allocator);
-        let allocator = self.cx.expr_mut_addr_of(self.span, allocator);
         args.insert(0, allocator);
 
         self.cx.expr_call(self.span, method, args)
@@ -205,8 +203,8 @@
                 args.push(self.cx.arg(self.span, align, ty_usize));
 
                 let layout_new = self.cx.path(self.span, vec![
-                    self.alloc,
-                    Ident::from_str("heap"),
+                    self.core,
+                    Ident::from_str("alloc"),
                     Ident::from_str("Layout"),
                     Ident::from_str("from_size_align_unchecked"),
                 ]);
@@ -219,286 +217,67 @@
                 layout
             }
 
-            AllocatorTy::LayoutRef => {
-                let ident = ident();
-                args.push(self.cx.arg(self.span, ident, self.ptr_u8()));
-
-                // Convert our `arg: *const u8` via:
-                //
-                //      &*(arg as *const Layout)
-                let expr = self.cx.expr_ident(self.span, ident);
-                let expr = self.cx.expr_cast(self.span, expr, self.layout_ptr());
-                let expr = self.cx.expr_deref(self.span, expr);
-                self.cx.expr_addr_of(self.span, expr)
-            }
-
-            AllocatorTy::AllocErr => {
-                // We're creating:
-                //
-                //      (*(arg as *const AllocErr)).clone()
-                let ident = ident();
-                args.push(self.cx.arg(self.span, ident, self.ptr_u8()));
-                let expr = self.cx.expr_ident(self.span, ident);
-                let expr = self.cx.expr_cast(self.span, expr, self.alloc_err_ptr());
-                let expr = self.cx.expr_deref(self.span, expr);
-                self.cx.expr_method_call(
-                    self.span,
-                    expr,
-                    Ident::from_str("clone"),
-                    Vec::new()
-                )
-            }
-
             AllocatorTy::Ptr => {
                 let ident = ident();
                 args.push(self.cx.arg(self.span, ident, self.ptr_u8()));
+                let arg = self.cx.expr_ident(self.span, ident);
+                self.cx.expr_cast(self.span, arg, self.ptr_void())
+            }
+
+            AllocatorTy::Usize => {
+                let ident = ident();
+                args.push(self.cx.arg(self.span, ident, self.usize()));
                 self.cx.expr_ident(self.span, ident)
             }
 
             AllocatorTy::ResultPtr |
-            AllocatorTy::ResultExcess |
-            AllocatorTy::ResultUnit |
-            AllocatorTy::Bang |
-            AllocatorTy::UsizePair |
             AllocatorTy::Unit => {
                 panic!("can't convert AllocatorTy to an argument")
             }
         }
     }
 
-    fn ret_ty(&self,
-              ty: &AllocatorTy,
-              args: &mut Vec<Arg>,
-              ident: &mut FnMut() -> Ident,
-              expr: P<Expr>) -> (P<Ty>, P<Expr>)
-    {
+    fn ret_ty(&self, ty: &AllocatorTy, expr: P<Expr>) -> (P<Ty>, P<Expr>) {
         match *ty {
-            AllocatorTy::UsizePair => {
-                // We're creating:
-                //
-                //      let arg = #expr;
-                //      *min = arg.0;
-                //      *max = arg.1;
-
-                let min = ident();
-                let max = ident();
-
-                args.push(self.cx.arg(self.span, min, self.ptr_usize()));
-                args.push(self.cx.arg(self.span, max, self.ptr_usize()));
-
-                let ident = ident();
-                let stmt = self.cx.stmt_let(self.span, false, ident, expr);
-                let min = self.cx.expr_ident(self.span, min);
-                let max = self.cx.expr_ident(self.span, max);
-                let layout = self.cx.expr_ident(self.span, ident);
-                let assign_min = self.cx.expr(self.span, ExprKind::Assign(
-                    self.cx.expr_deref(self.span, min),
-                    self.cx.expr_tup_field_access(self.span, layout.clone(), 0),
-                ));
-                let assign_min = self.cx.stmt_semi(assign_min);
-                let assign_max = self.cx.expr(self.span, ExprKind::Assign(
-                    self.cx.expr_deref(self.span, max),
-                    self.cx.expr_tup_field_access(self.span, layout.clone(), 1),
-                ));
-                let assign_max = self.cx.stmt_semi(assign_max);
-
-                let stmts = vec![stmt, assign_min, assign_max];
-                let block = self.cx.block(self.span, stmts);
-                let ty_unit = self.cx.ty(self.span, TyKind::Tup(Vec::new()));
-                (ty_unit, self.cx.expr_block(block))
-            }
-
-            AllocatorTy::ResultExcess => {
-                // We're creating:
-                //
-                //      match #expr {
-                //          Ok(ptr) => {
-                //              *excess = ptr.1;
-                //              ptr.0
-                //          }
-                //          Err(e) => {
-                //              ptr::write(err_ptr, e);
-                //              0 as *mut u8
-                //          }
-                //      }
-
-                let excess_ptr = ident();
-                args.push(self.cx.arg(self.span, excess_ptr, self.ptr_usize()));
-                let excess_ptr = self.cx.expr_ident(self.span, excess_ptr);
-
-                let err_ptr = ident();
-                args.push(self.cx.arg(self.span, err_ptr, self.ptr_u8()));
-                let err_ptr = self.cx.expr_ident(self.span, err_ptr);
-                let err_ptr = self.cx.expr_cast(self.span,
-                                                err_ptr,
-                                                self.alloc_err_ptr());
-
-                let name = ident();
-                let ok_expr = {
-                    let ptr = self.cx.expr_ident(self.span, name);
-                    let write = self.cx.expr(self.span, ExprKind::Assign(
-                        self.cx.expr_deref(self.span, excess_ptr),
-                        self.cx.expr_tup_field_access(self.span, ptr.clone(), 1),
-                    ));
-                    let write = self.cx.stmt_semi(write);
-                    let ret = self.cx.expr_tup_field_access(self.span,
-                                                            ptr.clone(),
-                                                            0);
-                    let ret = self.cx.stmt_expr(ret);
-                    let block = self.cx.block(self.span, vec![write, ret]);
-                    self.cx.expr_block(block)
-                };
-                let pat = self.cx.pat_ident(self.span, name);
-                let ok = self.cx.path_ident(self.span, Ident::from_str("Ok"));
-                let ok = self.cx.pat_tuple_struct(self.span, ok, vec![pat]);
-                let ok = self.cx.arm(self.span, vec![ok], ok_expr);
-
-                let name = ident();
-                let err_expr = {
-                    let err = self.cx.expr_ident(self.span, name);
-                    let write = self.cx.path(self.span, vec![
-                        self.alloc,
-                        Ident::from_str("heap"),
-                        Ident::from_str("__core"),
-                        Ident::from_str("ptr"),
-                        Ident::from_str("write"),
-                    ]);
-                    let write = self.cx.expr_path(write);
-                    let write = self.cx.expr_call(self.span, write,
-                                                  vec![err_ptr, err]);
-                    let write = self.cx.stmt_semi(write);
-                    let null = self.cx.expr_usize(self.span, 0);
-                    let null = self.cx.expr_cast(self.span, null, self.ptr_u8());
-                    let null = self.cx.stmt_expr(null);
-                    let block = self.cx.block(self.span, vec![write, null]);
-                    self.cx.expr_block(block)
-                };
-                let pat = self.cx.pat_ident(self.span, name);
-                let err = self.cx.path_ident(self.span, Ident::from_str("Err"));
-                let err = self.cx.pat_tuple_struct(self.span, err, vec![pat]);
-                let err = self.cx.arm(self.span, vec![err], err_expr);
-
-                let expr = self.cx.expr_match(self.span, expr, vec![ok, err]);
-                (self.ptr_u8(), expr)
-            }
-
             AllocatorTy::ResultPtr => {
                 // We're creating:
                 //
-                //      match #expr {
-                //          Ok(ptr) => ptr,
-                //          Err(e) => {
-                //              ptr::write(err_ptr, e);
-                //              0 as *mut u8
-                //          }
-                //      }
+                //      #expr as *mut u8
 
-                let err_ptr = ident();
-                args.push(self.cx.arg(self.span, err_ptr, self.ptr_u8()));
-                let err_ptr = self.cx.expr_ident(self.span, err_ptr);
-                let err_ptr = self.cx.expr_cast(self.span,
-                                                err_ptr,
-                                                self.alloc_err_ptr());
-
-                let name = ident();
-                let ok_expr = self.cx.expr_ident(self.span, name);
-                let pat = self.cx.pat_ident(self.span, name);
-                let ok = self.cx.path_ident(self.span, Ident::from_str("Ok"));
-                let ok = self.cx.pat_tuple_struct(self.span, ok, vec![pat]);
-                let ok = self.cx.arm(self.span, vec![ok], ok_expr);
-
-                let name = ident();
-                let err_expr = {
-                    let err = self.cx.expr_ident(self.span, name);
-                    let write = self.cx.path(self.span, vec![
-                        self.alloc,
-                        Ident::from_str("heap"),
-                        Ident::from_str("__core"),
-                        Ident::from_str("ptr"),
-                        Ident::from_str("write"),
-                    ]);
-                    let write = self.cx.expr_path(write);
-                    let write = self.cx.expr_call(self.span, write,
-                                                  vec![err_ptr, err]);
-                    let write = self.cx.stmt_semi(write);
-                    let null = self.cx.expr_usize(self.span, 0);
-                    let null = self.cx.expr_cast(self.span, null, self.ptr_u8());
-                    let null = self.cx.stmt_expr(null);
-                    let block = self.cx.block(self.span, vec![write, null]);
-                    self.cx.expr_block(block)
-                };
-                let pat = self.cx.pat_ident(self.span, name);
-                let err = self.cx.path_ident(self.span, Ident::from_str("Err"));
-                let err = self.cx.pat_tuple_struct(self.span, err, vec![pat]);
-                let err = self.cx.arm(self.span, vec![err], err_expr);
-
-                let expr = self.cx.expr_match(self.span, expr, vec![ok, err]);
+                let expr = self.cx.expr_cast(self.span, expr, self.ptr_u8());
                 (self.ptr_u8(), expr)
             }
 
-            AllocatorTy::ResultUnit => {
-                // We're creating:
-                //
-                //      #expr.is_ok() as u8
-
-                let cast = self.cx.expr_method_call(
-                    self.span,
-                    expr,
-                    Ident::from_str("is_ok"),
-                    Vec::new()
-                );
-                let u8 = self.cx.path_ident(self.span, Ident::from_str("u8"));
-                let u8 = self.cx.ty_path(u8);
-                let cast = self.cx.expr_cast(self.span, cast, u8.clone());
-                (u8, cast)
-            }
-
-            AllocatorTy::Bang => {
-                (self.cx.ty(self.span, TyKind::Never), expr)
-            }
-
             AllocatorTy::Unit => {
                 (self.cx.ty(self.span, TyKind::Tup(Vec::new())), expr)
             }
 
-            AllocatorTy::AllocErr |
             AllocatorTy::Layout |
-            AllocatorTy::LayoutRef |
+            AllocatorTy::Usize |
             AllocatorTy::Ptr => {
                 panic!("can't convert AllocatorTy to an output")
             }
         }
     }
 
+    fn usize(&self) -> P<Ty> {
+        let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
+        self.cx.ty_path(usize)
+    }
+
     fn ptr_u8(&self) -> P<Ty> {
         let u8 = self.cx.path_ident(self.span, Ident::from_str("u8"));
         let ty_u8 = self.cx.ty_path(u8);
         self.cx.ty_ptr(self.span, ty_u8, Mutability::Mutable)
     }
 
-    fn ptr_usize(&self) -> P<Ty> {
-        let usize = self.cx.path_ident(self.span, Ident::from_str("usize"));
-        let ty_usize = self.cx.ty_path(usize);
-        self.cx.ty_ptr(self.span, ty_usize, Mutability::Mutable)
-    }
-
-    fn layout_ptr(&self) -> P<Ty> {
-        let layout = self.cx.path(self.span, vec![
-            self.alloc,
-            Ident::from_str("heap"),
-            Ident::from_str("Layout"),
+    fn ptr_void(&self) -> P<Ty> {
+        let void = self.cx.path(self.span, vec![
+            self.core,
+            Ident::from_str("alloc"),
+            Ident::from_str("Void"),
         ]);
-        let layout = self.cx.ty_path(layout);
-        self.cx.ty_ptr(self.span, layout, Mutability::Mutable)
-    }
-
-    fn alloc_err_ptr(&self) -> P<Ty> {
-        let err = self.cx.path(self.span, vec![
-            self.alloc,
-            Ident::from_str("heap"),
-            Ident::from_str("AllocErr"),
-        ]);
-        let err = self.cx.ty_path(err);
-        self.cx.ty_ptr(self.span, err, Mutability::Mutable)
+        let ty_void = self.cx.ty_path(void);
+        self.cx.ty_ptr(self.span, ty_void, Mutability::Mutable)
     }
 }
diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs
index 0c7a9a9..9690868 100644
--- a/src/librustc_allocator/lib.rs
+++ b/src/librustc_allocator/lib.rs
@@ -24,23 +24,13 @@
         output: AllocatorTy::ResultPtr,
     },
     AllocatorMethod {
-        name: "oom",
-        inputs: &[AllocatorTy::AllocErr],
-        output: AllocatorTy::Bang,
-    },
-    AllocatorMethod {
         name: "dealloc",
         inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout],
         output: AllocatorTy::Unit,
     },
     AllocatorMethod {
-        name: "usable_size",
-        inputs: &[AllocatorTy::LayoutRef],
-        output: AllocatorTy::UsizePair,
-    },
-    AllocatorMethod {
         name: "realloc",
-        inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Layout],
+        inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Usize],
         output: AllocatorTy::ResultPtr,
     },
     AllocatorMethod {
@@ -48,26 +38,6 @@
         inputs: &[AllocatorTy::Layout],
         output: AllocatorTy::ResultPtr,
     },
-    AllocatorMethod {
-        name: "alloc_excess",
-        inputs: &[AllocatorTy::Layout],
-        output: AllocatorTy::ResultExcess,
-    },
-    AllocatorMethod {
-        name: "realloc_excess",
-        inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Layout],
-        output: AllocatorTy::ResultExcess,
-    },
-    AllocatorMethod {
-        name: "grow_in_place",
-        inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Layout],
-        output: AllocatorTy::ResultUnit,
-    },
-    AllocatorMethod {
-        name: "shrink_in_place",
-        inputs: &[AllocatorTy::Ptr, AllocatorTy::Layout, AllocatorTy::Layout],
-        output: AllocatorTy::ResultUnit,
-    },
 ];
 
 pub struct AllocatorMethod {
@@ -77,14 +47,9 @@
 }
 
 pub enum AllocatorTy {
-    AllocErr,
-    Bang,
     Layout,
-    LayoutRef,
     Ptr,
-    ResultExcess,
     ResultPtr,
-    ResultUnit,
     Unit,
-    UsizePair,
+    Usize,
 }
diff --git a/src/librustc_trans/allocator.rs b/src/librustc_trans/allocator.rs
index e1c145b..ffebb95 100644
--- a/src/librustc_trans/allocator.rs
+++ b/src/librustc_trans/allocator.rs
@@ -30,7 +30,6 @@
     };
     let i8 = llvm::LLVMInt8TypeInContext(llcx);
     let i8p = llvm::LLVMPointerType(i8, 0);
-    let usizep = llvm::LLVMPointerType(usize, 0);
     let void = llvm::LLVMVoidTypeInContext(llcx);
 
     for method in ALLOCATOR_METHODS {
@@ -41,40 +40,19 @@
                     args.push(usize); // size
                     args.push(usize); // align
                 }
-                AllocatorTy::LayoutRef => args.push(i8p),
                 AllocatorTy::Ptr => args.push(i8p),
-                AllocatorTy::AllocErr => args.push(i8p),
+                AllocatorTy::Usize => args.push(usize),
 
-                AllocatorTy::Bang |
-                AllocatorTy::ResultExcess |
                 AllocatorTy::ResultPtr |
-                AllocatorTy::ResultUnit |
-                AllocatorTy::UsizePair |
                 AllocatorTy::Unit => panic!("invalid allocator arg"),
             }
         }
         let output = match method.output {
-            AllocatorTy::UsizePair => {
-                args.push(usizep); // min
-                args.push(usizep); // max
-                None
-            }
-            AllocatorTy::Bang => None,
-            AllocatorTy::ResultExcess => {
-                args.push(i8p); // excess_ptr
-                args.push(i8p); // err_ptr
-                Some(i8p)
-            }
-            AllocatorTy::ResultPtr => {
-                args.push(i8p); // err_ptr
-                Some(i8p)
-            }
-            AllocatorTy::ResultUnit => Some(i8),
+            AllocatorTy::ResultPtr => Some(i8p),
             AllocatorTy::Unit => None,
 
-            AllocatorTy::AllocErr |
             AllocatorTy::Layout |
-            AllocatorTy::LayoutRef |
+            AllocatorTy::Usize |
             AllocatorTy::Ptr => panic!("invalid allocator output"),
         };
         let ty = llvm::LLVMFunctionType(output.unwrap_or(void),
diff --git a/src/libstd/alloc.rs b/src/libstd/alloc.rs
index 533ad3a..335dc7e 100644
--- a/src/libstd/alloc.rs
+++ b/src/libstd/alloc.rs
@@ -21,7 +21,7 @@
 #[doc(hidden)]
 #[allow(unused_attributes)]
 pub mod __default_lib_allocator {
-    use super::{System, Layout, Alloc, AllocErr, CannotReallocInPlace};
+    use super::{System, Layout, GlobalAlloc, Void};
     // for symbol names src/librustc/middle/allocator.rs
     // for signatures src/librustc_allocator/lib.rs
 
@@ -30,20 +30,9 @@
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rdl_alloc(size: usize,
-                                     align: usize,
-                                     _err: *mut u8) -> *mut u8 {
+    pub unsafe extern fn __rdl_alloc(size: usize, align: usize) -> *mut u8 {
         let layout = Layout::from_size_align_unchecked(size, align);
-        match System.alloc(layout) {
-            Ok(p) => p,
-            Err(AllocErr) => 0 as *mut u8,
-        }
-    }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rdl_oom(err: *const u8) -> ! {
-        System.oom((*(err as *const AllocErr)).clone())
+        System.alloc(layout) as *mut u8
     }
 
     #[no_mangle]
@@ -51,110 +40,76 @@
     pub unsafe extern fn __rdl_dealloc(ptr: *mut u8,
                                        size: usize,
                                        align: usize) {
-        System.dealloc(ptr, Layout::from_size_align_unchecked(size, align))
-    }
-
-    #[no_mangle]
-    #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rdl_usable_size(layout: *const u8,
-                                           min: *mut usize,
-                                           max: *mut usize) {
-        let pair = System.usable_size(&*(layout as *const Layout));
-        *min = pair.0;
-        *max = pair.1;
+        System.dealloc(ptr as *mut Void, Layout::from_size_align_unchecked(size, align))
     }
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
     pub unsafe extern fn __rdl_realloc(ptr: *mut u8,
                                        old_size: usize,
-                                       old_align: usize,
-                                       new_size: usize,
-                                       new_align: usize,
-                                       _err: *mut u8) -> *mut u8 {
-        let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
-        let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
-        match System.realloc(ptr, old_layout, new_layout) {
-            Ok(p) => p,
-            Err(AllocErr) => 0 as *mut u8,
-        }
+                                       align: usize,
+                                       new_size: usize) -> *mut u8 {
+        let old_layout = Layout::from_size_align_unchecked(old_size, align);
+        System.realloc(ptr as *mut Void, old_layout, new_size) as *mut u8
     }
 
     #[no_mangle]
     #[rustc_std_internal_symbol]
-    pub unsafe extern fn __rdl_alloc_zeroed(size: usize,
-                                            align: usize,
-                                            _err: *mut u8) -> *mut u8 {
+    pub unsafe extern fn __rdl_alloc_zeroed(size: usize, align: usize) -> *mut u8 {
         let layout = Layout::from_size_align_unchecked(size, align);
-        match System.alloc_zeroed(layout) {
-            Ok(p) => p,
-            Err(AllocErr) => 0 as *mut u8,
-        }
+        System.alloc_zeroed(layout) as *mut u8
     }
 
-    #[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 {
-        let layout = Layout::from_size_align_unchecked(size, align);
-        match System.alloc_excess(layout) {
-            Ok(p) => {
-                *excess = p.1;
-                p.0
-            }
-            Err(AllocErr) => 0 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_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 {
-        let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
-        let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
-        match System.realloc_excess(ptr, old_layout, new_layout) {
-            Ok(p) => {
-                *excess = p.1;
-                p.0
-            }
-            Err(AllocErr) => 0 as *mut u8,
+        #[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_grow_in_place(ptr: *mut u8,
-                                             old_size: usize,
-                                             old_align: usize,
-                                             new_size: usize,
-                                             new_align: usize) -> u8 {
-        let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
-        let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
-        match System.grow_in_place(ptr, old_layout, new_layout) {
-            Ok(()) => 1,
-            Err(CannotReallocInPlace) => 0,
+        #[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_shrink_in_place(ptr: *mut u8,
-                                               old_size: usize,
-                                               old_align: usize,
-                                               new_size: usize,
-                                               new_align: usize) -> u8 {
-        let old_layout = Layout::from_size_align_unchecked(old_size, old_align);
-        let new_layout = Layout::from_size_align_unchecked(new_size, new_align);
-        match System.shrink_in_place(ptr, old_layout, new_layout) {
-            Ok(()) => 1,
-            Err(CannotReallocInPlace) => 0,
+        #[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/llvm b/src/llvm
index 6ceaaa4..7243155 160000
--- a/src/llvm
+++ b/src/llvm
@@ -1 +1 @@
-Subproject commit 6ceaaa4b0176a200e4bbd347d6a991ab6c776ede
+Subproject commit 7243155b1c3da0a980c868a87adebf00e0b33989
diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger
index c4c0f1a..c3fc3e5 100644
--- a/src/rustllvm/llvm-rebuild-trigger
+++ b/src/rustllvm/llvm-rebuild-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2018-03-10
+2018-04-05
diff --git a/src/test/compile-fail/allocator/not-an-allocator.rs b/src/test/compile-fail/allocator/not-an-allocator.rs
index e430143..140cad2 100644
--- a/src/test/compile-fail/allocator/not-an-allocator.rs
+++ b/src/test/compile-fail/allocator/not-an-allocator.rs
@@ -12,15 +12,9 @@
 
 #[global_allocator]
 static A: usize = 0;
-//~^ the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
-//~| the trait bound `&usize:
+//~^ the trait bound `usize:
+//~| the trait bound `usize:
+//~| the trait bound `usize:
+//~| the trait bound `usize:
 
 fn main() {}
diff --git a/src/test/run-make-fulldeps/std-core-cycle/bar.rs b/src/test/run-make-fulldeps/std-core-cycle/bar.rs
index 6def5b6..20b8702 100644
--- a/src/test/run-make-fulldeps/std-core-cycle/bar.rs
+++ b/src/test/run-make-fulldeps/std-core-cycle/bar.rs
@@ -11,16 +11,16 @@
 #![feature(allocator_api)]
 #![crate_type = "rlib"]
 
-use std::heap::*;
+use std::alloc::*;
 
 pub struct A;
 
-unsafe impl<'a> Alloc for &'a A {
-    unsafe fn alloc(&mut self, _: Layout) -> Result<*mut u8, AllocErr> {
+unsafe impl GlobalAlloc for A {
+    unsafe fn alloc(&self, _: Layout) -> *mut Void {
         loop {}
     }
 
-    unsafe fn dealloc(&mut self, _ptr: *mut u8, _: Layout) {
+    unsafe fn dealloc(&self, _ptr: *mut Void, _: Layout) {
         loop {}
     }
 }
diff --git a/src/test/run-pass/allocator/auxiliary/custom.rs b/src/test/run-pass/allocator/auxiliary/custom.rs
index 8f4fbcd..95096efc 100644
--- a/src/test/run-pass/allocator/auxiliary/custom.rs
+++ b/src/test/run-pass/allocator/auxiliary/custom.rs
@@ -13,18 +13,18 @@
 #![feature(heap_api, allocator_api)]
 #![crate_type = "rlib"]
 
-use std::heap::{Alloc, System, AllocErr, Layout};
+use std::heap::{GlobalAlloc, System, Layout, Void};
 use std::sync::atomic::{AtomicUsize, Ordering};
 
 pub struct A(pub AtomicUsize);
 
-unsafe impl<'a> Alloc for &'a A {
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
+unsafe impl GlobalAlloc for A {
+    unsafe fn alloc(&self, layout: Layout) -> *mut Void {
         self.0.fetch_add(1, Ordering::SeqCst);
         System.alloc(layout)
     }
 
-    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
+    unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) {
         self.0.fetch_add(1, Ordering::SeqCst);
         System.dealloc(ptr, layout)
     }
diff --git a/src/test/run-pass/allocator/custom.rs b/src/test/run-pass/allocator/custom.rs
index 2208167..f7b2fd7 100644
--- a/src/test/run-pass/allocator/custom.rs
+++ b/src/test/run-pass/allocator/custom.rs
@@ -15,20 +15,20 @@
 
 extern crate helper;
 
-use std::heap::{Heap, Alloc, System, Layout, AllocErr};
+use std::alloc::{self, Global, Alloc, System, Layout, Void};
 use std::sync::atomic::{AtomicUsize, Ordering, ATOMIC_USIZE_INIT};
 
 static HITS: AtomicUsize = ATOMIC_USIZE_INIT;
 
 struct A;
 
-unsafe impl<'a> Alloc for &'a A {
-    unsafe fn alloc(&mut self, layout: Layout) -> Result<*mut u8, AllocErr> {
+unsafe impl alloc::GlobalAlloc for A {
+    unsafe fn alloc(&self, layout: Layout) -> *mut Void {
         HITS.fetch_add(1, Ordering::SeqCst);
         System.alloc(layout)
     }
 
-    unsafe fn dealloc(&mut self, ptr: *mut u8, layout: Layout) {
+    unsafe fn dealloc(&self, ptr: *mut Void, layout: Layout) {
         HITS.fetch_add(1, Ordering::SeqCst);
         System.dealloc(ptr, layout)
     }
@@ -45,10 +45,10 @@
     unsafe {
         let layout = Layout::from_size_align(4, 2).unwrap();
 
-        let ptr = Heap.alloc(layout.clone()).unwrap();
+        let ptr = Global.alloc(layout.clone()).unwrap();
         helper::work_with(&ptr);
         assert_eq!(HITS.load(Ordering::SeqCst), n + 1);
-        Heap.dealloc(ptr, layout.clone());
+        Global.dealloc(ptr, layout.clone());
         assert_eq!(HITS.load(Ordering::SeqCst), n + 2);
 
         let s = String::with_capacity(10);
diff --git a/src/test/run-pass/allocator/xcrate-use.rs b/src/test/run-pass/allocator/xcrate-use.rs
index 04d2ef4..78d604a 100644
--- a/src/test/run-pass/allocator/xcrate-use.rs
+++ b/src/test/run-pass/allocator/xcrate-use.rs
@@ -17,7 +17,7 @@
 extern crate custom;
 extern crate helper;
 
-use std::heap::{Heap, Alloc, System, Layout};
+use std::alloc::{Global, Alloc, System, Layout};
 use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT};
 
 #[global_allocator]
@@ -28,10 +28,10 @@
         let n = GLOBAL.0.load(Ordering::SeqCst);
         let layout = Layout::from_size_align(4, 2).unwrap();
 
-        let ptr = Heap.alloc(layout.clone()).unwrap();
+        let ptr = Global.alloc(layout.clone()).unwrap();
         helper::work_with(&ptr);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 1);
-        Heap.dealloc(ptr, layout.clone());
+        Global.dealloc(ptr, layout.clone());
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), n + 2);
 
         let ptr = System.alloc(layout.clone()).unwrap();
diff --git a/src/test/run-pass/allocator/xcrate-use2.rs b/src/test/run-pass/allocator/xcrate-use2.rs
index 155fb5d..52eb963 100644
--- a/src/test/run-pass/allocator/xcrate-use2.rs
+++ b/src/test/run-pass/allocator/xcrate-use2.rs
@@ -19,7 +19,7 @@
 extern crate custom_as_global;
 extern crate helper;
 
-use std::heap::{Heap, Alloc, System, Layout};
+use std::alloc::{Global, Alloc, GlobalAlloc, System, Layout};
 use std::sync::atomic::{Ordering, ATOMIC_USIZE_INIT};
 
 static GLOBAL: custom::A = custom::A(ATOMIC_USIZE_INIT);
@@ -30,25 +30,25 @@
         let layout = Layout::from_size_align(4, 2).unwrap();
 
         // Global allocator routes to the `custom_as_global` global
-        let ptr = Heap.alloc(layout.clone()).unwrap();
+        let ptr = Global.alloc(layout.clone()).unwrap();
         helper::work_with(&ptr);
         assert_eq!(custom_as_global::get(), n + 1);
-        Heap.dealloc(ptr, layout.clone());
+        Global.dealloc(ptr, layout.clone());
         assert_eq!(custom_as_global::get(), n + 2);
 
         // Usage of the system allocator avoids all globals
-        let ptr = System.alloc(layout.clone()).unwrap();
+        let ptr = System.alloc(layout.clone());
         helper::work_with(&ptr);
         assert_eq!(custom_as_global::get(), n + 2);
         System.dealloc(ptr, layout.clone());
         assert_eq!(custom_as_global::get(), n + 2);
 
         // Usage of our personal allocator doesn't affect other instances
-        let ptr = (&GLOBAL).alloc(layout.clone()).unwrap();
+        let ptr = GLOBAL.alloc(layout.clone());
         helper::work_with(&ptr);
         assert_eq!(custom_as_global::get(), n + 2);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 1);
-        (&GLOBAL).dealloc(ptr, layout);
+        GLOBAL.dealloc(ptr, layout);
         assert_eq!(custom_as_global::get(), n + 2);
         assert_eq!(GLOBAL.0.load(Ordering::SeqCst), 2);
     }