about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-09-28 21:55:15 -0700
committerGitHub <noreply@github.com>2016-09-28 21:55:15 -0700
commit91f34c0c70746f5c938d25d02a8a66b41240b2f0 (patch)
tree5181cf125d06fbb10f8a3d2271003dce4a9f8b62
parenteee2d04d877fe909309c39b6bdf711dc586d0a1e (diff)
parentf12f9504b33b3e98952bc2bbca41fe0b81fac6fe (diff)
downloadrust-91f34c0c70746f5c938d25d02a8a66b41240b2f0.tar.gz
rust-91f34c0c70746f5c938d25d02a8a66b41240b2f0.zip
Auto merge of #36818 - jonathandturner:rollup, r=jonathandturner
Rollup of 12 pull requests

- Successful merges: #35286, #35892, #36460, #36704, #36741, #36760, #36787, #36789, #36794, #36803, #36811, #36813
- Failed merges:
-rwxr-xr-xconfigure4
-rw-r--r--src/bootstrap/bin/rustc.rs3
-rw-r--r--src/bootstrap/compile.rs16
-rw-r--r--src/bootstrap/config.rs3
-rw-r--r--src/bootstrap/sanity.rs27
-rw-r--r--src/doc/book/syntax-index.md5
-rw-r--r--src/doc/grammar.md7
-rw-r--r--src/liballoc/arc.rs2
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/raw_vec.rs1
-rw-r--r--src/liballoc/rc.rs2
-rw-r--r--src/libcollections/lib.rs1
-rw-r--r--src/libcollections/macros.rs4
-rw-r--r--src/libcollections/vec.rs1
-rw-r--r--src/libcompiler_builtins/lib.rs4
-rw-r--r--src/libcore/clone.rs7
-rw-r--r--src/libcore/intrinsics.rs2
-rw-r--r--src/librustc/middle/cstore.rs2
-rw-r--r--src/librustc/middle/dependency_format.rs5
-rw-r--r--src/librustc/middle/weak_lang_items.rs5
-rw-r--r--src/librustc/session/config.rs36
-rw-r--r--src/librustc/session/mod.rs31
-rw-r--r--src/librustc/ty/context.rs17
-rw-r--r--src/librustc_back/lib.rs28
-rw-r--r--src/librustc_back/target/mod.rs21
-rw-r--r--src/librustc_driver/lib.rs39
-rw-r--r--src/librustc_errors/emitter.rs6
-rw-r--r--src/librustc_incremental/persist/directory.rs28
-rw-r--r--src/librustc_metadata/creader.rs4
-rw-r--r--src/librustc_metadata/csearch.rs2
-rw-r--r--src/librustc_metadata/cstore.rs2
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_metadata/schema.rs2
-rw-r--r--src/librustc_resolve/resolve_imports.rs5
-rw-r--r--src/librustc_trans/abi.rs72
-rw-r--r--src/librustc_trans/cabi_aarch64.rs70
-rw-r--r--src/librustc_trans/cabi_arm.rs31
-rw-r--r--src/librustc_trans/cabi_mips.rs68
-rw-r--r--src/librustc_trans/cabi_mips64.rs68
-rw-r--r--src/librustc_trans/cabi_powerpc.rs61
-rw-r--r--src/librustc_trans/cabi_powerpc64.rs63
-rw-r--r--src/librustc_trans/cabi_s390x.rs6
-rw-r--r--src/librustc_trans/cabi_x86_64.rs59
-rw-r--r--src/librustc_typeck/coherence/mod.rs214
-rw-r--r--src/librustc_typeck/coherence/orphan.rs109
-rw-r--r--src/librustc_typeck/coherence/overlap.rs80
-rw-r--r--src/librustc_typeck/coherence/unsafety.rs45
-rw-r--r--src/libstd/collections/hash/table.rs1
-rw-r--r--src/libstd/ffi/c_str.rs4
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libsyntax/ext/base.rs6
-rw-r--r--src/libsyntax/ext/expand.rs17
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs2
-rw-r--r--src/libsyntax/json.rs16
-rw-r--r--src/libsyntax/parse/parser.rs22
-rw-r--r--src/libsyntax/test.rs10
-rw-r--r--src/stage0.txt6
-rw-r--r--src/test/incremental/change_crate_order/auxiliary/a.rs14
-rw-r--r--src/test/incremental/change_crate_order/auxiliary/b.rs14
-rw-r--r--src/test/incremental/change_crate_order/main.rs34
-rw-r--r--src/test/run-make/llvm-phase/test.rs4
-rw-r--r--src/test/run-pass-fulldeps/compiler-calls.rs2
-rw-r--r--src/test/run-pass/cstring-drop.rs49
-rw-r--r--src/test/run-pass/issue-36768.rs18
-rw-r--r--src/test/run-pass/mod_dir_path.rs11
65 files changed, 694 insertions, 808 deletions
diff --git a/configure b/configure
index fd0397e5f87..59a3c1c828d 100755
--- a/configure
+++ b/configure
@@ -645,7 +645,6 @@ valopt datadir "${CFG_PREFIX}/share" "install data"
 valopt infodir "${CFG_PREFIX}/share/info" "install additional info"
 valopt llvm-root "" "set LLVM root"
 valopt python "" "set path to python"
-valopt nodejs "" "set path to nodejs"
 valopt jemalloc-root "" "set directory where libjemalloc_pic.a is located"
 valopt build "${DEFAULT_BUILD}" "GNUs ./configure syntax LLVM build triple"
 valopt android-cross-path "" "Android NDK standalone path (deprecated)"
@@ -762,9 +761,6 @@ if [ $(echo $python_version | grep -c '^Python 2\.7') -ne 1 ]; then
     err "Found $python_version, but Python 2.7 is required"
 fi
 
-# Checking for node, but not required
-probe CFG_NODEJS nodejs node
-
 # If we have no git directory then we are probably a tarball distribution
 # and shouldn't attempt to load submodules
 if [ ! -e ${CFG_SRC_DIR}.git ]
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index a70a15b383c..cdbbc229bc8 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -104,8 +104,7 @@ fn main() {
         let is_panic_abort = args.windows(2).any(|a| {
             &*a[0] == "--crate-name" && &*a[1] == "panic_abort"
         });
-        // FIXME(stage0): remove this `stage != "0"` condition
-        if is_panic_abort && stage != "0" {
+        if is_panic_abort {
             cmd.arg("-C").arg("panic=abort");
         }
 
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index 9de438cfa7d..16dbcae99fa 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -25,7 +25,7 @@ use std::process::Command;
 use build_helper::output;
 use filetime::FileTime;
 
-use util::{exe, staticlib, libdir, mtime, is_dylib, copy};
+use util::{exe, libdir, mtime, is_dylib, copy};
 use {Build, Compiler, Mode};
 
 /// Build the standard library.
@@ -40,20 +40,6 @@ pub fn std<'a>(build: &'a Build, target: &str, compiler: &Compiler<'a>) {
     let libdir = build.sysroot_libdir(compiler, target);
     let _ = fs::remove_dir_all(&libdir);
     t!(fs::create_dir_all(&libdir));
-    // FIXME(stage0) remove this `if` after the next snapshot
-    // The stage0 compiler still passes the `-lcompiler-rt` flag to the linker but now `bootstrap`
-    // never builds a `libcopmiler-rt.a`! We'll fill the hole by simply copying stage0's
-    // `libcompiler-rt.a` to where the stage1's one is expected (though we could as well just use
-    // an empty `.a` archive). Note that the symbols of that stage0 `libcompiler-rt.a` won't make
-    // it to the final binary because now `libcore.rlib` also contains the symbols that
-    // `libcompiler-rt.a` provides. Since that rlib appears first in the linker arguments, its
-    // symbols are used instead of `libcompiler-rt.a`'s.
-    if compiler.stage == 0 {
-        let rtlib = &staticlib("compiler-rt", target);
-        let src = build.rustc.parent().unwrap().parent().unwrap().join("lib").join("rustlib")
-            .join(target).join("lib").join(rtlib);
-        copy(&src, &libdir.join(rtlib));
-    }
 
     // Some platforms have startup objects that may be required to produce the
     // libstd dynamic library, for example.
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index 0f69bcfbb64..a8434c3efb3 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -396,9 +396,6 @@ impl Config {
                     self.rustc = Some(PathBuf::from(value).join("bin/rustc"));
                     self.cargo = Some(PathBuf::from(value).join("bin/cargo"));
                 }
-                "CFG_NODEJS" if value.len() > 0 => {
-                    self.nodejs = Some(PathBuf::from(value));
-                }
                 _ => {}
             }
         }
diff --git a/src/bootstrap/sanity.rs b/src/bootstrap/sanity.rs
index 05c35543e3e..962d0666f69 100644
--- a/src/bootstrap/sanity.rs
+++ b/src/bootstrap/sanity.rs
@@ -40,17 +40,23 @@ pub fn check(build: &mut Build) {
             panic!("PATH contains invalid character '\"'");
         }
     }
-    let mut need_cmd = |cmd: &OsStr| {
-        if !checked.insert(cmd.to_owned()) {
-            return
-        }
+    let have_cmd = |cmd: &OsStr| {
         for path in env::split_paths(&path).map(|p| p.join(cmd)) {
             if fs::metadata(&path).is_ok() ||
                fs::metadata(path.with_extension("exe")).is_ok() {
-                return
+                return Some(path);
             }
         }
-        panic!("\n\ncouldn't find required command: {:?}\n\n", cmd);
+        return None;
+    };
+
+    let mut need_cmd = |cmd: &OsStr| {
+        if !checked.insert(cmd.to_owned()) {
+            return
+        }
+        if have_cmd(cmd).is_none() {
+            panic!("\n\ncouldn't find required command: {:?}\n\n", cmd);
+        }
     };
 
     // If we've got a git directory we're gona need git to update
@@ -75,8 +81,13 @@ pub fn check(build: &mut Build) {
 
     need_cmd("python".as_ref());
 
-    // If a manual nodejs was added to the config,
-    // of if a nodejs install is detected through config, use it.
+    // Look for the nodejs command, needed for emscripten testing
+    if let Some(node) = have_cmd("node".as_ref()) {
+        build.config.nodejs = Some(node);
+    } else if let Some(node) = have_cmd("nodejs".as_ref()) {
+        build.config.nodejs = Some(node);
+    }
+
     if let Some(ref s) = build.config.nodejs {
         need_cmd(s.as_ref());
     }
diff --git a/src/doc/book/syntax-index.md b/src/doc/book/syntax-index.md
index 0259db221b6..1e05b01d30d 100644
--- a/src/doc/book/syntax-index.md
+++ b/src/doc/book/syntax-index.md
@@ -61,7 +61,6 @@
 * `-` (`- expr`): arithmetic negation.  Overloadable (`Neg`).
 * `-=` (`var -= expr`): arithmetic subtraction & assignment. Overloadable (`SubAssign`).
 * `->` (`fn(…) -> type`, `|…| -> type`): function and closure return type.  See [Functions], [Closures].
-* `-> !` (`fn(…) -> !`, `|…| -> !`): diverging function or closure. See [Diverging Functions].
 * `.` (`expr.ident`): member access.  See [Structs], [Method Syntax].
 * `..` (`..`, `expr..`, `..expr`, `expr..expr`): right-exclusive range literal.
 * `..` (`..expr`): struct literal update syntax.  See [Structs (Update syntax)].
@@ -159,6 +158,10 @@
 * `/*!…*/`: inner block doc comment.  See [Comments].
 * `/**…*/`: outer block doc comment.  See [Comments].
 
+<!-- Special types -->
+
+* `!`: always empty Never type.  See [Diverging Functions].
+
 <!-- Various things involving parens and tuples -->
 
 * `()`: empty tuple (*a.k.a.* unit), both literal and type.
diff --git a/src/doc/grammar.md b/src/doc/grammar.md
index be64379b516..690d44cc2cb 100644
--- a/src/doc/grammar.md
+++ b/src/doc/grammar.md
@@ -764,6 +764,13 @@ bound-list := bound | bound '+' bound-list
 bound := path | lifetime
 ```
 
+### Never type
+An empty type
+
+```antlr
+never_type : "!" ;
+```
+
 ### Object types
 
 **FIXME:** grammar?
diff --git a/src/liballoc/arc.rs b/src/liballoc/arc.rs
index 5f9ccd1820c..e3c92fc1aa8 100644
--- a/src/liballoc/arc.rs
+++ b/src/liballoc/arc.rs
@@ -127,7 +127,6 @@ const MAX_REFCOUNT: usize = (isize::MAX) as usize;
 /// }
 /// ```
 
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Arc<T: ?Sized> {
     ptr: Shared<ArcInner<T>>,
@@ -153,7 +152,6 @@ impl<T: ?Sized + Unsize<U>, U: ?Sized> CoerceUnsized<Arc<U>> for Arc<T> {}
 /// nodes behind strong `Arc<T>` pointers, and then storing the parent pointers
 /// as `Weak<T>` pointers.
 
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
 #[stable(feature = "arc_weak", since = "1.4.0")]
 pub struct Weak<T: ?Sized> {
     ptr: Shared<ArcInner<T>>,
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index c6453da3f46..31491106d97 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -88,7 +88,6 @@
 #![feature(staged_api)]
 #![feature(unboxed_closures)]
 #![feature(unique)]
-#![cfg_attr(stage0, feature(unsafe_no_drop_flag))]
 #![feature(unsize)]
 
 #![cfg_attr(not(test), feature(fused, fn_traits, placement_new_protocol))]
diff --git a/src/liballoc/raw_vec.rs b/src/liballoc/raw_vec.rs
index 23542215fa8..e153507956b 100644
--- a/src/liballoc/raw_vec.rs
+++ b/src/liballoc/raw_vec.rs
@@ -44,7 +44,6 @@ use core::cmp;
 /// `shrink_to_fit`, and `from_box` will actually set RawVec's private capacity
 /// field. This allows zero-sized types to not be special-cased by consumers of
 /// this type.
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
 pub struct RawVec<T> {
     ptr: Unique<T>,
     cap: usize,
diff --git a/src/liballoc/rc.rs b/src/liballoc/rc.rs
index e0f635f195b..4a4de419f2e 100644
--- a/src/liballoc/rc.rs
+++ b/src/liballoc/rc.rs
@@ -252,7 +252,6 @@ struct RcBox<T: ?Sized> {
 /// that you have to call them as e.g. `Rc::get_mut(&value)` instead of
 /// `value.get_mut()`.  This avoids conflicts with methods of the inner
 /// type `T`.
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Rc<T: ?Sized> {
     ptr: Shared<RcBox<T>>,
@@ -873,7 +872,6 @@ impl<T> From<T> for Rc<T> {
 ///
 /// [rc]: struct.Rc.html
 /// [downgrade]: struct.Rc.html#method.downgrade
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
 #[stable(feature = "rc_weak", since = "1.4.0")]
 pub struct Weak<T: ?Sized> {
     ptr: Shared<RcBox<T>>,
diff --git a/src/libcollections/lib.rs b/src/libcollections/lib.rs
index c5a92169347..990de541b67 100644
--- a/src/libcollections/lib.rs
+++ b/src/libcollections/lib.rs
@@ -52,7 +52,6 @@
 #![feature(step_by)]
 #![feature(unicode)]
 #![feature(unique)]
-#![cfg_attr(stage0, feature(unsafe_no_drop_flag))]
 #![cfg_attr(test, feature(rand, test))]
 
 #![no_std]
diff --git a/src/libcollections/macros.rs b/src/libcollections/macros.rs
index d6a8362d581..3115be00a4d 100644
--- a/src/libcollections/macros.rs
+++ b/src/libcollections/macros.rs
@@ -68,7 +68,9 @@ macro_rules! vec {
 }
 
 /// Use the syntax described in `std::fmt` to create a value of type `String`.
-/// See `std::fmt` for more information.
+/// See [`std::fmt`][fmt] for more information.
+///
+/// [fmt]: ../std/fmt/index.html
 ///
 /// # Examples
 ///
diff --git a/src/libcollections/vec.rs b/src/libcollections/vec.rs
index f8b4a92df2c..e868a542d55 100644
--- a/src/libcollections/vec.rs
+++ b/src/libcollections/vec.rs
@@ -268,7 +268,6 @@ use super::range::RangeArgument;
 /// Vec does not currently guarantee the order in which elements are dropped
 /// (the order has changed in the past, and may change again).
 ///
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Vec<T> {
     buf: RawVec<T>,
diff --git a/src/libcompiler_builtins/lib.rs b/src/libcompiler_builtins/lib.rs
index fbcf5204d25..4a703b3da68 100644
--- a/src/libcompiler_builtins/lib.rs
+++ b/src/libcompiler_builtins/lib.rs
@@ -8,9 +8,9 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![cfg_attr(not(stage0), feature(compiler_builtins))]
+#![feature(compiler_builtins)]
 #![no_std]
-#![cfg_attr(not(stage0), compiler_builtins)]
+#![compiler_builtins]
 #![unstable(feature = "compiler_builtins_lib",
             reason = "internal implementation detail of rustc right now",
             issue = "0")]
diff --git a/src/libcore/clone.rs b/src/libcore/clone.rs
index 0b800cacfc1..d72b18ae345 100644
--- a/src/libcore/clone.rs
+++ b/src/libcore/clone.rs
@@ -129,13 +129,6 @@ pub struct AssertParamIsClone<T: Clone + ?Sized> { _field: ::marker::PhantomData
            reason = "deriving hack, should not be public",
            issue = "0")]
 pub struct AssertParamIsCopy<T: Copy + ?Sized> { _field: ::marker::PhantomData<T> }
-#[cfg(stage0)]
-#[doc(hidden)]
-#[inline(always)]
-#[unstable(feature = "derive_clone_copy",
-           reason = "deriving hack, should not be public",
-           issue = "0")]
-pub fn assert_receiver_is_clone<T: Clone + ?Sized>(_: &T) {}
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T: ?Sized> Clone for &'a T {
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index 6c4da2a8851..e844a158484 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -194,14 +194,12 @@ extern "rust-intrinsic" {
     /// own, or if it does not enable any significant optimizations.
     pub fn assume(b: bool);
 
-    #[cfg(not(stage0))]
     /// Hints to the compiler that branch condition is likely to be true.
     /// Returns the value passed to it.
     ///
     /// Any use other than with `if` statements will probably not have an effect.
     pub fn likely(b: bool) -> bool;
 
-    #[cfg(not(stage0))]
     /// Hints to the compiler that branch condition is likely to be false.
     /// Returns the value passed to it.
     ///
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 107cf9b6cae..4e83cc328f8 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -32,7 +32,6 @@ use ty::{self, Ty, TyCtxt};
 use mir::repr::Mir;
 use mir::mir_map::MirMap;
 use session::Session;
-use session::config::PanicStrategy;
 use session::search_paths::PathKind;
 use util::nodemap::{NodeSet, DefIdMap};
 use std::path::PathBuf;
@@ -46,6 +45,7 @@ use syntax_pos::Span;
 use rustc_back::target::Target;
 use hir;
 use hir::intravisit::Visitor;
+use rustc_back::PanicStrategy;
 
 pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown};
 
diff --git a/src/librustc/middle/dependency_format.rs b/src/librustc/middle/dependency_format.rs
index c6908e11ed2..159b7256c7a 100644
--- a/src/librustc/middle/dependency_format.rs
+++ b/src/librustc/middle/dependency_format.rs
@@ -64,9 +64,10 @@
 use hir::def_id::CrateNum;
 
 use session;
-use session::config::{self, PanicStrategy};
+use session::config;
 use middle::cstore::LinkagePreference::{self, RequireStatic, RequireDynamic};
 use util::nodemap::FnvHashMap;
+use rustc_back::PanicStrategy;
 
 /// A list of dependencies for a certain crate type.
 ///
@@ -357,7 +358,7 @@ fn verify_ok(sess: &session::Session, list: &[Linkage]) {
     // only one, but we perform validation here that all the panic strategy
     // compilation modes for the whole DAG are valid.
     if let Some((cnum, found_strategy)) = panic_runtime {
-        let desired_strategy = sess.opts.cg.panic.clone();
+        let desired_strategy = sess.panic_strategy();
 
         // First up, validate that our selected panic runtime is indeed exactly
         // our same strategy.
diff --git a/src/librustc/middle/weak_lang_items.rs b/src/librustc/middle/weak_lang_items.rs
index c2f275e6dea..aa75c7a572b 100644
--- a/src/librustc/middle/weak_lang_items.rs
+++ b/src/librustc/middle/weak_lang_items.rs
@@ -10,10 +10,11 @@
 
 //! Validity checking for weak lang items
 
-use session::config::{self, PanicStrategy};
+use session::config;
 use session::Session;
 use middle::lang_items;
 
+use rustc_back::PanicStrategy;
 use syntax::ast;
 use syntax::parse::token::InternedString;
 use syntax_pos::Span;
@@ -92,7 +93,7 @@ fn verify(sess: &Session, items: &lang_items::LanguageItems) {
     // symbols. Other panic runtimes ensure that the relevant symbols are
     // available to link things together, but they're never exercised.
     let mut whitelisted = HashSet::new();
-    if sess.opts.cg.panic != PanicStrategy::Unwind {
+    if sess.panic_strategy() != PanicStrategy::Unwind {
         whitelisted.insert(lang_items::EhPersonalityLangItem);
         whitelisted.insert(lang_items::EhUnwindResumeLangItem);
     }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index e906c24df0f..f8b06bf2e97 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -19,6 +19,7 @@ pub use self::DebugInfoLevel::*;
 use session::{early_error, early_warn, Session};
 use session::search_paths::SearchPaths;
 
+use rustc_back::PanicStrategy;
 use rustc_back::target::Target;
 use lint;
 use middle::cstore;
@@ -492,21 +493,6 @@ impl Passes {
     }
 }
 
-#[derive(Clone, PartialEq, Hash, RustcEncodable, RustcDecodable)]
-pub enum PanicStrategy {
-    Unwind,
-    Abort,
-}
-
-impl PanicStrategy {
-    pub fn desc(&self) -> &str {
-        match *self {
-            PanicStrategy::Unwind => "unwind",
-            PanicStrategy::Abort => "abort",
-        }
-    }
-}
-
 /// Declare a macro that will define all CodegenOptions/DebuggingOptions fields and parsers all
 /// at once. The goal of this macro is to define an interface that can be
 /// programmatically used by the option parser in order to initialize the struct
@@ -620,7 +606,8 @@ macro_rules! options {
 
     #[allow(dead_code)]
     mod $mod_set {
-        use super::{$struct_name, Passes, SomePasses, AllPasses, PanicStrategy};
+        use super::{$struct_name, Passes, SomePasses, AllPasses};
+        use rustc_back::PanicStrategy;
 
         $(
             pub fn $opt(cg: &mut $struct_name, v: Option<&str>) -> bool {
@@ -732,10 +719,10 @@ macro_rules! options {
             }
         }
 
-        fn parse_panic_strategy(slot: &mut PanicStrategy, v: Option<&str>) -> bool {
+        fn parse_panic_strategy(slot: &mut Option<PanicStrategy>, v: Option<&str>) -> bool {
             match v {
-                Some("unwind") => *slot = PanicStrategy::Unwind,
-                Some("abort") => *slot = PanicStrategy::Abort,
+                Some("unwind") => *slot = Some(PanicStrategy::Unwind),
+                Some("abort") => *slot = Some(PanicStrategy::Abort),
                 _ => return false
             }
             true
@@ -809,7 +796,7 @@ options! {CodegenOptions, CodegenSetter, basic_codegen_options,
         "explicitly enable the cfg(debug_assertions) directive"),
     inline_threshold: Option<usize> = (None, parse_opt_uint, [TRACKED],
         "set the inlining threshold for"),
-    panic: PanicStrategy = (PanicStrategy::Unwind, parse_panic_strategy,
+    panic: Option<PanicStrategy> = (None, parse_panic_strategy,
         [TRACKED], "panic strategy to compile crate with"),
 }
 
@@ -1665,9 +1652,10 @@ mod dep_tracking {
     use std::collections::BTreeMap;
     use std::hash::{Hash, SipHasher};
     use std::path::PathBuf;
-    use super::{Passes, PanicStrategy, CrateType, OptLevel, DebugInfoLevel,
+    use super::{Passes, CrateType, OptLevel, DebugInfoLevel,
                 OutputTypes, Externs, ErrorOutputType};
     use syntax::feature_gate::UnstableFeatures;
+    use rustc_back::PanicStrategy;
 
     pub trait DepTrackingHash {
         fn hash(&self, &mut SipHasher, ErrorOutputType);
@@ -1706,6 +1694,7 @@ mod dep_tracking {
     impl_dep_tracking_hash_via_hash!(Option<bool>);
     impl_dep_tracking_hash_via_hash!(Option<usize>);
     impl_dep_tracking_hash_via_hash!(Option<String>);
+    impl_dep_tracking_hash_via_hash!(Option<PanicStrategy>);
     impl_dep_tracking_hash_via_hash!(Option<lint::Level>);
     impl_dep_tracking_hash_via_hash!(Option<PathBuf>);
     impl_dep_tracking_hash_via_hash!(CrateType);
@@ -1772,7 +1761,8 @@ mod tests {
     use std::iter::FromIterator;
     use std::path::PathBuf;
     use std::rc::Rc;
-    use super::{OutputType, OutputTypes, Externs, PanicStrategy};
+    use super::{OutputType, OutputTypes, Externs};
+    use rustc_back::PanicStrategy;
     use syntax::{ast, attr};
     use syntax::parse::token::InternedString;
     use syntax::codemap::dummy_spanned;
@@ -2318,7 +2308,7 @@ mod tests {
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
         opts = reference.clone();
-        opts.cg.panic = PanicStrategy::Abort;
+        opts.cg.panic = Some(PanicStrategy::Abort);
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
     }
 
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 268dbd70bb5..f706bab32c8 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -15,7 +15,7 @@ use lint;
 use middle::cstore::CrateStore;
 use middle::dependency_format;
 use session::search_paths::PathKind;
-use session::config::{DebugInfoLevel, PanicStrategy};
+use session::config::DebugInfoLevel;
 use ty::tls;
 use util::nodemap::{NodeMap, FnvHashMap};
 use util::common::duration_to_secs_str;
@@ -33,6 +33,7 @@ use syntax::{ast, codemap};
 use syntax::feature_gate::AttributeType;
 use syntax_pos::{Span, MultiSpan};
 
+use rustc_back::PanicStrategy;
 use rustc_back::target::Target;
 use rustc_data_structures::flock;
 use llvm;
@@ -42,6 +43,7 @@ use std::cell::{self, Cell, RefCell};
 use std::collections::HashMap;
 use std::env;
 use std::ffi::CString;
+use std::io::Write;
 use std::rc::Rc;
 use std::fmt;
 use std::time::Duration;
@@ -306,9 +308,13 @@ impl Session {
     pub fn lto(&self) -> bool {
         self.opts.cg.lto
     }
+    /// Returns the panic strategy for this compile session. If the user explicitly selected one
+    /// using '-C panic', use that, otherwise use the panic strategy defined by the target.
+    pub fn panic_strategy(&self) -> PanicStrategy {
+        self.opts.cg.panic.unwrap_or(self.target.target.options.panic_strategy)
+    }
     pub fn no_landing_pads(&self) -> bool {
-        self.opts.debugging_opts.no_landing_pads ||
-            self.opts.cg.panic == PanicStrategy::Abort
+        self.opts.debugging_opts.no_landing_pads || self.panic_strategy() == PanicStrategy::Abort
     }
     pub fn unstable_options(&self) -> bool {
         self.opts.debugging_opts.unstable_options
@@ -449,7 +455,8 @@ pub fn build_session(sopts: config::Options,
                                local_crate_source_file,
                                registry,
                                cstore,
-                               Rc::new(codemap::CodeMap::new()))
+                               Rc::new(codemap::CodeMap::new()),
+                               None)
 }
 
 pub fn build_session_with_codemap(sopts: config::Options,
@@ -457,7 +464,8 @@ pub fn build_session_with_codemap(sopts: config::Options,
                                   local_crate_source_file: Option<PathBuf>,
                                   registry: errors::registry::Registry,
                                   cstore: Rc<for<'a> CrateStore<'a>>,
-                                  codemap: Rc<codemap::CodeMap>)
+                                  codemap: Rc<codemap::CodeMap>,
+                                  emitter_dest: Option<Box<Write + Send>>)
                                   -> Session {
     // FIXME: This is not general enough to make the warning lint completely override
     // normal diagnostic warnings, since the warning lint can also be denied and changed
@@ -470,14 +478,21 @@ pub fn build_session_with_codemap(sopts: config::Options,
         .unwrap_or(true);
     let treat_err_as_bug = sopts.debugging_opts.treat_err_as_bug;
 
-    let emitter: Box<Emitter> = match sopts.error_format {
-        config::ErrorOutputType::HumanReadable(color_config) => {
+    let emitter: Box<Emitter> = match (sopts.error_format, emitter_dest) {
+        (config::ErrorOutputType::HumanReadable(color_config), None) => {
             Box::new(EmitterWriter::stderr(color_config,
                                            Some(codemap.clone())))
         }
-        config::ErrorOutputType::Json => {
+        (config::ErrorOutputType::HumanReadable(_), Some(dst)) => {
+            Box::new(EmitterWriter::new(dst,
+                                        Some(codemap.clone())))
+        }
+        (config::ErrorOutputType::Json, None) => {
             Box::new(JsonEmitter::stderr(Some(registry), codemap.clone()))
         }
+        (config::ErrorOutputType::Json, Some(dst)) => {
+            Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone()))
+        }
     };
 
     let diagnostic_handler =
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 0c7c387b67e..b1f80455dd9 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -17,7 +17,7 @@ use hir::TraitMap;
 use hir::def::DefMap;
 use hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE};
 use hir::map as ast_map;
-use hir::map::{DefKey, DefPath, DefPathData, DisambiguatedDefPathData};
+use hir::map::{DefKey, DefPathData, DisambiguatedDefPathData};
 use middle::free_region::FreeRegionMap;
 use middle::region::RegionMaps;
 use middle::resolve_lifetime;
@@ -546,8 +546,11 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         }
     }
 
-    pub fn retrace_path(self, path: &DefPath) -> Option<DefId> {
-        debug!("retrace_path(path={:?}, krate={:?})", path, self.crate_name(path.krate));
+    pub fn retrace_path(self,
+                        krate: CrateNum,
+                        path_data: &[DisambiguatedDefPathData])
+                        -> Option<DefId> {
+        debug!("retrace_path(path={:?}, krate={:?})", path_data, self.crate_name(krate));
 
         let root_key = DefKey {
             parent: None,
@@ -557,22 +560,22 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             },
         };
 
-        let root_index = self.def_index_for_def_key(path.krate, root_key)
+        let root_index = self.def_index_for_def_key(krate, root_key)
                              .expect("no root key?");
 
         debug!("retrace_path: root_index={:?}", root_index);
 
         let mut index = root_index;
-        for data in &path.data {
+        for data in path_data {
             let key = DefKey { parent: Some(index), disambiguated_data: data.clone() };
             debug!("retrace_path: key={:?}", key);
-            match self.def_index_for_def_key(path.krate, key) {
+            match self.def_index_for_def_key(krate, key) {
                 Some(i) => index = i,
                 None => return None,
             }
         }
 
-        Some(DefId { krate: path.krate, index: index })
+        Some(DefId { krate: krate, index: index })
     }
 
     pub fn type_parameter_def(self,
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index f7ae47d2e5e..c0f358ca801 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -45,8 +45,36 @@ extern crate libc;
 extern crate serialize;
 #[macro_use] extern crate log;
 
+extern crate serialize as rustc_serialize; // used by deriving
+
 pub mod tempdir;
 pub mod sha2;
 pub mod target;
 pub mod slice;
 pub mod dynamic_lib;
+
+use serialize::json::{Json, ToJson};
+
+#[derive(Clone, Copy, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
+pub enum PanicStrategy {
+    Unwind,
+    Abort,
+}
+
+impl PanicStrategy {
+    pub fn desc(&self) -> &str {
+        match *self {
+            PanicStrategy::Unwind => "unwind",
+            PanicStrategy::Abort => "abort",
+        }
+    }
+}
+
+impl ToJson for PanicStrategy {
+    fn to_json(&self) -> Json {
+        match *self {
+            PanicStrategy::Abort => "abort".to_json(),
+            PanicStrategy::Unwind => "unwind".to_json(),
+        }
+    }
+}
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 087078021a1..3eddd911749 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -50,6 +50,8 @@ use std::default::Default;
 use std::io::prelude::*;
 use syntax::abi::Abi;
 
+use PanicStrategy;
+
 mod android_base;
 mod apple_base;
 mod apple_ios_base;
@@ -347,6 +349,9 @@ pub struct TargetOptions {
     /// Maximum integer size in bits that this target can perform atomic
     /// operations on.
     pub max_atomic_width: u64,
+
+    /// Panic strategy: "unwind" or "abort"
+    pub panic_strategy: PanicStrategy,
 }
 
 impl Default for TargetOptions {
@@ -396,6 +401,7 @@ impl Default for TargetOptions {
             has_elf_tls: false,
             obj_is_bitcode: false,
             max_atomic_width: 0,
+            panic_strategy: PanicStrategy::Unwind,
         }
     }
 }
@@ -474,6 +480,19 @@ impl Target {
                     .map(|o| o.as_u64()
                          .map(|s| base.options.$key_name = s));
             } );
+            ($key_name:ident, PanicStrategy) => ( {
+                let name = (stringify!($key_name)).replace("_", "-");
+                obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
+                    match s {
+                        "unwind" => base.options.$key_name = PanicStrategy::Unwind,
+                        "abort" => base.options.$key_name = PanicStrategy::Abort,
+                        _ => return Some(Err(format!("'{}' is not a valid value for \
+                                                      panic-strategy. Use 'unwind' or 'abort'.",
+                                                     s))),
+                }
+                Some(Ok(()))
+            })).unwrap_or(Ok(()))
+            } );
             ($key_name:ident, list) => ( {
                 let name = (stringify!($key_name)).replace("_", "-");
                 obj.find(&name[..]).map(|o| o.as_array()
@@ -534,6 +553,7 @@ impl Target {
         key!(has_elf_tls, bool);
         key!(obj_is_bitcode, bool);
         key!(max_atomic_width, u64);
+        try!(key!(panic_strategy, PanicStrategy));
 
         Ok(base)
     }
@@ -676,6 +696,7 @@ impl ToJson for Target {
         target_option_val!(has_elf_tls);
         target_option_val!(obj_is_bitcode);
         target_option_val!(max_atomic_width);
+        target_option_val!(panic_strategy);
 
         Json::Object(d)
     }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 5089af89285..5ac4512fe39 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -74,6 +74,7 @@ use rustc::dep_graph::DepGraph;
 use rustc::session::{self, config, Session, build_session, CompileResult};
 use rustc::session::config::{Input, PrintRequest, OutputType, ErrorOutputType};
 use rustc::session::config::nightly_options;
+use rustc::session::early_error;
 use rustc::lint::Lint;
 use rustc::lint;
 use rustc_metadata::loader;
@@ -93,8 +94,6 @@ use std::str;
 use std::sync::{Arc, Mutex};
 use std::thread;
 
-use rustc::session::early_error;
-
 use syntax::{ast, json};
 use syntax::codemap::{CodeMap, FileLoader, RealFileLoader};
 use syntax::feature_gate::{GatedCfg, UnstableFeatures};
@@ -131,17 +130,18 @@ pub fn abort_on_err<T>(result: Result<T, usize>, sess: &Session) -> T {
     }
 }
 
-pub fn run(args: Vec<String>) -> isize {
+pub fn run<F>(run_compiler: F) -> isize
+    where F: FnOnce() -> (CompileResult, Option<Session>) + Send + 'static
+{
     monitor(move || {
-        let (result, session) = run_compiler(&args, &mut RustcDefaultCalls);
+        let (result, session) = run_compiler();
         if let Err(err_count) = result {
             if err_count > 0 {
                 match session {
                     Some(sess) => sess.fatal(&abort_msg(err_count)),
                     None => {
                         let emitter =
-                            errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
-                                                                   None);
+                            errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto, None);
                         let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
                         handler.emit(&MultiSpan::new(),
                                      &abort_msg(err_count),
@@ -155,20 +155,15 @@ pub fn run(args: Vec<String>) -> isize {
     0
 }
 
-pub fn run_compiler<'a>(args: &[String],
-                        callbacks: &mut CompilerCalls<'a>)
-                        -> (CompileResult, Option<Session>) {
-    run_compiler_with_file_loader(args, callbacks, box RealFileLoader)
-}
-
 // Parse args and run the compiler. This is the primary entry point for rustc.
 // See comments on CompilerCalls below for details about the callbacks argument.
 // The FileLoader provides a way to load files from sources other than the file system.
-pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
-                                            callbacks: &mut CompilerCalls<'a>,
-                                            loader: Box<L>)
-                                            -> (CompileResult, Option<Session>)
-    where L: FileLoader + 'static {
+pub fn run_compiler<'a>(args: &[String],
+                        callbacks: &mut CompilerCalls<'a>,
+                        file_loader: Option<Box<FileLoader + 'static>>,
+                        emitter_dest: Option<Box<Write + Send>>)
+                        -> (CompileResult, Option<Session>)
+{
     macro_rules! do_or_return {($expr: expr, $sess: expr) => {
         match $expr {
             Compilation::Stop => return (Ok(()), $sess),
@@ -207,13 +202,16 @@ pub fn run_compiler_with_file_loader<'a, L>(args: &[String],
 
     let dep_graph = DepGraph::new(sopts.build_dep_graph());
     let cstore = Rc::new(CStore::new(&dep_graph));
+
+    let loader = file_loader.unwrap_or(box RealFileLoader);
     let codemap = Rc::new(CodeMap::with_file_loader(loader));
     let sess = session::build_session_with_codemap(sopts,
                                                    &dep_graph,
                                                    input_file_path,
                                                    descriptions,
                                                    cstore.clone(),
-                                                   codemap);
+                                                   codemap,
+                                                   emitter_dest);
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
     let mut cfg = config::build_configuration(&sess, cfg);
     target_features::add_configuration(&mut cfg, &sess);
@@ -1144,6 +1142,9 @@ pub fn diagnostics_registry() -> errors::registry::Registry {
 }
 
 pub fn main() {
-    let result = run(env::args().collect());
+    let result = run(|| run_compiler(&env::args().collect::<Vec<_>>(),
+                                     &mut RustcDefaultCalls,
+                                     None,
+                                     None));
     process::exit(result as i32);
 }
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index 6456b72dfb5..1d7ff45b3b8 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -99,8 +99,10 @@ impl EmitterWriter {
     pub fn new(dst: Box<Write + Send>,
                code_map: Option<Rc<CodeMapper>>)
                -> EmitterWriter {
-        EmitterWriter { dst: Raw(dst),
-                        cm: code_map}
+        EmitterWriter {
+            dst: Raw(dst),
+            cm: code_map,
+        }
     }
 
     fn preprocess_annotations(&self, msp: &MultiSpan) -> Vec<FileWithAnnotatedLines> {
diff --git a/src/librustc_incremental/persist/directory.rs b/src/librustc_incremental/persist/directory.rs
index 619e237ee34..d238121872b 100644
--- a/src/librustc_incremental/persist/directory.rs
+++ b/src/librustc_incremental/persist/directory.rs
@@ -20,6 +20,7 @@ use rustc::ty::TyCtxt;
 use rustc::util::nodemap::DefIdMap;
 use std::fmt::{self, Debug};
 use std::iter::once;
+use std::collections::HashMap;
 
 /// Index into the DefIdDirectory
 #[derive(Copy, Clone, Debug, PartialOrd, Ord, Hash, PartialEq, Eq,
@@ -90,18 +91,29 @@ impl DefIdDirectory {
     }
 
     pub fn retrace(&self, tcx: TyCtxt) -> RetracedDefIdDirectory {
-        let max_current_crate = self.max_current_crate(tcx);
+
+        fn make_key(name: &str, disambiguator: &str) -> String {
+            format!("{}/{}", name, disambiguator)
+        }
+
+        let new_krates: HashMap<_, _> =
+            once(LOCAL_CRATE)
+            .chain(tcx.sess.cstore.crates())
+            .map(|krate| (make_key(&tcx.crate_name(krate),
+                                   &tcx.crate_disambiguator(krate)), krate))
+            .collect();
 
         let ids = self.paths.iter()
                             .map(|path| {
-                                if self.krate_still_valid(tcx, max_current_crate, path.krate) {
-                                    tcx.retrace_path(path)
+                                let old_krate_id = path.krate.as_usize();
+                                assert!(old_krate_id < self.krates.len());
+                                let old_crate_info = &self.krates[old_krate_id];
+                                let old_crate_key = make_key(&old_crate_info.name,
+                                                         &old_crate_info.disambiguator);
+                                if let Some(&new_crate_key) = new_krates.get(&old_crate_key) {
+                                    tcx.retrace_path(new_crate_key, &path.data)
                                 } else {
-                                    debug!("crate {} changed from {:?} to {:?}/{:?}",
-                                           path.krate,
-                                           self.krates[path.krate.as_usize()],
-                                           tcx.crate_name(path.krate),
-                                           tcx.crate_disambiguator(path.krate));
+                                    debug!("crate {:?} no longer exists", old_crate_key);
                                     None
                                 }
                             })
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index 2e03b7868a3..0c7f6204438 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -19,7 +19,7 @@ use rustc::hir::def_id::{CrateNum, DefIndex};
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::LoadedMacro;
 use rustc::session::{config, Session};
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 use rustc::session::search_paths::PathKind;
 use rustc::middle;
 use rustc::middle::cstore::{CrateStore, validate_crate_name, ExternCrate};
@@ -710,7 +710,7 @@ impl<'a> CrateReader<'a> {
         // The logic for finding the panic runtime here is pretty much the same
         // as the allocator case with the only addition that the panic strategy
         // compilation mode also comes into play.
-        let desired_strategy = self.sess.opts.cg.panic.clone();
+        let desired_strategy = self.sess.panic_strategy();
         let mut runtime_found = false;
         let mut needs_panic_runtime = attr::contains_name(&krate.attrs,
                                                           "needs_panic_runtime");
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
index 1f25136ffe1..16a5b5402fb 100644
--- a/src/librustc_metadata/csearch.rs
+++ b/src/librustc_metadata/csearch.rs
@@ -26,7 +26,7 @@ use rustc::hir::map::DefKey;
 use rustc::mir::repr::Mir;
 use rustc::mir::mir_map::MirMap;
 use rustc::util::nodemap::{NodeSet, DefIdMap};
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 
 use std::path::PathBuf;
 use syntax::ast;
diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs
index 0a1ff70a049..038d0f73d5c 100644
--- a/src/librustc_metadata/cstore.rs
+++ b/src/librustc_metadata/cstore.rs
@@ -19,7 +19,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId};
 use rustc::hir::map::DefKey;
 use rustc::hir::svh::Svh;
 use rustc::middle::cstore::ExternCrate;
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap, FnvHashSet};
 
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 0f067270b80..ca4fb77d95a 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1293,7 +1293,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             triple: tcx.sess.opts.target_triple.clone(),
             hash: link_meta.crate_hash,
             disambiguator: tcx.sess.local_crate_disambiguator().to_string(),
-            panic_strategy: tcx.sess.opts.cg.panic.clone(),
+            panic_strategy: tcx.sess.panic_strategy(),
             plugin_registrar_fn: tcx.sess.plugin_registrar_fn.get().map(|id| {
                 tcx.map.local_def_id(id).index
             }),
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index f4d1e8e17f8..58e18bc709e 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -18,7 +18,7 @@ use rustc::middle::cstore::{LinkagePreference, NativeLibraryKind};
 use rustc::middle::lang_items;
 use rustc::mir;
 use rustc::ty::{self, Ty};
-use rustc::session::config::PanicStrategy;
+use rustc_back::PanicStrategy;
 
 use rustc_serialize as serialize;
 use syntax::{ast, attr};
diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs
index ba45b773c09..1fc9c45de93 100644
--- a/src/librustc_resolve/resolve_imports.rs
+++ b/src/librustc_resolve/resolve_imports.rs
@@ -683,9 +683,8 @@ impl<'a, 'b:'a> ImportResolver<'a, 'b> {
         };
 
         match (value_result, type_result) {
-            // With `#![feature(item_like_imports)]`, all namespaces
-            // must be re-exported with extra visibility for an error to occur.
-            (Ok(value_binding), Ok(type_binding)) if self.new_import_semantics => {
+            // All namespaces must be re-exported with extra visibility for an error to occur.
+            (Ok(value_binding), Ok(type_binding)) => {
                 let vis = directive.vis.get();
                 if !value_binding.pseudo_vis().is_at_least(vis, self) &&
                    !type_binding.pseudo_vis().is_at_least(vis, self) {
diff --git a/src/librustc_trans/abi.rs b/src/librustc_trans/abi.rs
index 683ad76952a..b82c5629f9d 100644
--- a/src/librustc_trans/abi.rs
+++ b/src/librustc_trans/abi.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use llvm::{self, ValueRef};
+use llvm::{self, ValueRef, Integer, Pointer, Float, Double, Struct, Array, Vector};
 use base;
 use build::AllocaFcx;
 use common::{type_is_fat_ptr, BlockAndBuilder, C_uint};
@@ -598,3 +598,73 @@ impl FnType {
         }
     }
 }
+
+pub fn align_up_to(off: usize, a: usize) -> usize {
+    return (off + a - 1) / a * a;
+}
+
+fn align(off: usize, ty: Type, pointer: usize) -> usize {
+    let a = ty_align(ty, pointer);
+    return align_up_to(off, a);
+}
+
+pub fn ty_align(ty: Type, pointer: usize) -> usize {
+    match ty.kind() {
+        Integer => ((ty.int_width() as usize) + 7) / 8,
+        Pointer => pointer,
+        Float => 4,
+        Double => 8,
+        Struct => {
+            if ty.is_packed() {
+                1
+            } else {
+                let str_tys = ty.field_types();
+                str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t, pointer)))
+            }
+        }
+        Array => {
+            let elt = ty.element_type();
+            ty_align(elt, pointer)
+        }
+        Vector => {
+            let len = ty.vector_length();
+            let elt = ty.element_type();
+            ty_align(elt, pointer) * len
+        }
+        _ => bug!("ty_align: unhandled type")
+    }
+}
+
+pub fn ty_size(ty: Type, pointer: usize) -> usize {
+    match ty.kind() {
+        Integer => ((ty.int_width() as usize) + 7) / 8,
+        Pointer => pointer,
+        Float => 4,
+        Double => 8,
+        Struct => {
+            if ty.is_packed() {
+                let str_tys = ty.field_types();
+                str_tys.iter().fold(0, |s, t| s + ty_size(*t, pointer))
+            } else {
+                let str_tys = ty.field_types();
+                let size = str_tys.iter().fold(0, |s, t| {
+                    align(s, *t, pointer) + ty_size(*t, pointer)
+                });
+                align(size, ty, pointer)
+            }
+        }
+        Array => {
+            let len = ty.array_length();
+            let elt = ty.element_type();
+            let eltsz = ty_size(elt, pointer);
+            len * eltsz
+        }
+        Vector => {
+            let len = ty.vector_length();
+            let elt = ty.element_type();
+            let eltsz = ty_size(elt, pointer);
+            len * eltsz
+        },
+        _ => bug!("ty_size: unhandled type")
+    }
+}
diff --git a/src/librustc_trans/cabi_aarch64.rs b/src/librustc_trans/cabi_aarch64.rs
index fc11e3888d3..59a84439950 100644
--- a/src/librustc_trans/cabi_aarch64.rs
+++ b/src/librustc_trans/cabi_aarch64.rs
@@ -11,78 +11,12 @@
 #![allow(non_upper_case_globals)]
 
 use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use abi::{FnType, ArgType};
+use abi::{self, FnType, ArgType};
 use context::CrateContext;
 use type_::Type;
 
-use std::cmp;
-
-fn align_up_to(off: usize, a: usize) -> usize {
-    return (off + a - 1) / a * a;
-}
-
-fn align(off: usize, ty: Type) -> usize {
-    let a = ty_align(ty);
-    return align_up_to(off, a);
-}
-
-fn ty_align(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 8,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                1
-            } else {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
-            }
-        }
-        Array => {
-            let elt = ty.element_type();
-            ty_align(elt)
-        }
-        Vector => {
-            let len = ty.vector_length();
-            let elt = ty.element_type();
-            ty_align(elt) * len
-        }
-        _ => bug!("ty_align: unhandled type")
-    }
-}
-
 fn ty_size(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 8,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(0, |s, t| s + ty_size(*t))
-            } else {
-                let str_tys = ty.field_types();
-                let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
-                align(size, ty)
-            }
-        }
-        Array => {
-            let len = ty.array_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        Vector => {
-            let len = ty.vector_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        _ => bug!("ty_size: unhandled type")
-    }
+    abi::ty_size(ty, 8)
 }
 
 fn is_homogenous_aggregate_ty(ty: Type) -> Option<(Type, u64)> {
diff --git a/src/librustc_trans/cabi_arm.rs b/src/librustc_trans/cabi_arm.rs
index 68a2e8aa8ce..93d43f7d961 100644
--- a/src/librustc_trans/cabi_arm.rs
+++ b/src/librustc_trans/cabi_arm.rs
@@ -11,7 +11,7 @@
 #![allow(non_upper_case_globals)]
 
 use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use abi::{FnType, ArgType};
+use abi::{self, align_up_to, FnType, ArgType};
 use context::CrateContext;
 use type_::Type;
 
@@ -24,40 +24,13 @@ pub enum Flavor {
 
 type TyAlignFn = fn(ty: Type) -> usize;
 
-fn align_up_to(off: usize, a: usize) -> usize {
-    return (off + a - 1) / a * a;
-}
-
 fn align(off: usize, ty: Type, align_fn: TyAlignFn) -> usize {
     let a = align_fn(ty);
     return align_up_to(off, a);
 }
 
 fn general_ty_align(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 4,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                1
-            } else {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(1, |a, t| cmp::max(a, general_ty_align(*t)))
-            }
-        }
-        Array => {
-            let elt = ty.element_type();
-            general_ty_align(elt)
-        }
-        Vector => {
-            let len = ty.vector_length();
-            let elt = ty.element_type();
-            general_ty_align(elt) * len
-        }
-        _ => bug!("ty_align: unhandled type")
-    }
+    abi::ty_align(ty, 4)
 }
 
 // For more information see:
diff --git a/src/librustc_trans/cabi_mips.rs b/src/librustc_trans/cabi_mips.rs
index 680310e195a..25fe53e7ef4 100644
--- a/src/librustc_trans/cabi_mips.rs
+++ b/src/librustc_trans/cabi_mips.rs
@@ -13,77 +13,17 @@
 use libc::c_uint;
 use std::cmp;
 use llvm;
-use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use abi::{ArgType, FnType};
+use llvm::{Integer, Pointer, Float, Double, Vector};
+use abi::{self, align_up_to, ArgType, FnType};
 use context::CrateContext;
 use type_::Type;
 
-fn align_up_to(off: usize, a: usize) -> usize {
-    return (off + a - 1) / a * a;
-}
-
-fn align(off: usize, ty: Type) -> usize {
-    let a = ty_align(ty);
-    return align_up_to(off, a);
-}
-
 fn ty_align(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 4,
-        Float => 4,
-        Double => 8,
-        Struct => {
-          if ty.is_packed() {
-            1
-          } else {
-            let str_tys = ty.field_types();
-            str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
-          }
-        }
-        Array => {
-            let elt = ty.element_type();
-            ty_align(elt)
-        }
-        Vector => {
-            let len = ty.vector_length();
-            let elt = ty.element_type();
-            ty_align(elt) * len
-        }
-        _ => bug!("ty_align: unhandled type")
-    }
+    abi::ty_align(ty, 4)
 }
 
 fn ty_size(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 4,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(0, |s, t| s + ty_size(*t))
-            } else {
-                let str_tys = ty.field_types();
-                let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
-                align(size, ty)
-            }
-        }
-        Array => {
-            let len = ty.array_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        Vector => {
-            let len = ty.vector_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        _ => bug!("ty_size: unhandled type")
-    }
+    abi::ty_size(ty, 4)
 }
 
 fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
diff --git a/src/librustc_trans/cabi_mips64.rs b/src/librustc_trans/cabi_mips64.rs
index e92ef1eaec8..e6b500c88dc 100644
--- a/src/librustc_trans/cabi_mips64.rs
+++ b/src/librustc_trans/cabi_mips64.rs
@@ -13,77 +13,17 @@
 use libc::c_uint;
 use std::cmp;
 use llvm;
-use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use abi::{ArgType, FnType};
+use llvm::{Integer, Pointer, Float, Double, Vector};
+use abi::{self, align_up_to, ArgType, FnType};
 use context::CrateContext;
 use type_::Type;
 
-fn align_up_to(off: usize, a: usize) -> usize {
-    return (off + a - 1) / a * a;
-}
-
-fn align(off: usize, ty: Type) -> usize {
-    let a = ty_align(ty);
-    return align_up_to(off, a);
-}
-
 fn ty_align(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 8,
-        Float => 4,
-        Double => 8,
-        Struct => {
-          if ty.is_packed() {
-            1
-          } else {
-            let str_tys = ty.field_types();
-            str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
-          }
-        }
-        Array => {
-            let elt = ty.element_type();
-            ty_align(elt)
-        }
-        Vector => {
-            let len = ty.vector_length();
-            let elt = ty.element_type();
-            ty_align(elt) * len
-        }
-        _ => bug!("ty_align: unhandled type")
-    }
+    abi::ty_align(ty, 8)
 }
 
 fn ty_size(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 8,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(0, |s, t| s + ty_size(*t))
-            } else {
-                let str_tys = ty.field_types();
-                let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
-                align(size, ty)
-            }
-        }
-        Array => {
-            let len = ty.array_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        Vector => {
-            let len = ty.vector_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        _ => bug!("ty_size: unhandled type")
-    }
+    abi::ty_size(ty, 8)
 }
 
 fn classify_ret_ty(ccx: &CrateContext, ret: &mut ArgType) {
diff --git a/src/librustc_trans/cabi_powerpc.rs b/src/librustc_trans/cabi_powerpc.rs
index e05c31b1d88..4e1d7a93378 100644
--- a/src/librustc_trans/cabi_powerpc.rs
+++ b/src/librustc_trans/cabi_powerpc.rs
@@ -10,67 +10,26 @@
 
 use libc::c_uint;
 use llvm;
-use llvm::{Integer, Pointer, Float, Double, Struct, Array};
-use abi::{FnType, ArgType};
+use llvm::{Integer, Pointer, Float, Double, Vector};
+use abi::{self, align_up_to, FnType, ArgType};
 use context::CrateContext;
 use type_::Type;
 
 use std::cmp;
 
-fn align_up_to(off: usize, a: usize) -> usize {
-    return (off + a - 1) / a * a;
-}
-
-fn align(off: usize, ty: Type) -> usize {
-    let a = ty_align(ty);
-    return align_up_to(off, a);
-}
-
 fn ty_align(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 4,
-        Float => 4,
-        Double => 8,
-        Struct => {
-          if ty.is_packed() {
-            1
-          } else {
-            let str_tys = ty.field_types();
-            str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
-          }
-        }
-        Array => {
-            let elt = ty.element_type();
-            ty_align(elt)
-        }
-        _ => bug!("ty_size: unhandled type")
+    if ty.kind() == Vector {
+        bug!("ty_size: unhandled type")
+    } else {
+        abi::ty_align(ty, 4)
     }
 }
 
 fn ty_size(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 4,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(0, |s, t| s + ty_size(*t))
-            } else {
-                let str_tys = ty.field_types();
-                let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
-                align(size, ty)
-            }
-        }
-        Array => {
-            let len = ty.array_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        _ => bug!("ty_size: unhandled type")
+    if ty.kind() == Vector {
+        bug!("ty_size: unhandled type")
+    } else {
+        abi::ty_size(ty, 4)
     }
 }
 
diff --git a/src/librustc_trans/cabi_powerpc64.rs b/src/librustc_trans/cabi_powerpc64.rs
index ba54e369fd8..cdc7c1fd1af 100644
--- a/src/librustc_trans/cabi_powerpc64.rs
+++ b/src/librustc_trans/cabi_powerpc64.rs
@@ -15,67 +15,16 @@
 // Alignment of 128 bit types is not currently handled, this will
 // need to be fixed when PowerPC vector support is added.
 
-use llvm::{Integer, Pointer, Float, Double, Struct, Array};
-use abi::{FnType, ArgType};
+use llvm::{Integer, Pointer, Float, Double, Struct, Vector, Array};
+use abi::{self, FnType, ArgType};
 use context::CrateContext;
 use type_::Type;
 
-use std::cmp;
-
-fn align_up_to(off: usize, a: usize) -> usize {
-    return (off + a - 1) / a * a;
-}
-
-fn align(off: usize, ty: Type) -> usize {
-    let a = ty_align(ty);
-    return align_up_to(off, a);
-}
-
-fn ty_align(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 8,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                1
-            } else {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
-            }
-        }
-        Array => {
-            let elt = ty.element_type();
-            ty_align(elt)
-        }
-        _ => bug!("ty_align: unhandled type")
-    }
-}
-
 fn ty_size(ty: Type) -> usize {
-    match ty.kind() {
-        Integer => ((ty.int_width() as usize) + 7) / 8,
-        Pointer => 8,
-        Float => 4,
-        Double => 8,
-        Struct => {
-            if ty.is_packed() {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(0, |s, t| s + ty_size(*t))
-            } else {
-                let str_tys = ty.field_types();
-                let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
-                align(size, ty)
-            }
-        }
-        Array => {
-            let len = ty.array_length();
-            let elt = ty.element_type();
-            let eltsz = ty_size(elt);
-            len * eltsz
-        }
-        _ => bug!("ty_size: unhandled type")
+    if ty.kind() == Vector {
+        bug!("ty_size: unhandled type")
+    } else {
+        abi::ty_size(ty, 8)
     }
 }
 
diff --git a/src/librustc_trans/cabi_s390x.rs b/src/librustc_trans/cabi_s390x.rs
index 19404b667e1..5a666c6083d 100644
--- a/src/librustc_trans/cabi_s390x.rs
+++ b/src/librustc_trans/cabi_s390x.rs
@@ -12,16 +12,12 @@
 // for a pre-z13 machine or using -mno-vx.
 
 use llvm::{Integer, Pointer, Float, Double, Struct, Array, Vector};
-use abi::{FnType, ArgType};
+use abi::{align_up_to, FnType, ArgType};
 use context::CrateContext;
 use type_::Type;
 
 use std::cmp;
 
-fn align_up_to(off: usize, a: usize) -> usize {
-    return (off + a - 1) / a * a;
-}
-
 fn align(off: usize, ty: Type) -> usize {
     let a = ty_align(ty);
     return align_up_to(off, a);
diff --git a/src/librustc_trans/cabi_x86_64.rs b/src/librustc_trans/cabi_x86_64.rs
index eb67f4ca618..33990148c8b 100644
--- a/src/librustc_trans/cabi_x86_64.rs
+++ b/src/librustc_trans/cabi_x86_64.rs
@@ -16,12 +16,10 @@ use self::RegClass::*;
 
 use llvm::{Integer, Pointer, Float, Double};
 use llvm::{Struct, Array, Attribute, Vector};
-use abi::{ArgType, FnType};
+use abi::{self, ArgType, FnType};
 use context::CrateContext;
 use type_::Type;
 
-use std::cmp;
-
 #[derive(Clone, Copy, PartialEq)]
 enum RegClass {
     NoClass,
@@ -90,62 +88,11 @@ fn classify_ty(ty: Type) -> Vec<RegClass> {
     }
 
     fn ty_align(ty: Type) -> usize {
-        match ty.kind() {
-            Integer => ((ty.int_width() as usize) + 7) / 8,
-            Pointer => 8,
-            Float => 4,
-            Double => 8,
-            Struct => {
-              if ty.is_packed() {
-                1
-              } else {
-                let str_tys = ty.field_types();
-                str_tys.iter().fold(1, |a, t| cmp::max(a, ty_align(*t)))
-              }
-            }
-            Array => {
-                let elt = ty.element_type();
-                ty_align(elt)
-            }
-            Vector => {
-                let len = ty.vector_length();
-                let elt = ty.element_type();
-                ty_align(elt) * len
-            }
-            _ => bug!("ty_align: unhandled type")
-        }
+        abi::ty_align(ty, 8)
     }
 
     fn ty_size(ty: Type) -> usize {
-        match ty.kind() {
-            Integer => (ty.int_width() as usize + 7) / 8,
-            Pointer => 8,
-            Float => 4,
-            Double => 8,
-            Struct => {
-                let str_tys = ty.field_types();
-                if ty.is_packed() {
-                    str_tys.iter().fold(0, |s, t| s + ty_size(*t))
-                } else {
-                    let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t));
-                    align(size, ty)
-                }
-            }
-            Array => {
-                let len = ty.array_length();
-                let elt = ty.element_type();
-                let eltsz = ty_size(elt);
-                len * eltsz
-            }
-            Vector => {
-                let len = ty.vector_length();
-                let elt = ty.element_type();
-                let eltsz = ty_size(elt);
-                len * eltsz
-            }
-
-            _ => bug!("ty_size: unhandled type")
-        }
+        abi::ty_size(ty, 8)
     }
 
     fn all_mem(cls: &mut [RegClass]) {
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index 3b4c98fc71e..ca22faa2ec3 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -20,7 +20,7 @@ use middle::lang_items::UnsizeTraitLangItem;
 use rustc::ty::subst::Subst;
 use rustc::ty::{self, TyCtxt, TypeFoldable};
 use rustc::traits::{self, Reveal};
-use rustc::ty::{ParameterEnvironment};
+use rustc::ty::ParameterEnvironment;
 use rustc::ty::{Ty, TyBool, TyChar, TyError};
 use rustc::ty::{TyParam, TyRawPtr};
 use rustc::ty::{TyRef, TyAdt, TyTrait, TyNever, TyTuple};
@@ -44,13 +44,13 @@ mod orphan;
 mod overlap;
 mod unsafety;
 
-struct CoherenceChecker<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
+struct CoherenceChecker<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
     crate_context: &'a CrateCtxt<'a, 'gcx>,
     inference_context: InferCtxt<'a, 'gcx, 'tcx>,
 }
 
-struct CoherenceCheckVisitor<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
-    cc: &'a CoherenceChecker<'a, 'gcx, 'tcx>
+struct CoherenceCheckVisitor<'a, 'gcx: 'a + 'tcx, 'tcx: 'a> {
+    cc: &'a CoherenceChecker<'a, 'gcx, 'tcx>,
 }
 
 impl<'a, 'gcx, 'tcx, 'v> intravisit::Visitor<'v> for CoherenceCheckVisitor<'a, 'gcx, 'tcx> {
@@ -62,36 +62,25 @@ impl<'a, 'gcx, 'tcx, 'v> intravisit::Visitor<'v> for CoherenceCheckVisitor<'a, '
 }
 
 impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
-
     // Returns the def ID of the base type, if there is one.
     fn get_base_type_def_id(&self, span: Span, ty: Ty<'tcx>) -> Option<DefId> {
         match ty.sty {
-            TyAdt(def, _) => {
-                Some(def.did)
-            }
+            TyAdt(def, _) => Some(def.did),
 
-            TyTrait(ref t) => {
-                Some(t.principal.def_id())
-            }
+            TyTrait(ref t) => Some(t.principal.def_id()),
 
-            TyBox(_) => {
-                self.inference_context.tcx.lang_items.owned_box()
-            }
+            TyBox(_) => self.inference_context.tcx.lang_items.owned_box(),
 
-            TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) |
-            TyStr | TyArray(..) | TySlice(..) | TyFnDef(..) | TyFnPtr(_) |
-            TyTuple(..) | TyParam(..) | TyError | TyNever |
-            TyRawPtr(_) | TyRef(..) | TyProjection(..) => {
-                None
-            }
+            TyBool | TyChar | TyInt(..) | TyUint(..) | TyFloat(..) | TyStr | TyArray(..) |
+            TySlice(..) | TyFnDef(..) | TyFnPtr(_) | TyTuple(..) | TyParam(..) | TyError |
+            TyNever | TyRawPtr(_) | TyRef(..) | TyProjection(..) => None,
 
             TyInfer(..) | TyClosure(..) | TyAnon(..) => {
                 // `ty` comes from a user declaration so we should only expect types
                 // that the user can type
-                span_bug!(
-                    span,
-                    "coherence encountered unexpected type searching for base type: {}",
-                    ty);
+                span_bug!(span,
+                          "coherence encountered unexpected type searching for base type: {}",
+                          ty);
             }
         }
     }
@@ -100,9 +89,8 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
         // Check implementations and traits. This populates the tables
         // containing the inherent methods and extension methods. It also
         // builds up the trait inheritance table.
-        self.crate_context.tcx.visit_all_items_in_krate(
-            DepNode::CoherenceCheckImpl,
-            &mut CoherenceCheckVisitor { cc: self });
+        self.crate_context.tcx.visit_all_items_in_krate(DepNode::CoherenceCheckImpl,
+                                                        &mut CoherenceCheckVisitor { cc: self });
 
         // Populate the table of destructors. It might seem a bit strange to
         // do this here, but it's actually the most convenient place, since
@@ -167,7 +155,8 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
 
     fn add_trait_impl(&self, impl_trait_ref: ty::TraitRef<'gcx>, impl_def_id: DefId) {
         debug!("add_trait_impl: impl_trait_ref={:?} impl_def_id={:?}",
-               impl_trait_ref, impl_def_id);
+               impl_trait_ref,
+               impl_def_id);
         let trait_def = self.crate_context.tcx.lookup_trait_def(impl_trait_ref.def_id);
         trait_def.record_local_impl(self.crate_context.tcx, impl_def_id, impl_trait_ref);
     }
@@ -176,9 +165,9 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
     fn create_impl_from_item(&self, item: &Item) -> Vec<DefId> {
         match item.node {
             ItemImpl(.., ref impl_items) => {
-                impl_items.iter().map(|impl_item| {
-                    self.crate_context.tcx.map.local_def_id(impl_item.id)
-                }).collect()
+                impl_items.iter()
+                    .map(|impl_item| self.crate_context.tcx.map.local_def_id(impl_item.id))
+                    .collect()
             }
             _ => {
                 span_bug!(item.span, "can't convert a non-impl to an impl");
@@ -186,14 +175,14 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
         }
     }
 
-    //
     // Destructors
     //
 
     fn populate_destructors(&self) {
         let tcx = self.crate_context.tcx;
         let drop_trait = match tcx.lang_items.drop_trait() {
-            Some(id) => id, None => { return }
+            Some(id) => id,
+            None => return,
         };
         tcx.populate_implementations_for_trait_if_necessary(drop_trait);
         let drop_trait = tcx.lookup_trait_def(drop_trait);
@@ -219,13 +208,14 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
                         match tcx.map.find(impl_node_id) {
                             Some(hir_map::NodeItem(item)) => {
                                 let span = match item.node {
-                                    ItemImpl(.., ref ty, _) => {
-                                        ty.span
-                                    },
-                                    _ => item.span
+                                    ItemImpl(.., ref ty, _) => ty.span,
+                                    _ => item.span,
                                 };
-                                struct_span_err!(tcx.sess, span, E0120,
-                                    "the Drop trait may only be implemented on structures")
+                                struct_span_err!(tcx.sess,
+                                                 span,
+                                                 E0120,
+                                                 "the Drop trait may only be implemented on \
+                                                  structures")
                                     .span_label(span,
                                                 &format!("implementing Drop requires a struct"))
                                     .emit();
@@ -254,15 +244,14 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
         let copy_trait = tcx.lookup_trait_def(copy_trait);
 
         copy_trait.for_each_impl(tcx, |impl_did| {
-            debug!("check_implementations_of_copy: impl_did={:?}",
-                   impl_did);
+            debug!("check_implementations_of_copy: impl_did={:?}", impl_did);
 
             let impl_node_id = if let Some(n) = tcx.map.as_local_node_id(impl_did) {
                 n
             } else {
                 debug!("check_implementations_of_copy(): impl not in this \
                         crate");
-                return
+                return;
             };
 
             let self_type = tcx.lookup_item_type(impl_did);
@@ -280,14 +269,12 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
             match param_env.can_type_implement_copy(tcx, self_type, span) {
                 Ok(()) => {}
                 Err(CopyImplementationError::InfrigingField(name)) => {
-                       struct_span_err!(tcx.sess, span, E0204,
-                                 "the trait `Copy` may not be implemented for \
-                                 this type")
-                           .span_label(span, &format!(
-                                 "field `{}` does not implement `Copy`", name)
-                               )
-                           .emit()
-
+                    struct_span_err!(tcx.sess,
+                                     span,
+                                     E0204,
+                                     "the trait `Copy` may not be implemented for this type")
+                        .span_label(span, &format!("field `{}` does not implement `Copy`", name))
+                        .emit()
                 }
                 Err(CopyImplementationError::InfrigingVariant(name)) => {
                     let item = tcx.map.expect_item(impl_node_id);
@@ -297,10 +284,12 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
                         span
                     };
 
-                    struct_span_err!(tcx.sess, span, E0205,
+                    struct_span_err!(tcx.sess,
+                                     span,
+                                     E0205,
                                      "the trait `Copy` may not be implemented for this type")
-                        .span_label(span, &format!("variant `{}` does not implement `Copy`",
-                                                   name))
+                        .span_label(span,
+                                    &format!("variant `{}` does not implement `Copy`", name))
                         .emit()
                 }
                 Err(CopyImplementationError::NotAnAdt) => {
@@ -311,15 +300,19 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
                         span
                     };
 
-                    struct_span_err!(tcx.sess, span, E0206,
+                    struct_span_err!(tcx.sess,
+                                     span,
+                                     E0206,
                                      "the trait `Copy` may not be implemented for this type")
                         .span_label(span, &format!("type is not a structure or enumeration"))
                         .emit();
                 }
                 Err(CopyImplementationError::HasDestructor) => {
-                    struct_span_err!(tcx.sess, span, E0184,
-                              "the trait `Copy` may not be implemented for this type; \
-                               the type has a destructor")
+                    struct_span_err!(tcx.sess,
+                                     span,
+                                     E0184,
+                                     "the trait `Copy` may not be implemented for this type; the \
+                                      type has a destructor")
                         .span_label(span, &format!("Copy not allowed on types with destructors"))
                         .emit();
                 }
@@ -359,7 +352,8 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
             let trait_ref = self.crate_context.tcx.impl_trait_ref(impl_did).unwrap();
             let target = trait_ref.substs.type_at(1);
             debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (bound)",
-                   source, target);
+                   source,
+                   target);
 
             let span = tcx.map.span(impl_node_id);
             let param_env = ParameterEnvironment::for_item(tcx, impl_node_id);
@@ -368,15 +362,19 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
             assert!(!source.has_escaping_regions());
 
             debug!("check_implementations_of_coerce_unsized: {:?} -> {:?} (free)",
-                   source, target);
+                   source,
+                   target);
 
             tcx.infer_ctxt(None, Some(param_env), Reveal::ExactMatch).enter(|infcx| {
                 let origin = TypeOrigin::Misc(span);
-                let check_mutbl = |mt_a: ty::TypeAndMut<'gcx>, mt_b: ty::TypeAndMut<'gcx>,
+                let check_mutbl = |mt_a: ty::TypeAndMut<'gcx>,
+                                   mt_b: ty::TypeAndMut<'gcx>,
                                    mk_ptr: &Fn(Ty<'gcx>) -> Ty<'gcx>| {
                     if (mt_a.mutbl, mt_b.mutbl) == (hir::MutImmutable, hir::MutMutable) {
-                        infcx.report_mismatched_types(origin, mk_ptr(mt_b.ty),
-                                                      target, ty::error::TypeError::Mutability);
+                        infcx.report_mismatched_types(origin,
+                                                      mk_ptr(mt_b.ty),
+                                                      target,
+                                                      ty::error::TypeError::Mutability);
                     }
                     (mt_a.ty, mt_b.ty, unsize_trait, None)
                 };
@@ -394,37 +392,45 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
                     }
 
                     (&ty::TyAdt(def_a, substs_a), &ty::TyAdt(def_b, substs_b))
-                            if def_a.is_struct() && def_b.is_struct() => {
+                        if def_a.is_struct() && def_b.is_struct() => {
                         if def_a != def_b {
                             let source_path = tcx.item_path_str(def_a.did);
                             let target_path = tcx.item_path_str(def_b.did);
-                            span_err!(tcx.sess, span, E0377,
+                            span_err!(tcx.sess,
+                                      span,
+                                      E0377,
                                       "the trait `CoerceUnsized` may only be implemented \
                                        for a coercion between structures with the same \
                                        definition; expected {}, found {}",
-                                      source_path, target_path);
+                                      source_path,
+                                      target_path);
                             return;
                         }
 
                         let fields = &def_a.struct_variant().fields;
-                        let diff_fields = fields.iter().enumerate().filter_map(|(i, f)| {
-                            let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));
-
-                            if f.unsubst_ty().is_phantom_data() {
-                                // Ignore PhantomData fields
-                                None
-                            } else if infcx.sub_types(false, origin, b, a).is_ok() {
-                                // Ignore fields that aren't significantly changed
-                                None
-                            } else {
-                                // Collect up all fields that were significantly changed
-                                // i.e. those that contain T in coerce_unsized T -> U
-                                Some((i, a, b))
-                            }
-                        }).collect::<Vec<_>>();
+                        let diff_fields = fields.iter()
+                            .enumerate()
+                            .filter_map(|(i, f)| {
+                                let (a, b) = (f.ty(tcx, substs_a), f.ty(tcx, substs_b));
+
+                                if f.unsubst_ty().is_phantom_data() {
+                                    // Ignore PhantomData fields
+                                    None
+                                } else if infcx.sub_types(false, origin, b, a).is_ok() {
+                                    // Ignore fields that aren't significantly changed
+                                    None
+                                } else {
+                                    // Collect up all fields that were significantly changed
+                                    // i.e. those that contain T in coerce_unsized T -> U
+                                    Some((i, a, b))
+                                }
+                            })
+                            .collect::<Vec<_>>();
 
                         if diff_fields.is_empty() {
-                            span_err!(tcx.sess, span, E0374,
+                            span_err!(tcx.sess,
+                                      span,
+                                      E0374,
                                       "the trait `CoerceUnsized` may only be implemented \
                                        for a coercion between structures with one field \
                                        being coerced, none found");
@@ -437,16 +443,22 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
                                 tcx.map.span(impl_node_id)
                             };
 
-                            let mut err = struct_span_err!(tcx.sess, span, E0375,
-                                      "implementing the trait `CoerceUnsized` \
-                                       requires multiple coercions");
+                            let mut err = struct_span_err!(tcx.sess,
+                                                           span,
+                                                           E0375,
+                                                           "implementing the trait \
+                                                            `CoerceUnsized` requires multiple \
+                                                            coercions");
                             err.note("`CoerceUnsized` may only be implemented for \
                                       a coercion between structures with one field being coerced");
                             err.note(&format!("currently, {} fields need coercions: {}",
-                                             diff_fields.len(),
-                                             diff_fields.iter().map(|&(i, a, b)| {
-                                                format!("{} ({} to {})", fields[i].name, a, b)
-                                             }).collect::<Vec<_>>().join(", ") ));
+                                              diff_fields.len(),
+                                              diff_fields.iter()
+                                                  .map(|&(i, a, b)| {
+                                                      format!("{} ({} to {})", fields[i].name, a, b)
+                                                  })
+                                                  .collect::<Vec<_>>()
+                                                  .join(", ")));
                             err.span_label(span, &format!("requires multiple coercions"));
                             err.emit();
                             return;
@@ -458,7 +470,9 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
                     }
 
                     _ => {
-                        span_err!(tcx.sess, span, E0376,
+                        span_err!(tcx.sess,
+                                  span,
+                                  E0376,
                                   "the trait `CoerceUnsized` may only be implemented \
                                    for a coercion between structures");
                         return;
@@ -469,8 +483,8 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
 
                 // Register an obligation for `A: Trait<B>`.
                 let cause = traits::ObligationCause::misc(span, impl_node_id);
-                let predicate = tcx.predicate_for_trait_def(cause, trait_def_id, 0,
-                                                            source, &[target]);
+                let predicate =
+                    tcx.predicate_for_trait_def(cause, trait_def_id, 0, source, &[target]);
                 fulfill_cx.register_predicate_obligation(&infcx, predicate);
 
                 // Check that all transitive obligations are satisfied.
@@ -480,8 +494,8 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
 
                 // Finally, resolve all regions.
                 let mut free_regions = FreeRegionMap::new();
-                free_regions.relate_free_regions_from_predicates(
-                    &infcx.parameter_environment.caller_bounds);
+                free_regions.relate_free_regions_from_predicates(&infcx.parameter_environment
+                    .caller_bounds);
                 infcx.resolve_regions_and_report_errors(&free_regions, impl_node_id);
 
                 if let Some(kind) = kind {
@@ -495,7 +509,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> {
 fn enforce_trait_manually_implementable(tcx: TyCtxt, sp: Span, trait_def_id: DefId) {
     if tcx.sess.features.borrow().unboxed_closures {
         // the feature gate allows all of them
-        return
+        return;
     }
     let did = Some(trait_def_id);
     let li = &tcx.lang_items;
@@ -507,14 +521,15 @@ fn enforce_trait_manually_implementable(tcx: TyCtxt, sp: Span, trait_def_id: Def
     } else if did == li.fn_once_trait() {
         "FnOnce"
     } else {
-        return // everything OK
+        return; // everything OK
     };
     let mut err = struct_span_err!(tcx.sess,
                                    sp,
                                    E0183,
                                    "manual implementations of `{}` are experimental",
                                    trait_name);
-    help!(&mut err, "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
+    help!(&mut err,
+          "add `#![feature(unboxed_closures)]` to the crate attributes to enable");
     err.emit();
 }
 
@@ -522,9 +537,10 @@ pub fn check_coherence(ccx: &CrateCtxt) {
     let _task = ccx.tcx.dep_graph.in_task(DepNode::Coherence);
     ccx.tcx.infer_ctxt(None, None, Reveal::ExactMatch).enter(|infcx| {
         CoherenceChecker {
-            crate_context: ccx,
-            inference_context: infcx,
-        }.check();
+                crate_context: ccx,
+                inference_context: infcx,
+            }
+            .check();
     });
     unsafety::check(ccx.tcx);
     orphan::check(ccx.tcx);
diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs
index 70342a0cd25..bff794364c0 100644
--- a/src/librustc_typeck/coherence/orphan.rs
+++ b/src/librustc_typeck/coherence/orphan.rs
@@ -25,17 +25,20 @@ pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.visit_all_items_in_krate(DepNode::CoherenceOrphanCheck, &mut orphan);
 }
 
-struct OrphanChecker<'cx, 'tcx:'cx> {
-    tcx: TyCtxt<'cx, 'tcx, 'tcx>
+struct OrphanChecker<'cx, 'tcx: 'cx> {
+    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
 }
 
 impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
     fn check_def_id(&self, item: &hir::Item, def_id: DefId) {
         if def_id.krate != LOCAL_CRATE {
-            struct_span_err!(self.tcx.sess, item.span, E0116,
-                      "cannot define inherent `impl` for a type outside of the \
-                       crate where the type is defined")
-                .span_label(item.span, &format!("impl for type defined outside of crate."))
+            struct_span_err!(self.tcx.sess,
+                             item.span,
+                             E0116,
+                             "cannot define inherent `impl` for a type outside of the crate \
+                              where the type is defined")
+                .span_label(item.span,
+                            &format!("impl for type defined outside of crate."))
                 .note("define and implement a trait or new type instead")
                 .emit();
         }
@@ -48,11 +51,17 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                             ty: &str,
                             span: Span) {
         match lang_def_id {
-            Some(lang_def_id) if lang_def_id == impl_def_id => { /* OK */ },
+            Some(lang_def_id) if lang_def_id == impl_def_id => {
+                // OK
+            }
             _ => {
-                struct_span_err!(self.tcx.sess, span, E0390,
-                          "only a single inherent implementation marked with `#[lang = \"{}\"]` \
-                           is allowed for the `{}` primitive", lang, ty)
+                struct_span_err!(self.tcx.sess,
+                                 span,
+                                 E0390,
+                                 "only a single inherent implementation marked with `#[lang = \
+                                  \"{}\"]` is allowed for the `{}` primitive",
+                                 lang,
+                                 ty)
                     .span_help(span, "consider using a trait to implement these methods")
                     .emit();
             }
@@ -209,12 +218,14 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                         return;
                     }
                     _ => {
-                        struct_span_err!(self.tcx.sess, ty.span, E0118,
+                        struct_span_err!(self.tcx.sess,
+                                         ty.span,
+                                         E0118,
                                          "no base type found for inherent implementation")
-                        .span_label(ty.span, &format!("impl requires a base type"))
-                        .note(&format!("either implement a trait on it or create a newtype \
-                                        to wrap it instead"))
-                        .emit();
+                            .span_label(ty.span, &format!("impl requires a base type"))
+                            .note(&format!("either implement a trait on it or create a newtype \
+                                            to wrap it instead"))
+                            .emit();
                         return;
                     }
                 }
@@ -226,20 +237,23 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                 let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
                 let trait_def_id = trait_ref.def_id;
                 match traits::orphan_check(self.tcx, def_id) {
-                    Ok(()) => { }
+                    Ok(()) => {}
                     Err(traits::OrphanCheckErr::NoLocalInputType) => {
-                        struct_span_err!(
-                            self.tcx.sess, item.span, E0117,
-                             "only traits defined in the current crate can be \
-                             implemented for arbitrary types")
-                        .span_label(item.span, &format!("impl doesn't use types inside crate"))
-                        .note(&format!("the impl does not reference any \
-                                        types defined in this crate"))
-                        .emit();
+                        struct_span_err!(self.tcx.sess,
+                                         item.span,
+                                         E0117,
+                                         "only traits defined in the current crate can be \
+                                          implemented for arbitrary types")
+                            .span_label(item.span, &format!("impl doesn't use types inside crate"))
+                            .note(&format!("the impl does not reference any types defined in \
+                                            this crate"))
+                            .emit();
                         return;
                     }
                     Err(traits::OrphanCheckErr::UncoveredTy(param_ty)) => {
-                        span_err!(self.tcx.sess, item.span, E0210,
+                        span_err!(self.tcx.sess,
+                                  item.span,
+                                  E0210,
                                   "type parameter `{}` must be used as the type parameter for \
                                    some local type (e.g. `MyStruct<T>`); only traits defined in \
                                    the current crate can be implemented for a type parameter",
@@ -285,10 +299,8 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                        trait_ref,
                        trait_def_id,
                        self.tcx.trait_has_default_impl(trait_def_id));
-                if
-                    self.tcx.trait_has_default_impl(trait_def_id) &&
-                    trait_def_id.krate != LOCAL_CRATE
-                {
+                if self.tcx.trait_has_default_impl(trait_def_id) &&
+                   trait_def_id.krate != LOCAL_CRATE {
                     let self_ty = trait_ref.self_ty();
                     let opt_self_def_id = match self_ty.sty {
                         ty::TyAdt(self_def, _) => Some(self_def.did),
@@ -305,20 +317,17 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                             if self_def_id.is_local() {
                                 None
                             } else {
-                                Some(format!(
-                                    "cross-crate traits with a default impl, like `{}`, \
-                                     can only be implemented for a struct/enum type \
-                                     defined in the current crate",
-                                    self.tcx.item_path_str(trait_def_id)))
+                                Some(format!("cross-crate traits with a default impl, like `{}`, \
+                                              can only be implemented for a struct/enum type \
+                                              defined in the current crate",
+                                             self.tcx.item_path_str(trait_def_id)))
                             }
                         }
                         _ => {
-                            Some(format!(
-                                "cross-crate traits with a default impl, like `{}`, \
-                                 can only be implemented for a struct/enum type, \
-                                 not `{}`",
-                                self.tcx.item_path_str(trait_def_id),
-                                self_ty))
+                            Some(format!("cross-crate traits with a default impl, like `{}`, can \
+                                          only be implemented for a struct/enum type, not `{}`",
+                                         self.tcx.item_path_str(trait_def_id),
+                                         self_ty))
                         }
                     };
 
@@ -330,14 +339,18 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
 
                 // Disallow *all* explicit impls of `Sized` and `Unsize` for now.
                 if Some(trait_def_id) == self.tcx.lang_items.sized_trait() {
-                    struct_span_err!(self.tcx.sess, item.span, E0322,
-                              "explicit impls for the `Sized` trait are not permitted")
+                    struct_span_err!(self.tcx.sess,
+                                     item.span,
+                                     E0322,
+                                     "explicit impls for the `Sized` trait are not permitted")
                         .span_label(item.span, &format!("impl of 'Sized' not allowed"))
                         .emit();
                     return;
                 }
                 if Some(trait_def_id) == self.tcx.lang_items.unsize_trait() {
-                    span_err!(self.tcx.sess, item.span, E0328,
+                    span_err!(self.tcx.sess,
+                              item.span,
+                              E0328,
                               "explicit impls for the `Unsize` trait are not permitted");
                     return;
                 }
@@ -348,9 +361,11 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
                        self.tcx.map.node_to_string(item.id));
                 let trait_ref = self.tcx.impl_trait_ref(def_id).unwrap();
                 if trait_ref.def_id.krate != LOCAL_CRATE {
-                    struct_span_err!(self.tcx.sess, item_trait_ref.path.span, E0318,
-                              "cannot create default implementations for traits outside the \
-                               crate they're defined in; define a new trait instead")
+                    struct_span_err!(self.tcx.sess,
+                                     item_trait_ref.path.span,
+                                     E0318,
+                                     "cannot create default implementations for traits outside \
+                                      the crate they're defined in; define a new trait instead")
                         .span_label(item_trait_ref.path.span,
                                     &format!("`{}` trait not defined in this crate",
                                              item_trait_ref.path))
@@ -365,7 +380,7 @@ impl<'cx, 'tcx> OrphanChecker<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
+impl<'cx, 'tcx, 'v> intravisit::Visitor<'v> for OrphanChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &hir::Item) {
         self.check_item(item);
     }
diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs
index c42b8f88400..1bf140c21a5 100644
--- a/src/librustc_typeck/coherence/overlap.rs
+++ b/src/librustc_typeck/coherence/overlap.rs
@@ -23,15 +23,17 @@ use util::nodemap::DefIdMap;
 use lint;
 
 pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
-    let mut overlap = OverlapChecker { tcx: tcx,
-                                       default_impls: DefIdMap() };
+    let mut overlap = OverlapChecker {
+        tcx: tcx,
+        default_impls: DefIdMap(),
+    };
 
     // this secondary walk specifically checks for some other cases,
     // like defaulted traits, for which additional overlap rules exist
     tcx.visit_all_items_in_krate(DepNode::CoherenceOverlapCheckSpecial, &mut overlap);
 }
 
-struct OverlapChecker<'cx, 'tcx:'cx> {
+struct OverlapChecker<'cx, 'tcx: 'cx> {
     tcx: TyCtxt<'cx, 'tcx, 'tcx>,
 
     // maps from a trait def-id to an impl id
@@ -41,18 +43,21 @@ struct OverlapChecker<'cx, 'tcx:'cx> {
 impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
     fn check_for_common_items_in_impls(&self, impl1: DefId, impl2: DefId) {
         #[derive(Copy, Clone, PartialEq)]
-        enum Namespace { Type, Value }
+        enum Namespace {
+            Type,
+            Value,
+        }
 
         fn name_and_namespace<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                         def_id: DefId)
-                                        -> (ast::Name, Namespace)
-        {
+                                        -> (ast::Name, Namespace) {
             let item = tcx.impl_or_trait_item(def_id);
-            (item.name(), match item {
-                ty::TypeTraitItem(..) => Namespace::Type,
-                ty::ConstTraitItem(..) => Namespace::Value,
-                ty::MethodTraitItem(..) => Namespace::Value,
-            })
+            (item.name(),
+             match item {
+                 ty::TypeTraitItem(..) => Namespace::Type,
+                 ty::ConstTraitItem(..) => Namespace::Value,
+                 ty::MethodTraitItem(..) => Namespace::Value,
+             })
         }
 
         let impl_items = self.tcx.impl_or_trait_item_def_ids.borrow();
@@ -79,11 +84,11 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
         let inherent_impls = self.tcx.inherent_impls.borrow();
         let impls = match inherent_impls.get(&ty_def_id) {
             Some(impls) => impls,
-            None => return
+            None => return,
         };
 
         for (i, &impl1_def_id) in impls.iter().enumerate() {
-            for &impl2_def_id in &impls[(i+1)..] {
+            for &impl2_def_id in &impls[(i + 1)..] {
                 self.tcx.infer_ctxt(None, None, Reveal::ExactMatch).enter(|infcx| {
                     if traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id).is_some() {
                         self.check_for_common_items_in_impls(impl1_def_id, impl2_def_id)
@@ -94,10 +99,12 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
+impl<'cx, 'tcx, 'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &'v hir::Item) {
         match item.node {
-            hir::ItemEnum(..) | hir::ItemStruct(..) | hir::ItemUnion(..) => {
+            hir::ItemEnum(..) |
+            hir::ItemStruct(..) |
+            hir::ItemUnion(..) => {
                 let type_def_id = self.tcx.map.local_def_id(item.id);
                 self.check_for_overlapping_inherent_impls(type_def_id);
             }
@@ -111,12 +118,14 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
 
                 let prev_default_impl = self.default_impls.insert(trait_ref.def_id, item.id);
                 if let Some(prev_id) = prev_default_impl {
-                    let mut err = struct_span_err!(
-                        self.tcx.sess,
-                        self.tcx.span_of_impl(impl_def_id).unwrap(), E0521,
-                        "redundant default implementations of trait `{}`:",
-                        trait_ref);
-                    err.span_note(self.tcx.span_of_impl(self.tcx.map.local_def_id(prev_id))
+                    let mut err = struct_span_err!(self.tcx.sess,
+                                                   self.tcx.span_of_impl(impl_def_id).unwrap(),
+                                                   E0521,
+                                                   "redundant default implementations of trait \
+                                                    `{}`:",
+                                                   trait_ref);
+                    err.span_note(self.tcx
+                                      .span_of_impl(self.tcx.map.local_def_id(prev_id))
                                       .unwrap(),
                                   "redundant implementation is here:");
                     err.emit();
@@ -127,8 +136,8 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
                 let trait_ref = self.tcx.impl_trait_ref(impl_def_id).unwrap();
                 let trait_def_id = trait_ref.def_id;
 
-                let _task = self.tcx.dep_graph.in_task(
-                    DepNode::CoherenceOverlapCheck(trait_def_id));
+                let _task =
+                    self.tcx.dep_graph.in_task(DepNode::CoherenceOverlapCheck(trait_def_id));
 
                 let def = self.tcx.lookup_trait_def(trait_def_id);
 
@@ -137,17 +146,19 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
 
                 // insertion failed due to overlap
                 if let Err(overlap) = insert_result {
-                    let mut err = struct_span_err!(
-                        self.tcx.sess, self.tcx.span_of_impl(impl_def_id).unwrap(), E0119,
-                        "conflicting implementations of trait `{}`{}:",
-                        overlap.trait_desc,
-                        overlap.self_desc.clone().map_or(String::new(),
-                                                         |ty| format!(" for type `{}`", ty)));
+                    let mut err = struct_span_err!(self.tcx.sess,
+                                                   self.tcx.span_of_impl(impl_def_id).unwrap(),
+                                                   E0119,
+                                                   "conflicting implementations of trait `{}`{}:",
+                                                   overlap.trait_desc,
+                                                   overlap.self_desc.clone().map_or(String::new(),
+                                                                                    |ty| {
+                        format!(" for type `{}`", ty)
+                    }));
 
                     match self.tcx.span_of_impl(overlap.with_impl) {
                         Ok(span) => {
-                            err.span_label(span,
-                                           &format!("first implementation here"));
+                            err.span_label(span, &format!("first implementation here"));
                             err.span_label(self.tcx.span_of_impl(impl_def_id).unwrap(),
                                            &format!("conflicting implementation{}",
                                                     overlap.self_desc
@@ -155,8 +166,7 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
                                                                 |ty| format!(" for `{}`", ty))));
                         }
                         Err(cname) => {
-                            err.note(&format!("conflicting implementation in crate `{}`",
-                                              cname));
+                            err.note(&format!("conflicting implementation in crate `{}`", cname));
                         }
                     }
 
@@ -177,7 +187,9 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for OverlapChecker<'cx, 'tcx> {
                         let mut supertrait_def_ids =
                             traits::supertrait_def_ids(self.tcx, data.principal.def_id());
                         if supertrait_def_ids.any(|d| d == trait_def_id) {
-                            span_err!(self.tcx.sess, item.span, E0371,
+                            span_err!(self.tcx.sess,
+                                      item.span,
+                                      E0371,
                                       "the object type `{}` automatically \
                                        implements the trait `{}`",
                                       trait_ref.self_ty(),
diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs
index cdf5478e692..ff55ce0e5eb 100644
--- a/src/librustc_typeck/coherence/unsafety.rs
+++ b/src/librustc_typeck/coherence/unsafety.rs
@@ -20,21 +20,26 @@ pub fn check<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     tcx.map.krate().visit_all_items(&mut orphan);
 }
 
-struct UnsafetyChecker<'cx, 'tcx:'cx> {
-    tcx: TyCtxt<'cx, 'tcx, 'tcx>
+struct UnsafetyChecker<'cx, 'tcx: 'cx> {
+    tcx: TyCtxt<'cx, 'tcx, 'tcx>,
 }
 
 impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
-    fn check_unsafety_coherence(&mut self, item: &'v hir::Item,
+    fn check_unsafety_coherence(&mut self,
+                                item: &'v hir::Item,
                                 unsafety: hir::Unsafety,
                                 polarity: hir::ImplPolarity) {
         match self.tcx.impl_trait_ref(self.tcx.map.local_def_id(item.id)) {
             None => {
                 // Inherent impl.
                 match unsafety {
-                    hir::Unsafety::Normal => { /* OK */ }
+                    hir::Unsafety::Normal => {
+                        // OK
+                    }
                     hir::Unsafety::Unsafe => {
-                        span_err!(self.tcx.sess, item.span, E0197,
+                        span_err!(self.tcx.sess,
+                                  item.span,
+                                  E0197,
                                   "inherent impls cannot be declared as unsafe");
                     }
                 }
@@ -43,31 +48,33 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
             Some(trait_ref) => {
                 let trait_def = self.tcx.lookup_trait_def(trait_ref.def_id);
                 match (trait_def.unsafety, unsafety, polarity) {
-                    (hir::Unsafety::Unsafe,
-                     hir::Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
-                        span_err!(self.tcx.sess, item.span, E0198,
+                    (hir::Unsafety::Unsafe, hir::Unsafety::Unsafe, hir::ImplPolarity::Negative) => {
+                        span_err!(self.tcx.sess,
+                                  item.span,
+                                  E0198,
                                   "negative implementations are not unsafe");
                     }
 
                     (hir::Unsafety::Normal, hir::Unsafety::Unsafe, _) => {
-                        span_err!(self.tcx.sess, item.span, E0199,
+                        span_err!(self.tcx.sess,
+                                  item.span,
+                                  E0199,
                                   "implementing the trait `{}` is not unsafe",
                                   trait_ref);
                     }
 
-                    (hir::Unsafety::Unsafe,
-                     hir::Unsafety::Normal, hir::ImplPolarity::Positive) => {
-                        span_err!(self.tcx.sess, item.span, E0200,
+                    (hir::Unsafety::Unsafe, hir::Unsafety::Normal, hir::ImplPolarity::Positive) => {
+                        span_err!(self.tcx.sess,
+                                  item.span,
+                                  E0200,
                                   "the trait `{}` requires an `unsafe impl` declaration",
                                   trait_ref);
                     }
 
-                    (hir::Unsafety::Unsafe,
-                     hir::Unsafety::Normal, hir::ImplPolarity::Negative) |
-                    (hir::Unsafety::Unsafe,
-                     hir::Unsafety::Unsafe, hir::ImplPolarity::Positive) |
+                    (hir::Unsafety::Unsafe, hir::Unsafety::Normal, hir::ImplPolarity::Negative) |
+                    (hir::Unsafety::Unsafe, hir::Unsafety::Unsafe, hir::ImplPolarity::Positive) |
                     (hir::Unsafety::Normal, hir::Unsafety::Normal, _) => {
-                        /* OK */
+                        // OK
                     }
                 }
             }
@@ -75,7 +82,7 @@ impl<'cx, 'tcx, 'v> UnsafetyChecker<'cx, 'tcx> {
     }
 }
 
-impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
+impl<'cx, 'tcx, 'v> intravisit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
     fn visit_item(&mut self, item: &'v hir::Item) {
         match item.node {
             hir::ItemDefaultImpl(unsafety, _) => {
@@ -84,7 +91,7 @@ impl<'cx, 'tcx,'v> intravisit::Visitor<'v> for UnsafetyChecker<'cx, 'tcx> {
             hir::ItemImpl(unsafety, polarity, ..) => {
                 self.check_unsafety_coherence(item, unsafety, polarity);
             }
-            _ => { }
+            _ => {}
         }
     }
 }
diff --git a/src/libstd/collections/hash/table.rs b/src/libstd/collections/hash/table.rs
index 8f02c9c7d3d..afd833d8bdd 100644
--- a/src/libstd/collections/hash/table.rs
+++ b/src/libstd/collections/hash/table.rs
@@ -59,7 +59,6 @@ const EMPTY_BUCKET: u64 = 0;
 /// around just the "table" part of the hashtable. It enforces some
 /// invariants at the type level and employs some performance trickery,
 /// but in general is just a tricked out `Vec<Option<u64, K, V>>`.
-#[cfg_attr(stage0, unsafe_no_drop_flag)]
 pub struct RawTable<K, V> {
     capacity: usize,
     size: usize,
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index d6a5efbd279..6f5ce350e6c 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -314,9 +314,11 @@ impl CString {
 }
 
 // Turns this `CString` into an empty string to prevent
-// memory unsafe code from working by accident.
+// memory unsafe code from working by accident. Inline
+// to prevent LLVM from optimizing it away in debug builds.
 #[stable(feature = "cstring_drop", since = "1.13.0")]
 impl Drop for CString {
+    #[inline]
     fn drop(&mut self) {
         unsafe { *self.inner.get_unchecked_mut(0) = 0; }
     }
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 912045453e0..b3e4351e9b2 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -278,7 +278,6 @@
 #![feature(unboxed_closures)]
 #![feature(unicode)]
 #![feature(unique)]
-#![cfg_attr(stage0, feature(unsafe_no_drop_flag))]
 #![feature(unwind_attributes)]
 #![feature(vec_push_all)]
 #![feature(zero_one)]
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5082f64ccbb..4f64b3f2e1d 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -557,7 +557,9 @@ pub struct ExpansionData {
     pub depth: usize,
     pub backtrace: ExpnId,
     pub module: Rc<ModuleData>,
-    pub in_block: bool,
+
+    // True if non-inline modules without a `#[path]` are forbidden at the root of this expansion.
+    pub no_noninline_mod: bool,
 }
 
 /// One of these is made during expansion and incrementally updated as we go;
@@ -590,7 +592,7 @@ impl<'a> ExtCtxt<'a> {
                 depth: 0,
                 backtrace: NO_EXPANSION,
                 module: Rc::new(ModuleData { mod_path: Vec::new(), directory: PathBuf::new() }),
-                in_block: false,
+                no_noninline_mod: false,
             },
         }
     }
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 36a33dcc5c5..b1d828d0e3e 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -667,9 +667,9 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
     }
 
     fn fold_block(&mut self, block: P<Block>) -> P<Block> {
-        let orig_in_block = mem::replace(&mut self.cx.current_expansion.in_block, true);
+        let no_noninline_mod = mem::replace(&mut self.cx.current_expansion.no_noninline_mod, true);
         let result = noop_fold_block(block, self);
-        self.cx.current_expansion.in_block = orig_in_block;
+        self.cx.current_expansion.no_noninline_mod = no_noninline_mod;
         result
     }
 
@@ -708,6 +708,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                     return noop_fold_item(item, self);
                 }
 
+                let orig_no_noninline_mod = self.cx.current_expansion.no_noninline_mod;
                 let mut module = (*self.cx.current_expansion.module).clone();
                 module.mod_path.push(item.ident);
 
@@ -717,11 +718,14 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                 let inline_module = item.span.contains(inner) || inner == syntax_pos::DUMMY_SP;
 
                 if inline_module {
-                    module.directory.push(&*{
-                        ::attr::first_attr_value_str_by_name(&item.attrs, "path")
-                            .unwrap_or(item.ident.name.as_str())
-                    });
+                    if let Some(path) = attr::first_attr_value_str_by_name(&item.attrs, "path") {
+                        self.cx.current_expansion.no_noninline_mod = false;
+                        module.directory.push(&*path);
+                    } else {
+                        module.directory.push(&*item.ident.name.as_str());
+                    }
                 } else {
+                    self.cx.current_expansion.no_noninline_mod = false;
                     module.directory =
                         PathBuf::from(self.cx.parse_sess.codemap().span_to_filename(inner));
                     module.directory.pop();
@@ -731,6 +735,7 @@ impl<'a, 'b> Folder for InvocationCollector<'a, 'b> {
                     mem::replace(&mut self.cx.current_expansion.module, Rc::new(module));
                 let result = noop_fold_item(item, self);
                 self.cx.current_expansion.module = orig_module;
+                self.cx.current_expansion.no_noninline_mod = orig_no_noninline_mod;
                 return result;
             }
             // Ensure that test functions are accessible from the test harness.
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index 9f4c0b5eb80..2e0c7ddb540 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -122,7 +122,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                                            rhs);
                 let mut p = Parser::new(cx.parse_sess(), cx.cfg(), Box::new(trncbr));
                 p.directory = cx.current_expansion.module.directory.clone();
-                p.restrictions = match cx.current_expansion.in_block {
+                p.restrictions = match cx.current_expansion.no_noninline_mod {
                     true => Restrictions::NO_NONINLINE_MOD,
                     false => Restrictions::empty(),
                 };
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index a40c30b3e33..a1c273baeea 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -38,14 +38,24 @@ pub struct JsonEmitter {
 }
 
 impl JsonEmitter {
+    pub fn stderr(registry: Option<Registry>,
+                  code_map: Rc<CodeMap>) -> JsonEmitter {
+        JsonEmitter {
+            dst: Box::new(io::stderr()),
+            registry: registry,
+            cm: code_map,
+        }
+    }
+
     pub fn basic() -> JsonEmitter {
         JsonEmitter::stderr(None, Rc::new(CodeMap::new()))
     }
 
-    pub fn stderr(registry: Option<Registry>,
-                  code_map: Rc<CodeMap>) -> JsonEmitter {
+    pub fn new(dst: Box<Write + Send>,
+               registry: Option<Registry>,
+               code_map: Rc<CodeMap>) -> JsonEmitter {
         JsonEmitter {
-            dst: Box::new(io::stderr()),
+            dst: dst,
             registry: registry,
             cm: code_map,
         }
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d5ed1d157e4..5476166932d 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -5274,23 +5274,27 @@ impl<'a> Parser<'a> {
             }
         } else {
             let directory = self.directory.clone();
-            self.push_directory(id, &outer_attrs);
+            let restrictions = self.push_directory(id, &outer_attrs);
             self.expect(&token::OpenDelim(token::Brace))?;
             let mod_inner_lo = self.span.lo;
             let attrs = self.parse_inner_attributes()?;
-            let m = self.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)?;
+            let m = self.with_res(restrictions, |this| {
+                this.parse_mod_items(&token::CloseDelim(token::Brace), mod_inner_lo)
+            })?;
             self.directory = directory;
             Ok((id, ItemKind::Mod(m), Some(attrs)))
         }
     }
 
-    fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) {
-        let default_path = self.id_to_interned_str(id);
-        let file_path = match ::attr::first_attr_value_str_by_name(attrs, "path") {
-            Some(d) => d,
-            None => default_path,
-        };
-        self.directory.push(&*file_path)
+    fn push_directory(&mut self, id: Ident, attrs: &[Attribute]) -> Restrictions {
+        if let Some(path) = ::attr::first_attr_value_str_by_name(attrs, "path") {
+            self.directory.push(&*path);
+            self.restrictions - Restrictions::NO_NONINLINE_MOD
+        } else {
+            let default_path = self.id_to_interned_str(id);
+            self.directory.push(&*default_path);
+            self.restrictions
+        }
     }
 
     pub fn submod_path_from_attr(attrs: &[ast::Attribute], dir_path: &Path) -> Option<PathBuf> {
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index e4510520a55..6ccf9848c6d 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -19,7 +19,7 @@ use std::iter;
 use std::slice;
 use std::mem;
 use std::vec;
-use attr;
+use attr::{self, HasAttrs};
 use syntax_pos::{self, DUMMY_SP, NO_EXPANSION, Span, FileMap, BytePos};
 use std::rc::Rc;
 
@@ -226,12 +226,20 @@ fn mk_reexport_mod(cx: &mut TestCtxt, parent: ast::NodeId, tests: Vec<ast::Ident
                    tested_submods: Vec<(ast::Ident, ast::Ident)>) -> (P<ast::Item>, ast::Ident) {
     let super_ = token::str_to_ident("super");
 
+    // Generate imports with `#[allow(private_in_public)]` to work around issue #36768.
+    let allow_private_in_public = cx.ext_cx.attribute(DUMMY_SP, cx.ext_cx.meta_list(
+        DUMMY_SP,
+        InternedString::new("allow"),
+        vec![cx.ext_cx.meta_list_item_word(DUMMY_SP, InternedString::new("private_in_public"))],
+    ));
     let items = tests.into_iter().map(|r| {
         cx.ext_cx.item_use_simple(DUMMY_SP, ast::Visibility::Public,
                                   cx.ext_cx.path(DUMMY_SP, vec![super_, r]))
+            .map_attrs(|_| vec![allow_private_in_public.clone()])
     }).chain(tested_submods.into_iter().map(|(r, sym)| {
         let path = cx.ext_cx.path(DUMMY_SP, vec![super_, r, sym]);
         cx.ext_cx.item_use_simple_(DUMMY_SP, ast::Visibility::Public, r, path)
+            .map_attrs(|_| vec![allow_private_in_public.clone()])
     })).collect();
 
     let reexport_mod = ast::Mod {
diff --git a/src/stage0.txt b/src/stage0.txt
index f9cf819dc94..05189f2011b 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,6 +12,6 @@
 # tarball for a stable release you'll likely see `1.x.0-$date` where `1.x.0` was
 # released on `$date`
 
-rustc: beta-2016-08-17
-rustc_key: 195e6261
-cargo: nightly-2016-08-21
+rustc: beta-2016-09-28
+rustc_key: 62b3e239
+cargo: nightly-2016-09-26
diff --git a/src/test/incremental/change_crate_order/auxiliary/a.rs b/src/test/incremental/change_crate_order/auxiliary/a.rs
new file mode 100644
index 00000000000..69b4acd3e30
--- /dev/null
+++ b/src/test/incremental/change_crate_order/auxiliary/a.rs
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type="rlib"]
+
+pub static A : u32 = 32;
+
diff --git a/src/test/incremental/change_crate_order/auxiliary/b.rs b/src/test/incremental/change_crate_order/auxiliary/b.rs
new file mode 100644
index 00000000000..1ab97a312c1
--- /dev/null
+++ b/src/test/incremental/change_crate_order/auxiliary/b.rs
@@ -0,0 +1,14 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![crate_type="rlib"]
+
+pub static B: u32 = 32;
+
diff --git a/src/test/incremental/change_crate_order/main.rs b/src/test/incremental/change_crate_order/main.rs
new file mode 100644
index 00000000000..bd8742ff38e
--- /dev/null
+++ b/src/test/incremental/change_crate_order/main.rs
@@ -0,0 +1,34 @@
+// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// aux-build:a.rs
+// aux-build:b.rs
+// revisions:rpass1 rpass2
+
+#![feature(rustc_attrs)]
+
+
+#[cfg(rpass1)]
+extern crate a;
+#[cfg(rpass1)]
+extern crate b;
+
+#[cfg(rpass2)]
+extern crate b;
+#[cfg(rpass2)]
+extern crate a;
+
+use a::A;
+use b::B;
+
+//? #[rustc_clean(label="TypeckItemBody", cfg="rpass2")]
+pub fn main() {
+    A + B;
+}
diff --git a/src/test/run-make/llvm-phase/test.rs b/src/test/run-make/llvm-phase/test.rs
index 19e410fef53..05c1713561a 100644
--- a/src/test/run-make/llvm-phase/test.rs
+++ b/src/test/run-make/llvm-phase/test.rs
@@ -79,8 +79,8 @@ fn main() {
         format!("_ _ --sysroot {} --crate-type dylib", path.to_str().unwrap())
         .split(' ').map(|s| s.to_string()).collect();
 
-    let (result, _) = rustc_driver::run_compiler_with_file_loader(
-        &args, &mut JitCalls, box JitLoader);
+    let (result, _) = rustc_driver::run_compiler(
+        &args, &mut JitCalls, Some(box JitLoader), None);
     if let Err(n) = result {
         panic!("Error {}", n);
     }
diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs
index 775ba38004e..35e9f3f5c8d 100644
--- a/src/test/run-pass-fulldeps/compiler-calls.rs
+++ b/src/test/run-pass-fulldeps/compiler-calls.rs
@@ -86,6 +86,6 @@ fn main() {
     let mut tc = TestCalls { count: 1 };
     // we should never get use this filename, but lets make sure they are valid args.
     let args = vec!["compiler-calls".to_string(), "foo.rs".to_string()];
-    rustc_driver::run_compiler(&args, &mut tc);
+    rustc_driver::run_compiler(&args, &mut tc, None, None);
     assert_eq!(tc.count, 30);
 }
diff --git a/src/test/run-pass/cstring-drop.rs b/src/test/run-pass/cstring-drop.rs
deleted file mode 100644
index 960391bb8de..00000000000
--- a/src/test/run-pass/cstring-drop.rs
+++ /dev/null
@@ -1,49 +0,0 @@
-// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-// ignore-emscripten
-
-// Test that `CString::new("hello").unwrap().as_ptr()` pattern
-// leads to failure.
-
-use std::env;
-use std::ffi::{CString, CStr};
-use std::os::raw::c_char;
-use std::process::{Command, Stdio};
-
-fn main() {
-    let args: Vec<String> = env::args().collect();
-    if args.len() > 1 && args[1] == "child" {
-        // Repeat several times to be more confident that
-        // it is `Drop` for `CString` that does the cleanup,
-        // and not just some lucky UB.
-        let xs = vec![CString::new("Hello").unwrap(); 10];
-        let ys = xs.iter().map(|s| s.as_ptr()).collect::<Vec<_>>();
-        drop(xs);
-        assert!(ys.into_iter().any(is_hello));
-        return;
-    }
-
-    let output = Command::new(&args[0]).arg("child").output().unwrap();
-    assert!(!output.status.success());
-}
-
-fn is_hello(s: *const c_char) -> bool {
-    // `s` is a dangling pointer and reading it is technically
-    // undefined behavior. But we want to prevent the most diabolical
-    // kind of UB (apart from nasal demons): reading a value that was
-    // previously written.
-    //
-    // Segfaulting or reading an empty string is Ok,
-    // reading "Hello" is bad.
-    let s = unsafe { CStr::from_ptr(s) };
-    let hello = CString::new("Hello").unwrap();
-    s == hello.as_ref()
-}
diff --git a/src/test/run-pass/issue-36768.rs b/src/test/run-pass/issue-36768.rs
new file mode 100644
index 00000000000..bb4d12919a1
--- /dev/null
+++ b/src/test/run-pass/issue-36768.rs
@@ -0,0 +1,18 @@
+// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// compile-flags:--test
+#![deny(private_in_public)]
+
+#[test] fn foo() {}
+mod foo {}
+
+#[test] fn core() {}
+extern crate core;
diff --git a/src/test/run-pass/mod_dir_path.rs b/src/test/run-pass/mod_dir_path.rs
index e0327a1dcd4..28dee15cfa0 100644
--- a/src/test/run-pass/mod_dir_path.rs
+++ b/src/test/run-pass/mod_dir_path.rs
@@ -17,4 +17,15 @@ mod mod_dir_simple {
 
 pub fn main() {
     assert_eq!(mod_dir_simple::syrup::foo(), 10);
+
+    #[path = "auxiliary"]
+    mod foo {
+        mod two_macros;
+    }
+
+    #[path = "auxiliary"]
+    mod bar {
+        macro_rules! m { () => { mod two_macros; } }
+        m!();
+    }
 }