about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJeremy Soller <jackpot51@gmail.com>2016-10-31 09:40:24 -0600
committerJeremy Soller <jackpot51@gmail.com>2016-10-31 09:40:24 -0600
commit123d08b3d3901d5725af8303c1329b007089cde5 (patch)
treef257a46a600bfcc8faa09d843f5dbe0aae8c7b3b
parentc77979b419959dda0d628ffb4af15c5f2a9e8648 (diff)
parent074d30d030a3339565ab737c23312e6bbe625431 (diff)
downloadrust-123d08b3d3901d5725af8303c1329b007089cde5.tar.gz
rust-123d08b3d3901d5725af8303c1329b007089cde5.zip
Merge branch 'master' of https://github.com/rust-lang/rust into redox
-rw-r--r--mk/cfg/aarch64-unknown-fuchsia.mk1
-rw-r--r--mk/crates.mk9
-rw-r--r--src/Cargo.lock63
-rw-r--r--src/doc/reference.md12
-rw-r--r--src/liballoc_system/lib.rs5
-rw-r--r--src/libcollectionstest/binary_heap.rs4
-rw-r--r--src/libcollectionstest/btree/map.rs4
-rw-r--r--src/libcollectionstest/btree/mod.rs2
-rw-r--r--src/libcollectionstest/btree/set.rs74
-rw-r--r--src/libcollectionstest/lib.rs4
-rw-r--r--src/libcollectionstest/slice.rs36
-rw-r--r--src/libcollectionstest/vec.rs8
-rw-r--r--src/libcollectionstest/vec_deque.rs10
-rw-r--r--src/libcore/cmp.rs8
-rw-r--r--src/libcore/fmt/mod.rs4
-rw-r--r--src/libcore/macros.rs2
m---------src/liblibc0
-rw-r--r--src/libproc_macro/lib.rs4
-rw-r--r--src/libproc_macro_plugin/Cargo.toml1
-rw-r--r--src/libproc_macro_plugin/lib.rs42
-rw-r--r--src/libproc_macro_plugin/qquote.rs18
-rw-r--r--src/libproc_macro_tokens/Cargo.toml13
-rw-r--r--src/libproc_macro_tokens/build.rs (renamed from src/libproc_macro_plugin/build.rs)0
-rw-r--r--src/libproc_macro_tokens/lib.rs66
-rw-r--r--src/libproc_macro_tokens/parse.rs (renamed from src/libproc_macro_plugin/parse.rs)0
-rw-r--r--src/libproc_macro_tokens/prelude.rs (renamed from src/libproc_macro_plugin/prelude.rs)0
-rw-r--r--src/librustc/hir/lowering.rs5
-rw-r--r--src/librustc/hir/mod.rs3
-rw-r--r--src/librustc/lib.rs13
-rw-r--r--src/librustc/lint/builtin.rs9
-rw-r--r--src/librustc/middle/cstore.rs19
-rw-r--r--src/librustc/middle/expr_use_visitor.rs2
-rw-r--r--src/librustc/mir/cache.rs2
-rw-r--r--src/librustc/mir/mir_map.rs38
-rw-r--r--src/librustc/mir/mod.rs (renamed from src/librustc/mir/repr.rs)18
-rw-r--r--src/librustc/mir/tcx.rs2
-rw-r--r--src/librustc/mir/transform.rs21
-rw-r--r--src/librustc/mir/traversal.rs2
-rw-r--r--src/librustc/mir/visit.rs2
-rw-r--r--src/librustc/session/config.rs7
-rw-r--r--src/librustc/ty/context.rs29
-rw-r--r--src/librustc/ty/maps.rs4
-rw-r--r--src/librustc/ty/mod.rs18
-rw-r--r--src/librustc/ty/util.rs5
-rw-r--r--src/librustc/util/ppaux.rs58
-rw-r--r--src/librustc_back/lib.rs4
-rw-r--r--src/librustc_back/sha2.rs679
-rw-r--r--src/librustc_back/target/aarch64_unknown_fuchsia.rs28
-rw-r--r--src/librustc_back/target/aarch64_unknown_linux_gnu.rs4
-rw-r--r--src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs4
-rw-r--r--src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs4
-rw-r--r--src/librustc_back/target/mips_unknown_linux_gnu.rs4
-rw-r--r--src/librustc_back/target/mips_unknown_linux_musl.rs4
-rw-r--r--src/librustc_back/target/mips_unknown_linux_uclibc.rs4
-rw-r--r--src/librustc_back/target/mipsel_unknown_linux_gnu.rs4
-rw-r--r--src/librustc_back/target/mipsel_unknown_linux_musl.rs4
-rw-r--r--src/librustc_back/target/mipsel_unknown_linux_uclibc.rs4
-rw-r--r--src/librustc_back/target/mod.rs1
-rw-r--r--src/librustc_back/target/powerpc64_unknown_linux_gnu.rs3
-rw-r--r--src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs3
-rw-r--r--src/librustc_back/target/powerpc_unknown_linux_gnu.rs3
-rw-r--r--src/librustc_borrowck/borrowck/mir/abs_domain.rs4
-rw-r--r--src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/dataflow/impls.rs52
-rw-r--r--src/librustc_borrowck/borrowck/mir/dataflow/mod.rs52
-rw-r--r--src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs34
-rw-r--r--src/librustc_borrowck/borrowck/mir/elaborate_drops.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/gather_moves.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mir/mod.rs47
-rw-r--r--src/librustc_borrowck/borrowck/mir/patch.rs2
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs17
-rw-r--r--src/librustc_const_eval/pattern.rs4
-rw-r--r--src/librustc_data_structures/blake2b.rs84
-rw-r--r--src/librustc_data_structures/fmt_wrap.rs31
-rw-r--r--src/librustc_data_structures/lib.rs1
-rw-r--r--src/librustc_driver/Cargo.toml1
-rw-r--r--src/librustc_driver/driver.rs102
-rw-r--r--src/librustc_driver/lib.rs46
-rw-r--r--src/librustc_driver/pretty.rs57
-rw-r--r--src/librustc_driver/test.rs3
-rw-r--r--src/librustc_incremental/calculate_svh/hasher.rs36
-rw-r--r--src/librustc_incremental/persist/dirty_clean.rs2
-rw-r--r--src/librustc_lint/lib.rs4
-rw-r--r--src/librustc_metadata/creader.rs9
-rw-r--r--src/librustc_metadata/cstore_impl.rs20
-rw-r--r--src/librustc_metadata/decoder.rs44
-rw-r--r--src/librustc_metadata/encoder.rs324
-rw-r--r--src/librustc_metadata/index.rs16
-rw-r--r--src/librustc_metadata/index_builder.rs10
-rw-r--r--src/librustc_metadata/lib.rs6
-rw-r--r--src/librustc_metadata/locator.rs289
-rw-r--r--src/librustc_metadata/schema.rs66
-rw-r--r--src/librustc_mir/build/block.rs2
-rw-r--r--src/librustc_mir/build/cfg.rs2
-rw-r--r--src/librustc_mir/build/expr/as_constant.rs2
-rw-r--r--src/librustc_mir/build/expr/as_lvalue.rs2
-rw-r--r--src/librustc_mir/build/expr/as_operand.rs2
-rw-r--r--src/librustc_mir/build/expr/as_rvalue.rs2
-rw-r--r--src/librustc_mir/build/expr/as_temp.rs2
-rw-r--r--src/librustc_mir/build/expr/into.rs2
-rw-r--r--src/librustc_mir/build/expr/stmt.rs2
-rw-r--r--src/librustc_mir/build/into.rs2
-rw-r--r--src/librustc_mir/build/matches/mod.rs2
-rw-r--r--src/librustc_mir/build/matches/simplify.rs2
-rw-r--r--src/librustc_mir/build/matches/test.rs2
-rw-r--r--src/librustc_mir/build/matches/util.rs2
-rw-r--r--src/librustc_mir/build/misc.rs2
-rw-r--r--src/librustc_mir/build/mod.rs2
-rw-r--r--src/librustc_mir/build/scope.rs2
-rw-r--r--src/librustc_mir/def_use.rs2
-rw-r--r--src/librustc_mir/graphviz.rs6
-rw-r--r--src/librustc_mir/hair/cx/expr.rs2
-rw-r--r--src/librustc_mir/hair/cx/mod.rs2
-rw-r--r--src/librustc_mir/hair/mod.rs2
-rw-r--r--src/librustc_mir/mir_map.rs41
-rw-r--r--src/librustc_mir/pretty.rs6
-rw-r--r--src/librustc_mir/transform/add_call_guards.rs2
-rw-r--r--src/librustc_mir/transform/copy_prop.rs2
-rw-r--r--src/librustc_mir/transform/deaggregator.rs2
-rw-r--r--src/librustc_mir/transform/dump_mir.rs2
-rw-r--r--src/librustc_mir/transform/erase_regions.rs2
-rw-r--r--src/librustc_mir/transform/instcombine.rs2
-rw-r--r--src/librustc_mir/transform/no_landing_pads.rs2
-rw-r--r--src/librustc_mir/transform/promote_consts.rs2
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs183
-rw-r--r--src/librustc_mir/transform/simplify_branches.rs2
-rw-r--r--src/librustc_mir/transform/simplify_cfg.rs3
-rw-r--r--src/librustc_mir/transform/type_check.rs4
-rw-r--r--src/librustc_passes/ast_validation.rs10
-rw-r--r--src/librustc_passes/consts.rs8
-rw-r--r--src/librustc_plugin/load.rs10
-rw-r--r--src/librustc_resolve/diagnostics.rs26
-rw-r--r--src/librustc_resolve/lib.rs51
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs4
-rw-r--r--src/librustc_save_analysis/json_dumper.rs8
-rw-r--r--src/librustc_trans/assert_module_sources.rs2
-rw-r--r--src/librustc_trans/back/symbol_names.rs30
-rw-r--r--src/librustc_trans/base.rs28
-rw-r--r--src/librustc_trans/collector.rs19
-rw-r--r--src/librustc_trans/common.rs18
-rw-r--r--src/librustc_trans/context.rs58
-rw-r--r--src/librustc_trans/debuginfo/create_scope_map.rs4
-rw-r--r--src/librustc_trans/debuginfo/metadata.rs45
-rw-r--r--src/librustc_trans/debuginfo/mod.rs2
-rw-r--r--src/librustc_trans/lib.rs1
-rw-r--r--src/librustc_trans/mir/analyze.rs4
-rw-r--r--src/librustc_trans/mir/block.rs11
-rw-r--r--src/librustc_trans/mir/constant.rs6
-rw-r--r--src/librustc_trans/mir/lvalue.rs2
-rw-r--r--src/librustc_trans/mir/mod.rs25
-rw-r--r--src/librustc_trans/mir/operand.rs2
-rw-r--r--src/librustc_trans/mir/rvalue.rs2
-rw-r--r--src/librustc_trans/mir/statement.rs2
-rw-r--r--src/librustc_trans/monomorphize.rs2
-rw-r--r--src/librustc_typeck/astconv.rs22
-rw-r--r--src/librustc_typeck/check/_match.rs3
-rw-r--r--src/librustc_typeck/check/coercion.rs35
-rw-r--r--src/librustc_typeck/check/mod.rs139
-rw-r--r--src/librustc_typeck/diagnostics.rs11
-rw-r--r--src/librustdoc/core.rs10
-rw-r--r--src/librustdoc/test.rs36
-rw-r--r--src/libstd/build.rs2
-rw-r--r--src/libstd/io/impls.rs11
-rw-r--r--src/libstd/macros.rs2
-rw-r--r--src/libstd/os/raw.rs6
-rw-r--r--src/libstd/sys/unix/rand.rs54
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/attr.rs13
-rw-r--r--src/libsyntax/config.rs6
-rw-r--r--src/libsyntax/ext/base.rs8
-rw-r--r--src/libsyntax/ext/expand.rs5
-rw-r--r--src/libsyntax/ext/quote.rs14
-rw-r--r--src/libsyntax/ext/source_util.rs11
-rw-r--r--src/libsyntax/ext/tt/macro_parser.rs23
-rw-r--r--src/libsyntax/ext/tt/macro_rules.rs4
-rw-r--r--src/libsyntax/ext/tt/transcribe.rs7
-rw-r--r--src/libsyntax/fold.rs5
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/parse/mod.rs144
-rw-r--r--src/libsyntax/parse/parser.rs43
-rw-r--r--src/libsyntax/test.rs2
-rw-r--r--src/libsyntax/tokenstream.rs2
-rw-r--r--src/libsyntax/util/parser_testing.rs5
-rw-r--r--src/libsyntax/util/small_vector.rs50
-rw-r--r--src/libsyntax_ext/asm.rs2
-rw-r--r--src/libsyntax_ext/cfg.rs2
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs3
-rw-r--r--src/libsyntax_ext/proc_macro_registrar.rs2
-rw-r--r--src/libsyntax_pos/lib.rs3
m---------src/llvm0
-rw-r--r--src/rustllvm/llvm-auto-clean-trigger2
-rw-r--r--src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs3
-rw-r--r--src/test/compile-fail-fulldeps/issue-18986.rs2
-rw-r--r--src/test/compile-fail-fulldeps/qquote.rs2
-rw-r--r--src/test/compile-fail/E0071.rs9
-rw-r--r--src/test/compile-fail/enums-are-namespaced-xc.rs3
-rw-r--r--src/test/compile-fail/issue-12612.rs2
-rw-r--r--src/test/compile-fail/issue-16058.rs2
-rw-r--r--src/test/compile-fail/issue-1697.rs2
-rw-r--r--src/test/compile-fail/issue-17001.rs2
-rw-r--r--src/test/compile-fail/issue-17405.rs2
-rw-r--r--src/test/compile-fail/issue-17518.rs2
-rw-r--r--src/test/compile-fail/issue-21449.rs3
-rw-r--r--src/test/compile-fail/issue-26459.rs2
-rw-r--r--src/test/compile-fail/issue-27815.rs8
-rw-r--r--src/test/compile-fail/issue-36116.rs23
-rw-r--r--src/test/compile-fail/lexical-scopes.rs2
-rw-r--r--src/test/compile-fail/no-patterns-in-args-2.rs23
-rw-r--r--src/test/compile-fail/struct-path-alias-bounds.rs (renamed from src/test/compile-fail/E0422.rs)14
-rw-r--r--src/test/compile-fail/struct-path-associated-type.rs48
-rw-r--r--src/test/compile-fail/struct-path-self-type-mismatch.rs38
-rw-r--r--src/test/compile-fail/struct-path-self.rs47
-rw-r--r--src/test/compile-fail/trait-as-struct-constructor.rs3
-rw-r--r--src/test/compile-fail/unresolved-import.rs2
-rw-r--r--src/test/incremental/hashes/trait_defs.rs8
-rw-r--r--src/test/run-fail-fulldeps/qquote.rs2
-rw-r--r--src/test/run-make/issue-19371/foo.rs10
-rw-r--r--src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs5
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs4
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs4
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs4
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs2
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs2
-rw-r--r--src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs4
-rw-r--r--src/test/run-pass-fulldeps/compiler-calls.rs1
-rw-r--r--src/test/run-pass-fulldeps/macro-quote-1.rs4
-rw-r--r--src/test/run-pass-fulldeps/qquote.rs2
-rw-r--r--src/test/run-pass/by-value-self-in-mut-slot.rs2
-rw-r--r--src/test/run-pass/import-glob-crate.rs12
-rw-r--r--src/test/run-pass/issue-22546.rs6
-rw-r--r--src/test/run-pass/struct-path-associated-type.rs (renamed from src/test/compile-fail/struct-pat-associated-path.rs)30
-rw-r--r--src/test/run-pass/struct-path-self.rs54
-rw-r--r--src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs21
-rw-r--r--src/test/run-pass/uniq-self-in-mut-slot.rs2
-rw-r--r--src/tools/cargotest/main.rs2
-rw-r--r--src/tools/tidy/src/bins.rs25
-rw-r--r--src/tools/tidy/src/features.rs113
237 files changed, 2126 insertions, 2582 deletions
diff --git a/mk/cfg/aarch64-unknown-fuchsia.mk b/mk/cfg/aarch64-unknown-fuchsia.mk
new file mode 100644
index 00000000000..34aee77ae21
--- /dev/null
+++ b/mk/cfg/aarch64-unknown-fuchsia.mk
@@ -0,0 +1 @@
+# rustbuild-only target
diff --git a/mk/crates.mk b/mk/crates.mk
index efe7a579801..25192bfd27a 100644
--- a/mk/crates.mk
+++ b/mk/crates.mk
@@ -60,8 +60,8 @@ RUSTC_CRATES := rustc rustc_typeck rustc_mir rustc_borrowck rustc_resolve rustc_
                 rustc_data_structures rustc_platform_intrinsics rustc_errors \
                 rustc_plugin rustc_metadata rustc_passes rustc_save_analysis \
                 rustc_const_eval rustc_const_math rustc_incremental proc_macro
-HOST_CRATES := syntax syntax_ext proc_macro_plugin syntax_pos $(RUSTC_CRATES) rustdoc fmt_macros \
-		flate arena graphviz log serialize
+HOST_CRATES := syntax syntax_ext proc_macro_tokens proc_macro_plugin syntax_pos $(RUSTC_CRATES) \
+		rustdoc fmt_macros flate arena graphviz log serialize
 TOOLS := compiletest rustdoc rustc rustbook error_index_generator
 
 DEPS_core :=
@@ -102,8 +102,9 @@ DEPS_test := std getopts term native:rust_test_helpers
 
 DEPS_syntax := std term serialize log arena libc rustc_bitflags rustc_unicode rustc_errors syntax_pos
 DEPS_syntax_ext := syntax syntax_pos rustc_errors fmt_macros proc_macro
-DEPS_proc_macro_plugin := syntax syntax_pos rustc_plugin log
 DEPS_syntax_pos := serialize
+DEPS_proc_macro_tokens := syntax syntax_pos log
+DEPS_proc_macro_plugin := syntax syntax_pos rustc_plugin log proc_macro_tokens
 
 DEPS_rustc_const_math := std syntax log serialize
 DEPS_rustc_const_eval := rustc_const_math rustc syntax log serialize \
@@ -120,7 +121,7 @@ DEPS_rustc_driver := arena flate getopts graphviz libc rustc rustc_back rustc_bo
                      rustc_trans rustc_privacy rustc_lint rustc_plugin \
                      rustc_metadata syntax_ext proc_macro_plugin \
                      rustc_passes rustc_save_analysis rustc_const_eval \
-                     rustc_incremental syntax_pos rustc_errors proc_macro
+                     rustc_incremental syntax_pos rustc_errors proc_macro rustc_data_structures
 DEPS_rustc_errors := log libc serialize syntax_pos
 DEPS_rustc_lint := rustc log syntax syntax_pos rustc_const_eval
 DEPS_rustc_llvm := native:rustllvm libc std rustc_bitflags
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 683ba90adf9..5826995cc3c 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -19,7 +19,7 @@ version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
  "core 0.0.0",
- "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
 ]
 
@@ -42,10 +42,10 @@ dependencies = [
  "build_helper 0.1.0",
  "cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)",
- "gcc 0.3.35 (git+https://github.com/alexcrichton/gcc-rs)",
+ "gcc 0.3.38 (git+https://github.com/alexcrichton/gcc-rs)",
  "getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
  "md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -66,7 +66,7 @@ name = "cmake"
 version = "0.1.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -83,7 +83,7 @@ name = "compiler_builtins"
 version = "0.0.0"
 dependencies = [
  "core 0.0.0",
- "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -116,7 +116,7 @@ name = "filetime"
 version = "0.1.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -124,7 +124,7 @@ name = "flate"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -133,12 +133,12 @@ version = "0.0.0"
 
 [[package]]
 name = "gcc"
-version = "0.3.35"
-source = "git+https://github.com/alexcrichton/gcc-rs#03e22a4425c011fa8c96681591432456fa70d60c"
+version = "0.3.38"
+source = "git+https://github.com/alexcrichton/gcc-rs#be620ac6d3ddb498cd0c700d5312c6a4c3c19597"
 
 [[package]]
 name = "gcc"
-version = "0.3.35"
+version = "0.3.38"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -159,7 +159,7 @@ name = "idna"
 version = "0.1.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -182,14 +182,14 @@ dependencies = [
 
 [[package]]
 name = "libc"
-version = "0.2.15"
+version = "0.2.17"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "linkchecker"
 version = "0.1.0"
 dependencies = [
- "url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "url 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -203,7 +203,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "matches"
-version = "0.1.2"
+version = "0.1.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
@@ -216,7 +216,7 @@ name = "num_cpus"
 version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -249,12 +249,22 @@ name = "proc_macro_plugin"
 version = "0.0.0"
 dependencies = [
  "log 0.0.0",
+ "proc_macro_tokens 0.0.0",
  "rustc_plugin 0.0.0",
  "syntax 0.0.0",
  "syntax_pos 0.0.0",
 ]
 
 [[package]]
+name = "proc_macro_tokens"
+version = "0.0.0"
+dependencies = [
+ "log 0.0.0",
+ "syntax 0.0.0",
+ "syntax_pos 0.0.0",
+]
+
+[[package]]
 name = "rand"
 version = "0.0.0"
 dependencies = [
@@ -373,6 +383,7 @@ dependencies = [
  "rustc_back 0.0.0",
  "rustc_borrowck 0.0.0",
  "rustc_const_eval 0.0.0",
+ "rustc_data_structures 0.0.0",
  "rustc_errors 0.0.0",
  "rustc_incremental 0.0.0",
  "rustc_lint 0.0.0",
@@ -431,7 +442,7 @@ name = "rustc_llvm"
 version = "0.0.0"
 dependencies = [
  "build_helper 0.1.0",
- "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_bitflags 0.0.0",
 ]
 
@@ -585,7 +596,7 @@ version = "0.0.0"
 dependencies = [
  "arena 0.0.0",
  "build_helper 0.1.0",
- "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.0.0",
  "rustc 0.0.0",
  "rustc_back 0.0.0",
@@ -621,7 +632,7 @@ dependencies = [
  "collections 0.0.0",
  "compiler_builtins 0.0.0",
  "core 0.0.0",
- "gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)",
+ "gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.0.0",
  "panic_abort 0.0.0",
  "panic_unwind 0.0.0",
@@ -704,7 +715,7 @@ name = "unicode-bidi"
 version = "0.2.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -714,11 +725,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "url"
-version = "1.2.0"
+version = "1.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
@@ -735,20 +746,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum cmake 0.1.17 (registry+https://github.com/rust-lang/crates.io-index)" = "dfcf5bcece56ef953b8ea042509e9dcbdfe97820b7e20d86beb53df30ed94978"
 "checksum env_logger 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "15abd780e45b3ea4f76b4e9a26ff4843258dd8a3eed2775a0e7368c2e7936c2f"
 "checksum filetime 0.1.10 (registry+https://github.com/rust-lang/crates.io-index)" = "5363ab8e4139b8568a6237db5248646e5a8a2f89bd5ccb02092182b11fd3e922"
-"checksum gcc 0.3.35 (git+https://github.com/alexcrichton/gcc-rs)" = "<none>"
-"checksum gcc 0.3.35 (registry+https://github.com/rust-lang/crates.io-index)" = "91ecd03771effb0c968fd6950b37e89476a578aaf1c70297d8e92b6516ec3312"
+"checksum gcc 0.3.38 (git+https://github.com/alexcrichton/gcc-rs)" = "<none>"
+"checksum gcc 0.3.38 (registry+https://github.com/rust-lang/crates.io-index)" = "553f11439bdefe755bf366b264820f1da70f3aaf3924e594b886beb9c831bcf5"
 "checksum getopts 0.2.14 (registry+https://github.com/rust-lang/crates.io-index)" = "d9047cfbd08a437050b363d35ef160452c5fe8ea5187ae0a624708c91581d685"
 "checksum idna 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1053236e00ce4f668aeca4a769a09b3bf5a682d802abd6f3cb39374f6b162c11"
 "checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
-"checksum libc 0.2.15 (registry+https://github.com/rust-lang/crates.io-index)" = "23e3757828fa702a20072c37ff47938e9dd331b92fac6e223d26d4b7a55f7ee2"
+"checksum libc 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "044d1360593a78f5c8e5e710beccdc24ab71d1f01bc19a29bcacdba22e8475d8"
 "checksum log 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ab83497bf8bf4ed2a74259c1c802351fcd67a65baa86394b6ba73c36f4838054"
-"checksum matches 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "15305656809ce5a4805b1ff2946892810992197ce1270ff79baded852187942e"
+"checksum matches 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "bcc3ad8109fa4b522f9b0cd81440422781f564aaf8c195de6b9d6642177ad0dd"
 "checksum md5 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a5539a8dee9b4ae308c9c406a379838b435a8f2c84cf9fedc6d5a576be9888db"
 "checksum num_cpus 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)" = "cee7e88156f3f9e19bdd598f8d6c9db7bf4078f99f8381f43a55b09648d1a6e3"
 "checksum rustc-serialize 0.3.19 (registry+https://github.com/rust-lang/crates.io-index)" = "6159e4e6e559c81bd706afe9c8fd68f547d3e851ce12e76b1de7914bab61691b"
 "checksum toml 0.1.30 (registry+https://github.com/rust-lang/crates.io-index)" = "0590d72182e50e879c4da3b11c6488dae18fccb1ae0c7a3eda18e16795844796"
 "checksum unicode-bidi 0.2.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c1f7ceb96afdfeedee42bade65a0d585a6a0106f681b6749c8ff4daa8df30b3f"
 "checksum unicode-normalization 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "26643a2f83bac55f1976fb716c10234485f9202dcd65cfbdf9da49867b271172"
-"checksum url 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "afe9ec54bc4db14bc8744b7fed060d785ac756791450959b2248443319d5b119"
+"checksum url 1.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ba5a45db1d2e0effb7a1c00cc73ffc63a973da8c7d1fcd5b46f24285ade6c54"
 "checksum winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "167dc9d6949a9b857f3451275e911c3f44255842c1f7a76f33c55103a909087a"
 "checksum winapi-build 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2d315eee3b34aca4797b2da6b13ed88266e6d612562a0c46390af8299fc699bc"
diff --git a/src/doc/reference.md b/src/doc/reference.md
index 84f459bf872..4838ecd2d42 100644
--- a/src/doc/reference.md
+++ b/src/doc/reference.md
@@ -4023,9 +4023,9 @@ Methods that take either `self` or `Box<Self>` can optionally place them in a
 mutable variable by prefixing them with `mut` (similar to regular arguments):
 
 ```
-trait Changer {
-    fn change(mut self) -> Self;
-    fn modify(mut self: Box<Self>) -> Box<Self>;
+trait Changer: Sized {
+    fn change(mut self) {}
+    fn modify(mut self: Box<Self>) {}
 }
 ```
 
@@ -4078,6 +4078,12 @@ be ignored in favor of only building the artifacts specified by command line.
   Rust code into an existing non-Rust application because it will not have
   dynamic dependencies on other Rust code.
 
+* `--crate-type=cdylib`, `#[crate_type = "cdylib"]` - A dynamic system
+  library will be produced.  This is used when compiling Rust code as
+  a dynamic library to be loaded from another language.  This output type will
+  create `*.so` files on Linux, `*.dylib` files on OSX, and `*.dll` files on
+  Windows.
+
 * `--crate-type=rlib`, `#[crate_type = "rlib"]` - A "Rust library" file will be
   produced. This is used as an intermediate artifact and can be thought of as a
   "static Rust library". These `rlib` files, unlike `staticlib` files, are
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs
index b380ba180f4..a4fabb5a2c9 100644
--- a/src/liballoc_system/lib.rs
+++ b/src/liballoc_system/lib.rs
@@ -166,6 +166,7 @@ mod imp {
         fn HeapAlloc(hHeap: HANDLE, dwFlags: DWORD, dwBytes: SIZE_T) -> LPVOID;
         fn HeapReAlloc(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID, dwBytes: SIZE_T) -> LPVOID;
         fn HeapFree(hHeap: HANDLE, dwFlags: DWORD, lpMem: LPVOID) -> BOOL;
+        fn GetLastError() -> DWORD;
     }
 
     #[repr(C)]
@@ -230,11 +231,11 @@ mod imp {
     pub unsafe fn deallocate(ptr: *mut u8, _old_size: usize, align: usize) {
         if align <= MIN_ALIGN {
             let err = HeapFree(GetProcessHeap(), 0, ptr as LPVOID);
-            debug_assert!(err != 0);
+            debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError());
         } else {
             let header = get_header(ptr);
             let err = HeapFree(GetProcessHeap(), 0, header.0 as LPVOID);
-            debug_assert!(err != 0);
+            debug_assert!(err != 0, "Failed to free heap memory: {}", GetLastError());
         }
     }
 
diff --git a/src/libcollectionstest/binary_heap.rs b/src/libcollectionstest/binary_heap.rs
index faabcf4c372..9cd63d87931 100644
--- a/src/libcollectionstest/binary_heap.rs
+++ b/src/libcollectionstest/binary_heap.rs
@@ -299,5 +299,7 @@ fn test_extend_specialization() {
 
 #[allow(dead_code)]
 fn assert_covariance() {
-    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
+    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
+        d
+    }
 }
diff --git a/src/libcollectionstest/btree/map.rs b/src/libcollectionstest/btree/map.rs
index 49fce68d15e..8222da105cc 100644
--- a/src/libcollectionstest/btree/map.rs
+++ b/src/libcollectionstest/btree/map.rs
@@ -533,9 +533,7 @@ create_append_test!(test_append_1700, 1700);
 
 fn rand_data(len: usize) -> Vec<(u32, u32)> {
     let mut rng = DeterministicRng::new();
-    Vec::from_iter(
-        (0..len).map(|_| (rng.next(), rng.next()))
-    )
+    Vec::from_iter((0..len).map(|_| (rng.next(), rng.next())))
 }
 
 #[test]
diff --git a/src/libcollectionstest/btree/mod.rs b/src/libcollectionstest/btree/mod.rs
index ea43f423b7c..ae8b18d0c9f 100644
--- a/src/libcollectionstest/btree/mod.rs
+++ b/src/libcollectionstest/btree/mod.rs
@@ -25,7 +25,7 @@ impl DeterministicRng {
             x: 0x193a6754,
             y: 0xa8a7d469,
             z: 0x97830e05,
-            w: 0x113ba7bb
+            w: 0x113ba7bb,
         }
     }
 
diff --git a/src/libcollectionstest/btree/set.rs b/src/libcollectionstest/btree/set.rs
index a32e3f1a76a..6171b8ba624 100644
--- a/src/libcollectionstest/btree/set.rs
+++ b/src/libcollectionstest/btree/set.rs
@@ -15,45 +15,51 @@ use super::DeterministicRng;
 
 #[test]
 fn test_clone_eq() {
-  let mut m = BTreeSet::new();
+    let mut m = BTreeSet::new();
 
-  m.insert(1);
-  m.insert(2);
+    m.insert(1);
+    m.insert(2);
 
-  assert!(m.clone() == m);
+    assert!(m.clone() == m);
 }
 
 #[test]
 fn test_hash() {
-  let mut x = BTreeSet::new();
-  let mut y = BTreeSet::new();
+    let mut x = BTreeSet::new();
+    let mut y = BTreeSet::new();
 
-  x.insert(1);
-  x.insert(2);
-  x.insert(3);
+    x.insert(1);
+    x.insert(2);
+    x.insert(3);
 
-  y.insert(3);
-  y.insert(2);
-  y.insert(1);
+    y.insert(3);
+    y.insert(2);
+    y.insert(1);
 
-  assert!(::hash(&x) == ::hash(&y));
+    assert!(::hash(&x) == ::hash(&y));
 }
 
-fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F) where
-    F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> bool,
+fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
+    where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> bool
 {
     let mut set_a = BTreeSet::new();
     let mut set_b = BTreeSet::new();
 
-    for x in a { assert!(set_a.insert(*x)) }
-    for y in b { assert!(set_b.insert(*y)) }
+    for x in a {
+        assert!(set_a.insert(*x))
+    }
+    for y in b {
+        assert!(set_b.insert(*y))
+    }
 
     let mut i = 0;
-    f(&set_a, &set_b, &mut |&x| {
-        assert_eq!(x, expected[i]);
-        i += 1;
-        true
-    });
+    f(&set_a,
+      &set_b,
+      &mut |&x| {
+          assert_eq!(x, expected[i]);
+          i += 1;
+          true
+      });
     assert_eq!(i, expected.len());
 }
 
@@ -82,9 +88,7 @@ fn test_difference() {
     check_difference(&[], &[], &[]);
     check_difference(&[1, 12], &[], &[1, 12]);
     check_difference(&[], &[1, 2, 3, 9], &[]);
-    check_difference(&[1, 3, 5, 9, 11],
-                     &[3, 9],
-                     &[1, 5, 11]);
+    check_difference(&[1, 3, 5, 9, 11], &[3, 9], &[1, 5, 11]);
     check_difference(&[-5, 11, 22, 33, 40, 42],
                      &[-12, -5, 14, 23, 34, 38, 39, 50],
                      &[11, 22, 33, 40, 42]);
@@ -245,10 +249,18 @@ fn test_recovery() {
 fn test_variance() {
     use std::collections::btree_set::{IntoIter, Iter, Range};
 
-    fn set<'new>(v: BTreeSet<&'static str>) -> BTreeSet<&'new str> { v }
-    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> { v }
-    fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> { v }
-    fn range<'a, 'new>(v: Range<'a, &'static str>) -> Range<'a, &'new str> { v }
+    fn set<'new>(v: BTreeSet<&'static str>) -> BTreeSet<&'new str> {
+        v
+    }
+    fn iter<'a, 'new>(v: Iter<'a, &'static str>) -> Iter<'a, &'new str> {
+        v
+    }
+    fn into_iter<'new>(v: IntoIter<&'static str>) -> IntoIter<&'new str> {
+        v
+    }
+    fn range<'a, 'new>(v: Range<'a, &'static str>) -> Range<'a, &'new str> {
+        v
+    }
 }
 
 #[test]
@@ -277,9 +289,7 @@ fn test_append() {
 
 fn rand_data(len: usize) -> Vec<u32> {
     let mut rng = DeterministicRng::new();
-    Vec::from_iter(
-        (0..len).map(|_| rng.next())
-    )
+    Vec::from_iter((0..len).map(|_| rng.next()))
 }
 
 #[test]
diff --git a/src/libcollectionstest/lib.rs b/src/libcollectionstest/lib.rs
index 88fb6540a9a..5d3e03c2dee 100644
--- a/src/libcollectionstest/lib.rs
+++ b/src/libcollectionstest/lib.rs
@@ -36,7 +36,9 @@ extern crate rustc_unicode;
 use std::hash::{Hash, Hasher};
 use std::collections::hash_map::DefaultHasher;
 
-#[cfg(test)] #[macro_use] mod bench;
+#[cfg(test)]
+#[macro_use]
+mod bench;
 
 mod binary_heap;
 mod btree;
diff --git a/src/libcollectionstest/slice.rs b/src/libcollectionstest/slice.rs
index 130c16d7c15..a6230ef471c 100644
--- a/src/libcollectionstest/slice.rs
+++ b/src/libcollectionstest/slice.rs
@@ -420,12 +420,12 @@ fn test_sort_stability() {
             // number this element is, i.e. the second elements
             // will occur in sorted order.
             let mut v: Vec<_> = (0..len)
-                                    .map(|_| {
-                                        let n = thread_rng().gen::<usize>() % 10;
-                                        counts[n] += 1;
-                                        (n, counts[n])
-                                    })
-                                    .collect();
+                .map(|_| {
+                    let n = thread_rng().gen::<usize>() % 10;
+                    counts[n] += 1;
+                    (n, counts[n])
+                })
+                .collect();
 
             // only sort on the first element, so an unstable sort
             // may mix up the counts.
@@ -1116,13 +1116,13 @@ fn test_box_slice_clone_panics() {
     };
 
     spawn(move || {
-        // When xs is dropped, +5.
-        let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary]
-                     .into_boxed_slice();
+            // When xs is dropped, +5.
+            let xs = vec![canary.clone(), canary.clone(), canary.clone(), panic, canary]
+                .into_boxed_slice();
 
-        // When panic is cloned, +3.
-        xs.clone();
-    })
+            // When panic is cloned, +3.
+            xs.clone();
+        })
         .join()
         .unwrap_err();
 
@@ -1374,8 +1374,8 @@ mod bench {
         let mut rng = thread_rng();
         b.iter(|| {
             let mut v = rng.gen_iter::<BigSortable>()
-                           .take(5)
-                           .collect::<Vec<BigSortable>>();
+                .take(5)
+                .collect::<Vec<BigSortable>>();
             v.sort();
         });
         b.bytes = 5 * mem::size_of::<BigSortable>() as u64;
@@ -1386,8 +1386,8 @@ mod bench {
         let mut rng = thread_rng();
         b.iter(|| {
             let mut v = rng.gen_iter::<BigSortable>()
-                           .take(100)
-                           .collect::<Vec<BigSortable>>();
+                .take(100)
+                .collect::<Vec<BigSortable>>();
             v.sort();
         });
         b.bytes = 100 * mem::size_of::<BigSortable>() as u64;
@@ -1398,8 +1398,8 @@ mod bench {
         let mut rng = thread_rng();
         b.iter(|| {
             let mut v = rng.gen_iter::<BigSortable>()
-                           .take(10000)
-                           .collect::<Vec<BigSortable>>();
+                .take(10000)
+                .collect::<Vec<BigSortable>>();
             v.sort();
         });
         b.bytes = 10000 * mem::size_of::<BigSortable>() as u64;
diff --git a/src/libcollectionstest/vec.rs b/src/libcollectionstest/vec.rs
index 9a04673d1da..3bc1321d756 100644
--- a/src/libcollectionstest/vec.rs
+++ b/src/libcollectionstest/vec.rs
@@ -607,8 +607,12 @@ fn test_from_cow() {
 
 #[allow(dead_code)]
 fn assert_covariance() {
-    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
-    fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> { i }
+    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
+        d
+    }
+    fn into_iter<'new>(i: IntoIter<&'static str>) -> IntoIter<&'new str> {
+        i
+    }
 }
 
 #[bench]
diff --git a/src/libcollectionstest/vec_deque.rs b/src/libcollectionstest/vec_deque.rs
index 9dfd3430268..f1ea85a6c5b 100644
--- a/src/libcollectionstest/vec_deque.rs
+++ b/src/libcollectionstest/vec_deque.rs
@@ -686,9 +686,9 @@ fn test_show() {
     assert_eq!(format!("{:?}", ringbuf), "[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]");
 
     let ringbuf: VecDeque<_> = vec!["just", "one", "test", "more"]
-                                   .iter()
-                                   .cloned()
-                                   .collect();
+        .iter()
+        .cloned()
+        .collect();
     assert_eq!(format!("{:?}", ringbuf),
                "[\"just\", \"one\", \"test\", \"more\"]");
 }
@@ -1003,5 +1003,7 @@ fn test_contains() {
 
 #[allow(dead_code)]
 fn assert_covariance() {
-    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> { d }
+    fn drain<'new>(d: Drain<'static, &'static str>) -> Drain<'new, &'new str> {
+        d
+    }
 }
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 036633fe89d..e0f976e4161 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -706,24 +706,24 @@ mod impls {
 
     ord_impl! { char usize u8 u16 u32 u64 isize i8 i16 i32 i64 }
 
-    #[unstable(feature = "never_type", issue = "35121")]
+    #[unstable(feature = "never_type_impls", issue = "35121")]
     impl PartialEq for ! {
         fn eq(&self, _: &!) -> bool {
             *self
         }
     }
 
-    #[unstable(feature = "never_type", issue = "35121")]
+    #[unstable(feature = "never_type_impls", issue = "35121")]
     impl Eq for ! {}
 
-    #[unstable(feature = "never_type", issue = "35121")]
+    #[unstable(feature = "never_type_impls", issue = "35121")]
     impl PartialOrd for ! {
         fn partial_cmp(&self, _: &!) -> Option<Ordering> {
             *self
         }
     }
 
-    #[unstable(feature = "never_type", issue = "35121")]
+    #[unstable(feature = "never_type_impls", issue = "35121")]
     impl Ord for ! {
         fn cmp(&self, _: &!) -> Ordering {
             *self
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 9aba6703386..2d75a8ec420 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1356,14 +1356,14 @@ macro_rules! fmt_refs {
 
 fmt_refs! { Debug, Display, Octal, Binary, LowerHex, UpperHex, LowerExp, UpperExp }
 
-#[unstable(feature = "never_type", issue = "35121")]
+#[unstable(feature = "never_type_impls", issue = "35121")]
 impl Debug for ! {
     fn fmt(&self, _: &mut Formatter) -> Result {
         *self
     }
 }
 
-#[unstable(feature = "never_type", issue = "35121")]
+#[unstable(feature = "never_type_impls", issue = "35121")]
 impl Display for ! {
     fn fmt(&self, _: &mut Formatter) -> Result {
         *self
diff --git a/src/libcore/macros.rs b/src/libcore/macros.rs
index 5142b18dca1..e6c3f549ec8 100644
--- a/src/libcore/macros.rs
+++ b/src/libcore/macros.rs
@@ -553,7 +553,7 @@ pub mod builtin {
     /// For more information, see the documentation for [`std::concat_idents!`].
     ///
     /// [`std::concat_idents!`]: ../std/macro.concat_idents.html
-    #[unstable(feature = "concat_idents", issue = "29599")]
+    #[unstable(feature = "concat_idents_macro", issue = "29599")]
     #[macro_export]
     macro_rules! concat_idents {
         ($($e:ident),*) => ({ /* compiler built-in */ })
diff --git a/src/liblibc b/src/liblibc
-Subproject c95defce07a82f2f759f140c937dabd43a4f3d9
+Subproject 7d9b71f0971f8fa196d864d7071f216a59036d6
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 4b9b92fb3bb..1d2c64d6d93 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -136,10 +136,8 @@ impl FromStr for TokenStream {
     fn from_str(src: &str) -> Result<TokenStream, LexError> {
         __internal::with_parse_sess(|sess| {
             let src = src.to_string();
-            let cfg = Vec::new();
             let name = "<proc-macro source code>".to_string();
-            let mut parser = parse::new_parser_from_source_str(sess, cfg, name,
-                                                               src);
+            let mut parser = parse::new_parser_from_source_str(sess, name, src);
             let mut ret = TokenStream { inner: Vec::new() };
             loop {
                 match parser.parse_item() {
diff --git a/src/libproc_macro_plugin/Cargo.toml b/src/libproc_macro_plugin/Cargo.toml
index 70bb86d0f58..4bc3f488d32 100644
--- a/src/libproc_macro_plugin/Cargo.toml
+++ b/src/libproc_macro_plugin/Cargo.toml
@@ -12,3 +12,4 @@ log = { path = "../liblog" }
 rustc_plugin = { path = "../librustc_plugin" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+proc_macro_tokens = { path = "../libproc_macro_tokens" }
diff --git a/src/libproc_macro_plugin/lib.rs b/src/libproc_macro_plugin/lib.rs
index e82e97b5134..c45762bfb6e 100644
--- a/src/libproc_macro_plugin/lib.rs
+++ b/src/libproc_macro_plugin/lib.rs
@@ -13,43 +13,14 @@
 //! A library for procedural macro writers.
 //!
 //! ## Usage
-//! This package provides the `qquote!` macro for syntax creation, and the prelude
-//! (at libproc_macro::prelude) provides a number of operations:
-//! - `concat`, for concatenating two TokenStreams.
-//! - `ident_eq`, for checking if two identifiers are equal regardless of syntax context.
-//! - `str_to_token_ident`, for converting an `&str` into a Token.
-//! - `keyword_to_token_delim`, for converting a `parse::token::keywords::Keyword` into a
-//!    Token.
-//! - `build_delimited`, for creating a new TokenStream from an existing one and a delimiter
-//!    by wrapping the TokenStream in the delimiter.
-//! - `build_bracket_delimited`, `build_brace_delimited`, and `build_paren_delimited`, for
-//!    easing the above.
-//! - `build_empty_args`, which returns a TokenStream containing `()`.
-//! - `lex`, which takes an `&str` and returns the TokenStream it represents.
-//!
-//! The `qquote!` macro also imports `syntax::ext::proc_macro_shim::prelude::*`, so you
+//! This crate provides the `qquote!` macro for syntax creation.
+//!
+//! The `qquote!` macro imports `syntax::ext::proc_macro_shim::prelude::*`, so you
 //! will need to `extern crate syntax` for usage. (This is a temporary solution until more
-//! of the external API in libproc_macro is stabilized to support the token construction
+//! of the external API in libproc_macro_tokens is stabilized to support the token construction
 //! operations that the qausiquoter relies on.) The shim file also provides additional
 //! operations, such as `build_block_emitter` (as used in the `cond` example below).
 //!
-//! ## TokenStreams
-//!
-//! TokenStreams serve as the basis of the macro system. They are, in essence, vectors of
-//! TokenTrees, where indexing treats delimited values as a single term. That is, the term
-//! `even(a+c) && even(b)` will be indexibly encoded as `even | (a+c) | even | (b)` where,
-//! in reality, `(a+c)` is actually a decorated pointer to `a | + | c`.
-//!
-//! If a user has a TokenStream that is a single, delimited value, they can use
-//! `maybe_delimited` to destruct it and receive the internal vector as a new TokenStream
-//! as:
-//! ```
-//! `(a+c)`.maybe_delimited() ~> Some(a | + | c)`
-//! ```
-//!
-//! Check the TokenStream documentation for more information; the structure also provides
-//! cheap concatenation and slicing.
-//!
 //! ## Quasiquotation
 //!
 //! The quasiquoter creates output that, when run, constructs the tokenstream specified as
@@ -118,12 +89,11 @@
 extern crate rustc_plugin;
 extern crate syntax;
 extern crate syntax_pos;
+extern crate proc_macro_tokens;
 #[macro_use] extern crate log;
 
 mod qquote;
-pub mod build;
-pub mod parse;
-pub mod prelude;
+
 use qquote::qquote;
 
 use rustc_plugin::Registry;
diff --git a/src/libproc_macro_plugin/qquote.rs b/src/libproc_macro_plugin/qquote.rs
index b73d085656e..e5a3abc2ea9 100644
--- a/src/libproc_macro_plugin/qquote.rs
+++ b/src/libproc_macro_plugin/qquote.rs
@@ -24,12 +24,9 @@
 //! TokenStream that resembles the output syntax.
 //!
 
-extern crate rustc_plugin;
-extern crate syntax;
-extern crate syntax_pos;
+use proc_macro_tokens::build::*;
+use proc_macro_tokens::parse::lex;
 
-use build::*;
-use parse::lex;
 use qquote::int_build::*;
 
 use syntax::ast::Ident;
@@ -51,7 +48,7 @@ pub fn qquote<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[TokenTree])
     let output = qquoter(cx, TokenStream::from_tts(tts.clone().to_owned()));
     debug!("\nQQ out: {}\n", pprust::tts_to_string(&output.to_tts()[..]));
     let imports = concat(lex("use syntax::ext::proc_macro_shim::prelude::*;"),
-                         lex("use proc_macro_plugin::prelude::*;"));
+                         lex("use proc_macro_tokens::prelude::*;"));
     build_block_emitter(cx, sp, build_brace_delimited(concat(imports, output)))
 }
 
@@ -219,7 +216,7 @@ fn convert_complex_tts<'cx>(cx: &'cx mut ExtCtxt, tts: Vec<QTT>) -> (Bindings, T
 
                 let sep = build_delim_tok(qdl.delim);
 
-                pushes.push(build_mod_call(vec![str_to_ident("proc_macro_plugin"),
+                pushes.push(build_mod_call(vec![str_to_ident("proc_macro_tokens"),
                                                str_to_ident("build"),
                                                str_to_ident("build_delimited")],
                                           concat(from_tokens(vec![Token::Ident(new_id)]),
@@ -264,11 +261,8 @@ fn is_qquote(id: Ident) -> bool {
 }
 
 mod int_build {
-    extern crate syntax;
-    extern crate syntax_pos;
-
-    use parse::*;
-    use build::*;
+    use proc_macro_tokens::build::*;
+    use proc_macro_tokens::parse::*;
 
     use syntax::ast::{self, Ident};
     use syntax::codemap::{DUMMY_SP};
diff --git a/src/libproc_macro_tokens/Cargo.toml b/src/libproc_macro_tokens/Cargo.toml
new file mode 100644
index 00000000000..2b66d56759f
--- /dev/null
+++ b/src/libproc_macro_tokens/Cargo.toml
@@ -0,0 +1,13 @@
+[package]
+authors = ["The Rust Project Developers"]
+name = "proc_macro_tokens"
+version = "0.0.0"
+
+[lib]
+path = "lib.rs"
+crate-type = ["dylib"]
+
+[dependencies]
+syntax = { path = "../libsyntax" }
+syntax_pos = { path = "../libsyntax_pos" }
+log = { path = "../liblog" }
diff --git a/src/libproc_macro_plugin/build.rs b/src/libproc_macro_tokens/build.rs
index 7b7590b863b..7b7590b863b 100644
--- a/src/libproc_macro_plugin/build.rs
+++ b/src/libproc_macro_tokens/build.rs
diff --git a/src/libproc_macro_tokens/lib.rs b/src/libproc_macro_tokens/lib.rs
new file mode 100644
index 00000000000..3bfa2fbb29f
--- /dev/null
+++ b/src/libproc_macro_tokens/lib.rs
@@ -0,0 +1,66 @@
+// 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.
+
+//! # Proc_Macro
+//!
+//! A library for procedural macro writers.
+//!
+//! ## Usage
+//! This crate provides the prelude (at libproc_macro_tokens::prelude), which
+//! provides a number of operations:
+//! - `concat`, for concatenating two TokenStreams.
+//! - `ident_eq`, for checking if two identifiers are equal regardless of syntax context.
+//! - `str_to_token_ident`, for converting an `&str` into a Token.
+//! - `keyword_to_token_delim`, for converting a `parse::token::keywords::Keyword` into a
+//!    Token.
+//! - `build_delimited`, for creating a new TokenStream from an existing one and a delimiter
+//!    by wrapping the TokenStream in the delimiter.
+//! - `build_bracket_delimited`, `build_brace_delimited`, and `build_paren_delimited`, for
+//!    easing the above.
+//! - `build_empty_args`, which returns a TokenStream containing `()`.
+//! - `lex`, which takes an `&str` and returns the TokenStream it represents.
+//!
+//! ## TokenStreams
+//!
+//! TokenStreams serve as the basis of the macro system. They are, in essence, vectors of
+//! TokenTrees, where indexing treats delimited values as a single term. That is, the term
+//! `even(a+c) && even(b)` will be indexibly encoded as `even | (a+c) | even | (b)` where,
+//! in reality, `(a+c)` is actually a decorated pointer to `a | + | c`.
+//!
+//! If a user has a TokenStream that is a single, delimited value, they can use
+//! `maybe_delimited` to destruct it and receive the internal vector as a new TokenStream
+//! as:
+//! ```
+//! `(a+c)`.maybe_delimited() ~> Some(a | + | c)`
+//! ```
+//!
+//! Check the TokenStream documentation for more information; the structure also provides
+//! cheap concatenation and slicing.
+//!
+
+#![crate_name = "proc_macro_tokens"]
+#![unstable(feature = "rustc_private", issue = "27812")]
+#![crate_type = "dylib"]
+#![crate_type = "rlib"]
+#![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
+       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
+       html_root_url = "https://doc.rust-lang.org/nightly/")]
+#![cfg_attr(not(stage0), deny(warnings))]
+
+#![feature(staged_api)]
+#![feature(rustc_private)]
+
+extern crate syntax;
+extern crate syntax_pos;
+#[macro_use] extern crate log;
+
+pub mod build;
+pub mod parse;
+pub mod prelude;
diff --git a/src/libproc_macro_plugin/parse.rs b/src/libproc_macro_tokens/parse.rs
index 9af8a68cdcf..9af8a68cdcf 100644
--- a/src/libproc_macro_plugin/parse.rs
+++ b/src/libproc_macro_tokens/parse.rs
diff --git a/src/libproc_macro_plugin/prelude.rs b/src/libproc_macro_tokens/prelude.rs
index 4c0c8ba6c66..4c0c8ba6c66 100644
--- a/src/libproc_macro_plugin/prelude.rs
+++ b/src/libproc_macro_tokens/prelude.rs
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 11f635847a0..620ee30c956 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -124,7 +124,6 @@ impl<'a> LoweringContext<'a> {
         hir::Crate {
             module: self.lower_mod(&c.module),
             attrs: self.lower_attrs(&c.attrs),
-            config: c.config.clone().into(),
             span: c.span,
             exported_macros: c.exported_macros.iter().map(|m| self.lower_macro_def(m)).collect(),
             items: items,
@@ -1219,7 +1218,7 @@ impl<'a> LoweringContext<'a> {
                         alignstack,
                         dialect,
                         expn_id,
-                    }) => hir::ExprInlineAsm(hir::InlineAsm {
+                    }) => hir::ExprInlineAsm(P(hir::InlineAsm {
                     inputs: inputs.iter().map(|&(ref c, _)| c.clone()).collect(),
                     outputs: outputs.iter()
                                     .map(|out| {
@@ -1237,7 +1236,7 @@ impl<'a> LoweringContext<'a> {
                     alignstack: alignstack,
                     dialect: dialect,
                     expn_id: expn_id,
-                }, outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(),
+                }), outputs.iter().map(|out| self.lower_expr(&out.expr)).collect(),
                    inputs.iter().map(|&(_, ref input)| self.lower_expr(input)).collect()),
                 ExprKind::Struct(ref path, ref fields, ref maybe_expr) => {
                     hir::ExprStruct(self.lower_path(path),
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 1ac0a48713a..c451a789193 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -413,7 +413,6 @@ pub type CrateConfig = HirVec<P<MetaItem>>;
 pub struct Crate {
     pub module: Mod,
     pub attrs: HirVec<Attribute>,
-    pub config: CrateConfig,
     pub span: Span,
     pub exported_macros: HirVec<MacroDef>,
 
@@ -941,7 +940,7 @@ pub enum Expr_ {
     ExprRet(Option<P<Expr>>),
 
     /// Inline assembly (from `asm!`), with its outputs and inputs.
-    ExprInlineAsm(InlineAsm, Vec<P<Expr>>, Vec<P<Expr>>),
+    ExprInlineAsm(P<InlineAsm>, HirVec<P<Expr>>, HirVec<P<Expr>>),
 
     /// A struct or struct-like variant literal expression.
     ///
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index 25731df4778..d17402d2134 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -105,23 +105,12 @@ pub mod middle {
     pub mod weak_lang_items;
 }
 
-pub mod mir {
-    mod cache;
-    pub mod repr;
-    pub mod tcx;
-    pub mod visit;
-    pub mod transform;
-    pub mod traversal;
-    pub mod mir_map;
-}
-
+pub mod mir;
 pub mod session;
 pub mod traits;
 pub mod ty;
 
 pub mod util {
-    pub use rustc_back::sha2;
-
     pub mod common;
     pub mod ppaux;
     pub mod nodemap;
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 4ef42bb68eb..3472c77cf42 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -192,6 +192,12 @@ declare_lint! {
     "safe access to extern statics was erroneously allowed"
 }
 
+declare_lint! {
+    pub PATTERNS_IN_FNS_WITHOUT_BODY,
+    Warn,
+    "patterns in functions without body were erroneously allowed"
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -228,7 +234,8 @@ impl LintPass for HardwiredLints {
             SUPER_OR_SELF_IN_GLOBAL_PATH,
             HR_LIFETIME_IN_ASSOC_TYPE,
             LIFETIME_UNDERSCORE,
-            SAFE_EXTERN_STATICS
+            SAFE_EXTERN_STATICS,
+            PATTERNS_IN_FNS_WITHOUT_BODY
         )
     }
 }
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index a3a84f51780..59a5147ed1c 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -29,8 +29,7 @@ use hir::map::definitions::{Definitions, DefKey};
 use hir::svh::Svh;
 use middle::lang_items;
 use ty::{self, Ty, TyCtxt};
-use mir::repr::Mir;
-use mir::mir_map::MirMap;
+use mir::Mir;
 use session::Session;
 use session::search_paths::PathKind;
 use util::nodemap::{NodeSet, DefIdMap};
@@ -165,7 +164,6 @@ pub trait CrateStore<'tcx> {
     fn is_const_fn(&self, did: DefId) -> bool;
     fn is_defaulted_trait(&self, did: DefId) -> bool;
     fn is_default_impl(&self, impl_did: DefId) -> bool;
-    fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool;
     fn is_foreign_item(&self, did: DefId) -> bool;
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool;
 
@@ -209,8 +207,7 @@ pub trait CrateStore<'tcx> {
     fn local_node_for_inlined_defid(&'tcx self, def_id: DefId) -> Option<ast::NodeId>;
     fn defid_for_inlined_node(&'tcx self, node_id: ast::NodeId) -> Option<DefId>;
 
-    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                              -> Option<Mir<'tcx>>;
+    fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx>;
     fn is_item_mir_available(&self, def: DefId) -> bool;
 
     // This is basically a 1-based range of ints, which is a little
@@ -228,8 +225,7 @@ pub trait CrateStore<'tcx> {
     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            reexports: &def::ExportMap,
                            link_meta: &LinkMeta,
-                           reachable: &NodeSet,
-                           mir_map: &MirMap<'tcx>) -> Vec<u8>;
+                           reachable: &NodeSet) -> Vec<u8>;
     fn metadata_encoding_version(&self) -> &[u8];
 }
 
@@ -334,8 +330,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") }
     fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") }
     fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") }
-    fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool
-        { bug!("is_extern_item") }
     fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") }
     fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false }
 
@@ -390,8 +384,8 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
         bug!("defid_for_inlined_node")
     }
 
-    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                              -> Option<Mir<'tcx>> { bug!("maybe_get_item_mir") }
+    fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
+                        -> Mir<'tcx> { bug!("get_item_mir") }
     fn is_item_mir_available(&self, def: DefId) -> bool {
         bug!("is_item_mir_available")
     }
@@ -412,8 +406,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            reexports: &def::ExportMap,
                            link_meta: &LinkMeta,
-                           reachable: &NodeSet,
-                           mir_map: &MirMap<'tcx>) -> Vec<u8> { vec![] }
+                           reachable: &NodeSet) -> Vec<u8> { vec![] }
     fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") }
 }
 
diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs
index 799c02b7403..c37b6df369d 100644
--- a/src/librustc/middle/expr_use_visitor.rs
+++ b/src/librustc/middle/expr_use_visitor.rs
@@ -1017,7 +1017,7 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> {
                     delegate.matched_pat(pat, downcast_cmt, match_mode);
                 }
                 Some(Def::Struct(..)) | Some(Def::StructCtor(..)) | Some(Def::Union(..)) |
-                Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) => {
+                Some(Def::TyAlias(..)) | Some(Def::AssociatedTy(..)) | Some(Def::SelfTy(..)) => {
                     debug!("struct cmt_pat={:?} pat={:?}", cmt_pat, pat);
                     delegate.matched_pat(pat, cmt_pat, match_mode);
                 }
diff --git a/src/librustc/mir/cache.rs b/src/librustc/mir/cache.rs
index 1be7d00f072..bc9bbebb179 100644
--- a/src/librustc/mir/cache.rs
+++ b/src/librustc/mir/cache.rs
@@ -11,7 +11,7 @@
 use std::cell::{Ref, RefCell};
 use rustc_data_structures::indexed_vec::IndexVec;
 
-use mir::repr::{Mir, BasicBlock};
+use mir::{Mir, BasicBlock};
 
 use rustc_serialize as serialize;
 
diff --git a/src/librustc/mir/mir_map.rs b/src/librustc/mir/mir_map.rs
deleted file mode 100644
index 92de65798d3..00000000000
--- a/src/librustc/mir/mir_map.rs
+++ /dev/null
@@ -1,38 +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.
-
-use dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig};
-use hir::def_id::DefId;
-use mir::repr::Mir;
-use std::marker::PhantomData;
-
-pub struct MirMap<'tcx> {
-    pub map: DepTrackingMap<MirMapConfig<'tcx>>,
-}
-
-impl<'tcx> MirMap<'tcx> {
-    pub fn new(graph: DepGraph) -> Self {
-        MirMap {
-            map: DepTrackingMap::new(graph)
-        }
-    }
-}
-
-pub struct MirMapConfig<'tcx> {
-    data: PhantomData<&'tcx ()>
-}
-
-impl<'tcx> DepTrackingMapConfig for MirMapConfig<'tcx> {
-    type Key = DefId;
-    type Value = Mir<'tcx>;
-    fn to_dep_node(key: &DefId) -> DepNode<DefId> {
-        DepNode::Mir(*key)
-    }
-}
diff --git a/src/librustc/mir/repr.rs b/src/librustc/mir/mod.rs
index fa899c40269..9d82006ac9f 100644
--- a/src/librustc/mir/repr.rs
+++ b/src/librustc/mir/mod.rs
@@ -32,7 +32,11 @@ use std::vec::IntoIter;
 use syntax::ast::{self, Name};
 use syntax_pos::Span;
 
-use super::cache::Cache;
+mod cache;
+pub mod tcx;
+pub mod visit;
+pub mod transform;
+pub mod traversal;
 
 macro_rules! newtype_index {
     ($name:ident, $debug_name:expr) => (
@@ -59,7 +63,8 @@ macro_rules! newtype_index {
 }
 
 /// Lowered representation of a single function.
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+// Do not implement clone for Mir, its easy to do so accidently and its kind of expensive.
+#[derive(RustcEncodable, RustcDecodable, Debug)]
 pub struct Mir<'tcx> {
     /// List of basic blocks. References to basic block use a newtyped index type `BasicBlock`
     /// that indexes into this vector.
@@ -106,7 +111,7 @@ pub struct Mir<'tcx> {
     pub span: Span,
 
     /// A cache for various calculations
-    cache: Cache
+    cache: cache::Cache
 }
 
 /// where execution begins
@@ -137,7 +142,7 @@ impl<'tcx> Mir<'tcx> {
             upvar_decls: upvar_decls,
             spread_arg: None,
             span: span,
-            cache: Cache::new()
+            cache: cache::Cache::new()
         }
     }
 
@@ -1138,8 +1143,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
                     AggregateKind::Adt(adt_def, variant, substs, _) => {
                         let variant_def = &adt_def.variants[variant];
 
-                        ppaux::parameterized(fmt, substs, variant_def.did,
-                                             ppaux::Ns::Value, &[])?;
+                        ppaux::parameterized(fmt, substs, variant_def.did, &[])?;
 
                         match variant_def.ctor_kind {
                             CtorKind::Const => Ok(()),
@@ -1234,7 +1238,7 @@ impl<'tcx> Debug for Literal<'tcx> {
         use self::Literal::*;
         match *self {
             Item { def_id, substs } => {
-                ppaux::parameterized(fmt, substs, def_id, ppaux::Ns::Value, &[])
+                ppaux::parameterized(fmt, substs, def_id, &[])
             }
             Value { ref value } => {
                 write!(fmt, "const ")?;
diff --git a/src/librustc/mir/tcx.rs b/src/librustc/mir/tcx.rs
index 8dd82b2d079..f9afbaf104a 100644
--- a/src/librustc/mir/tcx.rs
+++ b/src/librustc/mir/tcx.rs
@@ -13,7 +13,7 @@
  * building is complete.
  */
 
-use mir::repr::*;
+use mir::*;
 use ty::subst::{Subst, Substs};
 use ty::{self, AdtDef, Ty, TyCtxt};
 use ty::fold::{TypeFoldable, TypeFolder, TypeVisitor};
diff --git a/src/librustc/mir/transform.rs b/src/librustc/mir/transform.rs
index 8cd5f5844d2..3576ae662a0 100644
--- a/src/librustc/mir/transform.rs
+++ b/src/librustc/mir/transform.rs
@@ -11,8 +11,7 @@
 use dep_graph::DepNode;
 use hir;
 use hir::map::DefPathData;
-use mir::mir_map::MirMap;
-use mir::repr::{Mir, Promoted};
+use mir::{Mir, Promoted};
 use ty::TyCtxt;
 use syntax::ast::NodeId;
 use util::common::time;
@@ -85,12 +84,11 @@ pub trait Pass {
     fn disambiguator<'a>(&'a self) -> Option<Box<fmt::Display+'a>> { None }
 }
 
-/// A pass which inspects the whole MirMap.
+/// A pass which inspects the whole Mir map.
 pub trait MirMapPass<'tcx>: Pass {
     fn run_pass<'a>(
         &mut self,
         tcx: TyCtxt<'a, 'tcx, 'tcx>,
-        map: &mut MirMap<'tcx>,
         hooks: &mut [Box<for<'s> MirPassHook<'s>>]);
 }
 
@@ -114,13 +112,18 @@ pub trait MirPass<'tcx>: Pass {
 impl<'tcx, T: MirPass<'tcx>> MirMapPass<'tcx> for T {
     fn run_pass<'a>(&mut self,
                     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                    map: &mut MirMap<'tcx>,
                     hooks: &mut [Box<for<'s> MirPassHook<'s>>])
     {
-        let def_ids = map.map.keys();
+        let def_ids = tcx.mir_map.borrow().keys();
         for def_id in def_ids {
+            if !def_id.is_local() {
+                continue;
+            }
+
             let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let mir = map.map.get_mut(&def_id).unwrap();
+            let mir = &mut tcx.mir_map.borrow()[&def_id].borrow_mut();
+            tcx.dep_graph.write(DepNode::Mir(def_id));
+
             let id = tcx.map.as_local_node_id(def_id).unwrap();
             let src = MirSource::from_node(tcx, id);
 
@@ -163,11 +166,11 @@ impl<'a, 'tcx> Passes {
         passes
     }
 
-    pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>, map: &mut MirMap<'tcx>) {
+    pub fn run_passes(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>) {
         let Passes { ref mut passes, ref mut plugin_passes, ref mut pass_hooks } = *self;
         for pass in plugin_passes.iter_mut().chain(passes.iter_mut()) {
             time(tcx.sess.time_passes(), &*pass.name(),
-                 || pass.run_pass(tcx, map, pass_hooks));
+                 || pass.run_pass(tcx, pass_hooks));
         }
     }
 
diff --git a/src/librustc/mir/traversal.rs b/src/librustc/mir/traversal.rs
index 1af5123b4df..6057e7ec7e0 100644
--- a/src/librustc/mir/traversal.rs
+++ b/src/librustc/mir/traversal.rs
@@ -13,7 +13,7 @@ use std::vec;
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::Idx;
 
-use super::repr::*;
+use super::*;
 
 /// Preorder traversal of a graph.
 ///
diff --git a/src/librustc/mir/visit.rs b/src/librustc/mir/visit.rs
index cb8d3f97f7b..db7267ca0d4 100644
--- a/src/librustc/mir/visit.rs
+++ b/src/librustc/mir/visit.rs
@@ -12,7 +12,7 @@ use middle::const_val::ConstVal;
 use hir::def_id::DefId;
 use ty::subst::Substs;
 use ty::{ClosureSubsts, Region, Ty};
-use mir::repr::*;
+use mir::*;
 use rustc_const_math::ConstUsize;
 use rustc_data_structures::tuple_slice::TupleSlice;
 use rustc_data_structures::indexed_vec::Idx;
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 0ad53529dd1..7b5413984a2 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1237,10 +1237,9 @@ pub fn rustc_optgroups() -> Vec<RustcOptGroup> {
 pub fn parse_cfgspecs(cfgspecs: Vec<String> ) -> ast::CrateConfig {
     cfgspecs.into_iter().map(|s| {
         let sess = parse::ParseSess::new();
-        let mut parser = parse::new_parser_from_source_str(&sess,
-                                                           Vec::new(),
-                                                           "cfgspec".to_string(),
-                                                           s.to_string());
+        let mut parser =
+            parse::new_parser_from_source_str(&sess, "cfgspec".to_string(), s.to_string());
+
         let meta_item = panictry!(parser.parse_meta_item());
 
         if !parser.reader.is_eof() {
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 8c7a2da3be7..62cc78141db 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -22,6 +22,7 @@ use middle::free_region::FreeRegionMap;
 use middle::region::RegionMaps;
 use middle::resolve_lifetime;
 use middle::stability;
+use mir::Mir;
 use ty::subst::{Kind, Substs};
 use traits;
 use ty::{self, TraitRef, Ty, TypeAndMut};
@@ -65,8 +66,9 @@ pub struct CtxtArenas<'tcx> {
 
     // references
     generics: TypedArena<ty::Generics<'tcx>>,
-    trait_defs: TypedArena<ty::TraitDef<'tcx>>,
-    adt_defs: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
+    trait_def: TypedArena<ty::TraitDef<'tcx>>,
+    adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
+    mir: TypedArena<RefCell<Mir<'tcx>>>,
 }
 
 impl<'tcx> CtxtArenas<'tcx> {
@@ -81,8 +83,9 @@ impl<'tcx> CtxtArenas<'tcx> {
             layout: TypedArena::new(),
 
             generics: TypedArena::new(),
-            trait_defs: TypedArena::new(),
-            adt_defs: TypedArena::new()
+            trait_def: TypedArena::new(),
+            adt_def: TypedArena::new(),
+            mir: TypedArena::new()
         }
     }
 }
@@ -358,6 +361,15 @@ pub struct GlobalCtxt<'tcx> {
 
     pub map: ast_map::Map<'tcx>,
 
+    /// Maps from the def-id of a function/method or const/static
+    /// to its MIR. Mutation is done at an item granularity to
+    /// allow MIR optimization passes to function and still
+    /// access cross-crate MIR (e.g. inlining or const eval).
+    ///
+    /// Note that cross-crate MIR appears to be always borrowed
+    /// (in the `RefCell` sense) to prevent accidental mutation.
+    pub mir_map: RefCell<DepTrackingMap<maps::Mir<'tcx>>>,
+
     // Records the free variables refrenced by every closure
     // expression. Do not track deps for this, just recompute it from
     // scratch every time.
@@ -604,6 +616,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.global_interners.arenas.generics.alloc(generics)
     }
 
+    pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell<Mir<'gcx>> {
+        self.global_interners.arenas.mir.alloc(RefCell::new(mir))
+    }
+
     pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
                             -> &'gcx ty::TraitDef<'gcx> {
         let did = def.trait_ref.def_id;
@@ -617,7 +633,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
     pub fn alloc_trait_def(self, def: ty::TraitDef<'gcx>)
                            -> &'gcx ty::TraitDef<'gcx> {
-        self.global_interners.arenas.trait_defs.alloc(def)
+        self.global_interners.arenas.trait_def.alloc(def)
     }
 
     pub fn insert_adt_def(self, did: DefId, adt_def: ty::AdtDefMaster<'gcx>) {
@@ -633,7 +649,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                           variants: Vec<ty::VariantDefData<'gcx, 'gcx>>)
                           -> ty::AdtDefMaster<'gcx> {
         let def = ty::AdtDefData::new(self, did, kind, variants);
-        let interned = self.global_interners.arenas.adt_defs.alloc(def);
+        let interned = self.global_interners.arenas.adt_def.alloc(def);
         self.insert_adt_def(did, interned);
         interned
     }
@@ -738,6 +754,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             super_predicates: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             fulfilled_predicates: RefCell::new(fulfilled_predicates),
             map: map,
+            mir_map: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
             freevars: RefCell::new(freevars),
             maybe_unused_trait_imports: maybe_unused_trait_imports,
             tcache: RefCell::new(DepTrackingMap::new(dep_graph.clone())),
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index 3a552a8b437..cad87081a93 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -10,7 +10,10 @@
 
 use dep_graph::{DepNode, DepTrackingMapConfig};
 use hir::def_id::DefId;
+use mir;
 use ty::{self, Ty};
+
+use std::cell::RefCell;
 use std::marker::PhantomData;
 use std::rc::Rc;
 use syntax::{attr, ast};
@@ -43,3 +46,4 @@ dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
 dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc<Vec<ty::ImplOrTraitItem<'tcx>>> }
 dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc<Vec<attr::ReprAttr>> }
 dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId }
+dep_map_ty! { Mir: Mir(DefId) -> &'tcx RefCell<mir::Mir<'tcx>> }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index f65976a8c11..588857e557c 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -24,6 +24,7 @@ use hir::def::{Def, CtorKind, PathResolution, ExportMap};
 use hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
 use middle::lang_items::{FnTraitLangItem, FnMutTraitLangItem, FnOnceTraitLangItem};
 use middle::region::{CodeExtent, ROOT_CODE_EXTENT};
+use mir::Mir;
 use traits;
 use ty;
 use ty::subst::{Subst, Substs};
@@ -34,7 +35,7 @@ use util::nodemap::FnvHashMap;
 
 use serialize::{self, Encodable, Encoder};
 use std::borrow::Cow;
-use std::cell::{Cell, RefCell};
+use std::cell::{Cell, RefCell, Ref};
 use std::hash::{Hash, Hasher};
 use std::iter;
 use std::ops::Deref;
@@ -1698,7 +1699,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> {
         match def {
             Def::Variant(vid) | Def::VariantCtor(vid, ..) => self.variant_with_id(vid),
             Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
-            Def::TyAlias(..) | Def::AssociatedTy(..) => self.struct_variant(),
+            Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => self.struct_variant(),
             _ => bug!("unexpected def {:?} in variant_of_def", def)
         }
     }
@@ -2519,6 +2520,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             || self.sess.cstore.item_super_predicates(self.global_tcx(), did))
     }
 
+    /// Given the did of an item, returns its MIR, borrowed immutably.
+    pub fn item_mir(self, did: DefId) -> Ref<'gcx, Mir<'gcx>> {
+        lookup_locally_or_in_crate_store("mir_map", did, &self.mir_map, || {
+            let mir = self.sess.cstore.get_item_mir(self.global_tcx(), did);
+            let mir = self.alloc_mir(mir);
+
+            // Perma-borrow MIR from extern crates to prevent mutation.
+            mem::forget(mir.borrow());
+
+            mir
+        }).borrow()
+    }
+
     /// If `type_needs_drop` returns true, then `ty` is definitely
     /// non-copy and *might* have a destructor attached; if it returns
     /// false, then `ty` definitely has no destructor (i.e. no drop glue).
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index bb36fa1487e..cca4069ba5a 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -405,6 +405,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 ///
 /// The same goes for endianess: We always convert multi-byte integers to little
 /// endian before hashing.
+#[derive(Debug)]
 pub struct ArchIndependentHasher<H> {
     inner: H,
 }
@@ -413,6 +414,10 @@ impl<H> ArchIndependentHasher<H> {
     pub fn new(inner: H) -> ArchIndependentHasher<H> {
         ArchIndependentHasher { inner: inner }
     }
+
+    pub fn into_inner(self) -> H {
+        self.inner
+    }
 }
 
 impl<H: Hasher> Hasher for ArchIndependentHasher<H> {
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index af92569cc35..5ca56741029 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -9,12 +9,13 @@
 // except according to those terms.
 
 use hir::def_id::DefId;
+use hir::map::definitions::DefPathData;
 use ty::subst::{self, Subst};
 use ty::{BrAnon, BrEnv, BrFresh, BrNamed};
 use ty::{TyBool, TyChar, TyAdt};
 use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
 use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
-use ty::TyClosure;
+use ty::{TyClosure, TyProjection, TyAnon};
 use ty::{TyBox, TyTrait, TyInt, TyUint, TyInfer};
 use ty::{self, Ty, TyCtxt, TypeFoldable};
 use ty::fold::{TypeFolder, TypeVisitor};
@@ -56,17 +57,9 @@ fn fn_sig(f: &mut fmt::Formatter,
     Ok(())
 }
 
-/// Namespace of the path given to parameterized to print.
-#[derive(Copy, Clone, PartialEq, Debug)]
-pub enum Ns {
-    Type,
-    Value
-}
-
 pub fn parameterized(f: &mut fmt::Formatter,
                      substs: &subst::Substs,
                      did: DefId,
-                     ns: Ns,
                      projections: &[ty::ProjectionPredicate])
                      -> fmt::Result {
     let mut verbose = false;
@@ -75,8 +68,34 @@ pub fn parameterized(f: &mut fmt::Formatter,
     let mut num_regions = 0;
     let mut num_types = 0;
     let mut item_name = None;
+    let mut is_value_path = false;
     let fn_trait_kind = ty::tls::with(|tcx| {
-        let mut generics = tcx.lookup_generics(did);
+        // Unfortunately, some kinds of items (e.g., closures) don't have
+        // generics. So walk back up the find the closest parent that DOES
+        // have them.
+        let mut item_def_id = did;
+        loop {
+            let key = tcx.def_key(item_def_id);
+            match key.disambiguated_data.data {
+                DefPathData::TypeNs(_) => {
+                    break;
+                }
+                DefPathData::ValueNs(_) | DefPathData::EnumVariant(_) => {
+                    is_value_path = true;
+                    break;
+                }
+                _ => {
+                    // if we're making a symbol for something, there ought
+                    // to be a value or type-def or something in there
+                    // *somewhere*
+                    item_def_id.index = key.parent.unwrap_or_else(|| {
+                        bug!("finding type for {:?}, encountered def-id {:?} with no \
+                             parent", did, item_def_id);
+                    });
+                }
+            }
+        }
+        let mut generics = tcx.lookup_generics(item_def_id);
         let mut path_def_id = did;
         verbose = tcx.sess.verbose();
         has_self = generics.has_self;
@@ -84,7 +103,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
         let mut child_types = 0;
         if let Some(def_id) = generics.parent {
             // Methods.
-            assert_eq!(ns, Ns::Value);
+            assert!(is_value_path);
             child_types = generics.types.len();
             generics = tcx.lookup_generics(def_id);
             num_regions = generics.regions.len();
@@ -97,7 +116,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
             item_name = Some(tcx.item_name(did));
             path_def_id = def_id;
         } else {
-            if ns == Ns::Value {
+            if is_value_path {
                 // Functions.
                 assert_eq!(has_self, false);
             } else {
@@ -192,7 +211,7 @@ pub fn parameterized(f: &mut fmt::Formatter,
     start_or_continue(f, "", ">")?;
 
     // For values, also print their name and type parameters.
-    if ns == Ns::Value {
+    if is_value_path {
         empty.set(true);
 
         if has_self {
@@ -298,7 +317,6 @@ impl<'tcx> fmt::Display for TraitAndProjections<'tcx> {
         let TraitAndProjections(ref trait_ref, ref projection_bounds) = *self;
         parameterized(f, trait_ref.substs,
                       trait_ref.def_id,
-                      Ns::Type,
                       projection_bounds)
     }
 }
@@ -398,7 +416,7 @@ impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
             let trait_ref = tcx.lift(&ty::Binder(*self))
                                .expect("could not lift TraitRef for printing")
                                .with_self_ty(tcx, dummy_self).0;
-            parameterized(f, trait_ref.substs, trait_ref.def_id, Ns::Type, &[])
+            parameterized(f, trait_ref.substs, trait_ref.def_id, &[])
         })
     }
 }
@@ -798,7 +816,7 @@ impl<'tcx> fmt::Display for ty::Binder<ty::OutlivesPredicate<&'tcx ty::Region,
 
 impl<'tcx> fmt::Display for ty::TraitRef<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        parameterized(f, self.substs, self.def_id, Ns::Type, &[])
+        parameterized(f, self.substs, self.def_id, &[])
     }
 }
 
@@ -851,7 +869,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
                 }
 
                 write!(f, "{} {{", bare_fn.sig.0)?;
-                parameterized(f, substs, def_id, Ns::Value, &[])?;
+                parameterized(f, substs, def_id, &[])?;
                 write!(f, "}}")
             }
             TyFnPtr(ref bare_fn) => {
@@ -874,13 +892,13 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
                           !tcx.tcache.borrow().contains_key(&def.did) {
                         write!(f, "{}<..>", tcx.item_path_str(def.did))
                     } else {
-                        parameterized(f, substs, def.did, Ns::Type, &[])
+                        parameterized(f, substs, def.did, &[])
                     }
                 })
             }
             TyTrait(ref data) => write!(f, "{}", data),
-            ty::TyProjection(ref data) => write!(f, "{}", data),
-            ty::TyAnon(def_id, substs) => {
+            TyProjection(ref data) => write!(f, "{}", data),
+            TyAnon(def_id, substs) => {
                 ty::tls::with(|tcx| {
                     // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
                     // by looking up the projections associated with the def_id.
diff --git a/src/librustc_back/lib.rs b/src/librustc_back/lib.rs
index e6d1982d31c..da5f787bdf3 100644
--- a/src/librustc_back/lib.rs
+++ b/src/librustc_back/lib.rs
@@ -36,9 +36,8 @@
 #![feature(rand)]
 #![feature(rustc_private)]
 #![feature(staged_api)]
-#![feature(step_by)]
 #![cfg_attr(stage0, feature(question_mark))]
-#![cfg_attr(test, feature(test, rand))]
+#![cfg_attr(test, feature(rand))]
 
 extern crate syntax;
 extern crate libc;
@@ -48,7 +47,6 @@ extern crate serialize;
 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;
diff --git a/src/librustc_back/sha2.rs b/src/librustc_back/sha2.rs
deleted file mode 100644
index 97fb39c17ea..00000000000
--- a/src/librustc_back/sha2.rs
+++ /dev/null
@@ -1,679 +0,0 @@
-// Copyright 2012-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.
-
-//! This module implements only the Sha256 function since that is all that is needed for internal
-//! use. This implementation is not intended for external use or for any use where security is
-//! important.
-
-use serialize::hex::ToHex;
-
-/// Write a u32 into a vector, which must be 4 bytes long. The value is written in big-endian
-/// format.
-fn write_u32_be(dst: &mut[u8], input: u32) {
-    dst[0] = (input >> 24) as u8;
-    dst[1] = (input >> 16) as u8;
-    dst[2] = (input >> 8) as u8;
-    dst[3] = input as u8;
-}
-
-/// Read the value of a vector of bytes as a u32 value in big-endian format.
-fn read_u32_be(input: &[u8]) -> u32 {
-    (input[0] as u32) << 24 |
-        (input[1] as u32) << 16 |
-        (input[2] as u32) << 8 |
-        (input[3] as u32)
-}
-
-/// Read a vector of bytes into a vector of u32s. The values are read in big-endian format.
-fn read_u32v_be(dst: &mut[u32], input: &[u8]) {
-    assert!(dst.len() * 4 == input.len());
-    let mut pos = 0;
-    for chunk in input.chunks(4) {
-        dst[pos] = read_u32_be(chunk);
-        pos += 1;
-    }
-}
-
-trait ToBits: Sized {
-    /// Convert the value in bytes to the number of bits, a tuple where the 1st item is the
-    /// high-order value and the 2nd item is the low order value.
-    fn to_bits(self) -> (Self, Self);
-}
-
-impl ToBits for u64 {
-    fn to_bits(self) -> (u64, u64) {
-        (self >> 61, self << 3)
-    }
-}
-
-/// Adds the specified number of bytes to the bit count. panic!() if this would cause numeric
-/// overflow.
-fn add_bytes_to_bits(bits: u64, bytes: u64) -> u64 {
-    let (new_high_bits, new_low_bits) = bytes.to_bits();
-
-    if new_high_bits > 0 {
-        panic!("numeric overflow occurred.")
-    }
-
-    match bits.checked_add(new_low_bits) {
-        Some(x) => x,
-        None => panic!("numeric overflow occurred.")
-    }
-}
-
-/// A FixedBuffer, likes its name implies, is a fixed size buffer. When the buffer becomes full, it
-/// must be processed. The input() method takes care of processing and then clearing the buffer
-/// automatically. However, other methods do not and require the caller to process the buffer. Any
-/// method that modifies the buffer directory or provides the caller with bytes that can be modified
-/// results in those bytes being marked as used by the buffer.
-trait FixedBuffer {
-    /// Input a vector of bytes. If the buffer becomes full, process it with the provided
-    /// function and then clear the buffer.
-    fn input<F>(&mut self, input: &[u8], func: F) where
-        F: FnMut(&[u8]);
-
-    /// Reset the buffer.
-    fn reset(&mut self);
-
-    /// Zero the buffer up until the specified index. The buffer position currently must not be
-    /// greater than that index.
-    fn zero_until(&mut self, idx: usize);
-
-    /// Get a slice of the buffer of the specified size. There must be at least that many bytes
-    /// remaining in the buffer.
-    fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8];
-
-    /// Get the current buffer. The buffer must already be full. This clears the buffer as well.
-    fn full_buffer<'s>(&'s mut self) -> &'s [u8];
-
-    /// Get the current position of the buffer.
-    fn position(&self) -> usize;
-
-    /// Get the number of bytes remaining in the buffer until it is full.
-    fn remaining(&self) -> usize;
-
-    /// Get the size of the buffer
-    fn size(&self) -> usize;
-}
-
-/// A FixedBuffer of 64 bytes useful for implementing Sha256 which has a 64 byte blocksize.
-struct FixedBuffer64 {
-    buffer: [u8; 64],
-    buffer_idx: usize,
-}
-
-impl FixedBuffer64 {
-    /// Create a new FixedBuffer64
-    fn new() -> FixedBuffer64 {
-        FixedBuffer64 {
-            buffer: [0; 64],
-            buffer_idx: 0
-        }
-    }
-}
-
-impl FixedBuffer for FixedBuffer64 {
-    fn input<F>(&mut self, input: &[u8], mut func: F) where
-        F: FnMut(&[u8]),
-    {
-        let mut i = 0;
-
-        let size = self.size();
-
-        // If there is already data in the buffer, copy as much as we can into it and process
-        // the data if the buffer becomes full.
-        if self.buffer_idx != 0 {
-            let buffer_remaining = size - self.buffer_idx;
-            if input.len() >= buffer_remaining {
-                self.buffer[self.buffer_idx..size]
-                    .copy_from_slice(&input[..buffer_remaining]);
-                self.buffer_idx = 0;
-                func(&self.buffer);
-                i += buffer_remaining;
-            } else {
-                self.buffer[self.buffer_idx..self.buffer_idx + input.len()]
-                    .copy_from_slice(input);
-                self.buffer_idx += input.len();
-                return;
-            }
-        }
-
-        // While we have at least a full buffer size chunk's worth of data, process that data
-        // without copying it into the buffer
-        while input.len() - i >= size {
-            func(&input[i..i + size]);
-            i += size;
-        }
-
-        // Copy any input data into the buffer. At this point in the method, the amount of
-        // data left in the input vector will be less than the buffer size and the buffer will
-        // be empty.
-        let input_remaining = input.len() - i;
-        self.buffer[..input_remaining].copy_from_slice(&input[i..]);
-        self.buffer_idx += input_remaining;
-    }
-
-    fn reset(&mut self) {
-        self.buffer_idx = 0;
-    }
-
-    fn zero_until(&mut self, idx: usize) {
-        assert!(idx >= self.buffer_idx);
-        for slot in self.buffer[self.buffer_idx..idx].iter_mut() {
-            *slot = 0;
-        }
-        self.buffer_idx = idx;
-    }
-
-    fn next<'s>(&'s mut self, len: usize) -> &'s mut [u8] {
-        self.buffer_idx += len;
-        &mut self.buffer[self.buffer_idx - len..self.buffer_idx]
-    }
-
-    fn full_buffer<'s>(&'s mut self) -> &'s [u8] {
-        assert!(self.buffer_idx == 64);
-        self.buffer_idx = 0;
-        &self.buffer[..64]
-    }
-
-    fn position(&self) -> usize { self.buffer_idx }
-
-    fn remaining(&self) -> usize { 64 - self.buffer_idx }
-
-    fn size(&self) -> usize { 64 }
-}
-
-/// The StandardPadding trait adds a method useful for Sha256 to a FixedBuffer struct.
-trait StandardPadding {
-    /// Add padding to the buffer. The buffer must not be full when this method is called and is
-    /// guaranteed to have exactly rem remaining bytes when it returns. If there are not at least
-    /// rem bytes available, the buffer will be zero padded, processed, cleared, and then filled
-    /// with zeros again until only rem bytes are remaining.
-    fn standard_padding<F>(&mut self, rem: usize, func: F) where F: FnMut(&[u8]);
-}
-
-impl <T: FixedBuffer> StandardPadding for T {
-    fn standard_padding<F>(&mut self, rem: usize, mut func: F) where F: FnMut(&[u8]) {
-        let size = self.size();
-
-        self.next(1)[0] = 128;
-
-        if self.remaining() < rem {
-            self.zero_until(size);
-            func(self.full_buffer());
-        }
-
-        self.zero_until(size - rem);
-    }
-}
-
-/// The Digest trait specifies an interface common to digest functions, such as SHA-1 and the SHA-2
-/// family of digest functions.
-pub trait Digest {
-    /// Provide message data.
-    ///
-    /// # Arguments
-    ///
-    /// * input - A vector of message data
-    fn input(&mut self, input: &[u8]);
-
-    /// Retrieve the digest result. This method may be called multiple times.
-    ///
-    /// # Arguments
-    ///
-    /// * out - the vector to hold the result. Must be large enough to contain output_bits().
-    fn result(&mut self, out: &mut [u8]);
-
-    /// Reset the digest. This method must be called after result() and before supplying more
-    /// data.
-    fn reset(&mut self);
-
-    /// Get the output size in bits.
-    fn output_bits(&self) -> usize;
-
-    /// Convenience function that feeds a string into a digest.
-    ///
-    /// # Arguments
-    ///
-    /// * `input` The string to feed into the digest
-    fn input_str(&mut self, input: &str) {
-        self.input(input.as_bytes());
-    }
-
-    /// Convenience function that retrieves the result of a digest as a
-    /// newly allocated vec of bytes.
-    fn result_bytes(&mut self) -> Vec<u8> {
-        let mut buf = vec![0; (self.output_bits()+7)/8];
-        self.result(&mut buf);
-        buf
-    }
-
-    /// Convenience function that retrieves the result of a digest as a
-    /// String in hexadecimal format.
-    fn result_str(&mut self) -> String {
-        self.result_bytes().to_hex().to_string()
-    }
-}
-
-// A structure that represents that state of a digest computation for the SHA-2 512 family of digest
-// functions
-struct Engine256State {
-    h0: u32,
-    h1: u32,
-    h2: u32,
-    h3: u32,
-    h4: u32,
-    h5: u32,
-    h6: u32,
-    h7: u32,
-}
-
-impl Engine256State {
-    fn new(h: &[u32; 8]) -> Engine256State {
-        Engine256State {
-            h0: h[0],
-            h1: h[1],
-            h2: h[2],
-            h3: h[3],
-            h4: h[4],
-            h5: h[5],
-            h6: h[6],
-            h7: h[7]
-        }
-    }
-
-    fn reset(&mut self, h: &[u32; 8]) {
-        self.h0 = h[0];
-        self.h1 = h[1];
-        self.h2 = h[2];
-        self.h3 = h[3];
-        self.h4 = h[4];
-        self.h5 = h[5];
-        self.h6 = h[6];
-        self.h7 = h[7];
-    }
-
-    fn process_block(&mut self, data: &[u8]) {
-        fn ch(x: u32, y: u32, z: u32) -> u32 {
-            ((x & y) ^ ((!x) & z))
-        }
-
-        fn maj(x: u32, y: u32, z: u32) -> u32 {
-            ((x & y) ^ (x & z) ^ (y & z))
-        }
-
-        fn sum0(x: u32) -> u32 {
-            ((x >> 2) | (x << 30)) ^ ((x >> 13) | (x << 19)) ^ ((x >> 22) | (x << 10))
-        }
-
-        fn sum1(x: u32) -> u32 {
-            ((x >> 6) | (x << 26)) ^ ((x >> 11) | (x << 21)) ^ ((x >> 25) | (x << 7))
-        }
-
-        fn sigma0(x: u32) -> u32 {
-            ((x >> 7) | (x << 25)) ^ ((x >> 18) | (x << 14)) ^ (x >> 3)
-        }
-
-        fn sigma1(x: u32) -> u32 {
-            ((x >> 17) | (x << 15)) ^ ((x >> 19) | (x << 13)) ^ (x >> 10)
-        }
-
-        let mut a = self.h0;
-        let mut b = self.h1;
-        let mut c = self.h2;
-        let mut d = self.h3;
-        let mut e = self.h4;
-        let mut f = self.h5;
-        let mut g = self.h6;
-        let mut h = self.h7;
-
-        let mut w = [0; 64];
-
-        // Sha-512 and Sha-256 use basically the same calculations which are implemented
-        // by these macros. Inlining the calculations seems to result in better generated code.
-        macro_rules! schedule_round { ($t:expr) => (
-            w[$t] = sigma1(w[$t - 2]).wrapping_add(w[$t - 7])
-                .wrapping_add(sigma0(w[$t - 15])).wrapping_add(w[$t - 16]);
-            )
-        }
-
-        macro_rules! sha2_round {
-            ($A:ident, $B:ident, $C:ident, $D:ident,
-             $E:ident, $F:ident, $G:ident, $H:ident, $K:ident, $t:expr) => (
-                {
-                    $H = $H.wrapping_add(sum1($E)).wrapping_add(ch($E, $F, $G))
-                        .wrapping_add($K[$t]).wrapping_add(w[$t]);
-                    $D = $D.wrapping_add($H);
-                    $H = $H.wrapping_add(sum0($A)).wrapping_add(maj($A, $B, $C));
-                }
-             )
-        }
-
-        read_u32v_be(&mut w[0..16], data);
-
-        // Putting the message schedule inside the same loop as the round calculations allows for
-        // the compiler to generate better code.
-        for t in (0..48).step_by(8) {
-            schedule_round!(t + 16);
-            schedule_round!(t + 17);
-            schedule_round!(t + 18);
-            schedule_round!(t + 19);
-            schedule_round!(t + 20);
-            schedule_round!(t + 21);
-            schedule_round!(t + 22);
-            schedule_round!(t + 23);
-
-            sha2_round!(a, b, c, d, e, f, g, h, K32, t);
-            sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
-            sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
-            sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
-            sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
-            sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
-            sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
-            sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
-        }
-
-        for t in (48..64).step_by(8) {
-            sha2_round!(a, b, c, d, e, f, g, h, K32, t);
-            sha2_round!(h, a, b, c, d, e, f, g, K32, t + 1);
-            sha2_round!(g, h, a, b, c, d, e, f, K32, t + 2);
-            sha2_round!(f, g, h, a, b, c, d, e, K32, t + 3);
-            sha2_round!(e, f, g, h, a, b, c, d, K32, t + 4);
-            sha2_round!(d, e, f, g, h, a, b, c, K32, t + 5);
-            sha2_round!(c, d, e, f, g, h, a, b, K32, t + 6);
-            sha2_round!(b, c, d, e, f, g, h, a, K32, t + 7);
-        }
-
-        self.h0 = self.h0.wrapping_add(a);
-        self.h1 = self.h1.wrapping_add(b);
-        self.h2 = self.h2.wrapping_add(c);
-        self.h3 = self.h3.wrapping_add(d);
-        self.h4 = self.h4.wrapping_add(e);
-        self.h5 = self.h5.wrapping_add(f);
-        self.h6 = self.h6.wrapping_add(g);
-        self.h7 = self.h7.wrapping_add(h);
-    }
-}
-
-static K32: [u32; 64] = [
-    0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5,
-    0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
-    0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3,
-    0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
-    0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc,
-    0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
-    0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7,
-    0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967,
-    0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13,
-    0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85,
-    0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3,
-    0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070,
-    0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5,
-    0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
-    0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208,
-    0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
-];
-
-// A structure that keeps track of the state of the Sha-256 operation and contains the logic
-// necessary to perform the final calculations.
-struct Engine256 {
-    length_bits: u64,
-    buffer: FixedBuffer64,
-    state: Engine256State,
-    finished: bool,
-}
-
-impl Engine256 {
-    fn new(h: &[u32; 8]) -> Engine256 {
-        Engine256 {
-            length_bits: 0,
-            buffer: FixedBuffer64::new(),
-            state: Engine256State::new(h),
-            finished: false
-        }
-    }
-
-    fn reset(&mut self, h: &[u32; 8]) {
-        self.length_bits = 0;
-        self.buffer.reset();
-        self.state.reset(h);
-        self.finished = false;
-    }
-
-    fn input(&mut self, input: &[u8]) {
-        assert!(!self.finished);
-        // Assumes that input.len() can be converted to u64 without overflow
-        self.length_bits = add_bytes_to_bits(self.length_bits, input.len() as u64);
-        let self_state = &mut self.state;
-        self.buffer.input(input, |input: &[u8]| { self_state.process_block(input) });
-    }
-
-    fn finish(&mut self) {
-        if !self.finished {
-            let self_state = &mut self.state;
-            self.buffer.standard_padding(8, |input: &[u8]| { self_state.process_block(input) });
-            write_u32_be(self.buffer.next(4), (self.length_bits >> 32) as u32 );
-            write_u32_be(self.buffer.next(4), self.length_bits as u32);
-            self_state.process_block(self.buffer.full_buffer());
-
-            self.finished = true;
-        }
-    }
-}
-
-/// The SHA-256 hash algorithm
-pub struct Sha256 {
-    engine: Engine256
-}
-
-impl Sha256 {
-    /// Construct a new instance of a SHA-256 digest.
-    /// Do not – under any circumstances – use this where timing attacks might be possible!
-    pub fn new() -> Sha256 {
-        Sha256 {
-            engine: Engine256::new(&H256)
-        }
-    }
-}
-
-impl Digest for Sha256 {
-    fn input(&mut self, d: &[u8]) {
-        self.engine.input(d);
-    }
-
-    fn result(&mut self, out: &mut [u8]) {
-        self.engine.finish();
-
-        write_u32_be(&mut out[0..4], self.engine.state.h0);
-        write_u32_be(&mut out[4..8], self.engine.state.h1);
-        write_u32_be(&mut out[8..12], self.engine.state.h2);
-        write_u32_be(&mut out[12..16], self.engine.state.h3);
-        write_u32_be(&mut out[16..20], self.engine.state.h4);
-        write_u32_be(&mut out[20..24], self.engine.state.h5);
-        write_u32_be(&mut out[24..28], self.engine.state.h6);
-        write_u32_be(&mut out[28..32], self.engine.state.h7);
-    }
-
-    fn reset(&mut self) {
-        self.engine.reset(&H256);
-    }
-
-    fn output_bits(&self) -> usize { 256 }
-}
-
-static H256: [u32; 8] = [
-    0x6a09e667,
-    0xbb67ae85,
-    0x3c6ef372,
-    0xa54ff53a,
-    0x510e527f,
-    0x9b05688c,
-    0x1f83d9ab,
-    0x5be0cd19
-];
-
-#[cfg(test)]
-mod tests {
-    #![allow(deprecated)]
-    extern crate rand;
-
-    use self::rand::Rng;
-    use self::rand::isaac::IsaacRng;
-    use serialize::hex::FromHex;
-    use std::u64;
-    use super::{Digest, Sha256};
-
-    // A normal addition - no overflow occurs
-    #[test]
-    fn test_add_bytes_to_bits_ok() {
-        assert!(super::add_bytes_to_bits(100, 10) == 180);
-    }
-
-    // A simple failure case - adding 1 to the max value
-    #[test]
-    #[should_panic]
-    fn test_add_bytes_to_bits_overflow() {
-        super::add_bytes_to_bits(u64::MAX, 1);
-    }
-
-    struct Test {
-        input: String,
-        output_str: String,
-    }
-
-    fn test_hash<D: Digest>(sh: &mut D, tests: &[Test]) {
-        // Test that it works when accepting the message all at once
-        for t in tests {
-            sh.reset();
-            sh.input_str(&t.input);
-            let out_str = sh.result_str();
-            assert!(out_str == t.output_str);
-        }
-
-        // Test that it works when accepting the message in pieces
-        for t in tests {
-            sh.reset();
-            let len = t.input.len();
-            let mut left = len;
-            while left > 0 {
-                let take = (left + 1) / 2;
-                sh.input_str(&t.input[len - left..take + len - left]);
-                left = left - take;
-            }
-            let out_str = sh.result_str();
-            assert!(out_str == t.output_str);
-        }
-    }
-
-    #[test]
-    fn test_sha256() {
-        // Examples from wikipedia
-        let wikipedia_tests = vec!(
-            Test {
-                input: "".to_string(),
-                output_str: "e3b0c44298fc1c149afb\
-            f4c8996fb92427ae41e4649b934ca495991b7852b855".to_string()
-            },
-            Test {
-                input: "The quick brown fox jumps over the lazy \
-                        dog".to_string(),
-                output_str: "d7a8fbb307d7809469ca\
-            9abcb0082e4f8d5651e46d3cdb762d02d0bf37c9e592".to_string()
-            },
-            Test {
-                input: "The quick brown fox jumps over the lazy \
-                        dog.".to_string(),
-                output_str: "ef537f25c895bfa78252\
-            6529a9b63d97aa631564d5d789c2b765448c8635fb6c".to_string()
-            });
-
-        let tests = wikipedia_tests;
-
-        let mut sh: Box<_> = box Sha256::new();
-
-        test_hash(&mut *sh, &tests);
-    }
-
-    /// Feed 1,000,000 'a's into the digest with varying input sizes and check that the result is
-    /// correct.
-    fn test_digest_1million_random<D: Digest>(digest: &mut D, blocksize: usize, expected: &str) {
-        let total_size = 1000000;
-        let buffer = vec![b'a'; blocksize * 2];
-        let mut rng = IsaacRng::new_unseeded();
-        let mut count = 0;
-
-        digest.reset();
-
-        while count < total_size {
-            let next: usize = rng.gen_range(0, 2 * blocksize + 1);
-            let remaining = total_size - count;
-            let size = if next > remaining { remaining } else { next };
-            digest.input(&buffer[..size]);
-            count += size;
-        }
-
-        let result_str = digest.result_str();
-        let result_bytes = digest.result_bytes();
-
-        assert_eq!(expected, result_str);
-
-        let expected_vec: Vec<u8> = expected.from_hex()
-                                            .unwrap()
-                                            .into_iter()
-                                            .collect();
-        assert_eq!(expected_vec, result_bytes);
-    }
-
-    #[test]
-    fn test_1million_random_sha256() {
-        let mut sh = Sha256::new();
-        test_digest_1million_random(
-            &mut sh,
-            64,
-            "cdc76e5c9914fb9281a1c7e284d73e67f1809a48a497200e046d39ccc7112cd0");
-    }
-}
-
-#[cfg(test)]
-mod bench {
-    extern crate test;
-    use self::test::Bencher;
-    use super::{Sha256, Digest};
-
-    #[bench]
-    pub fn sha256_10(b: &mut Bencher) {
-        let mut sh = Sha256::new();
-        let bytes = [1; 10];
-        b.iter(|| {
-            sh.input(&bytes);
-        });
-        b.bytes = bytes.len() as u64;
-    }
-
-    #[bench]
-    pub fn sha256_1k(b: &mut Bencher) {
-        let mut sh = Sha256::new();
-        let bytes = [1; 1024];
-        b.iter(|| {
-            sh.input(&bytes);
-        });
-        b.bytes = bytes.len() as u64;
-    }
-
-    #[bench]
-    pub fn sha256_64k(b: &mut Bencher) {
-        let mut sh = Sha256::new();
-        let bytes = [1; 65536];
-        b.iter(|| {
-            sh.input(&bytes);
-        });
-        b.bytes = bytes.len() as u64;
-    }
-}
diff --git a/src/librustc_back/target/aarch64_unknown_fuchsia.rs b/src/librustc_back/target/aarch64_unknown_fuchsia.rs
new file mode 100644
index 00000000000..a93a46d1402
--- /dev/null
+++ b/src/librustc_back/target/aarch64_unknown_fuchsia.rs
@@ -0,0 +1,28 @@
+// 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.
+
+use target::{Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::fuchsia_base::opts();
+    base.max_atomic_width = Some(128);
+
+    Ok(Target {
+        llvm_target: "aarch64-unknown-fuchsia".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128".to_string(),
+        arch: "aarch64".to_string(),
+        target_os: "fuchsia".to_string(),
+        target_env: "".to_string(),
+        target_vendor: "unknown".to_string(),
+        options: base,
+    })
+}
diff --git a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
index b031de76fc3..5f6335d405f 100644
--- a/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/aarch64_unknown_linux_gnu.rs
@@ -13,6 +13,10 @@ use target::{Target, TargetOptions, TargetResult};
 pub fn target() -> TargetResult {
     let mut base = super::linux_base::opts();
     base.max_atomic_width = Some(128);
+
+    // see #36994
+    base.exe_allocation_crate = "alloc_system".to_string();
+
     Ok(Target {
         llvm_target: "aarch64-unknown-linux-gnu".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
index 9f0b6fcc436..c284840ecb4 100644
--- a/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
+++ b/src/librustc_back/target/mips64_unknown_linux_gnuabi64.rs
@@ -25,6 +25,10 @@ pub fn target() -> TargetResult {
             cpu: "mips64r2".to_string(),
             features: "+mips64r2".to_string(),
             max_atomic_width: Some(64),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs
index 9c4531c5b21..17895836fe8 100644
--- a/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs
+++ b/src/librustc_back/target/mips64el_unknown_linux_gnuabi64.rs
@@ -25,6 +25,10 @@ pub fn target() -> TargetResult {
             cpu: "mips64r2".to_string(),
             features: "+mips64r2".to_string(),
             max_atomic_width: Some(64),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mips_unknown_linux_gnu.rs b/src/librustc_back/target/mips_unknown_linux_gnu.rs
index e744dce2bb4..a6d8fae2536 100644
--- a/src/librustc_back/target/mips_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/mips_unknown_linux_gnu.rs
@@ -24,6 +24,10 @@ pub fn target() -> TargetResult {
             cpu: "mips32r2".to_string(),
             features: "+mips32r2".to_string(),
             max_atomic_width: Some(32),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mips_unknown_linux_musl.rs b/src/librustc_back/target/mips_unknown_linux_musl.rs
index 4254c1b83e3..e4a6d2a55d9 100644
--- a/src/librustc_back/target/mips_unknown_linux_musl.rs
+++ b/src/librustc_back/target/mips_unknown_linux_musl.rs
@@ -24,6 +24,10 @@ pub fn target() -> TargetResult {
             cpu: "mips32r2".to_string(),
             features: "+mips32r2,+soft-float".to_string(),
             max_atomic_width: Some(32),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         }
     })
diff --git a/src/librustc_back/target/mips_unknown_linux_uclibc.rs b/src/librustc_back/target/mips_unknown_linux_uclibc.rs
index e6b2672a8e3..ccc64ea393b 100644
--- a/src/librustc_back/target/mips_unknown_linux_uclibc.rs
+++ b/src/librustc_back/target/mips_unknown_linux_uclibc.rs
@@ -24,6 +24,10 @@ pub fn target() -> TargetResult {
             cpu: "mips32r2".to_string(),
             features: "+mips32r2,+soft-float".to_string(),
             max_atomic_width: Some(32),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs
index 4949055861e..9b8b1d5713f 100644
--- a/src/librustc_back/target/mipsel_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/mipsel_unknown_linux_gnu.rs
@@ -25,6 +25,10 @@ pub fn target() -> TargetResult {
             cpu: "mips32".to_string(),
             features: "+mips32".to_string(),
             max_atomic_width: Some(32),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mipsel_unknown_linux_musl.rs b/src/librustc_back/target/mipsel_unknown_linux_musl.rs
index f282ac7e88b..5693bddd048 100644
--- a/src/librustc_back/target/mipsel_unknown_linux_musl.rs
+++ b/src/librustc_back/target/mipsel_unknown_linux_musl.rs
@@ -24,6 +24,10 @@ pub fn target() -> TargetResult {
             cpu: "mips32".to_string(),
             features: "+mips32,+soft-float".to_string(),
             max_atomic_width: Some(32),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         }
     })
diff --git a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs
index 0f9b562068f..3acade5a474 100644
--- a/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs
+++ b/src/librustc_back/target/mipsel_unknown_linux_uclibc.rs
@@ -25,6 +25,10 @@ pub fn target() -> TargetResult {
             cpu: "mips32".to_string(),
             features: "+mips32,+soft-float".to_string(),
             max_atomic_width: Some(32),
+
+            // see #36994
+            exe_allocation_crate: "alloc_system".to_string(),
+
             ..super::linux_base::opts()
         },
     })
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index fc52f46a514..4d9315a1a3b 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -177,6 +177,7 @@ supported_targets! {
     ("x86_64-apple-darwin", x86_64_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
 
+    ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia),
     ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),
 
     ("i386-apple-ios", i386_apple_ios),
diff --git a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs
index 333bfad4a26..909c5488dcb 100644
--- a/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/powerpc64_unknown_linux_gnu.rs
@@ -16,6 +16,9 @@ pub fn target() -> TargetResult {
     base.pre_link_args.push("-m64".to_string());
     base.max_atomic_width = Some(64);
 
+    // see #36994
+    base.exe_allocation_crate = "alloc_system".to_string();
+
     Ok(Target {
         llvm_target: "powerpc64-unknown-linux-gnu".to_string(),
         target_endian: "big".to_string(),
diff --git a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs
index e75da133314..a692346ca0f 100644
--- a/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/powerpc64le_unknown_linux_gnu.rs
@@ -16,6 +16,9 @@ pub fn target() -> TargetResult {
     base.pre_link_args.push("-m64".to_string());
     base.max_atomic_width = Some(64);
 
+    // see #36994
+    base.exe_allocation_crate = "alloc_system".to_string();
+
     Ok(Target {
         llvm_target: "powerpc64le-unknown-linux-gnu".to_string(),
         target_endian: "little".to_string(),
diff --git a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs
index 45d28dd031f..284772c4331 100644
--- a/src/librustc_back/target/powerpc_unknown_linux_gnu.rs
+++ b/src/librustc_back/target/powerpc_unknown_linux_gnu.rs
@@ -15,6 +15,9 @@ pub fn target() -> TargetResult {
     base.pre_link_args.push("-m32".to_string());
     base.max_atomic_width = Some(32);
 
+    // see #36994
+    base.exe_allocation_crate = "alloc_system".to_string();
+
     Ok(Target {
         llvm_target: "powerpc-unknown-linux-gnu".to_string(),
         target_endian: "big".to_string(),
diff --git a/src/librustc_borrowck/borrowck/mir/abs_domain.rs b/src/librustc_borrowck/borrowck/mir/abs_domain.rs
index 155b615d83c..dc450433ad9 100644
--- a/src/librustc_borrowck/borrowck/mir/abs_domain.rs
+++ b/src/librustc_borrowck/borrowck/mir/abs_domain.rs
@@ -21,8 +21,8 @@
 //! `a[x]` would still overlap them both. But that is not this
 //! representation does today.)
 
-use rustc::mir::repr::{Lvalue, LvalueElem};
-use rustc::mir::repr::{Operand, Projection, ProjectionElem};
+use rustc::mir::{Lvalue, LvalueElem};
+use rustc::mir::{Operand, Projection, ProjectionElem};
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 pub struct AbstractOperand;
diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs b/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs
index f6260527039..28f58723862 100644
--- a/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs
+++ b/src/librustc_borrowck/borrowck/mir/dataflow/graphviz.rs
@@ -11,7 +11,7 @@
 //! Hook into libgraphviz for rendering dataflow graphs for MIR.
 
 use syntax::ast::NodeId;
-use rustc::mir::repr::{BasicBlock, Mir};
+use rustc::mir::{BasicBlock, Mir};
 use rustc_data_structures::bitslice::bits_to_string;
 use rustc_data_structures::indexed_set::{IdxSet};
 use rustc_data_structures::indexed_vec::Idx;
diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
index dce167975cf..fcb453d81aa 100644
--- a/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
+++ b/src/librustc_borrowck/borrowck/mir/dataflow/impls.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::{self, Mir, Location};
+use rustc::mir::{self, Mir, Location};
 use rustc_data_structures::bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep.
 use rustc_data_structures::bitslice::{BitwiseOperator};
 use rustc_data_structures::indexed_set::{IdxSet};
@@ -245,7 +245,7 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
     fn statement_effect(&self,
                         ctxt: &Self::Ctxt,
                         sets: &mut BlockSets<MovePathIndex>,
-                        bb: repr::BasicBlock,
+                        bb: mir::BasicBlock,
                         idx: usize)
     {
         drop_flag_effects_for_location(
@@ -258,7 +258,7 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
     fn terminator_effect(&self,
                          ctxt: &Self::Ctxt,
                          sets: &mut BlockSets<MovePathIndex>,
-                         bb: repr::BasicBlock,
+                         bb: mir::BasicBlock,
                          statements_len: usize)
     {
         drop_flag_effects_for_location(
@@ -271,9 +271,9 @@ impl<'a, 'tcx> BitDenotation for MaybeInitializedLvals<'a, 'tcx> {
     fn propagate_call_return(&self,
                              ctxt: &Self::Ctxt,
                              in_out: &mut IdxSet<MovePathIndex>,
-                             _call_bb: repr::BasicBlock,
-                             _dest_bb: repr::BasicBlock,
-                             dest_lval: &repr::Lvalue) {
+                             _call_bb: mir::BasicBlock,
+                             _dest_bb: mir::BasicBlock,
+                             dest_lval: &mir::Lvalue) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_lval to 1 (initialized).
         on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
@@ -306,7 +306,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
     fn statement_effect(&self,
                         ctxt: &Self::Ctxt,
                         sets: &mut BlockSets<MovePathIndex>,
-                        bb: repr::BasicBlock,
+                        bb: mir::BasicBlock,
                         idx: usize)
     {
         drop_flag_effects_for_location(
@@ -319,7 +319,7 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
     fn terminator_effect(&self,
                          ctxt: &Self::Ctxt,
                          sets: &mut BlockSets<MovePathIndex>,
-                         bb: repr::BasicBlock,
+                         bb: mir::BasicBlock,
                          statements_len: usize)
     {
         drop_flag_effects_for_location(
@@ -332,9 +332,9 @@ impl<'a, 'tcx> BitDenotation for MaybeUninitializedLvals<'a, 'tcx> {
     fn propagate_call_return(&self,
                              ctxt: &Self::Ctxt,
                              in_out: &mut IdxSet<MovePathIndex>,
-                             _call_bb: repr::BasicBlock,
-                             _dest_bb: repr::BasicBlock,
-                             dest_lval: &repr::Lvalue) {
+                             _call_bb: mir::BasicBlock,
+                             _dest_bb: mir::BasicBlock,
+                             dest_lval: &mir::Lvalue) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_lval to 0 (initialized).
         on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
@@ -366,7 +366,7 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
     fn statement_effect(&self,
                         ctxt: &Self::Ctxt,
                         sets: &mut BlockSets<MovePathIndex>,
-                        bb: repr::BasicBlock,
+                        bb: mir::BasicBlock,
                         idx: usize)
     {
         drop_flag_effects_for_location(
@@ -379,7 +379,7 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
     fn terminator_effect(&self,
                          ctxt: &Self::Ctxt,
                          sets: &mut BlockSets<MovePathIndex>,
-                         bb: repr::BasicBlock,
+                         bb: mir::BasicBlock,
                          statements_len: usize)
     {
         drop_flag_effects_for_location(
@@ -392,9 +392,9 @@ impl<'a, 'tcx> BitDenotation for DefinitelyInitializedLvals<'a, 'tcx> {
     fn propagate_call_return(&self,
                              ctxt: &Self::Ctxt,
                              in_out: &mut IdxSet<MovePathIndex>,
-                             _call_bb: repr::BasicBlock,
-                             _dest_bb: repr::BasicBlock,
-                             dest_lval: &repr::Lvalue) {
+                             _call_bb: mir::BasicBlock,
+                             _dest_bb: mir::BasicBlock,
+                             dest_lval: &mir::Lvalue) {
         // when a call returns successfully, that means we need to set
         // the bits for that dest_lval to 1 (initialized).
         on_lookup_result_bits(self.tcx, self.mir, &ctxt.move_data,
@@ -418,7 +418,7 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
     fn statement_effect(&self,
                         ctxt: &Self::Ctxt,
                         sets: &mut BlockSets<MoveOutIndex>,
-                        bb: repr::BasicBlock,
+                        bb: mir::BasicBlock,
                         idx: usize) {
         let (tcx, mir, move_data) = (self.tcx, self.mir, &ctxt.move_data);
         let stmt = &mir[bb].statements[idx];
@@ -437,10 +437,10 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
         }
         let bits_per_block = self.bits_per_block(ctxt);
         match stmt.kind {
-            repr::StatementKind::SetDiscriminant { .. } => {
+            mir::StatementKind::SetDiscriminant { .. } => {
                 span_bug!(stmt.source_info.span, "SetDiscriminant should not exist in borrowck");
             }
-            repr::StatementKind::Assign(ref lvalue, _) => {
+            mir::StatementKind::Assign(ref lvalue, _) => {
                 // assigning into this `lvalue` kills all
                 // MoveOuts from it, and *also* all MoveOuts
                 // for children and associated fragment sets.
@@ -453,16 +453,16 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
                                          sets.kill_set.add(&moi);
                                      });
             }
-            repr::StatementKind::StorageLive(_) |
-            repr::StatementKind::StorageDead(_) |
-            repr::StatementKind::Nop => {}
+            mir::StatementKind::StorageLive(_) |
+            mir::StatementKind::StorageDead(_) |
+            mir::StatementKind::Nop => {}
         }
     }
 
     fn terminator_effect(&self,
                          ctxt: &Self::Ctxt,
                          sets: &mut BlockSets<MoveOutIndex>,
-                         bb: repr::BasicBlock,
+                         bb: mir::BasicBlock,
                          statements_len: usize)
     {
         let (mir, move_data) = (self.mir, &ctxt.move_data);
@@ -481,9 +481,9 @@ impl<'a, 'tcx> BitDenotation for MovingOutStatements<'a, 'tcx> {
     fn propagate_call_return(&self,
                              ctxt: &Self::Ctxt,
                              in_out: &mut IdxSet<MoveOutIndex>,
-                             _call_bb: repr::BasicBlock,
-                             _dest_bb: repr::BasicBlock,
-                             dest_lval: &repr::Lvalue) {
+                             _call_bb: mir::BasicBlock,
+                             _dest_bb: mir::BasicBlock,
+                             dest_lval: &mir::Lvalue) {
         let move_data = &ctxt.move_data;
         let bits_per_block = self.bits_per_block(ctxt);
 
diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs
index 0c510e95b67..51817afbfea 100644
--- a/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/dataflow/mod.rs
@@ -13,7 +13,7 @@ use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::bitslice::{bitwise, BitwiseOperator};
 
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::{self, Mir};
+use rustc::mir::{self, Mir};
 
 use std::fmt::Debug;
 use std::io;
@@ -78,14 +78,12 @@ impl<'a, 'tcx: 'a, BD> DataflowAnalysis<'a, 'tcx, BD>
         // the kill-sets.
 
         {
-            let sets = &mut self.flow_state.sets.for_block(repr::START_BLOCK.index());
+            let sets = &mut self.flow_state.sets.for_block(mir::START_BLOCK.index());
             self.flow_state.operator.start_block_effect(&self.ctxt, sets);
         }
 
         for (bb, data) in self.mir.basic_blocks().iter_enumerated() {
-            let &repr::BasicBlockData { ref statements,
-                                        ref terminator,
-                                        is_cleanup: _ } = data;
+            let &mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = data;
 
             let sets = &mut self.flow_state.sets.for_block(bb.index());
             for j_stmt in 0..statements.len() {
@@ -122,7 +120,7 @@ impl<'b, 'a: 'b, 'tcx: 'a, BD> PropagationContext<'b, 'a, 'tcx, BD>
                 in_out.subtract(sets.kill_set);
             }
             builder.propagate_bits_into_graph_successors_of(
-                in_out, &mut self.changed, (repr::BasicBlock::new(bb_idx), bb_data));
+                in_out, &mut self.changed, (mir::BasicBlock::new(bb_idx), bb_data));
         }
     }
 }
@@ -336,7 +334,7 @@ pub trait BitDenotation {
     fn statement_effect(&self,
                         ctxt: &Self::Ctxt,
                         sets: &mut BlockSets<Self::Idx>,
-                        bb: repr::BasicBlock,
+                        bb: mir::BasicBlock,
                         idx_stmt: usize);
 
     /// Mutates the block-sets (the flow sets for the given
@@ -352,7 +350,7 @@ pub trait BitDenotation {
     fn terminator_effect(&self,
                          ctxt: &Self::Ctxt,
                          sets: &mut BlockSets<Self::Idx>,
-                         bb: repr::BasicBlock,
+                         bb: mir::BasicBlock,
                          idx_term: usize);
 
     /// Mutates the block-sets according to the (flow-dependent)
@@ -377,9 +375,9 @@ pub trait BitDenotation {
     fn propagate_call_return(&self,
                              ctxt: &Self::Ctxt,
                              in_out: &mut IdxSet<Self::Idx>,
-                             call_bb: repr::BasicBlock,
-                             dest_bb: repr::BasicBlock,
-                             dest_lval: &repr::Lvalue);
+                             call_bb: mir::BasicBlock,
+                             dest_bb: mir::BasicBlock,
+                             dest_lval: &mir::Lvalue);
 }
 
 impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D>
@@ -444,39 +442,39 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D>
         &mut self,
         in_out: &mut IdxSet<D::Idx>,
         changed: &mut bool,
-        (bb, bb_data): (repr::BasicBlock, &repr::BasicBlockData))
+        (bb, bb_data): (mir::BasicBlock, &mir::BasicBlockData))
     {
         match bb_data.terminator().kind {
-            repr::TerminatorKind::Return |
-            repr::TerminatorKind::Resume |
-            repr::TerminatorKind::Unreachable => {}
-            repr::TerminatorKind::Goto { ref target } |
-            repr::TerminatorKind::Assert { ref target, cleanup: None, .. } |
-            repr::TerminatorKind::Drop { ref target, location: _, unwind: None } |
-            repr::TerminatorKind::DropAndReplace {
+            mir::TerminatorKind::Return |
+            mir::TerminatorKind::Resume |
+            mir::TerminatorKind::Unreachable => {}
+            mir::TerminatorKind::Goto { ref target } |
+            mir::TerminatorKind::Assert { ref target, cleanup: None, .. } |
+            mir::TerminatorKind::Drop { ref target, location: _, unwind: None } |
+            mir::TerminatorKind::DropAndReplace {
                 ref target, value: _, location: _, unwind: None
             } => {
                 self.propagate_bits_into_entry_set_for(in_out, changed, target);
             }
-            repr::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } |
-            repr::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } |
-            repr::TerminatorKind::DropAndReplace {
+            mir::TerminatorKind::Assert { ref target, cleanup: Some(ref unwind), .. } |
+            mir::TerminatorKind::Drop { ref target, location: _, unwind: Some(ref unwind) } |
+            mir::TerminatorKind::DropAndReplace {
                 ref target, value: _, location: _, unwind: Some(ref unwind)
             } => {
                 self.propagate_bits_into_entry_set_for(in_out, changed, target);
                 self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
             }
-            repr::TerminatorKind::If { ref targets, .. } => {
+            mir::TerminatorKind::If { ref targets, .. } => {
                 self.propagate_bits_into_entry_set_for(in_out, changed, &targets.0);
                 self.propagate_bits_into_entry_set_for(in_out, changed, &targets.1);
             }
-            repr::TerminatorKind::Switch { ref targets, .. } |
-            repr::TerminatorKind::SwitchInt { ref targets, .. } => {
+            mir::TerminatorKind::Switch { ref targets, .. } |
+            mir::TerminatorKind::SwitchInt { ref targets, .. } => {
                 for target in targets {
                     self.propagate_bits_into_entry_set_for(in_out, changed, target);
                 }
             }
-            repr::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => {
+            mir::TerminatorKind::Call { ref cleanup, ref destination, func: _, args: _ } => {
                 if let Some(ref unwind) = *cleanup {
                     self.propagate_bits_into_entry_set_for(in_out, changed, unwind);
                 }
@@ -494,7 +492,7 @@ impl<'a, 'tcx: 'a, D> DataflowAnalysis<'a, 'tcx, D>
     fn propagate_bits_into_entry_set_for(&mut self,
                                          in_out: &IdxSet<D::Idx>,
                                          changed: &mut bool,
-                                         bb: &repr::BasicBlock) {
+                                         bb: &mir::BasicBlock) {
         let entry_set = self.flow_state.sets.for_block(bb.index()).on_entry;
         let set_changed = bitwise(entry_set.words_mut(),
                                   in_out.words(),
diff --git a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
index 5e22d477c51..b8c26a0512f 100644
--- a/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
+++ b/src/librustc_borrowck/borrowck/mir/dataflow/sanity_check.rs
@@ -13,7 +13,7 @@ use syntax::ast;
 use syntax_pos::Span;
 
 use rustc::ty::{self, TyCtxt};
-use rustc::mir::repr::{self, Mir};
+use rustc::mir::{self, Mir};
 use rustc_data_structures::indexed_vec::Idx;
 
 use super::super::gather_moves::{MovePathIndex, LookupResult};
@@ -59,13 +59,11 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            mir: &Mir<'tcx>,
                            ctxt: &O::Ctxt,
                            results: &DataflowResults<O>,
-                           bb: repr::BasicBlock) where
+                           bb: mir::BasicBlock) where
     O: BitDenotation<Ctxt=MoveDataParamEnv<'tcx>, Idx=MovePathIndex>
 {
     let move_data = &ctxt.move_data;
-    let repr::BasicBlockData { ref statements,
-                               ref terminator,
-                               is_cleanup: _ } = mir[bb];
+    let mir::BasicBlockData { ref statements, ref terminator, is_cleanup: _ } = mir[bb];
 
     let (args, span) = match is_rustc_peek(tcx, terminator) {
         Some(args_and_span) => args_and_span,
@@ -73,7 +71,7 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     };
     assert!(args.len() == 1);
     let peek_arg_lval = match args[0] {
-        repr::Operand::Consume(ref lval @ repr::Lvalue::Local(_)) => Some(lval),
+        mir::Operand::Consume(ref lval @ mir::Lvalue::Local(_)) => Some(lval),
         _ => None,
     };
 
@@ -103,21 +101,19 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     for (j, stmt) in statements.iter().enumerate() {
         debug!("rustc_peek: ({:?},{}) {:?}", bb, j, stmt);
         let (lvalue, rvalue) = match stmt.kind {
-            repr::StatementKind::Assign(ref lvalue, ref rvalue) => {
+            mir::StatementKind::Assign(ref lvalue, ref rvalue) => {
                 (lvalue, rvalue)
             }
-            repr::StatementKind::StorageLive(_) |
-            repr::StatementKind::StorageDead(_) |
-            repr::StatementKind::Nop => continue,
-            repr::StatementKind::SetDiscriminant{ .. } =>
+            mir::StatementKind::StorageLive(_) |
+            mir::StatementKind::StorageDead(_) |
+            mir::StatementKind::Nop => continue,
+            mir::StatementKind::SetDiscriminant{ .. } =>
                 span_bug!(stmt.source_info.span,
                           "sanity_check should run before Deaggregator inserts SetDiscriminant"),
         };
 
         if lvalue == peek_arg_lval {
-            if let repr::Rvalue::Ref(_,
-                                     repr::BorrowKind::Shared,
-                                     ref peeking_at_lval) = *rvalue {
+            if let mir::Rvalue::Ref(_, mir::BorrowKind::Shared, ref peeking_at_lval) = *rvalue {
                 // Okay, our search is over.
                 match move_data.rev_lookup.find(peeking_at_lval) {
                     LookupResult::Exact(peek_mpi) => {
@@ -162,12 +158,12 @@ fn each_block<'a, 'tcx, O>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn is_rustc_peek<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                           terminator: &'a Option<repr::Terminator<'tcx>>)
-                           -> Option<(&'a [repr::Operand<'tcx>], Span)> {
-    if let Some(repr::Terminator { ref kind, source_info, .. }) = *terminator {
-        if let repr::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
+                           terminator: &'a Option<mir::Terminator<'tcx>>)
+                           -> Option<(&'a [mir::Operand<'tcx>], Span)> {
+    if let Some(mir::Terminator { ref kind, source_info, .. }) = *terminator {
+        if let mir::TerminatorKind::Call { func: ref oper, ref args, .. } = *kind
         {
-            if let repr::Operand::Constant(ref func) = *oper
+            if let mir::Operand::Constant(ref func) = *oper
             {
                 if let ty::TyFnDef(def_id, _, &ty::BareFnTy { abi, .. }) = func.ty.sty
                 {
diff --git a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
index fce5553c2fe..191cd981b61 100644
--- a/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
+++ b/src/librustc_borrowck/borrowck/mir/elaborate_drops.rs
@@ -17,7 +17,7 @@ use super::{DropFlagState, MoveDataParamEnv};
 use super::patch::MirPatch;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::subst::{Kind, Subst, Substs};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::transform::{Pass, MirPass, MirSource};
 use rustc::middle::const_val::ConstVal;
 use rustc::middle::lang_items;
diff --git a/src/librustc_borrowck/borrowck/mir/gather_moves.rs b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
index 16e25d2b772..1dc5769e63c 100644
--- a/src/librustc_borrowck/borrowck/mir/gather_moves.rs
+++ b/src/librustc_borrowck/borrowck/mir/gather_moves.rs
@@ -10,7 +10,7 @@
 
 
 use rustc::ty::{self, TyCtxt, ParameterEnvironment};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::util::nodemap::FnvHashMap;
 use rustc_data_structures::indexed_vec::{IndexVec};
 
diff --git a/src/librustc_borrowck/borrowck/mir/mod.rs b/src/librustc_borrowck/borrowck/mir/mod.rs
index 2a3c602b134..cea9170da9f 100644
--- a/src/librustc_borrowck/borrowck/mir/mod.rs
+++ b/src/librustc_borrowck/borrowck/mir/mod.rs
@@ -17,8 +17,7 @@ use syntax_pos::{Span, DUMMY_SP};
 use rustc::hir;
 use rustc::hir::intravisit::{FnKind};
 
-use rustc::mir::repr;
-use rustc::mir::repr::{BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};
+use rustc::mir::{self, BasicBlock, BasicBlockData, Mir, Statement, Terminator, Location};
 use rustc::session::Session;
 use rustc::ty::{self, TyCtxt};
 
@@ -56,15 +55,13 @@ pub struct MoveDataParamEnv<'tcx> {
     param_env: ty::ParameterEnvironment<'tcx>,
 }
 
-pub fn borrowck_mir<'a, 'tcx: 'a>(
-    bcx: &mut BorrowckCtxt<'a, 'tcx>,
-    fk: FnKind,
-    _decl: &hir::FnDecl,
-    mir: &'a Mir<'tcx>,
-    body: &hir::Block,
-    _sp: Span,
-    id: ast::NodeId,
-    attributes: &[ast::Attribute]) {
+pub fn borrowck_mir(bcx: &mut BorrowckCtxt,
+                    fk: FnKind,
+                    _decl: &hir::FnDecl,
+                    body: &hir::Block,
+                    _sp: Span,
+                    id: ast::NodeId,
+                    attributes: &[ast::Attribute]) {
     match fk {
         FnKind::ItemFn(name, ..) |
         FnKind::Method(name, ..) => {
@@ -76,8 +73,10 @@ pub fn borrowck_mir<'a, 'tcx: 'a>(
     }
 
     let tcx = bcx.tcx;
-
     let param_env = ty::ParameterEnvironment::for_item(tcx, id);
+
+    let mir = &tcx.item_mir(tcx.map.local_def_id(id));
+
     let move_data = MoveData::gather_moves(mir, tcx, &param_env);
     let mdpe = MoveDataParamEnv { move_data: move_data, param_env: param_env };
     let flow_inits =
@@ -171,8 +170,8 @@ pub struct MirBorrowckCtxt<'b, 'a: 'b, 'tcx: 'a> {
     mir: &'b Mir<'tcx>,
     node_id: ast::NodeId,
     move_data: MoveData<'tcx>,
-    flow_inits: DataflowResults<MaybeInitializedLvals<'a, 'tcx>>,
-    flow_uninits: DataflowResults<MaybeUninitializedLvals<'a, 'tcx>>
+    flow_inits: DataflowResults<MaybeInitializedLvals<'b, 'tcx>>,
+    flow_uninits: DataflowResults<MaybeUninitializedLvals<'b, 'tcx>>
 }
 
 impl<'b, 'a: 'b, 'tcx: 'a> MirBorrowckCtxt<'b, 'a, 'tcx> {
@@ -214,12 +213,12 @@ fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
                                         path: MovePathIndex,
                                         mut cond: F)
                                         -> Option<MovePathIndex>
-    where F: FnMut(&repr::LvalueProjection<'tcx>) -> bool
+    where F: FnMut(&mir::LvalueProjection<'tcx>) -> bool
 {
     let mut next_child = move_data.move_paths[path].first_child;
     while let Some(child_index) = next_child {
         match move_data.move_paths[child_index].lvalue {
-            repr::Lvalue::Projection(ref proj) => {
+            mir::Lvalue::Projection(ref proj) => {
                 if cond(proj) {
                     return Some(child_index)
                 }
@@ -252,7 +251,7 @@ fn move_path_children_matching<'tcx, F>(move_data: &MoveData<'tcx>,
 /// FIXME: we have to do something for moving slice patterns.
 fn lvalue_contents_drop_state_cannot_differ<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                       mir: &Mir<'tcx>,
-                                                      lv: &repr::Lvalue<'tcx>) -> bool {
+                                                      lv: &mir::Lvalue<'tcx>) -> bool {
     let ty = lv.ty(mir, tcx).to_ty(tcx);
     match ty.sty {
         ty::TyArray(..) | ty::TySlice(..) | ty::TyRef(..) | ty::TyRawPtr(..) => {
@@ -339,7 +338,7 @@ fn drop_flag_effects_for_function_entry<'a, 'tcx, F>(
 {
     let move_data = &ctxt.move_data;
     for arg in mir.args_iter() {
-        let lvalue = repr::Lvalue::Local(arg);
+        let lvalue = mir::Lvalue::Local(arg);
         let lookup_result = move_data.rev_lookup.find(&lvalue);
         on_lookup_result_bits(tcx, mir, move_data,
                               lookup_result,
@@ -379,23 +378,23 @@ fn drop_flag_effects_for_location<'a, 'tcx, F>(
     let block = &mir[loc.block];
     match block.statements.get(loc.statement_index) {
         Some(stmt) => match stmt.kind {
-            repr::StatementKind::SetDiscriminant{ .. } => {
+            mir::StatementKind::SetDiscriminant{ .. } => {
                 span_bug!(stmt.source_info.span, "SetDiscrimant should not exist during borrowck");
             }
-            repr::StatementKind::Assign(ref lvalue, _) => {
+            mir::StatementKind::Assign(ref lvalue, _) => {
                 debug!("drop_flag_effects: assignment {:?}", stmt);
                  on_lookup_result_bits(tcx, mir, move_data,
                                        move_data.rev_lookup.find(lvalue),
                                        |moi| callback(moi, DropFlagState::Present))
             }
-            repr::StatementKind::StorageLive(_) |
-            repr::StatementKind::StorageDead(_) |
-            repr::StatementKind::Nop => {}
+            mir::StatementKind::StorageLive(_) |
+            mir::StatementKind::StorageDead(_) |
+            mir::StatementKind::Nop => {}
         },
         None => {
             debug!("drop_flag_effects: replace {:?}", block.terminator());
             match block.terminator().kind {
-                repr::TerminatorKind::DropAndReplace { ref location, .. } => {
+                mir::TerminatorKind::DropAndReplace { ref location, .. } => {
                     on_lookup_result_bits(tcx, mir, move_data,
                                           move_data.rev_lookup.find(location),
                                           |moi| callback(moi, DropFlagState::Present))
diff --git a/src/librustc_borrowck/borrowck/mir/patch.rs b/src/librustc_borrowck/borrowck/mir/patch.rs
index 5d018c98684..19f240da730 100644
--- a/src/librustc_borrowck/borrowck/mir/patch.rs
+++ b/src/librustc_borrowck/borrowck/mir/patch.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use rustc::ty::Ty;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
 
 /// This struct represents a patch to MIR, which can add
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 89b12e76c3c..ef6936b6e7d 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -51,8 +51,6 @@ use rustc::hir::{FnDecl, Block};
 use rustc::hir::intravisit;
 use rustc::hir::intravisit::{Visitor, FnKind};
 
-use rustc::mir::mir_map::MirMap;
-
 pub mod check_loans;
 
 pub mod gather_loans;
@@ -102,10 +100,9 @@ impl<'a, 'tcx, 'v> Visitor<'v> for BorrowckCtxt<'a, 'tcx> {
     }
 }
 
-pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, mir_map: &MirMap<'tcx>) {
+pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
-        mir_map: Some(mir_map),
         free_region_map: FreeRegionMap::new(),
         stats: BorrowStats {
             loaned_paths_same: 0,
@@ -168,12 +165,9 @@ fn borrowck_fn(this: &mut BorrowckCtxt,
                attributes: &[ast::Attribute]) {
     debug!("borrowck_fn(id={})", id);
 
-    let def_id = this.tcx.map.local_def_id(id);
-
     if attributes.iter().any(|item| item.check_name("rustc_mir_borrowck")) {
-        let mir = this.mir_map.unwrap().map.get(&def_id).unwrap();
         this.with_temp_region_map(id, |this| {
-            mir::borrowck_mir(this, fk, decl, mir, body, sp, id, attributes)
+            mir::borrowck_mir(this, fk, decl, body, sp, id, attributes)
         });
     }
 
@@ -249,7 +243,6 @@ fn build_borrowck_dataflow_data<'a, 'tcx>(this: &mut BorrowckCtxt<'a, 'tcx>,
 /// the `BorrowckCtxt` itself , e.g. the flowgraph visualizer.
 pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    mir_map: Option<&'a MirMap<'tcx>>,
     fn_parts: FnParts<'a>,
     cfg: &cfg::CFG)
     -> (BorrowckCtxt<'a, 'tcx>, AnalysisData<'a, 'tcx>)
@@ -257,7 +250,6 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
 
     let mut bccx = BorrowckCtxt {
         tcx: tcx,
-        mir_map: mir_map,
         free_region_map: FreeRegionMap::new(),
         stats: BorrowStats {
             loaned_paths_same: 0,
@@ -297,10 +289,7 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
     free_region_map: FreeRegionMap,
 
     // Statistics:
-    stats: BorrowStats,
-
-    // NodeId to MIR mapping (for methods that carry the #[rustc_mir] attribute).
-    mir_map: Option<&'a MirMap<'tcx>>,
+    stats: BorrowStats
 }
 
 #[derive(Clone)]
diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs
index a6c886533c8..946a3974747 100644
--- a/src/librustc_const_eval/pattern.rs
+++ b/src/librustc_const_eval/pattern.rs
@@ -11,7 +11,7 @@
 use eval;
 
 use rustc::middle::const_val::ConstVal;
-use rustc::mir::repr::{Field, BorrowKind, Mutability};
+use rustc::mir::{Field, BorrowKind, Mutability};
 use rustc::ty::{self, TyCtxt, AdtDef, Ty, Region};
 use rustc::hir::{self, PatKind};
 use rustc::hir::def::Def;
@@ -436,7 +436,7 @@ impl<'a, 'gcx, 'tcx> PatternContext<'a, 'gcx, 'tcx> {
             }
 
             Def::Struct(..) | Def::StructCtor(..) | Def::Union(..) |
-            Def::TyAlias(..) | Def::AssociatedTy(..) => {
+            Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => {
                 PatternKind::Leaf { subpatterns: subpatterns }
             }
 
diff --git a/src/librustc_data_structures/blake2b.rs b/src/librustc_data_structures/blake2b.rs
index 996df2e7fcf..8c82c135dc4 100644
--- a/src/librustc_data_structures/blake2b.rs
+++ b/src/librustc_data_structures/blake2b.rs
@@ -20,17 +20,25 @@
 // implementation. If you have the luxury of being able to use crates from
 // crates.io, you can go there and find still faster implementations.
 
+use std::mem;
+use std::slice;
+
 pub struct Blake2bCtx {
     b: [u8; 128],
     h: [u64; 8],
     t: [u64; 2],
     c: usize,
-    outlen: usize,
+    outlen: u16,
+    finalized: bool
 }
 
 impl ::std::fmt::Debug for Blake2bCtx {
     fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
-        write!(fmt, "{:?}", self.h)
+        try!(write!(fmt, "hash: "));
+        for v in &self.h[..] {
+            try!(write!(fmt, "{:x}", v));
+        }
+        Ok(())
     }
 }
 
@@ -136,7 +144,7 @@ fn blake2b_compress(ctx: &mut Blake2bCtx, last: bool) {
     }
 }
 
-pub fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx {
+fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx {
     assert!(outlen > 0 && outlen <= 64 && key.len() <= 64);
 
     let mut ctx = Blake2bCtx {
@@ -144,7 +152,8 @@ pub fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx {
         h: BLAKE2B_IV,
         t: [0; 2],
         c: 0,
-        outlen: outlen,
+        outlen: outlen as u16,
+        finalized: false,
     };
 
     ctx.h[0] ^= 0x01010000 ^ ((key.len() << 8) as u64) ^ (outlen as u64);
@@ -157,8 +166,9 @@ pub fn blake2b_new(outlen: usize, key: &[u8]) -> Blake2bCtx {
     ctx
 }
 
-pub fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8])
-{
+fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8]) {
+    assert!(!ctx.finalized, "Blake2bCtx already finalized");
+
     let mut bytes_to_copy = data.len();
     let mut space_in_buffer = ctx.b.len() - ctx.c;
 
@@ -183,8 +193,10 @@ pub fn blake2b_update(ctx: &mut Blake2bCtx, mut data: &[u8])
     }
 }
 
-pub fn blake2b_final(mut ctx: Blake2bCtx, out: &mut [u8])
+fn blake2b_final(ctx: &mut Blake2bCtx)
 {
+    assert!(!ctx.finalized, "Blake2bCtx already finalized");
+
     ctx.t[0] = ctx.t[0].wrapping_add(ctx.c as u64);
     if ctx.t[0] < ctx.c as u64 {
         ctx.t[1] += 1;
@@ -195,7 +207,7 @@ pub fn blake2b_final(mut ctx: Blake2bCtx, out: &mut [u8])
         ctx.c += 1;
     }
 
-    blake2b_compress(&mut ctx, true);
+    blake2b_compress(ctx, true);
 
     if cfg!(target_endian = "big") {
         // Make sure that the data is in memory in little endian format, as is
@@ -205,13 +217,13 @@ pub fn blake2b_final(mut ctx: Blake2bCtx, out: &mut [u8])
         }
     }
 
-    checked_mem_copy(&ctx.h, out, ctx.outlen);
+    ctx.finalized = true;
 }
 
 #[inline(always)]
 fn checked_mem_copy<T1, T2>(from: &[T1], to: &mut [T2], byte_count: usize) {
-    let from_size = from.len() * ::std::mem::size_of::<T1>();
-    let to_size = to.len() * ::std::mem::size_of::<T2>();
+    let from_size = from.len() * mem::size_of::<T1>();
+    let to_size = to.len() * mem::size_of::<T2>();
     assert!(from_size >= byte_count);
     assert!(to_size >= byte_count);
     let from_byte_ptr = from.as_ptr() as * const u8;
@@ -225,7 +237,45 @@ pub fn blake2b(out: &mut [u8], key: &[u8],  data: &[u8])
 {
     let mut ctx = blake2b_new(out.len(), key);
     blake2b_update(&mut ctx, data);
-    blake2b_final(ctx, out);
+    blake2b_final(&mut ctx);
+    checked_mem_copy(&ctx.h, out, ctx.outlen as usize);
+}
+
+pub struct Blake2bHasher(Blake2bCtx);
+
+impl ::std::hash::Hasher for Blake2bHasher {
+    fn write(&mut self, bytes: &[u8]) {
+        blake2b_update(&mut self.0, bytes);
+    }
+
+    fn finish(&self) -> u64 {
+        assert!(self.0.outlen == 8,
+                "Hasher initialized with incompatible output length");
+        u64::from_le(self.0.h[0])
+    }
+}
+
+impl Blake2bHasher {
+    pub fn new(outlen: usize, key: &[u8]) -> Blake2bHasher {
+        Blake2bHasher(blake2b_new(outlen, key))
+    }
+
+    pub fn finalize(&mut self) -> &[u8] {
+        if !self.0.finalized {
+            blake2b_final(&mut self.0);
+        }
+        debug_assert!(mem::size_of_val(&self.0.h) >= self.0.outlen as usize);
+        let raw_ptr = (&self.0.h[..]).as_ptr() as * const u8;
+        unsafe {
+            slice::from_raw_parts(raw_ptr, self.0.outlen as usize)
+        }
+    }
+}
+
+impl ::std::fmt::Debug for Blake2bHasher {
+    fn fmt(&self, fmt: &mut ::std::fmt::Formatter) -> Result<(), ::std::fmt::Error> {
+        write!(fmt, "{:?}", self.0)
+    }
 }
 
 #[cfg(test)]
@@ -245,6 +295,8 @@ fn selftest_seq(out: &mut [u8], seed: u32)
 #[test]
 fn blake2b_selftest()
 {
+    use std::hash::Hasher;
+
     // grand hash of hash results
     const BLAKE2B_RES: [u8; 32] = [
         0xC2, 0x3A, 0x78, 0x00, 0xD9, 0x81, 0x23, 0xBD,
@@ -261,7 +313,7 @@ fn blake2b_selftest()
     let mut md = [0u8; 64];
     let mut key = [0u8; 64];
 
-    let mut ctx = blake2b_new(32, &[]);
+    let mut hasher = Blake2bHasher::new(32, &[]);
 
     for i in 0 .. 4 {
        let outlen = B2B_MD_LEN[i];
@@ -270,16 +322,16 @@ fn blake2b_selftest()
 
             selftest_seq(&mut data[.. inlen], inlen as u32); // unkeyed hash
             blake2b(&mut md[.. outlen], &[], &data[.. inlen]);
-            blake2b_update(&mut ctx, &md[.. outlen]); // hash the hash
+            hasher.write(&md[.. outlen]); // hash the hash
 
             selftest_seq(&mut key[0 .. outlen], outlen as u32); // keyed hash
             blake2b(&mut md[.. outlen], &key[.. outlen], &data[.. inlen]);
-            blake2b_update(&mut ctx, &md[.. outlen]); // hash the hash
+            hasher.write(&md[.. outlen]); // hash the hash
        }
     }
 
     // compute and compare the hash of hashes
-    blake2b_final(ctx, &mut md[..]);
+    let md = hasher.finalize();
     for i in 0 .. 32 {
         assert_eq!(md[i], BLAKE2B_RES[i]);
     }
diff --git a/src/librustc_data_structures/fmt_wrap.rs b/src/librustc_data_structures/fmt_wrap.rs
new file mode 100644
index 00000000000..50fd1d802b7
--- /dev/null
+++ b/src/librustc_data_structures/fmt_wrap.rs
@@ -0,0 +1,31 @@
+// 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.
+
+use std::fmt;
+
+// Provide some more formatting options for some data types (at the moment
+// that's just `{:x}` for slices of u8).
+
+pub struct FmtWrap<T>(pub T);
+
+impl<'a> fmt::LowerHex for FmtWrap<&'a [u8]> {
+    fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+        for byte in self.0.iter() {
+            try!(write!(formatter, "{:02x}", byte));
+        }
+        Ok(())
+    }
+}
+
+#[test]
+fn test_lower_hex() {
+    let bytes: &[u8] = &[0x01, 0x23, 0x45, 0x67, 0x89, 0xab, 0xcd, 0xef];
+    assert_eq!("0123456789abcdef", &format!("{:x}", FmtWrap(bytes)));
+}
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index 143c180f823..fc963dac949 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -49,6 +49,7 @@ pub mod accumulate_vec;
 pub mod bitslice;
 pub mod blake2b;
 pub mod bitvec;
+pub mod fmt_wrap;
 pub mod graph;
 pub mod ivar;
 pub mod indexed_set;
diff --git a/src/librustc_driver/Cargo.toml b/src/librustc_driver/Cargo.toml
index 98e2aa88189..99d3e155e89 100644
--- a/src/librustc_driver/Cargo.toml
+++ b/src/librustc_driver/Cargo.toml
@@ -18,6 +18,7 @@ rustc = { path = "../librustc" }
 rustc_back = { path = "../librustc_back" }
 rustc_borrowck = { path = "../librustc_borrowck" }
 rustc_const_eval = { path = "../librustc_const_eval" }
+rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
 rustc_incremental = { path = "../librustc_incremental" }
 rustc_lint = { path = "../librustc_lint" }
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 9b27f7a29e9..da1d5ad2c4a 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -12,8 +12,10 @@ use rustc::hir;
 use rustc::hir::{map as hir_map, FreevarMap, TraitMap};
 use rustc::hir::def::DefMap;
 use rustc::hir::lowering::lower_crate;
+use rustc_data_structures::blake2b::Blake2bHasher;
+use rustc_data_structures::fmt_wrap::FmtWrap;
+use rustc::ty::util::ArchIndependentHasher;
 use rustc_mir as mir;
-use rustc::mir::mir_map::MirMap;
 use rustc::session::{Session, CompileResult, compile_result_from_err_count};
 use rustc::session::config::{self, Input, OutputFilenames, OutputType,
                              OutputTypes};
@@ -24,7 +26,6 @@ use rustc::middle::privacy::AccessLevels;
 use rustc::ty::{self, TyCtxt};
 use rustc::util::common::time;
 use rustc::util::nodemap::NodeSet;
-use rustc_back::sha2::{Sha256, Digest};
 use rustc_borrowck as borrowck;
 use rustc_incremental::{self, IncrementalHashesMap};
 use rustc_resolve::{MakeGlobMap, Resolver};
@@ -68,7 +69,6 @@ pub struct Resolutions {
 
 pub fn compile_input(sess: &Session,
                      cstore: &CStore,
-                     cfg: ast::CrateConfig,
                      input: &Input,
                      outdir: &Option<PathBuf>,
                      output: &Option<PathBuf>,
@@ -92,7 +92,7 @@ pub fn compile_input(sess: &Session,
     // large chunks of memory alive and we want to free them as soon as
     // possible to keep the peak memory usage low
     let (outputs, trans) = {
-        let krate = match phase_1_parse_input(sess, cfg, input) {
+        let krate = match phase_1_parse_input(sess, input) {
             Ok(krate) => krate,
             Err(mut parse_error) => {
                 parse_error.emit();
@@ -175,7 +175,7 @@ pub fn compile_input(sess: &Session,
                                     resolutions,
                                     &arenas,
                                     &crate_name,
-                                    |tcx, mir_map, analysis, incremental_hashes_map, result| {
+                                    |tcx, analysis, incremental_hashes_map, result| {
             {
                 // Eventually, we will want to track plugins.
                 let _ignore = tcx.dep_graph.in_ignore();
@@ -187,7 +187,6 @@ pub fn compile_input(sess: &Session,
                                                                    opt_crate,
                                                                    tcx.map.krate(),
                                                                    &analysis,
-                                                                   mir_map.as_ref(),
                                                                    tcx,
                                                                    &crate_name);
                 (control.after_analysis.callback)(&mut state);
@@ -203,10 +202,7 @@ pub fn compile_input(sess: &Session,
                 println!("Pre-trans");
                 tcx.print_debug_stats();
             }
-            let trans = phase_4_translate_to_llvm(tcx,
-                                                  mir_map.unwrap(),
-                                                  analysis,
-                                                  &incremental_hashes_map);
+            let trans = phase_4_translate_to_llvm(tcx, analysis, &incremental_hashes_map);
 
             if log_enabled!(::log::INFO) {
                 println!("Post-trans");
@@ -348,7 +344,6 @@ pub struct CompileState<'a, 'b, 'ast: 'a, 'tcx: 'b> where 'ast: 'tcx {
     pub hir_crate: Option<&'a hir::Crate>,
     pub ast_map: Option<&'a hir_map::Map<'ast>>,
     pub resolutions: Option<&'a Resolutions>,
-    pub mir_map: Option<&'b MirMap<'tcx>>,
     pub analysis: Option<&'a ty::CrateAnalysis<'a>>,
     pub tcx: Option<TyCtxt<'b, 'tcx, 'tcx>>,
     pub trans: Option<&'a trans::CrateTranslation>,
@@ -375,7 +370,6 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
             ast_map: None,
             resolutions: None,
             analysis: None,
-            mir_map: None,
             tcx: None,
             trans: None,
         }
@@ -449,13 +443,11 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
                             krate: Option<&'a ast::Crate>,
                             hir_crate: &'a hir::Crate,
                             analysis: &'a ty::CrateAnalysis<'a>,
-                            mir_map: Option<&'b MirMap<'tcx>>,
                             tcx: TyCtxt<'b, 'tcx, 'tcx>,
                             crate_name: &'a str)
                             -> CompileState<'a, 'b, 'ast, 'tcx> {
         CompileState {
             analysis: Some(analysis),
-            mir_map: mir_map,
             tcx: Some(tcx),
             expanded_crate: krate,
             hir_crate: Some(hir_crate),
@@ -491,23 +483,17 @@ impl<'a, 'b, 'ast, 'tcx> CompileState<'a, 'b, 'ast, 'tcx> {
     }
 }
 
-pub fn phase_1_parse_input<'a>(sess: &'a Session,
-                               cfg: ast::CrateConfig,
-                               input: &Input)
-                               -> PResult<'a, ast::Crate> {
+pub fn phase_1_parse_input<'a>(sess: &'a Session, input: &Input) -> PResult<'a, ast::Crate> {
     let continue_after_error = sess.opts.debugging_opts.continue_parse_after_error;
     sess.diagnostic().set_continue_after_error(continue_after_error);
 
     let krate = time(sess.time_passes(), "parsing", || {
         match *input {
             Input::File(ref file) => {
-                parse::parse_crate_from_file(file, cfg.clone(), &sess.parse_sess)
+                parse::parse_crate_from_file(file, &sess.parse_sess)
             }
             Input::Str { ref input, ref name } => {
-                parse::parse_crate_from_source_str(name.clone(),
-                                                   input.clone(),
-                                                   cfg.clone(),
-                                                   &sess.parse_sess)
+                parse::parse_crate_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
             }
         }
     })?;
@@ -645,7 +631,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
     // its contents but the results of name resolution on those contents. Hopefully we'll push
     // this back at some point.
     let _ignore = sess.dep_graph.in_ignore();
-    let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name, krate.config.clone());
+    let mut crate_loader = CrateLoader::new(sess, &cstore, crate_name);
     crate_loader.preprocess(&krate);
     let resolver_arenas = Resolver::arenas();
     let mut resolver =
@@ -686,7 +672,7 @@ pub fn phase_2_configure_and_expand<'a, F>(sess: &Session,
             should_test: sess.opts.test,
             ..syntax::ext::expand::ExpansionConfig::default(crate_name.to_string())
         };
-        let mut ecx = ExtCtxt::new(&sess.parse_sess, krate.config.clone(), cfg, &mut resolver);
+        let mut ecx = ExtCtxt::new(&sess.parse_sess, cfg, &mut resolver);
         let err_count = ecx.parse_sess.span_diagnostic.err_count();
 
         let krate = ecx.monotonic_expander().expand_crate(krate);
@@ -812,17 +798,16 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
                                                f: F)
                                                -> Result<R, usize>
     where F: for<'a> FnOnce(TyCtxt<'a, 'tcx, 'tcx>,
-                            Option<MirMap<'tcx>>,
                             ty::CrateAnalysis,
                             IncrementalHashesMap,
                             CompileResult) -> R
 {
     macro_rules! try_with_f {
-        ($e: expr, ($t: expr, $m: expr, $a: expr, $h: expr)) => {
+        ($e: expr, ($t: expr, $a: expr, $h: expr)) => {
             match $e {
                 Ok(x) => x,
                 Err(x) => {
-                    f($t, $m, $a, $h, Err(x));
+                    f($t, $a, $h, Err(x));
                     return Err(x);
                 }
             }
@@ -888,7 +873,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
              || rustc_incremental::load_dep_graph(tcx, &incremental_hashes_map));
 
         // passes are timed inside typeck
-        try_with_f!(typeck::check_crate(tcx), (tcx, None, analysis, incremental_hashes_map));
+        try_with_f!(typeck::check_crate(tcx), (tcx, analysis, incremental_hashes_map));
 
         time(time_passes,
              "const checking",
@@ -928,28 +913,28 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
              "rvalue checking",
              || rvalues::check_crate(tcx));
 
-        let mut mir_map =
-            time(time_passes,
-                 "MIR dump",
-                 || mir::mir_map::build_mir_for_crate(tcx));
+        time(time_passes,
+             "MIR dump",
+             || mir::mir_map::build_mir_for_crate(tcx));
 
         time(time_passes, "MIR passes", || {
             let mut passes = sess.mir_passes.borrow_mut();
             // Push all the built-in passes.
             passes.push_hook(box mir::transform::dump_mir::DumpMir);
             passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("initial"));
-            passes.push_pass(box mir::transform::qualify_consts::QualifyAndPromoteConstants);
+            passes.push_pass(
+                box mir::transform::qualify_consts::QualifyAndPromoteConstants::default());
             passes.push_pass(box mir::transform::type_check::TypeckMir);
             passes.push_pass(
                 box mir::transform::simplify_branches::SimplifyBranches::new("initial"));
             passes.push_pass(box mir::transform::simplify_cfg::SimplifyCfg::new("qualify-consts"));
             // And run everything.
-            passes.run_passes(tcx, &mut mir_map);
+            passes.run_passes(tcx);
         });
 
         time(time_passes,
              "borrow checking",
-             || borrowck::check_crate(tcx, &mir_map));
+             || borrowck::check_crate(tcx));
 
         // Avoid overwhelming user with errors if type checking failed.
         // I'm not sure how helpful this is, to be honest, but it avoids
@@ -958,11 +943,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
         // lint warnings and so on -- kindck used to do this abort, but
         // kindck is gone now). -nmatsakis
         if sess.err_count() > 0 {
-            return Ok(f(tcx,
-                        Some(mir_map),
-                        analysis,
-                        incremental_hashes_map,
-                        Err(sess.err_count())));
+            return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
         }
 
         analysis.reachable =
@@ -990,20 +971,15 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 
         // The above three passes generate errors w/o aborting
         if sess.err_count() > 0 {
-            return Ok(f(tcx,
-                        Some(mir_map),
-                        analysis,
-                        incremental_hashes_map,
-                        Err(sess.err_count())));
+            return Ok(f(tcx, analysis, incremental_hashes_map, Err(sess.err_count())));
         }
 
-        Ok(f(tcx, Some(mir_map), analysis, incremental_hashes_map, Ok(())))
+        Ok(f(tcx, analysis, incremental_hashes_map, Ok(())))
     })
 }
 
 /// Run the translation phase to LLVM, after which the AST and analysis can
 pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                           mut mir_map: MirMap<'tcx>,
                                            analysis: ty::CrateAnalysis,
                                            incremental_hashes_map: &IncrementalHashesMap)
                                            -> trans::CrateTranslation {
@@ -1037,13 +1013,13 @@ pub fn phase_4_translate_to_llvm<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         passes.push_pass(box mir::transform::add_call_guards::AddCallGuards);
         passes.push_pass(box mir::transform::dump_mir::Marker("PreTrans"));
 
-        passes.run_passes(tcx, &mut mir_map);
+        passes.run_passes(tcx);
     });
 
     let translation =
         time(time_passes,
              "translation",
-             move || trans::trans_crate(tcx, &mir_map, analysis, &incremental_hashes_map));
+             move || trans::trans_crate(tcx, analysis, &incremental_hashes_map));
 
     time(time_passes,
          "assert dep graph",
@@ -1247,7 +1223,16 @@ pub fn collect_crate_types(session: &Session, attrs: &[ast::Attribute]) -> Vec<c
 }
 
 pub fn compute_crate_disambiguator(session: &Session) -> String {
-    let mut hasher = Sha256::new();
+    use std::hash::Hasher;
+
+    // The crate_disambiguator is a 128 bit hash. The disambiguator is fed
+    // into various other hashes quite a bit (symbol hashes, incr. comp. hashes,
+    // debuginfo type IDs, etc), so we don't want it to be too wide. 128 bits
+    // should still be safe enough to avoid collisions in practice.
+    // FIXME(mw): It seems that the crate_disambiguator is used everywhere as
+    //            a hex-string instead of raw bytes. We should really use the
+    //            smaller representation.
+    let mut hasher = ArchIndependentHasher::new(Blake2bHasher::new(128 / 8, &[]));
 
     let mut metadata = session.opts.cg.metadata.clone();
     // We don't want the crate_disambiguator to dependent on the order
@@ -1256,24 +1241,23 @@ pub fn compute_crate_disambiguator(session: &Session) -> String {
     // Every distinct -C metadata value is only incorporated once:
     metadata.dedup();
 
-    hasher.input_str("metadata");
+    hasher.write(b"metadata");
     for s in &metadata {
         // Also incorporate the length of a metadata string, so that we generate
         // different values for `-Cmetadata=ab -Cmetadata=c` and
         // `-Cmetadata=a -Cmetadata=bc`
-        hasher.input_str(&format!("{}", s.len())[..]);
-        hasher.input_str(&s[..]);
+        hasher.write_usize(s.len());
+        hasher.write(s.as_bytes());
     }
 
-    let mut hash = hasher.result_str();
+    let mut hash_state = hasher.into_inner();
+    let hash_bytes = hash_state.finalize();
 
     // If this is an executable, add a special suffix, so that we don't get
     // symbol conflicts when linking against a library of the same name.
-    if session.crate_types.borrow().contains(&config::CrateTypeExecutable) {
-       hash.push_str("-exe");
-    }
+    let is_exe = session.crate_types.borrow().contains(&config::CrateTypeExecutable);
 
-    hash
+    format!("{:x}{}", FmtWrap(hash_bytes), if is_exe { "-exe" } else {""})
 }
 
 pub fn build_output_filenames(input: &Input,
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index cb001688da2..cb78baa12a6 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -42,6 +42,7 @@ extern crate rustc;
 extern crate rustc_back;
 extern crate rustc_borrowck;
 extern crate rustc_const_eval;
+extern crate rustc_data_structures;
 extern crate rustc_errors as errors;
 extern crate rustc_passes;
 extern crate rustc_lint;
@@ -205,24 +206,20 @@ pub fn run_compiler<'a>(args: &[String],
 
     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,
-                                                   emitter_dest);
+    let mut sess = session::build_session_with_codemap(
+        sopts, &dep_graph, input_file_path, descriptions, cstore.clone(), 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);
+    sess.parse_sess.config = cfg;
 
-    do_or_return!(callbacks.late_callback(&matches, &sess, &cfg, &input, &odir, &ofile),
-                  Some(sess));
+    do_or_return!(callbacks.late_callback(&matches, &sess, &input, &odir, &ofile), Some(sess));
 
     let plugins = sess.opts.debugging_opts.extra_plugins.clone();
     let control = callbacks.build_controller(&sess, &matches);
-    (driver::compile_input(&sess, &cstore, cfg, &input, &odir, &ofile,
-                           Some(plugins), &control),
+    (driver::compile_input(&sess, &cstore, &input, &odir, &ofile, Some(plugins), &control),
      Some(sess))
 }
 
@@ -310,7 +307,6 @@ pub trait CompilerCalls<'a> {
     fn late_callback(&mut self,
                      _: &getopts::Matches,
                      _: &Session,
-                     _: &ast::CrateConfig,
                      _: &Input,
                      _: &Option<PathBuf>,
                      _: &Option<PathBuf>)
@@ -439,7 +435,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                 }
                 let dep_graph = DepGraph::new(sopts.build_dep_graph());
                 let cstore = Rc::new(CStore::new(&dep_graph));
-                let sess = build_session(sopts.clone(),
+                let mut sess = build_session(sopts.clone(),
                     &dep_graph,
                     None,
                     descriptions.clone(),
@@ -447,11 +443,10 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
                 rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
                 let mut cfg = config::build_configuration(&sess, cfg.clone());
                 target_features::add_configuration(&mut cfg, &sess);
-                let should_stop = RustcDefaultCalls::print_crate_info(&sess,
-                                                                      &cfg,
-                                                                      None,
-                                                                      odir,
-                                                                      ofile);
+                sess.parse_sess.config = cfg;
+                let should_stop =
+                    RustcDefaultCalls::print_crate_info(&sess, None, odir, ofile);
+
                 if should_stop == Compilation::Stop {
                     return None;
                 }
@@ -467,12 +462,11 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls {
     fn late_callback(&mut self,
                      matches: &getopts::Matches,
                      sess: &Session,
-                     cfg: &ast::CrateConfig,
                      input: &Input,
                      odir: &Option<PathBuf>,
                      ofile: &Option<PathBuf>)
                      -> Compilation {
-        RustcDefaultCalls::print_crate_info(sess, cfg, Some(input), odir, ofile)
+        RustcDefaultCalls::print_crate_info(sess, Some(input), odir, ofile)
             .and_then(|| RustcDefaultCalls::list_metadata(sess, matches, input))
     }
 
@@ -593,7 +587,6 @@ impl RustcDefaultCalls {
 
 
     fn print_crate_info(sess: &Session,
-                        cfg: &ast::CrateConfig,
                         input: Option<&Input>,
                         odir: &Option<PathBuf>,
                         ofile: &Option<PathBuf>)
@@ -649,8 +642,8 @@ impl RustcDefaultCalls {
                     let allow_unstable_cfg = UnstableFeatures::from_environment()
                         .is_nightly_build();
 
-                    for cfg in cfg {
-                        if !allow_unstable_cfg && GatedCfg::gate(&*cfg).is_some() {
+                    for cfg in &sess.parse_sess.config {
+                        if !allow_unstable_cfg && GatedCfg::gate(cfg).is_some() {
                             continue;
                         }
 
@@ -1036,13 +1029,10 @@ pub fn handle_options(args: &[String]) -> Option<getopts::Matches> {
 fn parse_crate_attrs<'a>(sess: &'a Session, input: &Input) -> PResult<'a, Vec<ast::Attribute>> {
     match *input {
         Input::File(ref ifile) => {
-            parse::parse_crate_attrs_from_file(ifile, Vec::new(), &sess.parse_sess)
+            parse::parse_crate_attrs_from_file(ifile, &sess.parse_sess)
         }
         Input::Str { ref name, ref input } => {
-            parse::parse_crate_attrs_from_source_str(name.clone(),
-                                                     input.clone(),
-                                                     Vec::new(),
-                                                     &sess.parse_sess)
+            parse::parse_crate_attrs_from_source_str(name.clone(), input.clone(), &sess.parse_sess)
         }
     }
 }
diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs
index 215287f8439..10ff7dc89f9 100644
--- a/src/librustc_driver/pretty.rs
+++ b/src/librustc_driver/pretty.rs
@@ -52,8 +52,6 @@ use rustc::hir::map::{blocks, NodePrinter};
 use rustc::hir;
 use rustc::hir::print as pprust_hir;
 
-use rustc::mir::mir_map::MirMap;
-
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub enum PpSourceMode {
     PpmNormal,
@@ -234,7 +232,7 @@ impl PpSourceMode {
                                                                  resolutions.clone(),
                                                                  arenas,
                                                                  id,
-                                                                 |tcx, _, _, _, _| {
+                                                                 |tcx, _, _, _| {
                     let annotation = TypedAnnotation {
                         tcx: tcx,
                     };
@@ -695,7 +693,6 @@ impl fold::Folder for ReplaceBodyWithLoop {
 
 fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
                                        tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                       mir_map: Option<&MirMap<'tcx>>,
                                        code: blocks::Code,
                                        mode: PpFlowGraphMode,
                                        mut out: W)
@@ -725,7 +722,6 @@ fn print_flowgraph<'a, 'tcx, W: Write>(variants: Vec<borrowck_dot::Variant>,
         blocks::FnLikeCode(fn_like) => {
             let (bccx, analysis_data) =
                 borrowck::build_borrowck_dataflow_data_for_fn(tcx,
-                                                              mir_map,
                                                               fn_like.to_fn_parts(),
                                                               &cfg);
 
@@ -952,32 +948,28 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
                                                      resolutions.clone(),
                                                      arenas,
                                                      crate_name,
-                                                     |tcx, mir_map, _, _, _| {
+                                                     |tcx, _, _, _| {
         match ppm {
             PpmMir | PpmMirCFG => {
-                if let Some(mir_map) = mir_map {
-                    if let Some(nodeid) = nodeid {
-                        let def_id = tcx.map.local_def_id(nodeid);
-                        match ppm {
-                            PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mir_map, &mut out),
-                            PpmMirCFG => {
-                                write_mir_graphviz(tcx, iter::once(def_id), &mir_map, &mut out)
-                            }
-                            _ => unreachable!(),
-                        }?;
-                    } else {
-                        match ppm {
-                            PpmMir => write_mir_pretty(tcx,
-                                                       mir_map.map.keys().into_iter(),
-                                                       &mir_map,
-                                                       &mut out),
-                            PpmMirCFG => write_mir_graphviz(tcx,
-                                                            mir_map.map.keys().into_iter(),
-                                                            &mir_map,
-                                                            &mut out),
-                            _ => unreachable!(),
-                        }?;
-                    }
+                if let Some(nodeid) = nodeid {
+                    let def_id = tcx.map.local_def_id(nodeid);
+                    match ppm {
+                        PpmMir => write_mir_pretty(tcx, iter::once(def_id), &mut out),
+                        PpmMirCFG => {
+                            write_mir_graphviz(tcx, iter::once(def_id), &mut out)
+                        }
+                        _ => unreachable!(),
+                    }?;
+                } else {
+                    match ppm {
+                        PpmMir => write_mir_pretty(tcx,
+                                                   tcx.mir_map.borrow().keys().into_iter(),
+                                                   &mut out),
+                        PpmMirCFG => write_mir_graphviz(tcx,
+                                                        tcx.mir_map.borrow().keys().into_iter(),
+                                                        &mut out),
+                        _ => unreachable!(),
+                    }?;
                 }
                 Ok(())
             }
@@ -995,12 +987,7 @@ fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session,
 
                         let out: &mut Write = &mut out;
 
-                        print_flowgraph(variants,
-                                        tcx,
-                                        mir_map.as_ref(),
-                                        code,
-                                        mode,
-                                        out)
+                        print_flowgraph(variants, tcx, code, mode, out)
                     }
                     None => {
                         let message = format!("--pretty=flowgraph needs block, fn, or method; got \
diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs
index c400610a688..50903c89a58 100644
--- a/src/librustc_driver/test.rs
+++ b/src/librustc_driver/test.rs
@@ -106,12 +106,11 @@ fn test_env<F>(source_string: &str,
     let sess = session::build_session_(options, &dep_graph, None, diagnostic_handler,
                                        Rc::new(CodeMap::new()), cstore.clone());
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
-    let krate_config = Vec::new();
     let input = config::Input::Str {
         name: driver::anon_src(),
         input: source_string.to_string(),
     };
-    let krate = driver::phase_1_parse_input(&sess, krate_config, &input).unwrap();
+    let krate = driver::phase_1_parse_input(&sess, &input).unwrap();
     let driver::ExpansionResult { defs, resolutions, mut hir_forest, .. } = {
         driver::phase_2_configure_and_expand(
             &sess, &cstore, krate, None, "test", None, MakeGlobMap::No, |_| Ok(()),
diff --git a/src/librustc_incremental/calculate_svh/hasher.rs b/src/librustc_incremental/calculate_svh/hasher.rs
index d92a8d375e0..49683a81227 100644
--- a/src/librustc_incremental/calculate_svh/hasher.rs
+++ b/src/librustc_incremental/calculate_svh/hasher.rs
@@ -8,21 +8,22 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use std::hash::Hasher;
 use std::mem;
-use rustc_data_structures::blake2b;
+use rustc_data_structures::blake2b::Blake2bHasher;
+use rustc::ty::util::ArchIndependentHasher;
 use ich::Fingerprint;
 
 #[derive(Debug)]
 pub struct IchHasher {
-    state: blake2b::Blake2bCtx,
+    state: ArchIndependentHasher<Blake2bHasher>,
     bytes_hashed: u64,
 }
 
 impl IchHasher {
     pub fn new() -> IchHasher {
+        let hash_size = mem::size_of::<Fingerprint>();
         IchHasher {
-            state: blake2b::blake2b_new(mem::size_of::<Fingerprint>(), &[]),
+            state: ArchIndependentHasher::new(Blake2bHasher::new(hash_size, &[])),
             bytes_hashed: 0
         }
     }
@@ -33,40 +34,19 @@ impl IchHasher {
 
     pub fn finish(self) -> Fingerprint {
         let mut fingerprint = Fingerprint::zero();
-        blake2b::blake2b_final(self.state, &mut fingerprint.0);
+        fingerprint.0.copy_from_slice(self.state.into_inner().finalize());
         fingerprint
     }
 }
 
-impl Hasher for IchHasher {
+impl ::std::hash::Hasher for IchHasher {
     fn finish(&self) -> u64 {
         bug!("Use other finish() implementation to get the full 128-bit hash.");
     }
 
     #[inline]
     fn write(&mut self, bytes: &[u8]) {
-        blake2b::blake2b_update(&mut self.state, bytes);
+        self.state.write(bytes);
         self.bytes_hashed += bytes.len() as u64;
     }
-
-    #[inline]
-    fn write_u16(&mut self, i: u16) {
-        self.write(&unsafe { mem::transmute::<_, [u8; 2]>(i.to_le()) })
-    }
-
-    #[inline]
-    fn write_u32(&mut self, i: u32) {
-        self.write(&unsafe { mem::transmute::<_, [u8; 4]>(i.to_le()) })
-    }
-
-    #[inline]
-    fn write_u64(&mut self, i: u64) {
-        self.write(&unsafe { mem::transmute::<_, [u8; 8]>(i.to_le()) })
-    }
-
-    #[inline]
-    fn write_usize(&mut self, i: usize) {
-        // always hash as u64, so we don't depend on the size of `usize`
-        self.write_u64(i as u64);
-    }
 }
diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs
index 0418148ffc7..94478f6603a 100644
--- a/src/librustc_incremental/persist/dirty_clean.rs
+++ b/src/librustc_incremental/persist/dirty_clean.rs
@@ -264,7 +264,7 @@ impl<'a, 'tcx, 'm> DirtyCleanMetadataVisitor<'a, 'tcx, 'm> {
 /// flag called `foo`.
 fn check_config(tcx: TyCtxt, attr: &ast::Attribute) -> bool {
     debug!("check_config(attr={:?})", attr);
-    let config = &tcx.map.krate().config;
+    let config = &tcx.sess.parse_sess.config;
     debug!("check_config: config={:?}", config);
     for item in attr.meta_item_list().unwrap_or(&[]) {
         if item.check_name(CFG) {
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index d191c82abed..6f114e09a6c 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -225,6 +225,10 @@ pub fn register_builtins(store: &mut lint::LintStore, sess: Option<&Session>) {
             id: LintId::of(SAFE_EXTERN_STATICS),
             reference: "issue #36247 <https://github.com/rust-lang/rust/issues/35112>",
         },
+        FutureIncompatibleInfo {
+            id: LintId::of(PATTERNS_IN_FNS_WITHOUT_BODY),
+            reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
+        },
         ]);
 
     // Register renamed and removed lints
diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs
index d160d29af7d..f4558a2871d 100644
--- a/src/librustc_metadata/creader.rs
+++ b/src/librustc_metadata/creader.rs
@@ -52,7 +52,6 @@ pub struct CrateLoader<'a> {
     next_crate_num: CrateNum,
     foreign_item_map: FnvHashMap<String, Vec<ast::NodeId>>,
     local_crate_name: String,
-    local_crate_config: ast::CrateConfig,
 }
 
 fn dump_crates(cstore: &CStore) {
@@ -144,18 +143,13 @@ enum LoadResult {
 }
 
 impl<'a> CrateLoader<'a> {
-    pub fn new(sess: &'a Session,
-               cstore: &'a CStore,
-               local_crate_name: &str,
-               local_crate_config: ast::CrateConfig)
-               -> Self {
+    pub fn new(sess: &'a Session, cstore: &'a CStore, local_crate_name: &str) -> Self {
         CrateLoader {
             sess: sess,
             cstore: cstore,
             next_crate_num: cstore.next_crate_num(),
             foreign_item_map: FnvHashMap(),
             local_crate_name: local_crate_name.to_owned(),
-            local_crate_config: local_crate_config,
         }
     }
 
@@ -541,7 +535,6 @@ impl<'a> CrateLoader<'a> {
             // NB: Don't use parse::parse_tts_from_source_str because it parses with
             // quote_depth > 0.
             let mut p = parse::new_parser_from_source_str(&self.sess.parse_sess,
-                                                          self.local_crate_config.clone(),
                                                           source_name.clone(),
                                                           def.body);
             let lo = p.span.lo;
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 7637b769f93..a618c98ff77 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -23,8 +23,7 @@ use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX};
 use rustc::dep_graph::DepNode;
 use rustc::hir::map as hir_map;
 use rustc::hir::map::DefKey;
-use rustc::mir::repr::Mir;
-use rustc::mir::mir_map::MirMap;
+use rustc::mir::Mir;
 use rustc::util::nodemap::{NodeSet, DefIdMap};
 use rustc_back::PanicStrategy;
 
@@ -207,11 +206,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         self.get_crate_data(impl_did.krate).is_default_impl(impl_did.index)
     }
 
-    fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool {
-        self.dep_graph.read(DepNode::MetaData(did));
-        self.get_crate_data(did.krate).is_extern_item(did.index, tcx)
-    }
-
     fn is_foreign_item(&self, did: DefId) -> bool {
         self.get_crate_data(did.krate).is_foreign_item(did.index)
     }
@@ -467,10 +461,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         self.defid_for_inlined_node.borrow().get(&node_id).map(|x| *x)
     }
 
-    fn maybe_get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
-                              -> Option<Mir<'tcx>> {
+    fn get_item_mir<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Mir<'tcx> {
         self.dep_graph.read(DepNode::MetaData(def));
-        self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index)
+        self.get_crate_data(def.krate).maybe_get_item_mir(tcx, def.index).unwrap_or_else(|| {
+            bug!("get_item_mir: missing MIR for {}", tcx.item_path_str(def))
+        })
     }
 
     fn is_item_mir_available(&self, def: DefId) -> bool {
@@ -523,10 +518,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
     fn encode_metadata<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
                            reexports: &def::ExportMap,
                            link_meta: &LinkMeta,
-                           reachable: &NodeSet,
-                           mir_map: &MirMap<'tcx>) -> Vec<u8>
+                           reachable: &NodeSet) -> Vec<u8>
     {
-        encoder::encode_metadata(tcx, self, reexports, link_meta, reachable, mir_map)
+        encoder::encode_metadata(tcx, self, reexports, link_meta, reachable)
     }
 
     fn metadata_encoding_version(&self) -> &[u8]
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index 0d42ff8ce27..ccd497860de 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -30,7 +30,7 @@ use rustc::ty::subst::Substs;
 
 use rustc_const_math::ConstInt;
 
-use rustc::mir::repr::Mir;
+use rustc::mir::Mir;
 
 use std::borrow::Cow;
 use std::cell::Ref;
@@ -1009,30 +1009,6 @@ impl<'a, 'tcx> CrateMetadata {
         constness == hir::Constness::Const
     }
 
-    pub fn is_extern_item(&self, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> bool {
-        let item = match self.maybe_entry(id) {
-            Some(item) => item.decode(self),
-            None => return false,
-        };
-        let applicable = match item.kind {
-            EntryKind::ImmStatic |
-            EntryKind::MutStatic |
-            EntryKind::ForeignImmStatic |
-            EntryKind::ForeignMutStatic => true,
-
-            EntryKind::Fn(_) |
-            EntryKind::ForeignFn(_) => self.get_generics(id, tcx).types.is_empty(),
-
-            _ => false,
-        };
-
-        if applicable {
-            attr::contains_extern_indicator(tcx.sess.diagnostic(), &self.get_attributes(&item))
-        } else {
-            false
-        }
-    }
-
     pub fn is_foreign_item(&self, id: DefIndex) -> bool {
         match self.entry(id).kind {
             EntryKind::ForeignImmStatic |
@@ -1138,6 +1114,14 @@ impl<'a, 'tcx> CrateMetadata {
 
                 match reusable_filemap {
                     Some(fm) => {
+
+                        debug!("CrateMetaData::imported_filemaps reuse \
+                                filemap {:?} original (start_pos {:?} end_pos {:?}) \
+                                translated (start_pos {:?} end_pos {:?})",
+                               filemap_to_import.name,
+                               filemap_to_import.start_pos, filemap_to_import.end_pos,
+                               fm.start_pos, fm.end_pos);
+
                         cstore::ImportedFileMap {
                             original_start_pos: filemap_to_import.start_pos,
                             original_end_pos: filemap_to_import.end_pos,
@@ -1176,6 +1160,12 @@ impl<'a, 'tcx> CrateMetadata {
                                                                                source_length,
                                                                                lines,
                                                                                multibyte_chars);
+                        debug!("CrateMetaData::imported_filemaps alloc \
+                                filemap {:?} original (start_pos {:?} end_pos {:?}) \
+                                translated (start_pos {:?} end_pos {:?})",
+                               local_version.name, start_pos, end_pos,
+                               local_version.start_pos, local_version.end_pos);
+
                         cstore::ImportedFileMap {
                             original_start_pos: start_pos,
                             original_end_pos: end_pos,
@@ -1193,6 +1183,10 @@ impl<'a, 'tcx> CrateMetadata {
 }
 
 fn are_equal_modulo_startpos(fm1: &syntax_pos::FileMap, fm2: &syntax_pos::FileMap) -> bool {
+    if fm1.byte_length() != fm2.byte_length() {
+        return false;
+    }
+
     if fm1.name != fm2.name {
         return false;
     }
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 21630dde5f5..e8734e42757 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -22,7 +22,6 @@ use rustc::mir;
 use rustc::traits::specialization_graph;
 use rustc::ty::{self, Ty, TyCtxt};
 
-use rustc::mir::mir_map::MirMap;
 use rustc::session::config::{self, CrateTypeProcMacro};
 use rustc::util::nodemap::{FnvHashMap, NodeSet};
 
@@ -51,7 +50,6 @@ pub struct EncodeContext<'a, 'tcx: 'a> {
     link_meta: &'a LinkMeta,
     cstore: &'a cstore::CStore,
     reachable: &'a NodeSet,
-    mir_map: &'a MirMap<'tcx>,
 
     lazy_state: LazyState,
     type_shorthands: FnvHashMap<Ty<'tcx>, usize>,
@@ -117,7 +115,8 @@ impl<'a, 'tcx> SpecializedEncoder<Ty<'tcx>> for EncodeContext<'a, 'tcx> {
 }
 
 impl<'a, 'tcx> SpecializedEncoder<ty::GenericPredicates<'tcx>> for EncodeContext<'a, 'tcx> {
-    fn specialized_encode(&mut self, predicates: &ty::GenericPredicates<'tcx>)
+    fn specialized_encode(&mut self,
+                          predicates: &ty::GenericPredicates<'tcx>)
                           -> Result<(), Self::Error> {
         predicates.parent.encode(self)?;
         predicates.predicates.len().encode(self)?;
@@ -142,13 +141,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         r
     }
 
-    fn emit_lazy_distance(&mut self, position: usize, min_size: usize)
+    fn emit_lazy_distance(&mut self,
+                          position: usize,
+                          min_size: usize)
                           -> Result<(), <Self as Encoder>::Error> {
         let min_end = position + min_size;
         let distance = match self.lazy_state {
-            LazyState::NoNode => {
-                bug!("emit_lazy_distance: outside of a metadata node")
-            }
+            LazyState::NoNode => bug!("emit_lazy_distance: outside of a metadata node"),
             LazyState::NodeStart(start) => {
                 assert!(min_end <= start);
                 start - min_end
@@ -172,7 +171,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     }
 
     fn lazy_seq<I, T>(&mut self, iter: I) -> LazySeq<T>
-    where I: IntoIterator<Item=T>, T: Encodable {
+        where I: IntoIterator<Item = T>,
+              T: Encodable
+    {
         self.emit_node(|ecx, pos| {
             let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count();
 
@@ -182,7 +183,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     }
 
     fn lazy_seq_ref<'b, I, T>(&mut self, iter: I) -> LazySeq<T>
-    where I: IntoIterator<Item=&'b T>, T: 'b + Encodable {
+        where I: IntoIterator<Item = &'b T>,
+              T: 'b + Encodable
+    {
         self.emit_node(|ecx, pos| {
             let len = iter.into_iter().map(|value| value.encode(ecx).unwrap()).count();
 
@@ -192,11 +195,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     }
 
     /// Encode the given value or a previously cached shorthand.
-    fn encode_with_shorthand<T, U, M>(&mut self, value: &T, variant: &U, map: M)
+    fn encode_with_shorthand<T, U, M>(&mut self,
+                                      value: &T,
+                                      variant: &U,
+                                      map: M)
                                       -> Result<(), <Self as Encoder>::Error>
-    where M: for<'b> Fn(&'b mut Self) -> &'b mut FnvHashMap<T, usize>,
-          T: Clone + Eq + Hash,
-          U: Encodable {
+        where M: for<'b> Fn(&'b mut Self) -> &'b mut FnvHashMap<T, usize>,
+              T: Clone + Eq + Hash,
+              U: Encodable
+    {
         let existing_shorthand = map(self).get(value).cloned();
         if let Some(shorthand) = existing_shorthand {
             return self.emit_usize(shorthand);
@@ -208,9 +215,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         // The shorthand encoding uses the same usize as the
         // discriminant, with an offset so they can't conflict.
-        let discriminant = unsafe {
-            intrinsics::discriminant_value(variant)
-        };
+        let discriminant = unsafe { intrinsics::discriminant_value(variant) };
         assert!(discriminant < SHORTHAND_OFFSET as u64);
         let shorthand = start + SHORTHAND_OFFSET;
 
@@ -250,8 +255,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     /// the right to access any information in the adt-def (including,
     /// e.g., the length of the various vectors).
     fn encode_enum_variant_info(&mut self,
-                                (enum_did, Untracked(index)):
-                                (DefId, Untracked<usize>)) -> Entry<'tcx> {
+                                (enum_did, Untracked(index)): (DefId, Untracked<usize>))
+                                -> Entry<'tcx> {
         let tcx = self.tcx;
         let def = tcx.lookup_adt_def(enum_did);
         let variant = &def.variants[index];
@@ -260,7 +265,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         let data = VariantData {
             ctor_kind: variant.ctor_kind,
             disr: variant.disr_val.to_u64_unchecked(),
-            struct_ctor: None
+            struct_ctor: None,
         };
 
         let enum_id = tcx.map.as_local_node_id(enum_did).unwrap();
@@ -285,24 +290,23 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             predicates: Some(self.encode_predicates(def_id)),
 
             ast: None,
-            mir: None
+            mir: None,
         }
     }
 
     fn encode_info_for_mod(&mut self,
-                           FromId(id, (md, attrs, vis)):
-                           FromId<(&hir::Mod, &[ast::Attribute], &hir::Visibility)>)
+                           FromId(id, (md, attrs, vis)): FromId<(&hir::Mod,
+                                                                 &[ast::Attribute],
+                                                                 &hir::Visibility)>)
                            -> Entry<'tcx> {
         let tcx = self.tcx;
         let def_id = tcx.map.local_def_id(id);
 
         let data = ModData {
             reexports: match self.reexports.get(&id) {
-                Some(exports) if *vis == hir::Public => {
-                    self.lazy_seq_ref(exports)
-                }
-                _ => LazySeq::empty()
-            }
+                Some(exports) if *vis == hir::Public => self.lazy_seq_ref(exports),
+                _ => LazySeq::empty(),
+            },
         };
 
         Entry {
@@ -353,8 +357,7 @@ impl Visibility for ty::Visibility {
 }
 
 impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
-    fn encode_fields(&mut self,
-                     adt_def_id: DefId) {
+    fn encode_fields(&mut self, adt_def_id: DefId) {
         let def = self.tcx.lookup_adt_def(adt_def_id);
         for (variant_index, variant) in def.variants.iter().enumerate() {
             for (field_index, field) in variant.fields.iter().enumerate() {
@@ -374,8 +377,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     /// the adt-def (including, e.g., the length of the various
     /// vectors).
     fn encode_field(&mut self,
-                    (adt_def_id, Untracked((variant_index, field_index))):
-                    (DefId, Untracked<(usize, usize)>)) -> Entry<'tcx> {
+                    (adt_def_id, Untracked((variant_index, field_index))): (DefId,
+                                                                            Untracked<(usize,
+                                                                                       usize)>))
+                    -> Entry<'tcx> {
         let tcx = self.tcx;
         let variant = &tcx.lookup_adt_def(adt_def_id).variants[variant_index];
         let field = &variant.fields[field_index];
@@ -400,19 +405,18 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             predicates: Some(self.encode_predicates(def_id)),
 
             ast: None,
-            mir: None
+            mir: None,
         }
     }
 
-    fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId))
-                          -> Entry<'tcx> {
+    fn encode_struct_ctor(&mut self, (adt_def_id, def_id): (DefId, DefId)) -> Entry<'tcx> {
         let tcx = self.tcx;
         let variant = tcx.lookup_adt_def(adt_def_id).struct_variant();
 
         let data = VariantData {
             ctor_kind: variant.ctor_kind,
             disr: variant.disr_val.to_u64_unchecked(),
-            struct_ctor: Some(def_id.index)
+            struct_ctor: Some(def_id.index),
         };
 
         let struct_id = tcx.map.as_local_node_id(adt_def_id).unwrap();
@@ -434,7 +438,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             predicates: Some(self.encode_predicates(def_id)),
 
             ast: None,
-            mir: None
+            mir: None,
         }
     }
 
@@ -469,7 +473,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let fn_data = if let hir::MethodTraitItem(ref sig, _) = ast_item.node {
                     FnData {
                         constness: hir::Constness::NotConst,
-                        arg_names: self.encode_fn_arg_names(&sig.decl)
+                        arg_names: self.encode_fn_arg_names(&sig.decl),
                     }
                 } else {
                     bug!()
@@ -477,13 +481,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let data = MethodData {
                     fn_data: fn_data,
                     container: container(method_ty.has_body),
-                    explicit_self: self.lazy(&method_ty.explicit_self)
+                    explicit_self: self.lazy(&method_ty.explicit_self),
                 };
                 EntryKind::Method(self.lazy(&data))
             }
-            ty::TypeTraitItem(_) => {
-                EntryKind::AssociatedType(container(false))
-            }
+            ty::TypeTraitItem(_) => EntryKind::AssociatedType(container(false)),
         };
 
         Entry {
@@ -497,9 +499,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
             ty: match trait_item {
                 ty::ConstTraitItem(_) |
-                ty::MethodTraitItem(_) => {
-                    Some(self.encode_item_type(def_id))
-                }
+                ty::MethodTraitItem(_) => Some(self.encode_item_type(def_id)),
                 ty::TypeTraitItem(ref associated_type) => {
                     associated_type.ty.map(|ty| self.lazy(&ty))
                 }
@@ -515,7 +515,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             } else {
                 None
             },
-            mir: self.encode_mir(def_id)
+            mir: self.encode_mir(def_id),
         }
     }
 
@@ -527,18 +527,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let container = match ast_item.defaultness {
             hir::Defaultness::Default => AssociatedContainer::ImplDefault,
-            hir::Defaultness::Final => AssociatedContainer::ImplFinal
+            hir::Defaultness::Final => AssociatedContainer::ImplFinal,
         };
 
         let kind = match impl_item {
-            ty::ConstTraitItem(_) => {
-                EntryKind::AssociatedConst(container)
-            }
+            ty::ConstTraitItem(_) => EntryKind::AssociatedConst(container),
             ty::MethodTraitItem(ref method_ty) => {
                 let fn_data = if let hir::ImplItemKind::Method(ref sig, _) = ast_item.node {
                     FnData {
                         constness: sig.constness,
-                        arg_names: self.encode_fn_arg_names(&sig.decl)
+                        arg_names: self.encode_fn_arg_names(&sig.decl),
                     }
                 } else {
                     bug!()
@@ -546,13 +544,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let data = MethodData {
                     fn_data: fn_data,
                     container: container,
-                    explicit_self: self.lazy(&method_ty.explicit_self)
+                    explicit_self: self.lazy(&method_ty.explicit_self),
                 };
                 EntryKind::Method(self.lazy(&data))
             }
-            ty::TypeTraitItem(_) => {
-                EntryKind::AssociatedType(container)
-            }
+            ty::TypeTraitItem(_) => EntryKind::AssociatedType(container),
         };
 
         let (ast, mir) = if let ty::ConstTraitItem(_) = impl_item {
@@ -578,9 +574,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
             ty: match impl_item {
                 ty::ConstTraitItem(_) |
-                ty::MethodTraitItem(_) => {
-                    Some(self.encode_item_type(def_id))
-                }
+                ty::MethodTraitItem(_) => Some(self.encode_item_type(def_id)),
                 ty::TypeTraitItem(ref associated_type) => {
                     associated_type.ty.map(|ty| self.lazy(&ty))
                 }
@@ -595,11 +589,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             } else {
                 None
             },
-            mir: if mir {
-                self.encode_mir(def_id)
-            } else {
-                None
-            }
+            mir: if mir { self.encode_mir(def_id) } else { None },
         }
     }
 
@@ -613,8 +603,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         }))
     }
 
-    fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::repr::Mir<'tcx>>> {
-        self.mir_map.map.get(&def_id).map(|mir| self.lazy(mir))
+    fn encode_mir(&mut self, def_id: DefId) -> Option<Lazy<mir::Mir<'tcx>>> {
+        self.tcx.mir_map.borrow().get(&def_id).map(|mir| self.lazy(&*mir.borrow()))
     }
 
     // Encodes the inherent implementations of a structure, enumeration, or trait.
@@ -638,8 +628,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.tcx.lookup_deprecation(def_id).map(|depr| self.lazy(&depr))
     }
 
-    fn encode_info_for_item(&mut self,
-                            (def_id, item): (DefId, &hir::Item)) -> Entry<'tcx> {
+    fn encode_info_for_item(&mut self, (def_id, item): (DefId, &hir::Item)) -> Entry<'tcx> {
         let tcx = self.tcx;
 
         debug!("encoding info for item at {}",
@@ -652,7 +641,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemFn(ref decl, _, constness, ..) => {
                 let data = FnData {
                     constness: constness,
-                    arg_names: self.encode_fn_arg_names(&decl)
+                    arg_names: self.encode_fn_arg_names(&decl),
                 };
 
                 EntryKind::Fn(self.lazy(&data))
@@ -666,9 +655,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ItemStruct(ref struct_def, _) => {
                 let variant = tcx.lookup_adt_def(def_id).struct_variant();
 
-                /* Encode def_ids for each field and method
-                for methods, write all the stuff get_trait_method
-                needs to know*/
+                // Encode def_ids for each field and method
+                // for methods, write all the stuff get_trait_method
+                // needs to know
                 let struct_ctor = if !struct_def.is_struct() {
                     Some(tcx.map.local_def_id(struct_def.id()).index)
                 } else {
@@ -677,7 +666,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 EntryKind::Struct(self.lazy(&VariantData {
                     ctor_kind: variant.ctor_kind,
                     disr: variant.disr_val.to_u64_unchecked(),
-                    struct_ctor: struct_ctor
+                    struct_ctor: struct_ctor,
                 }))
             }
             hir::ItemUnion(..) => {
@@ -686,7 +675,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 EntryKind::Union(self.lazy(&VariantData {
                     ctor_kind: variant.ctor_kind,
                     disr: variant.disr_val.to_u64_unchecked(),
-                    struct_ctor: None
+                    struct_ctor: None,
                 }))
             }
             hir::ItemDefaultImpl(..) => {
@@ -694,7 +683,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     polarity: hir::ImplPolarity::Positive,
                     parent_impl: None,
                     coerce_unsized_kind: None,
-                    trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref))
+                    trait_ref: tcx.impl_trait_ref(def_id).map(|trait_ref| self.lazy(&trait_ref)),
                 };
 
                 EntryKind::DefaultImpl(self.lazy(&data))
@@ -716,9 +705,11 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let data = ImplData {
                     polarity: polarity,
                     parent_impl: parent,
-                    coerce_unsized_kind: tcx.custom_coerce_unsized_kinds.borrow()
-                                            .get(&def_id).cloned(),
-                    trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref))
+                    coerce_unsized_kind: tcx.custom_coerce_unsized_kinds
+                        .borrow()
+                        .get(&def_id)
+                        .cloned(),
+                    trait_ref: trait_ref.map(|trait_ref| self.lazy(&trait_ref)),
                 };
 
                 EntryKind::Impl(self.lazy(&data))
@@ -730,14 +721,13 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     paren_sugar: trait_def.paren_sugar,
                     has_default_impl: tcx.trait_has_default_impl(def_id),
                     trait_ref: self.lazy(&trait_def.trait_ref),
-                    super_predicates: self.lazy(&tcx.lookup_super_predicates(def_id))
+                    super_predicates: self.lazy(&tcx.lookup_super_predicates(def_id)),
                 };
 
                 EntryKind::Trait(self.lazy(&data))
             }
-            hir::ItemExternCrate(_) | hir::ItemUse(_) => {
-                bug!("cannot encode info for item {:?}", item)
-            }
+            hir::ItemExternCrate(_) |
+            hir::ItemUse(_) => bug!("cannot encode info for item {:?}", item),
         };
 
         Entry {
@@ -747,9 +737,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             attributes: self.encode_attributes(&item.attrs),
             children: match item.node {
                 hir::ItemForeignMod(ref fm) => {
-                    self.lazy_seq(fm.items.iter().map(|foreign_item| {
-                        tcx.map.local_def_id(foreign_item.id).index
-                    }))
+                    self.lazy_seq(fm.items
+                        .iter()
+                        .map(|foreign_item| tcx.map.local_def_id(foreign_item.id).index))
                 }
                 hir::ItemEnum(..) => {
                     let def = self.tcx.lookup_adt_def(def_id);
@@ -773,7 +763,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         def_id.index
                     }))
                 }
-                _ => LazySeq::empty()
+                _ => LazySeq::empty(),
             },
             stability: self.encode_stability(def_id),
             deprecation: self.encode_deprecation(def_id),
@@ -786,20 +776,16 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 hir::ItemEnum(..) |
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
-                hir::ItemImpl(..) => {
-                    Some(self.encode_item_type(def_id))
-                }
-                _ => None
+                hir::ItemImpl(..) => Some(self.encode_item_type(def_id)),
+                _ => None,
             },
             inherent_impls: self.encode_inherent_implementations(def_id),
             variances: match item.node {
                 hir::ItemEnum(..) |
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
-                hir::ItemTrait(..) => {
-                    self.encode_item_variances(def_id)
-                }
-                _ => LazySeq::empty()
+                hir::ItemTrait(..) => self.encode_item_variances(def_id),
+                _ => LazySeq::empty(),
             },
             generics: match item.node {
                 hir::ItemStatic(..) |
@@ -810,10 +796,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
                 hir::ItemImpl(..) |
-                hir::ItemTrait(..) => {
-                    Some(self.encode_generics(def_id))
-                }
-                _ => None
+                hir::ItemTrait(..) => Some(self.encode_generics(def_id)),
+                _ => None,
             },
             predicates: match item.node {
                 hir::ItemStatic(..) |
@@ -824,10 +808,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 hir::ItemStruct(..) |
                 hir::ItemUnion(..) |
                 hir::ItemImpl(..) |
-                hir::ItemTrait(..) => {
-                    Some(self.encode_predicates(def_id))
-                }
-                _ => None
+                hir::ItemTrait(..) => Some(self.encode_predicates(def_id)),
+                _ => None,
             },
 
             ast: match item.node {
@@ -835,12 +817,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 hir::ItemFn(_, _, hir::Constness::Const, ..) => {
                     Some(self.encode_inlined_item(InlinedItemRef::Item(def_id, item)))
                 }
-                _ => None
+                _ => None,
             },
             mir: match item.node {
-                hir::ItemConst(..) => {
-                    self.encode_mir(def_id)
-                }
+                hir::ItemConst(..) => self.encode_mir(def_id),
                 hir::ItemFn(_, _, constness, _, ref generics, _) => {
                     let tps_len = generics.ty_params.len();
                     let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs);
@@ -850,8 +830,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                         None
                     }
                 }
-                _ => None
-            }
+                _ => None,
+            },
         }
     }
 }
@@ -861,8 +841,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
     /// encode some sub-items. Usually we want some info from the item
     /// so it's easier to do that here then to wait until we would encounter
     /// normally in the visitor walk.
-    fn encode_addl_info_for_item(&mut self,
-                                 item: &hir::Item) {
+    fn encode_addl_info_for_item(&mut self, item: &hir::Item) {
         let def_id = self.tcx.map.local_def_id(item.id);
         match item.node {
             hir::ItemStatic(..) |
@@ -930,12 +909,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hir::ForeignItemFn(ref fndecl, _) => {
                 let data = FnData {
                     constness: hir::Constness::NotConst,
-                    arg_names: self.encode_fn_arg_names(&fndecl)
+                    arg_names: self.encode_fn_arg_names(&fndecl),
                 };
                 EntryKind::ForeignFn(self.lazy(&data))
             }
             hir::ForeignItemStatic(_, true) => EntryKind::ForeignMutStatic,
-            hir::ForeignItemStatic(_, false) => EntryKind::ForeignImmStatic
+            hir::ForeignItemStatic(_, false) => EntryKind::ForeignImmStatic,
         };
 
         Entry {
@@ -954,7 +933,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             predicates: Some(self.encode_predicates(def_id)),
 
             ast: None,
-            mir: None
+            mir: None,
         }
     }
 }
@@ -972,10 +951,9 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> {
         intravisit::walk_item(self, item);
         let def_id = self.index.tcx.map.local_def_id(item.id);
         match item.node {
-            hir::ItemExternCrate(_) | hir::ItemUse(_) => (), // ignore these
-            _ => self.index.record(def_id,
-                                   EncodeContext::encode_info_for_item,
-                                   (def_id, item)),
+            hir::ItemExternCrate(_) |
+            hir::ItemUse(_) => (), // ignore these
+            _ => self.index.record(def_id, EncodeContext::encode_info_for_item, (def_id, item)),
         }
         self.index.encode_addl_info_for_item(item);
     }
@@ -996,9 +974,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
     fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
         if let hir::TyImplTrait(_) = ty.node {
             let def_id = self.tcx.map.local_def_id(ty.id);
-            self.record(def_id,
-                        EncodeContext::encode_info_for_anon_ty,
-                        def_id);
+            self.record(def_id, EncodeContext::encode_info_for_anon_ty, def_id);
         }
     }
 
@@ -1006,11 +982,9 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
         match expr.node {
             hir::ExprClosure(..) => {
                 let def_id = self.tcx.map.local_def_id(expr.id);
-                self.record(def_id,
-                            EncodeContext::encode_info_for_closure,
-                            def_id);
+                self.record(def_id, EncodeContext::encode_info_for_closure, def_id);
             }
-            _ => { }
+            _ => {}
         }
     }
 }
@@ -1033,7 +1007,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             predicates: Some(self.encode_predicates(def_id)),
 
             ast: None,
-            mir: None
+            mir: None,
         }
     }
 
@@ -1042,7 +1016,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
 
         let data = ClosureData {
             kind: tcx.closure_kind(def_id),
-            ty: self.lazy(&tcx.tables.borrow().closure_tys[&def_id])
+            ty: self.lazy(&tcx.tables.borrow().closure_tys[&def_id]),
         };
 
         Entry {
@@ -1061,7 +1035,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             predicates: None,
 
             ast: None,
-            mir: self.encode_mir(def_id)
+            mir: self.encode_mir(def_id),
         }
     }
 
@@ -1071,9 +1045,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         index.record(DefId::local(CRATE_DEF_INDEX),
                      EncodeContext::encode_info_for_mod,
                      FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &hir::Public)));
-        let mut visitor = EncodeVisitor {
-            index: index,
-        };
+        let mut visitor = EncodeVisitor { index: index };
         krate.visit_all_items(&mut visitor);
         visitor.index.into_items()
     }
@@ -1083,8 +1055,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     }
 
     fn encode_crate_deps(&mut self) -> LazySeq<CrateDep> {
-        fn get_ordered_deps(cstore: &cstore::CStore)
-                            -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
+        fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<(CrateNum, Rc<cstore::CrateMetadata>)> {
             // Pull the cnums and name,vers,hash out of cstore
             let mut deps = Vec::new();
             cstore.iter_crate_data(|cnum, val| {
@@ -1113,13 +1084,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             CrateDep {
                 name: syntax::parse::token::intern(dep.name()),
                 hash: dep.hash(),
-                explicitly_linked: dep.explicitly_linked.get()
+                explicitly_linked: dep.explicitly_linked.get(),
             }
         }))
     }
 
-    fn encode_lang_items(&mut self)
-                         -> (LazySeq<(DefIndex, usize)>, LazySeq<lang_items::LangItem>) {
+    fn encode_lang_items(&mut self) -> (LazySeq<(DefIndex, usize)>, LazySeq<lang_items::LangItem>) {
         let tcx = self.tcx;
         let lang_items = tcx.lang_items.items().iter();
         (self.lazy_seq(lang_items.enumerate().filter_map(|(i, &opt_def_id)| {
@@ -1129,7 +1099,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 }
             }
             None
-        })), self.lazy_seq_ref(&tcx.lang_items.missing))
+        })),
+         self.lazy_seq_ref(&tcx.lang_items.missing))
     }
 
     fn encode_native_libraries(&mut self) -> LazySeq<(NativeLibraryKind, String)> {
@@ -1137,9 +1108,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
         self.lazy_seq(used_libraries.into_iter().filter_map(|(lib, kind)| {
             match kind {
                 cstore::NativeStatic => None, // these libraries are not propagated
-                cstore::NativeFramework | cstore::NativeUnknown => {
-                    Some((kind, lib))
-                }
+                cstore::NativeFramework | cstore::NativeUnknown => Some((kind, lib)),
             }
         }))
     }
@@ -1147,13 +1116,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_codemap(&mut self) -> LazySeq<syntax_pos::FileMap> {
         let codemap = self.tcx.sess.codemap();
         let all_filemaps = codemap.files.borrow();
-        self.lazy_seq_ref(all_filemaps.iter().filter(|filemap| {
-            // No need to export empty filemaps, as they can't contain spans
-            // that need translation.
-            // Also no need to re-export imported filemaps, as any downstream
-            // crate will import them from their original source.
-            !filemap.lines.borrow().is_empty() && !filemap.is_imported()
-        }).map(|filemap| &**filemap))
+        self.lazy_seq_ref(all_filemaps.iter()
+            .filter(|filemap| {
+                // No need to export empty filemaps, as they can't contain spans
+                // that need translation.
+                // Also no need to re-export imported filemaps, as any downstream
+                // crate will import them from their original source.
+                !filemap.lines.borrow().is_empty() && !filemap.is_imported()
+            })
+            .map(|filemap| &**filemap))
     }
 
     /// Serialize the text of the exported macros
@@ -1164,15 +1135,15 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 name: def.name,
                 attrs: def.attrs.to_vec(),
                 span: def.span,
-                body: ::syntax::print::pprust::tts_to_string(&def.body)
+                body: ::syntax::print::pprust::tts_to_string(&def.body),
             }
         }))
     }
 }
 
-struct ImplVisitor<'a, 'tcx:'a> {
+struct ImplVisitor<'a, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    impls: FnvHashMap<DefId, Vec<DefIndex>>
+    impls: FnvHashMap<DefId, Vec<DefIndex>>,
 }
 
 impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> {
@@ -1180,7 +1151,8 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> {
         if let hir::ItemImpl(..) = item.node {
             let impl_id = self.tcx.map.local_def_id(item.id);
             if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) {
-                self.impls.entry(trait_ref.def_id)
+                self.impls
+                    .entry(trait_ref.def_id)
                     .or_insert(vec![])
                     .push(impl_id.index);
             }
@@ -1193,16 +1165,19 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
     fn encode_impls(&mut self) -> LazySeq<TraitImpls> {
         let mut visitor = ImplVisitor {
             tcx: self.tcx,
-            impls: FnvHashMap()
+            impls: FnvHashMap(),
         };
         self.tcx.map.krate().visit_all_items(&mut visitor);
 
-        let all_impls: Vec<_> = visitor.impls.into_iter().map(|(trait_def_id, impls)| {
-            TraitImpls {
-                trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
-                impls: self.lazy_seq(impls)
-            }
-        }).collect();
+        let all_impls: Vec<_> = visitor.impls
+            .into_iter()
+            .map(|(trait_def_id, impls)| {
+                TraitImpls {
+                    trait_id: (trait_def_id.krate.as_u32(), trait_def_id.index),
+                    impls: self.lazy_seq(impls),
+                }
+            })
+            .collect();
 
         self.lazy_seq(all_impls)
     }
@@ -1232,7 +1207,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     }
                 }))
             }
-            None => LazySeq::empty()
+            None => LazySeq::empty(),
         }
     }
 
@@ -1291,9 +1266,10 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
             hash: link_meta.crate_hash,
             disambiguator: tcx.sess.local_crate_disambiguator().to_string(),
             panic_strategy: tcx.sess.panic_strategy(),
-            plugin_registrar_fn: tcx.sess.plugin_registrar_fn.get().map(|id| {
-                tcx.map.local_def_id(id).index
-            }),
+            plugin_registrar_fn: tcx.sess
+                .plugin_registrar_fn
+                .get()
+                .map(|id| tcx.map.local_def_id(id).index),
             macro_derive_registrar: if is_proc_macro {
                 let id = tcx.sess.derive_registrar_fn.get().unwrap();
                 Some(tcx.map.local_def_id(id).index)
@@ -1368,8 +1344,8 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                  cstore: &cstore::CStore,
                                  reexports: &def::ExportMap,
                                  link_meta: &LinkMeta,
-                                 reachable: &NodeSet,
-                                 mir_map: &MirMap<'tcx>) -> Vec<u8> {
+                                 reachable: &NodeSet)
+                                 -> Vec<u8> {
     let mut cursor = Cursor::new(vec![]);
     cursor.write_all(METADATA_HEADER).unwrap();
 
@@ -1377,17 +1353,17 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     cursor.write_all(&[0, 0, 0, 0]).unwrap();
 
     let root = EncodeContext {
-        opaque: opaque::Encoder::new(&mut cursor),
-        tcx: tcx,
-        reexports: reexports,
-        link_meta: link_meta,
-        cstore: cstore,
-        reachable: reachable,
-        mir_map: mir_map,
-        lazy_state: LazyState::NoNode,
-        type_shorthands: Default::default(),
-        predicate_shorthands: Default::default()
-    }.encode_crate_root();
+            opaque: opaque::Encoder::new(&mut cursor),
+            tcx: tcx,
+            reexports: reexports,
+            link_meta: link_meta,
+            cstore: cstore,
+            reachable: reachable,
+            lazy_state: LazyState::NoNode,
+            type_shorthands: Default::default(),
+            predicate_shorthands: Default::default(),
+        }
+        .encode_crate_root();
     let mut result = cursor.into_inner();
 
     // Encode the root position.
@@ -1395,8 +1371,8 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let pos = root.position;
     result[header + 0] = (pos >> 24) as u8;
     result[header + 1] = (pos >> 16) as u8;
-    result[header + 2] = (pos >>  8) as u8;
-    result[header + 3] = (pos >>  0) as u8;
+    result[header + 2] = (pos >> 8) as u8;
+    result[header + 3] = (pos >> 0) as u8;
 
     result
 }
diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs
index ef83251f51e..53e6988c756 100644
--- a/src/librustc_metadata/index.rs
+++ b/src/librustc_metadata/index.rs
@@ -28,9 +28,7 @@ pub struct Index {
 
 impl Index {
     pub fn new(max_index: usize) -> Index {
-        Index {
-            positions: vec![u32::MAX; max_index]
-        }
+        Index { positions: vec![u32::MAX; max_index] }
     }
 
     pub fn record(&mut self, def_id: DefId, entry: Lazy<Entry>) {
@@ -46,7 +44,9 @@ impl Index {
 
         assert!(self.positions[item] == u32::MAX,
                 "recorded position for item {:?} twice, first at {:?} and now at {:?}",
-                item, self.positions[item], position);
+                item,
+                self.positions[item],
+                position);
 
         self.positions[item] = position.to_le();
     }
@@ -67,7 +67,8 @@ impl<'tcx> LazySeq<Index> {
         let index = def_index.as_usize();
 
         debug!("Index::lookup: index={:?} words.len={:?}",
-               index, words.len());
+               index,
+               words.len());
 
         let position = u32::from_le(words[index]);
         if position == u32::MAX {
@@ -79,8 +80,9 @@ impl<'tcx> LazySeq<Index> {
         }
     }
 
-    pub fn iter_enumerated<'a>(&self, bytes: &'a [u8])
-                               -> impl Iterator<Item=(DefIndex, Lazy<Entry<'tcx>>)> + 'a {
+    pub fn iter_enumerated<'a>(&self,
+                               bytes: &'a [u8])
+                               -> impl Iterator<Item = (DefIndex, Lazy<Entry<'tcx>>)> + 'a {
         let words = &bytes_to_words(&bytes[self.position..])[..self.len];
         words.iter().enumerate().filter_map(|(index, &position)| {
             if position == u32::MAX {
diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs
index aeb6f63252c..9938e20d186 100644
--- a/src/librustc_metadata/index_builder.rs
+++ b/src/librustc_metadata/index_builder.rs
@@ -138,11 +138,11 @@ pub trait DepGraphRead {
 }
 
 impl DepGraphRead for DefId {
-    fn read(&self, _tcx: TyCtxt) { }
+    fn read(&self, _tcx: TyCtxt) {}
 }
 
 impl DepGraphRead for ast::NodeId {
-    fn read(&self, _tcx: TyCtxt) { }
+    fn read(&self, _tcx: TyCtxt) {}
 }
 
 impl<T> DepGraphRead for Option<T>
@@ -179,8 +179,8 @@ macro_rules! read_tuple {
         }
     }
 }
-read_tuple!(A,B);
-read_tuple!(A,B,C);
+read_tuple!(A, B);
+read_tuple!(A, B, C);
 
 macro_rules! read_hir {
     ($t:ty) => {
@@ -208,7 +208,7 @@ read_hir!(hir::ForeignItem);
 pub struct Untracked<T>(pub T);
 
 impl<T> DepGraphRead for Untracked<T> {
-    fn read(&self, _tcx: TyCtxt) { }
+    fn read(&self, _tcx: TyCtxt) {}
 }
 
 /// Newtype that can be used to package up misc data extracted from a
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index 300c5f0dec7..ef81dbd7f29 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -30,8 +30,10 @@
 #![feature(specialization)]
 #![feature(staged_api)]
 
-#[macro_use] extern crate log;
-#[macro_use] extern crate syntax;
+#[macro_use]
+extern crate log;
+#[macro_use]
+extern crate syntax;
 extern crate syntax_pos;
 extern crate flate;
 extern crate serialize as rustc_serialize; // used by deriving
diff --git a/src/librustc_metadata/locator.rs b/src/librustc_metadata/locator.rs
index e684cd16366..0461d7ec061 100644
--- a/src/librustc_metadata/locator.rs
+++ b/src/librustc_metadata/locator.rs
@@ -273,7 +273,7 @@ pub struct ArchiveMetadata {
 pub struct CratePaths {
     pub ident: String,
     pub dylib: Option<PathBuf>,
-    pub rlib: Option<PathBuf>
+    pub rlib: Option<PathBuf>,
 }
 
 pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
@@ -281,14 +281,14 @@ pub const METADATA_FILENAME: &'static str = "rust.metadata.bin";
 #[derive(Copy, Clone, PartialEq)]
 enum CrateFlavor {
     Rlib,
-    Dylib
+    Dylib,
 }
 
 impl fmt::Display for CrateFlavor {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.write_str(match *self {
             CrateFlavor::Rlib => "rlib",
-            CrateFlavor::Dylib => "dylib"
+            CrateFlavor::Dylib => "dylib",
         })
     }
 }
@@ -296,10 +296,10 @@ impl fmt::Display for CrateFlavor {
 impl CratePaths {
     fn paths(&self) -> Vec<PathBuf> {
         match (&self.dylib, &self.rlib) {
-            (&None,    &None)              => vec!(),
+            (&None, &None) => vec![],
             (&Some(ref p), &None) |
-            (&None, &Some(ref p))          => vec!(p.clone()),
-            (&Some(ref p1), &Some(ref p2)) => vec!(p1.clone(), p2.clone()),
+            (&None, &Some(ref p)) => vec![p.clone()],
+            (&Some(ref p1), &Some(ref p2)) => vec![p1.clone(), p2.clone()],
         }
     }
 }
@@ -316,53 +316,72 @@ impl<'a> Context<'a> {
     pub fn report_errs(&mut self) -> ! {
         let add = match self.root {
             &None => String::new(),
-            &Some(ref r) => format!(" which `{}` depends on",
-                                    r.ident)
+            &Some(ref r) => format!(" which `{}` depends on", r.ident),
         };
         let mut err = if !self.rejected_via_hash.is_empty() {
-            struct_span_err!(self.sess, self.span, E0460,
+            struct_span_err!(self.sess,
+                             self.span,
+                             E0460,
                              "found possibly newer version of crate `{}`{}",
-                             self.ident, add)
+                             self.ident,
+                             add)
         } else if !self.rejected_via_triple.is_empty() {
-            struct_span_err!(self.sess, self.span, E0461,
+            struct_span_err!(self.sess,
+                             self.span,
+                             E0461,
                              "couldn't find crate `{}` with expected target triple {}{}",
-                             self.ident, self.triple, add)
+                             self.ident,
+                             self.triple,
+                             add)
         } else if !self.rejected_via_kind.is_empty() {
-            struct_span_err!(self.sess, self.span, E0462,
+            struct_span_err!(self.sess,
+                             self.span,
+                             E0462,
                              "found staticlib `{}` instead of rlib or dylib{}",
-                             self.ident, add)
+                             self.ident,
+                             add)
         } else if !self.rejected_via_version.is_empty() {
-            struct_span_err!(self.sess, self.span, E0514,
+            struct_span_err!(self.sess,
+                             self.span,
+                             E0514,
                              "found crate `{}` compiled by an incompatible version of rustc{}",
-                             self.ident, add)
+                             self.ident,
+                             add)
         } else {
-            let mut err = struct_span_err!(self.sess, self.span, E0463,
+            let mut err = struct_span_err!(self.sess,
+                                           self.span,
+                                           E0463,
                                            "can't find crate for `{}`{}",
-                                           self.ident, add);
+                                           self.ident,
+                                           add);
             err.span_label(self.span, &format!("can't find crate"));
             err
         };
 
         if !self.rejected_via_triple.is_empty() {
             let mismatches = self.rejected_via_triple.iter();
-            for (i, &CrateMismatch{ ref path, ref got }) in mismatches.enumerate() {
+            for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() {
                 err.note(&format!("crate `{}`, path #{}, triple {}: {}",
-                                  self.ident, i+1, got, path.display()));
+                                  self.ident,
+                                  i + 1,
+                                  got,
+                                  path.display()));
             }
         }
         if !self.rejected_via_hash.is_empty() {
             err.note("perhaps that crate needs to be recompiled?");
             let mismatches = self.rejected_via_hash.iter();
-            for (i, &CrateMismatch{ ref path, .. }) in mismatches.enumerate() {
-                err.note(&format!("crate `{}` path #{}: {}",
-                                  self.ident, i+1, path.display()));
+            for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
+                err.note(&format!("crate `{}` path #{}: {}", self.ident, i + 1, path.display()));
             }
             match self.root {
                 &None => {}
                 &Some(ref r) => {
                     for (i, path) in r.paths().iter().enumerate() {
                         err.note(&format!("crate `{}` path #{}: {}",
-                                          r.ident, i+1, path.display()));
+                                          r.ident,
+                                          i + 1,
+                                          path.display()));
                     }
                 }
             }
@@ -371,8 +390,7 @@ impl<'a> Context<'a> {
             err.help("please recompile that crate using --crate-type lib");
             let mismatches = self.rejected_via_kind.iter();
             for (i, &CrateMismatch { ref path, .. }) in mismatches.enumerate() {
-                err.note(&format!("crate `{}` path #{}: {}",
-                                  self.ident, i+1, path.display()));
+                err.note(&format!("crate `{}` path #{}: {}", self.ident, i + 1, path.display()));
             }
         }
         if !self.rejected_via_version.is_empty() {
@@ -381,7 +399,10 @@ impl<'a> Context<'a> {
             let mismatches = self.rejected_via_version.iter();
             for (i, &CrateMismatch { ref path, ref got }) in mismatches.enumerate() {
                 err.note(&format!("crate `{}` path #{}: {} compiled by {:?}",
-                                  self.ident, i+1, path.display(), got));
+                                  self.ident,
+                                  i + 1,
+                                  path.display(),
+                                  got));
             }
         }
 
@@ -410,7 +431,7 @@ impl<'a> Context<'a> {
         let staticlib_prefix = format!("{}{}", staticpair.0, self.crate_name);
 
         let mut candidates = FnvHashMap();
-        let mut staticlibs = vec!();
+        let mut staticlibs = vec![];
 
         // First, find all possible candidate rlibs and dylibs purely based on
         // the name of the files themselves. We're trying to match against an
@@ -430,38 +451,36 @@ impl<'a> Context<'a> {
                 None => return FileDoesntMatch,
                 Some(file) => file,
             };
-            let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) &&
-                                  file.ends_with(".rlib") {
-                (&file[(rlib_prefix.len()) .. (file.len() - ".rlib".len())],
-                 true)
+            let (hash, rlib) = if file.starts_with(&rlib_prefix[..]) && file.ends_with(".rlib") {
+                (&file[(rlib_prefix.len())..(file.len() - ".rlib".len())], true)
             } else if file.starts_with(&dylib_prefix) &&
-                      file.ends_with(&dypair.1) {
-                (&file[(dylib_prefix.len()) .. (file.len() - dypair.1.len())],
-                 false)
+                                         file.ends_with(&dypair.1) {
+                (&file[(dylib_prefix.len())..(file.len() - dypair.1.len())], false)
             } else {
-                if file.starts_with(&staticlib_prefix[..]) &&
-                   file.ends_with(&staticpair.1) {
+                if file.starts_with(&staticlib_prefix[..]) && file.ends_with(&staticpair.1) {
                     staticlibs.push(CrateMismatch {
                         path: path.to_path_buf(),
-                        got: "static".to_string()
+                        got: "static".to_string(),
                     });
                 }
-                return FileDoesntMatch
+                return FileDoesntMatch;
             };
             info!("lib candidate: {}", path.display());
 
             let hash_str = hash.to_string();
             let slot = candidates.entry(hash_str)
-                                 .or_insert_with(|| (FnvHashMap(), FnvHashMap()));
+                .or_insert_with(|| (FnvHashMap(), FnvHashMap()));
             let (ref mut rlibs, ref mut dylibs) = *slot;
-            fs::canonicalize(path).map(|p| {
-                if rlib {
-                    rlibs.insert(p, kind);
-                } else {
-                    dylibs.insert(p, kind);
-                }
-                FileMatches
-            }).unwrap_or(FileDoesntMatch)
+            fs::canonicalize(path)
+                .map(|p| {
+                    if rlib {
+                        rlibs.insert(p, kind);
+                    } else {
+                        dylibs.insert(p, kind);
+                    }
+                    FileMatches
+                })
+                .unwrap_or(FileDoesntMatch)
         });
         self.rejected_via_kind.extend(staticlibs);
 
@@ -479,11 +498,12 @@ impl<'a> Context<'a> {
             let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
             let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
             if let Some((h, m)) = slot {
-                libraries.insert(h, Library {
-                    dylib: dylib,
-                    rlib: rlib,
-                    metadata: m,
-                });
+                libraries.insert(h,
+                                 Library {
+                                     dylib: dylib,
+                                     rlib: rlib,
+                                     metadata: m,
+                                 });
             }
         }
 
@@ -494,7 +514,9 @@ impl<'a> Context<'a> {
             0 => None,
             1 => Some(libraries.into_iter().next().unwrap().1),
             _ => {
-                let mut err = struct_span_err!(self.sess, self.span, E0464,
+                let mut err = struct_span_err!(self.sess,
+                                               self.span,
+                                               E0464,
                                                "multiple matching crates for `{}`",
                                                self.crate_name);
                 err.note("candidates:");
@@ -521,8 +543,11 @@ impl<'a> Context<'a> {
     // read the metadata from it if `*slot` is `None`. If the metadata couldn't
     // be read, it is assumed that the file isn't a valid rust library (no
     // errors are emitted).
-    fn extract_one(&mut self, m: FnvHashMap<PathBuf, PathKind>, flavor: CrateFlavor,
-                   slot: &mut Option<(Svh, MetadataBlob)>) -> Option<(PathBuf, PathKind)> {
+    fn extract_one(&mut self,
+                   m: FnvHashMap<PathBuf, PathKind>,
+                   flavor: CrateFlavor,
+                   slot: &mut Option<(Svh, MetadataBlob)>)
+                   -> Option<(PathBuf, PathKind)> {
         let mut ret: Option<(PathBuf, PathKind)> = None;
         let mut error = 0;
 
@@ -532,9 +557,9 @@ impl<'a> Context<'a> {
             //                read both, but reading dylib metadata is quite
             //                slow.
             if m.is_empty() {
-                return None
+                return None;
             } else if m.len() == 1 {
-                return Some(m.into_iter().next().unwrap())
+                return Some(m.into_iter().next().unwrap());
             }
         }
 
@@ -547,23 +572,28 @@ impl<'a> Context<'a> {
                         (h, blob)
                     } else {
                         info!("metadata mismatch");
-                        continue
+                        continue;
                     }
                 }
                 Err(err) => {
                     info!("no metadata found: {}", err);
-                    continue
+                    continue;
                 }
             };
             // If we see multiple hashes, emit an error about duplicate candidates.
             if slot.as_ref().map_or(false, |s| s.0 != hash) {
-                let mut e = struct_span_err!(self.sess, self.span, E0465,
+                let mut e = struct_span_err!(self.sess,
+                                             self.span,
+                                             E0465,
                                              "multiple {} candidates for `{}` found",
-                                             flavor, self.crate_name);
+                                             flavor,
+                                             self.crate_name);
                 e.span_note(self.span,
                             &format!(r"candidate #1: {}",
-                                     ret.as_ref().unwrap().0
-                                        .display()));
+                                     ret.as_ref()
+                                         .unwrap()
+                                         .0
+                                         .display()));
                 if let Some(ref mut e) = err {
                     e.emit();
                 }
@@ -574,9 +604,10 @@ impl<'a> Context<'a> {
             if error > 0 {
                 error += 1;
                 err.as_mut().unwrap().span_note(self.span,
-                                                &format!(r"candidate #{}: {}", error,
+                                                &format!(r"candidate #{}: {}",
+                                                         error,
                                                          lib.display()));
-                continue
+                continue;
             }
             *slot = Some((hash, metadata));
             ret = Some((lib, kind));
@@ -595,37 +626,39 @@ impl<'a> Context<'a> {
         let rustc_version = rustc_version();
         if root.rustc_version != rustc_version {
             info!("Rejecting via version: expected {} got {}",
-                  rustc_version, root.rustc_version);
+                  rustc_version,
+                  root.rustc_version);
             self.rejected_via_version.push(CrateMismatch {
                 path: libpath.to_path_buf(),
-                got: root.rustc_version
+                got: root.rustc_version,
             });
             return None;
         }
 
         if self.should_match_name {
             if self.crate_name != root.name {
-                info!("Rejecting via crate name"); return None;
+                info!("Rejecting via crate name");
+                return None;
             }
         }
 
         if root.triple != self.triple {
             info!("Rejecting via crate triple: expected {} got {}",
-                  self.triple, root.triple);
+                  self.triple,
+                  root.triple);
             self.rejected_via_triple.push(CrateMismatch {
                 path: libpath.to_path_buf(),
-                got: root.triple
+                got: root.triple,
             });
             return None;
         }
 
         if let Some(myhash) = self.hash {
             if *myhash != root.hash {
-                info!("Rejecting via hash: expected {} got {}",
-                      *myhash, root.hash);
+                info!("Rejecting via hash: expected {} got {}", *myhash, root.hash);
                 self.rejected_via_hash.push(CrateMismatch {
                     path: libpath.to_path_buf(),
-                    got: myhash.to_string()
+                    got: myhash.to_string(),
                 });
                 return None;
             }
@@ -649,8 +682,8 @@ impl<'a> Context<'a> {
         (t.options.staticlib_prefix.clone(), t.options.staticlib_suffix.clone())
     }
 
-    fn find_commandline_library<'b, LOCS> (&mut self, locs: LOCS) -> Option<Library>
-        where LOCS: Iterator<Item=&'b String>
+    fn find_commandline_library<'b, LOCS>(&mut self, locs: LOCS) -> Option<Library>
+        where LOCS: Iterator<Item = &'b String>
     {
         // First, filter out all libraries that look suspicious. We only accept
         // files which actually exist that have the correct naming scheme for
@@ -663,30 +696,33 @@ impl<'a> Context<'a> {
             let locs = locs.map(|l| PathBuf::from(l)).filter(|loc| {
                 if !loc.exists() {
                     sess.err(&format!("extern location for {} does not exist: {}",
-                                     self.crate_name, loc.display()));
+                                      self.crate_name,
+                                      loc.display()));
                     return false;
                 }
                 let file = match loc.file_name().and_then(|s| s.to_str()) {
                     Some(file) => file,
                     None => {
                         sess.err(&format!("extern location for {} is not a file: {}",
-                                         self.crate_name, loc.display()));
+                                          self.crate_name,
+                                          loc.display()));
                         return false;
                     }
                 };
                 if file.starts_with("lib") && file.ends_with(".rlib") {
-                    return true
+                    return true;
                 } else {
                     let (ref prefix, ref suffix) = dylibname;
-                    if file.starts_with(&prefix[..]) &&
-                       file.ends_with(&suffix[..]) {
-                        return true
+                    if file.starts_with(&prefix[..]) && file.ends_with(&suffix[..]) {
+                        return true;
                     }
                 }
                 sess.struct_err(&format!("extern location for {} is of an unknown type: {}",
-                                         self.crate_name, loc.display()))
+                                         self.crate_name,
+                                         loc.display()))
                     .help(&format!("file name should be lib*.rlib or {}*.{}",
-                                   dylibname.0, dylibname.1))
+                                   dylibname.0,
+                                   dylibname.1))
                     .emit();
                 false
             });
@@ -695,11 +731,9 @@ impl<'a> Context<'a> {
             // there's at most one rlib and at most one dylib.
             for loc in locs {
                 if loc.file_name().unwrap().to_str().unwrap().ends_with(".rlib") {
-                    rlibs.insert(fs::canonicalize(&loc).unwrap(),
-                                 PathKind::ExternFlag);
+                    rlibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
                 } else {
-                    dylibs.insert(fs::canonicalize(&loc).unwrap(),
-                                  PathKind::ExternFlag);
+                    dylibs.insert(fs::canonicalize(&loc).unwrap(), PathKind::ExternFlag);
                 }
             }
         };
@@ -709,13 +743,17 @@ impl<'a> Context<'a> {
         let rlib = self.extract_one(rlibs, CrateFlavor::Rlib, &mut slot);
         let dylib = self.extract_one(dylibs, CrateFlavor::Dylib, &mut slot);
 
-        if rlib.is_none() && dylib.is_none() { return None }
+        if rlib.is_none() && dylib.is_none() {
+            return None;
+        }
         match slot {
-            Some((_, metadata)) => Some(Library {
-                dylib: dylib,
-                rlib: rlib,
-                metadata: metadata,
-            }),
+            Some((_, metadata)) => {
+                Some(Library {
+                    dylib: dylib,
+                    rlib: rlib,
+                    metadata: metadata,
+                })
+            }
             None => None,
         }
     }
@@ -728,9 +766,9 @@ pub fn note_crate_name(err: &mut DiagnosticBuilder, name: &str) {
 impl ArchiveMetadata {
     fn new(ar: ArchiveRO) -> Option<ArchiveMetadata> {
         let data = {
-            let section = ar.iter().filter_map(|s| s.ok()).find(|sect| {
-                sect.name() == Some(METADATA_FILENAME)
-            });
+            let section = ar.iter()
+                .filter_map(|s| s.ok())
+                .find(|sect| sect.name() == Some(METADATA_FILENAME));
             match section {
                 Some(s) => s.data() as *const [u8],
                 None => {
@@ -746,12 +784,14 @@ impl ArchiveMetadata {
         })
     }
 
-    pub fn as_slice<'a>(&'a self) -> &'a [u8] { unsafe { &*self.data } }
+    pub fn as_slice<'a>(&'a self) -> &'a [u8] {
+        unsafe { &*self.data }
+    }
 }
 
-fn verify_decompressed_encoding_version(blob: &MetadataBlob, filename: &Path)
-                                        -> Result<(), String>
-{
+fn verify_decompressed_encoding_version(blob: &MetadataBlob,
+                                        filename: &Path)
+                                        -> Result<(), String> {
     if !blob.is_compatible() {
         Err((format!("incompatible metadata version found: '{}'",
                      filename.display())))
@@ -761,16 +801,21 @@ fn verify_decompressed_encoding_version(blob: &MetadataBlob, filename: &Path)
 }
 
 // Just a small wrapper to time how long reading metadata takes.
-fn get_metadata_section(target: &Target, flavor: CrateFlavor, filename: &Path)
+fn get_metadata_section(target: &Target,
+                        flavor: CrateFlavor,
+                        filename: &Path)
                         -> Result<MetadataBlob, String> {
     let start = Instant::now();
     let ret = get_metadata_section_imp(target, flavor, filename);
-    info!("reading {:?} => {:?}", filename.file_name().unwrap(),
+    info!("reading {:?} => {:?}",
+          filename.file_name().unwrap(),
           start.elapsed());
-    return ret
+    return ret;
 }
 
-fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Path)
+fn get_metadata_section_imp(target: &Target,
+                            flavor: CrateFlavor,
+                            filename: &Path)
                             -> Result<MetadataBlob, String> {
     if !filename.exists() {
         return Err(format!("no such file: '{}'", filename.display()));
@@ -783,13 +828,11 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
             Some(ar) => ar,
             None => {
                 debug!("llvm didn't like `{}`", filename.display());
-                return Err(format!("failed to read rlib metadata: '{}'",
-                                   filename.display()));
+                return Err(format!("failed to read rlib metadata: '{}'", filename.display()));
             }
         };
         return match ArchiveMetadata::new(archive).map(|ar| MetadataBlob::Archive(ar)) {
-            None => Err(format!("failed to read rlib metadata: '{}'",
-                                filename.display())),
+            None => Err(format!("failed to read rlib metadata: '{}'", filename.display())),
             Some(blob) => {
                 verify_decompressed_encoding_version(&blob, filename)?;
                 Ok(blob)
@@ -800,22 +843,19 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
         let buf = common::path2cstr(filename);
         let mb = llvm::LLVMRustCreateMemoryBufferWithContentsOfFile(buf.as_ptr());
         if mb as isize == 0 {
-            return Err(format!("error reading library: '{}'",
-                               filename.display()))
+            return Err(format!("error reading library: '{}'", filename.display()));
         }
         let of = match ObjectFile::new(mb) {
             Some(of) => of,
             _ => {
-                return Err((format!("provided path not an object file: '{}'",
-                                    filename.display())))
+                return Err((format!("provided path not an object file: '{}'", filename.display())))
             }
         };
         let si = mk_section_iter(of.llof);
         while llvm::LLVMIsSectionIteratorAtEnd(of.llof, si.llsi) == False {
             let mut name_buf = ptr::null();
             let name_len = llvm::LLVMRustGetSectionName(si.llsi, &mut name_buf);
-            let name = slice::from_raw_parts(name_buf as *const u8,
-                                             name_len as usize).to_vec();
+            let name = slice::from_raw_parts(name_buf as *const u8, name_len as usize).to_vec();
             let name = String::from_utf8(name).unwrap();
             debug!("get_metadata_section: name {}", name);
             if read_meta_section_name(target) == name {
@@ -823,8 +863,7 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
                 let csz = llvm::LLVMGetSectionSize(si.llsi) as usize;
                 let cvbuf: *const u8 = cbuf as *const u8;
                 let vlen = METADATA_HEADER.len();
-                debug!("checking {} bytes of metadata-version stamp",
-                       vlen);
+                debug!("checking {} bytes of metadata-version stamp", vlen);
                 let minsz = cmp::min(vlen, csz);
                 let buf0 = slice::from_raw_parts(cvbuf, minsz);
                 let version_ok = buf0 == METADATA_HEADER;
@@ -834,8 +873,7 @@ fn get_metadata_section_imp(target: &Target, flavor: CrateFlavor, filename: &Pat
                 }
 
                 let cvbuf1 = cvbuf.offset(vlen as isize);
-                debug!("inflating {} bytes of compressed metadata",
-                       csz - vlen);
+                debug!("inflating {} bytes of compressed metadata", csz - vlen);
                 let bytes = slice::from_raw_parts(cvbuf1, csz - vlen);
                 match flate::inflate_bytes(bytes) {
                     Ok(inflated) => {
@@ -879,14 +917,15 @@ pub fn read_meta_section_name(_target: &Target) -> &'static str {
 }
 
 // A diagnostic function for dumping crate metadata to an output stream
-pub fn list_file_metadata(target: &Target, path: &Path,
-                          out: &mut io::Write) -> io::Result<()> {
+pub fn list_file_metadata(target: &Target, path: &Path, out: &mut io::Write) -> io::Result<()> {
     let filename = path.file_name().unwrap().to_str().unwrap();
-    let flavor = if filename.ends_with(".rlib") { CrateFlavor::Rlib } else { CrateFlavor::Dylib };
+    let flavor = if filename.ends_with(".rlib") {
+        CrateFlavor::Rlib
+    } else {
+        CrateFlavor::Dylib
+    };
     match get_metadata_section(target, flavor, path) {
         Ok(metadata) => metadata.list_crate_metadata(out),
-        Err(msg) => {
-            write!(out, "{}\n", msg)
-        }
+        Err(msg) => write!(out, "{}\n", msg),
     }
 }
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 0bb126ee0ff..3d1bd77d8bc 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -27,7 +27,8 @@ use syntax_pos::{self, Span};
 use std::marker::PhantomData;
 
 pub fn rustc_version() -> String {
-    format!("rustc {}", option_env!("CFG_VERSION").unwrap_or("unknown version"))
+    format!("rustc {}",
+            option_env!("CFG_VERSION").unwrap_or("unknown version"))
 }
 
 /// Metadata encoding version.
@@ -41,11 +42,8 @@ pub const METADATA_VERSION: u8 = 3;
 /// as a length of 0 by old compilers.
 ///
 /// This header is followed by the position of the `CrateRoot`.
-pub const METADATA_HEADER: &'static [u8; 12] = &[
-    0, 0, 0, 0,
-    b'r', b'u', b's', b't',
-    0, 0, 0, METADATA_VERSION
-];
+pub const METADATA_HEADER: &'static [u8; 12] =
+    &[0, 0, 0, 0, b'r', b'u', b's', b't', 0, 0, 0, METADATA_VERSION];
 
 /// The shorthand encoding uses an enum's variant index `usize`
 /// and is offset by this value so it never matches a real variant.
@@ -70,14 +68,14 @@ pub const SHORTHAND_OFFSET: usize = 0x80;
 #[must_use]
 pub struct Lazy<T> {
     pub position: usize,
-    _marker: PhantomData<T>
+    _marker: PhantomData<T>,
 }
 
 impl<T> Lazy<T> {
     pub fn with_position(position: usize) -> Lazy<T> {
         Lazy {
             position: position,
-            _marker: PhantomData
+            _marker: PhantomData,
         }
     }
 
@@ -90,7 +88,9 @@ impl<T> Lazy<T> {
 
 impl<T> Copy for Lazy<T> {}
 impl<T> Clone for Lazy<T> {
-    fn clone(&self) -> Self { *self }
+    fn clone(&self) -> Self {
+        *self
+    }
 }
 
 impl<T> serialize::UseSpecializedEncodable for Lazy<T> {}
@@ -112,7 +112,7 @@ impl<T> serialize::UseSpecializedDecodable for Lazy<T> {}
 pub struct LazySeq<T> {
     pub len: usize,
     pub position: usize,
-    _marker: PhantomData<T>
+    _marker: PhantomData<T>,
 }
 
 impl<T> LazySeq<T> {
@@ -124,7 +124,7 @@ impl<T> LazySeq<T> {
         LazySeq {
             len: len,
             position: position,
-            _marker: PhantomData
+            _marker: PhantomData,
         }
     }
 
@@ -136,7 +136,9 @@ impl<T> LazySeq<T> {
 
 impl<T> Copy for LazySeq<T> {}
 impl<T> Clone for LazySeq<T> {
-    fn clone(&self) -> Self { *self }
+    fn clone(&self) -> Self {
+        *self
+    }
 }
 
 impl<T> serialize::UseSpecializedEncodable for LazySeq<T> {}
@@ -155,7 +157,7 @@ pub enum LazyState {
     /// Inside a metadata node, with a previous `Lazy` or `LazySeq`.
     /// The position is a conservative estimate of where that
     /// previous `Lazy` / `LazySeq` would end (see their comments).
-    Previous(usize)
+    Previous(usize),
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -185,13 +187,13 @@ pub struct CrateRoot {
 pub struct CrateDep {
     pub name: ast::Name,
     pub hash: hir::svh::Svh,
-    pub explicitly_linked: bool
+    pub explicitly_linked: bool,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct TraitImpls {
     pub trait_id: (u32, DefIndex),
-    pub impls: LazySeq<DefIndex>
+    pub impls: LazySeq<DefIndex>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -199,7 +201,7 @@ pub struct MacroDef {
     pub name: ast::Name,
     pub attrs: Vec<ast::Attribute>,
     pub span: Span,
-    pub body: String
+    pub body: String,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -219,7 +221,7 @@ pub struct Entry<'tcx> {
     pub predicates: Option<Lazy<ty::GenericPredicates<'tcx>>>,
 
     pub ast: Option<Lazy<astencode::Ast<'tcx>>>,
-    pub mir: Option<Lazy<mir::repr::Mir<'tcx>>>
+    pub mir: Option<Lazy<mir::Mir<'tcx>>>,
 }
 
 #[derive(Copy, Clone, RustcEncodable, RustcDecodable)]
@@ -245,18 +247,18 @@ pub enum EntryKind<'tcx> {
     DefaultImpl(Lazy<ImplData<'tcx>>),
     Method(Lazy<MethodData<'tcx>>),
     AssociatedType(AssociatedContainer),
-    AssociatedConst(AssociatedContainer)
+    AssociatedConst(AssociatedContainer),
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct ModData {
-    pub reexports: LazySeq<def::Export>
+    pub reexports: LazySeq<def::Export>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct FnData {
     pub constness: hir::Constness,
-    pub arg_names: LazySeq<ast::Name>
+    pub arg_names: LazySeq<ast::Name>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -266,7 +268,7 @@ pub struct VariantData {
 
     /// If this is a struct's only variant, this
     /// is the index of the "struct ctor" item.
-    pub struct_ctor: Option<DefIndex>
+    pub struct_ctor: Option<DefIndex>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -275,7 +277,7 @@ pub struct TraitData<'tcx> {
     pub paren_sugar: bool,
     pub has_default_impl: bool,
     pub trait_ref: Lazy<ty::TraitRef<'tcx>>,
-    pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>
+    pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
@@ -283,7 +285,7 @@ pub struct ImplData<'tcx> {
     pub polarity: hir::ImplPolarity,
     pub parent_impl: Option<DefId>,
     pub coerce_unsized_kind: Option<ty::adjustment::CustomCoerceUnsized>,
-    pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>
+    pub trait_ref: Option<Lazy<ty::TraitRef<'tcx>>>,
 }
 
 /// Describes whether the container of an associated item
@@ -294,21 +296,17 @@ pub enum AssociatedContainer {
     TraitRequired,
     TraitWithDefault,
     ImplDefault,
-    ImplFinal
+    ImplFinal,
 }
 
 impl AssociatedContainer {
     pub fn with_def_id(&self, def_id: DefId) -> ty::ImplOrTraitItemContainer {
         match *self {
             AssociatedContainer::TraitRequired |
-            AssociatedContainer::TraitWithDefault => {
-                ty::TraitContainer(def_id)
-            }
+            AssociatedContainer::TraitWithDefault => ty::TraitContainer(def_id),
 
             AssociatedContainer::ImplDefault |
-            AssociatedContainer::ImplFinal => {
-                ty::ImplContainer(def_id)
-            }
+            AssociatedContainer::ImplFinal => ty::ImplContainer(def_id),
         }
     }
 
@@ -318,7 +316,7 @@ impl AssociatedContainer {
 
             AssociatedContainer::TraitWithDefault |
             AssociatedContainer::ImplDefault |
-            AssociatedContainer::ImplFinal => true
+            AssociatedContainer::ImplFinal => true,
         }
     }
 
@@ -328,7 +326,7 @@ impl AssociatedContainer {
             AssociatedContainer::TraitWithDefault |
             AssociatedContainer::ImplDefault => hir::Defaultness::Default,
 
-            AssociatedContainer::ImplFinal => hir::Defaultness::Final
+            AssociatedContainer::ImplFinal => hir::Defaultness::Final,
         }
     }
 }
@@ -337,11 +335,11 @@ impl AssociatedContainer {
 pub struct MethodData<'tcx> {
     pub fn_data: FnData,
     pub container: AssociatedContainer,
-    pub explicit_self: Lazy<ty::ExplicitSelfCategory<'tcx>>
+    pub explicit_self: Lazy<ty::ExplicitSelfCategory<'tcx>>,
 }
 
 #[derive(RustcEncodable, RustcDecodable)]
 pub struct ClosureData<'tcx> {
     pub kind: ty::ClosureKind,
-    pub ty: Lazy<ty::ClosureTy<'tcx>>
+    pub ty: Lazy<ty::ClosureTy<'tcx>>,
 }
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index 34d79732646..b53f8c4da86 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -10,7 +10,7 @@
 
 use build::{BlockAnd, BlockAndExtension, Builder};
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::hir;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
diff --git a/src/librustc_mir/build/cfg.rs b/src/librustc_mir/build/cfg.rs
index 026a79b32b8..9f612175e5d 100644
--- a/src/librustc_mir/build/cfg.rs
+++ b/src/librustc_mir/build/cfg.rs
@@ -14,7 +14,7 @@
 //! Routines for manipulating the control-flow graph.
 
 use build::CFG;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 impl<'tcx> CFG<'tcx> {
     pub fn block_data(&self, blk: BasicBlock) -> &BasicBlockData<'tcx> {
diff --git a/src/librustc_mir/build/expr/as_constant.rs b/src/librustc_mir/build/expr/as_constant.rs
index a08d14d9e20..6230123a9ca 100644
--- a/src/librustc_mir/build/expr/as_constant.rs
+++ b/src/librustc_mir/build/expr/as_constant.rs
@@ -12,7 +12,7 @@
 
 use build::Builder;
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     /// Compile `expr`, yielding a compile-time constant. Assumes that
diff --git a/src/librustc_mir/build/expr/as_lvalue.rs b/src/librustc_mir/build/expr/as_lvalue.rs
index 118b23cf987..58abaa0c484 100644
--- a/src/librustc_mir/build/expr/as_lvalue.rs
+++ b/src/librustc_mir/build/expr/as_lvalue.rs
@@ -13,7 +13,7 @@
 use build::{BlockAnd, BlockAndExtension, Builder};
 use build::expr::category::Category;
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 use rustc_data_structures::indexed_vec::Idx;
 
diff --git a/src/librustc_mir/build/expr/as_operand.rs b/src/librustc_mir/build/expr/as_operand.rs
index beb9ca256ab..09cdcc74ef6 100644
--- a/src/librustc_mir/build/expr/as_operand.rs
+++ b/src/librustc_mir/build/expr/as_operand.rs
@@ -13,7 +13,7 @@
 use build::{BlockAnd, BlockAndExtension, Builder};
 use build::expr::category::Category;
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     /// Compile `expr` into a value that can be used as an operand.
diff --git a/src/librustc_mir/build/expr/as_rvalue.rs b/src/librustc_mir/build/expr/as_rvalue.rs
index dcb301cab00..490f675c3d5 100644
--- a/src/librustc_mir/build/expr/as_rvalue.rs
+++ b/src/librustc_mir/build/expr/as_rvalue.rs
@@ -22,7 +22,7 @@ use hair::*;
 use rustc_const_math::{ConstInt, ConstIsize};
 use rustc::middle::const_val::ConstVal;
 use rustc::ty;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use syntax::ast;
 use syntax_pos::Span;
 
diff --git a/src/librustc_mir/build/expr/as_temp.rs b/src/librustc_mir/build/expr/as_temp.rs
index 85128cbbbaf..fb12e08affd 100644
--- a/src/librustc_mir/build/expr/as_temp.rs
+++ b/src/librustc_mir/build/expr/as_temp.rs
@@ -13,7 +13,7 @@
 use build::{BlockAnd, BlockAndExtension, Builder};
 use build::expr::category::Category;
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     /// Compile `expr` into a fresh temporary. This is used when building
diff --git a/src/librustc_mir/build/expr/into.rs b/src/librustc_mir/build/expr/into.rs
index 58265b5b0d3..5fa08442221 100644
--- a/src/librustc_mir/build/expr/into.rs
+++ b/src/librustc_mir/build/expr/into.rs
@@ -14,7 +14,7 @@ use build::{BlockAnd, BlockAndExtension, Builder};
 use build::expr::category::{Category, RvalueFunc};
 use hair::*;
 use rustc::ty;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     /// Compile `expr`, storing the result into `destination`, which
diff --git a/src/librustc_mir/build/expr/stmt.rs b/src/librustc_mir/build/expr/stmt.rs
index 9448527e6e6..4a1926e7c57 100644
--- a/src/librustc_mir/build/expr/stmt.rs
+++ b/src/librustc_mir/build/expr/stmt.rs
@@ -12,7 +12,7 @@ use build::{BlockAnd, BlockAndExtension, Builder};
 use build::scope::LoopScope;
 use hair::*;
 use rustc::middle::region::CodeExtent;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use syntax_pos::Span;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
diff --git a/src/librustc_mir/build/into.rs b/src/librustc_mir/build/into.rs
index 17ccb701c2b..5c133780e43 100644
--- a/src/librustc_mir/build/into.rs
+++ b/src/librustc_mir/build/into.rs
@@ -16,7 +16,7 @@
 
 use build::{BlockAnd, Builder};
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 pub trait EvalInto<'tcx> {
     fn eval_into<'a, 'gcx>(self,
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index a9ea82140b5..727e634ef92 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -18,7 +18,7 @@ use rustc_data_structures::fnv::FnvHashMap;
 use rustc_data_structures::bitvec::BitVector;
 use rustc::middle::const_val::ConstVal;
 use rustc::ty::{AdtDef, Ty};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use hair::*;
 use syntax::ast::{Name, NodeId};
 use syntax_pos::Span;
diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs
index 8392248e3f2..71282dcf0ba 100644
--- a/src/librustc_mir/build/matches/simplify.rs
+++ b/src/librustc_mir/build/matches/simplify.rs
@@ -25,7 +25,7 @@
 use build::{BlockAnd, BlockAndExtension, Builder};
 use build::matches::{Binding, MatchPair, Candidate};
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 use std::mem;
 
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 78a1604a5cb..5984b0f7893 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -22,7 +22,7 @@ use rustc_data_structures::fnv::FnvHashMap;
 use rustc_data_structures::bitvec::BitVector;
 use rustc::middle::const_val::ConstVal;
 use rustc::ty::{self, Ty};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use syntax_pos::Span;
 use std::cmp::Ordering;
 
diff --git a/src/librustc_mir/build/matches/util.rs b/src/librustc_mir/build/matches/util.rs
index 53ebf6fceb5..a013875b311 100644
--- a/src/librustc_mir/build/matches/util.rs
+++ b/src/librustc_mir/build/matches/util.rs
@@ -11,7 +11,7 @@
 use build::Builder;
 use build::matches::MatchPair;
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use std::u32;
 
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
diff --git a/src/librustc_mir/build/misc.rs b/src/librustc_mir/build/misc.rs
index 4bc51c3a625..a5f51ef35b7 100644
--- a/src/librustc_mir/build/misc.rs
+++ b/src/librustc_mir/build/misc.rs
@@ -17,7 +17,7 @@ use rustc_const_math::{ConstInt, ConstUsize, ConstIsize};
 use rustc::middle::const_val::ConstVal;
 use rustc::ty::{self, Ty};
 
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use syntax::ast;
 use syntax_pos::Span;
 
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index a7249677e01..d6fcc79a9a2 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -13,7 +13,7 @@ use hair::Pattern;
 
 use rustc::middle::region::{CodeExtent, CodeExtentData, ROOT_CODE_EXTENT};
 use rustc::ty::{self, Ty};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::util::nodemap::NodeMap;
 use rustc::hir;
 use syntax::abi::Abi;
diff --git a/src/librustc_mir/build/scope.rs b/src/librustc_mir/build/scope.rs
index 185668ff767..af8170a1b8f 100644
--- a/src/librustc_mir/build/scope.rs
+++ b/src/librustc_mir/build/scope.rs
@@ -91,7 +91,7 @@ use rustc::middle::region::{CodeExtent, CodeExtentData};
 use rustc::middle::lang_items;
 use rustc::ty::subst::{Kind, Subst};
 use rustc::ty::{Ty, TyCtxt};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use syntax_pos::Span;
 use rustc_data_structures::indexed_vec::Idx;
 use rustc_data_structures::fnv::FnvHashMap;
diff --git a/src/librustc_mir/def_use.rs b/src/librustc_mir/def_use.rs
index 343d802119e..d20d50c5611 100644
--- a/src/librustc_mir/def_use.rs
+++ b/src/librustc_mir/def_use.rs
@@ -10,7 +10,7 @@
 
 //! Def-use analysis.
 
-use rustc::mir::repr::{Local, Location, Lvalue, Mir};
+use rustc::mir::{Local, Location, Lvalue, Mir};
 use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor};
 use rustc_data_structures::indexed_vec::IndexVec;
 use std::marker::PhantomData;
diff --git a/src/librustc_mir/graphviz.rs b/src/librustc_mir/graphviz.rs
index 1c1f0ca7902..dd4dd4699d8 100644
--- a/src/librustc_mir/graphviz.rs
+++ b/src/librustc_mir/graphviz.rs
@@ -10,8 +10,7 @@
 
 use dot;
 use rustc::hir::def_id::DefId;
-use rustc::mir::repr::*;
-use rustc::mir::mir_map::MirMap;
+use rustc::mir::*;
 use rustc::ty::TyCtxt;
 use std::fmt::Debug;
 use std::io::{self, Write};
@@ -22,14 +21,13 @@ use rustc_data_structures::indexed_vec::Idx;
 /// Write a graphviz DOT graph of a list of MIRs.
 pub fn write_mir_graphviz<'a, 'b, 'tcx, W, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                               iter: I,
-                                              mir_map: &MirMap<'tcx>,
                                               w: &mut W)
                                               -> io::Result<()>
     where W: Write, I: Iterator<Item=DefId>
 {
     for def_id in iter {
         let nodeid = tcx.map.as_local_node_id(def_id).unwrap();
-        let mir = &mir_map.map[&def_id];
+        let mir = &tcx.item_mir(def_id);
 
         writeln!(w, "digraph Mir_{} {{", nodeid)?;
 
diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs
index 45c49a4627f..1b324ac3132 100644
--- a/src/librustc_mir/hair/cx/expr.rs
+++ b/src/librustc_mir/hair/cx/expr.rs
@@ -21,7 +21,7 @@ use rustc_const_eval as const_eval;
 use rustc::middle::region::CodeExtent;
 use rustc::ty::{self, AdtKind, VariantDef, Ty};
 use rustc::ty::cast::CastKind as TyCastKind;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::hir;
 use syntax::ptr::P;
 
diff --git a/src/librustc_mir/hair/cx/mod.rs b/src/librustc_mir/hair/cx/mod.rs
index f87e0acaa4c..678db1e544c 100644
--- a/src/librustc_mir/hair/cx/mod.rs
+++ b/src/librustc_mir/hair/cx/mod.rs
@@ -16,7 +16,7 @@
  */
 
 use hair::*;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::transform::MirSource;
 
 use rustc::middle::const_val::ConstVal;
diff --git a/src/librustc_mir/hair/mod.rs b/src/librustc_mir/hair/mod.rs
index 49a592b07fb..e211334e547 100644
--- a/src/librustc_mir/hair/mod.rs
+++ b/src/librustc_mir/hair/mod.rs
@@ -14,7 +14,7 @@
 //! unit-tested and separated from the Rust source and compiler data
 //! structures.
 
-use rustc::mir::repr::{BinOp, BorrowKind, Field, Literal, UnOp, TypedConstVal};
+use rustc::mir::{BinOp, BorrowKind, Field, Literal, UnOp, TypedConstVal};
 use rustc::hir::def_id::DefId;
 use rustc::middle::region::CodeExtent;
 use rustc::ty::subst::Substs;
diff --git a/src/librustc_mir/mir_map.rs b/src/librustc_mir/mir_map.rs
index 2dcefcc12f6..b0e2d6e73d3 100644
--- a/src/librustc_mir/mir_map.rs
+++ b/src/librustc_mir/mir_map.rs
@@ -19,13 +19,12 @@
 use build;
 use rustc::dep_graph::DepNode;
 use rustc::hir::def_id::DefId;
-use rustc::mir::repr::Mir;
+use rustc::mir::Mir;
 use rustc::mir::transform::MirSource;
 use rustc::mir::visit::MutVisitor;
 use pretty;
 use hair::cx::Cx;
 
-use rustc::mir::mir_map::MirMap;
 use rustc::infer::InferCtxtBuilder;
 use rustc::traits::Reveal;
 use rustc::ty::{self, Ty, TyCtxt};
@@ -37,16 +36,10 @@ use syntax_pos::Span;
 
 use std::mem;
 
-pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) -> MirMap<'tcx> {
-    let mut map = MirMap::new(tcx.dep_graph.clone());
-    {
-        let mut dump = BuildMir {
-            tcx: tcx,
-            map: &mut map,
-        };
-        tcx.visit_all_items_in_krate(DepNode::Mir, &mut dump);
-    }
-    map
+pub fn build_mir_for_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
+    tcx.visit_all_items_in_krate(DepNode::Mir, &mut BuildMir {
+        tcx: tcx
+    });
 }
 
 /// A pass to lift all the types and substitutions in a Mir
@@ -83,8 +76,7 @@ impl<'a, 'gcx: 'tcx, 'tcx> MutVisitor<'tcx> for GlobalizeMir<'a, 'gcx> {
 // BuildMir -- walks a crate, looking for fn items and methods to build MIR from
 
 struct BuildMir<'a, 'tcx: 'a> {
-    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-    map: &'a mut MirMap<'tcx>,
+    tcx: TyCtxt<'a, 'tcx, 'tcx>
 }
 
 /// Helper type of a temporary returned by BuildMir::cx(...).
@@ -93,8 +85,7 @@ struct BuildMir<'a, 'tcx: 'a> {
 struct CxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     src: MirSource,
     def_id: DefId,
-    infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>,
-    map: &'a mut MirMap<'gcx>,
+    infcx: InferCtxtBuilder<'a, 'gcx, 'tcx>
 }
 
 impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
@@ -104,8 +95,7 @@ impl<'a, 'gcx, 'tcx> BuildMir<'a, 'gcx> {
         CxBuilder {
             src: src,
             infcx: self.tcx.infer_ctxt(None, Some(param_env), Reveal::NotSpecializable),
-            def_id: def_id,
-            map: self.map
+            def_id: def_id
         }
     }
 }
@@ -114,13 +104,14 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
     fn build<F>(&'tcx mut self, f: F)
         where F: for<'b> FnOnce(Cx<'b, 'gcx, 'tcx>) -> (Mir<'tcx>, build::ScopeAuxiliaryVec)
     {
-        let src = self.src;
-        let mir = self.infcx.enter(|infcx| {
+        let (src, def_id) = (self.src, self.def_id);
+        self.infcx.enter(|infcx| {
             let (mut mir, scope_auxiliary) = f(Cx::new(&infcx, src));
 
             // Convert the Mir to global types.
+            let tcx = infcx.tcx.global_tcx();
             let mut globalizer = GlobalizeMir {
-                tcx: infcx.tcx.global_tcx(),
+                tcx: tcx,
                 span: mir.span
             };
             globalizer.visit_mir(&mut mir);
@@ -128,13 +119,11 @@ impl<'a, 'gcx, 'tcx> CxBuilder<'a, 'gcx, 'tcx> {
                 mem::transmute::<Mir, Mir<'gcx>>(mir)
             };
 
-            pretty::dump_mir(infcx.tcx.global_tcx(), "mir_map", &0,
-                             src, &mir, Some(&scope_auxiliary));
+            pretty::dump_mir(tcx, "mir_map", &0, src, &mir, Some(&scope_auxiliary));
 
-            mir
+            let mir = tcx.alloc_mir(mir);
+            assert!(tcx.mir_map.borrow_mut().insert(def_id, mir).is_none());
         });
-
-        assert!(self.map.map.insert(self.def_id, mir).is_none())
     }
 }
 
diff --git a/src/librustc_mir/pretty.rs b/src/librustc_mir/pretty.rs
index 5c88c898621..d2fc8aeaa2e 100644
--- a/src/librustc_mir/pretty.rs
+++ b/src/librustc_mir/pretty.rs
@@ -11,8 +11,7 @@
 use build::{ScopeAuxiliaryVec, ScopeId};
 use rustc::hir;
 use rustc::hir::def_id::DefId;
-use rustc::mir::repr::*;
-use rustc::mir::mir_map::MirMap;
+use rustc::mir::*;
 use rustc::mir::transform::MirSource;
 use rustc::ty::TyCtxt;
 use rustc_data_structures::fnv::FnvHashMap;
@@ -90,14 +89,13 @@ pub fn dump_mir<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 /// Write out a human-readable textual representation for the given MIR.
 pub fn write_mir_pretty<'a, 'b, 'tcx, I>(tcx: TyCtxt<'b, 'tcx, 'tcx>,
                                          iter: I,
-                                         mir_map: &MirMap<'tcx>,
                                          w: &mut Write)
                                          -> io::Result<()>
     where I: Iterator<Item=DefId>, 'tcx: 'a
 {
     let mut first = true;
     for def_id in iter {
-        let mir = &mir_map.map[&def_id];
+        let mir = &tcx.item_mir(def_id);
 
         if first {
             first = false;
diff --git a/src/librustc_mir/transform/add_call_guards.rs b/src/librustc_mir/transform/add_call_guards.rs
index c028504d6f9..89e644e4fb0 100644
--- a/src/librustc_mir/transform/add_call_guards.rs
+++ b/src/librustc_mir/transform/add_call_guards.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::transform::{MirPass, MirSource, Pass};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 
diff --git a/src/librustc_mir/transform/copy_prop.rs b/src/librustc_mir/transform/copy_prop.rs
index 783162cd558..8c8c42a1c76 100644
--- a/src/librustc_mir/transform/copy_prop.rs
+++ b/src/librustc_mir/transform/copy_prop.rs
@@ -30,7 +30,7 @@
 //! future.
 
 use def_use::DefUseAnalysis;
-use rustc::mir::repr::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind};
+use rustc::mir::{Constant, Local, Location, Lvalue, Mir, Operand, Rvalue, StatementKind};
 use rustc::mir::transform::{MirPass, MirSource, Pass};
 use rustc::mir::visit::MutVisitor;
 use rustc::ty::TyCtxt;
diff --git a/src/librustc_mir/transform/deaggregator.rs b/src/librustc_mir/transform/deaggregator.rs
index 198a6d256bc..fcdeae6d6c0 100644
--- a/src/librustc_mir/transform/deaggregator.rs
+++ b/src/librustc_mir/transform/deaggregator.rs
@@ -9,7 +9,7 @@
 // except according to those terms.
 
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::transform::{MirPass, MirSource, Pass};
 use rustc_data_structures::indexed_vec::Idx;
 
diff --git a/src/librustc_mir/transform/dump_mir.rs b/src/librustc_mir/transform/dump_mir.rs
index 694b017bbd7..b8fd9fb12ab 100644
--- a/src/librustc_mir/transform/dump_mir.rs
+++ b/src/librustc_mir/transform/dump_mir.rs
@@ -13,7 +13,7 @@
 use std::fmt;
 
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::transform::{Pass, MirPass, MirPassHook, MirSource};
 use pretty;
 
diff --git a/src/librustc_mir/transform/erase_regions.rs b/src/librustc_mir/transform/erase_regions.rs
index 485ca3ea84a..cebd9dd9668 100644
--- a/src/librustc_mir/transform/erase_regions.rs
+++ b/src/librustc_mir/transform/erase_regions.rs
@@ -14,7 +14,7 @@
 
 use rustc::ty::subst::Substs;
 use rustc::ty::{Ty, TyCtxt};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::visit::MutVisitor;
 use rustc::mir::transform::{MirPass, MirSource, Pass};
 
diff --git a/src/librustc_mir/transform/instcombine.rs b/src/librustc_mir/transform/instcombine.rs
index b4159af6f07..a01724d6d0e 100644
--- a/src/librustc_mir/transform/instcombine.rs
+++ b/src/librustc_mir/transform/instcombine.rs
@@ -10,7 +10,7 @@
 
 //! Performs various peephole optimizations.
 
-use rustc::mir::repr::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
+use rustc::mir::{Location, Lvalue, Mir, Operand, ProjectionElem, Rvalue, Local};
 use rustc::mir::transform::{MirPass, MirSource, Pass};
 use rustc::mir::visit::{MutVisitor, Visitor};
 use rustc::ty::TyCtxt;
diff --git a/src/librustc_mir/transform/no_landing_pads.rs b/src/librustc_mir/transform/no_landing_pads.rs
index 32fddd293ca..6ef5720b330 100644
--- a/src/librustc_mir/transform/no_landing_pads.rs
+++ b/src/librustc_mir/transform/no_landing_pads.rs
@@ -12,7 +12,7 @@
 //! specified.
 
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::visit::MutVisitor;
 use rustc::mir::transform::{Pass, MirPass, MirSource};
 
diff --git a/src/librustc_mir/transform/promote_consts.rs b/src/librustc_mir/transform/promote_consts.rs
index 9afc97d1e31..41698574e0f 100644
--- a/src/librustc_mir/transform/promote_consts.rs
+++ b/src/librustc_mir/transform/promote_consts.rs
@@ -22,7 +22,7 @@
 //! initialization and can otherwise silence errors, if
 //! move analysis runs after promotion on broken MIR.
 
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::visit::{LvalueContext, MutVisitor, Visitor};
 use rustc::mir::traversal::ReversePostorder;
 use rustc::ty::TyCtxt;
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index b00a88093d7..b33a7060e37 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -16,7 +16,6 @@
 
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::{IndexVec, Idx};
-use rustc::dep_graph::DepNode;
 use rustc::hir;
 use rustc::hir::map as hir_map;
 use rustc::hir::def_id::DefId;
@@ -25,10 +24,9 @@ use rustc::hir::map::blocks::FnLikeNode;
 use rustc::traits::{self, Reveal};
 use rustc::ty::{self, TyCtxt, Ty};
 use rustc::ty::cast::CastTy;
-use rustc::mir::repr::*;
-use rustc::mir::mir_map::MirMap;
-use rustc::mir::traversal::{self, ReversePostorder};
-use rustc::mir::transform::{Pass, MirMapPass, MirPassHook, MirSource};
+use rustc::mir::*;
+use rustc::mir::traversal::ReversePostorder;
+use rustc::mir::transform::{Pass, MirPass, MirSource};
 use rustc::mir::visit::{LvalueContext, Visitor};
 use rustc::util::nodemap::DefIdMap;
 use syntax::abi::Abi;
@@ -142,7 +140,6 @@ struct Qualifier<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
     tcx: TyCtxt<'a, 'gcx, 'tcx>,
     param_env: ty::ParameterEnvironment<'tcx>,
     qualif_map: &'a mut DefIdMap<Qualif>,
-    mir_map: Option<&'a MirMap<'tcx>>,
     temp_qualif: IndexVec<Local, Option<Qualif>>,
     return_qualif: Option<Qualif>,
     qualif: Qualif,
@@ -155,7 +152,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
     fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>,
            param_env: ty::ParameterEnvironment<'tcx>,
            qualif_map: &'a mut DefIdMap<Qualif>,
-           mir_map: Option<&'a MirMap<'tcx>>,
            def_id: DefId,
            mir: &'a Mir<'tcx>,
            mode: Mode)
@@ -172,7 +168,6 @@ impl<'a, 'tcx> Qualifier<'a, 'tcx, 'tcx> {
             tcx: tcx,
             param_env: param_env,
             qualif_map: qualif_map,
-            mir_map: mir_map,
             temp_qualif: IndexVec::from_elem(None, &mir.local_decls),
             return_qualif: None,
             qualif: Qualif::empty(),
@@ -595,7 +590,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
                     } else {
                         let qualif = qualify_const_item_cached(self.tcx,
                                                                self.qualif_map,
-                                                               self.mir_map,
                                                                def_id);
                         self.add(qualif);
                     }
@@ -949,7 +943,6 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> {
 
 fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                        qualif_map: &mut DefIdMap<Qualif>,
-                                       mir_map: Option<&MirMap<'tcx>>,
                                        def_id: DefId)
                                        -> Qualif {
     match qualif_map.entry(def_id) {
@@ -960,124 +953,100 @@ fn qualify_const_item_cached<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         }
     }
 
-    let extern_mir;
-    let param_env_and_mir = if def_id.is_local() {
-        mir_map.and_then(|map| map.map.get(&def_id)).map(|mir| {
-            let node_id = tcx.map.as_local_node_id(def_id).unwrap();
-            (ty::ParameterEnvironment::for_item(tcx, node_id), mir)
-        })
-    } else if let Some(mir) = tcx.sess.cstore.maybe_get_item_mir(tcx, def_id) {
-        // These should only be monomorphic constants.
-        extern_mir = mir;
-        Some((tcx.empty_parameter_environment(), &extern_mir))
+    let param_env = if def_id.is_local() {
+        let node_id = tcx.map.as_local_node_id(def_id).unwrap();
+        ty::ParameterEnvironment::for_item(tcx, node_id)
     } else {
-        None
+        // These should only be monomorphic constants.
+        tcx.empty_parameter_environment()
     };
 
-    let (param_env, mir) = param_env_and_mir.unwrap_or_else(|| {
-        bug!("missing constant MIR for {}", tcx.item_path_str(def_id))
-    });
-
-    let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, mir_map,
-                                       def_id, mir, Mode::Const);
+    let mir = &tcx.item_mir(def_id);
+    let mut qualifier = Qualifier::new(tcx, param_env, qualif_map, def_id, mir, Mode::Const);
     let qualif = qualifier.qualify_const();
     qualifier.qualif_map.insert(def_id, qualif);
     qualif
 }
 
-pub struct QualifyAndPromoteConstants;
+#[derive(Default)]
+pub struct QualifyAndPromoteConstants {
+    qualif_map: DefIdMap<Qualif>
+}
 
 impl Pass for QualifyAndPromoteConstants {}
 
-impl<'tcx> MirMapPass<'tcx> for QualifyAndPromoteConstants {
-    fn run_pass<'a>(&mut self,
-                    tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                    map: &mut MirMap<'tcx>,
-                    hooks: &mut [Box<for<'s> MirPassHook<'s>>]) {
-        let mut qualif_map = DefIdMap();
-
-        // First, visit `const` items, potentially recursing, to get
-        // accurate MUTABLE_INTERIOR and NEEDS_DROP qualifications.
-        let keys = map.map.keys();
-        for &def_id in &keys {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let id = tcx.map.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
-            if let MirSource::Const(_) = src {
-                qualify_const_item_cached(tcx, &mut qualif_map, Some(map), def_id);
+impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants {
+    fn run_pass<'a>(&mut self, tcx: TyCtxt<'a, 'tcx, 'tcx>,
+                    src: MirSource, mir: &mut Mir<'tcx>) {
+        let id = src.item_id();
+        let def_id = tcx.map.local_def_id(id);
+        let mode = match src {
+            MirSource::Fn(_) => {
+                if is_const_fn(tcx, def_id) {
+                    Mode::ConstFn
+                } else {
+                    Mode::Fn
+                }
             }
-        }
-
-        // Then, handle everything else, without recursing,
-        // as the MIR map is not shared, since promotion
-        // in functions (including `const fn`) mutates it.
-        for &def_id in &keys {
-            let _task = tcx.dep_graph.in_task(DepNode::Mir(def_id));
-            let id = tcx.map.as_local_node_id(def_id).unwrap();
-            let src = MirSource::from_node(tcx, id);
-            let mode = match src {
-                MirSource::Fn(_) => {
-                    if is_const_fn(tcx, def_id) {
-                        Mode::ConstFn
-                    } else {
-                        Mode::Fn
+            MirSource::Const(_) => {
+                match self.qualif_map.entry(def_id) {
+                    Entry::Occupied(_) => return,
+                    Entry::Vacant(entry) => {
+                        // Guard against `const` recursion.
+                        entry.insert(Qualif::RECURSIVE);
                     }
                 }
-                MirSource::Const(_) => continue,
-                MirSource::Static(_, hir::MutImmutable) => Mode::Static,
-                MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
-                MirSource::Promoted(..) => bug!()
-            };
-            let param_env = ty::ParameterEnvironment::for_item(tcx, id);
-
-            let mir = map.map.get_mut(&def_id).unwrap();
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, false);
+                Mode::Const
             }
-
-            if mode == Mode::Fn || mode == Mode::ConstFn {
-                // This is ugly because Qualifier holds onto mir,
-                // which can't be mutated until its scope ends.
-                let (temps, candidates) = {
-                    let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
-                                                       None, def_id, mir, mode);
-                    if mode == Mode::ConstFn {
-                        // Enforce a constant-like CFG for `const fn`.
-                        qualifier.qualify_const();
-                    } else {
-                        while let Some((bb, data)) = qualifier.rpo.next() {
-                            qualifier.visit_basic_block_data(bb, data);
-                        }
+            MirSource::Static(_, hir::MutImmutable) => Mode::Static,
+            MirSource::Static(_, hir::MutMutable) => Mode::StaticMut,
+            MirSource::Promoted(..) => return
+        };
+        let param_env = ty::ParameterEnvironment::for_item(tcx, id);
+
+        if mode == Mode::Fn || mode == Mode::ConstFn {
+            // This is ugly because Qualifier holds onto mir,
+            // which can't be mutated until its scope ends.
+            let (temps, candidates) = {
+                let mut qualifier = Qualifier::new(tcx, param_env,
+                                                   &mut self.qualif_map,
+                                                   def_id, mir, mode);
+                if mode == Mode::ConstFn {
+                    // Enforce a constant-like CFG for `const fn`.
+                    qualifier.qualify_const();
+                } else {
+                    while let Some((bb, data)) = qualifier.rpo.next() {
+                        qualifier.visit_basic_block_data(bb, data);
                     }
+                }
 
-                    (qualifier.temp_promotion_state,
-                     qualifier.promotion_candidates)
-                };
+                (qualifier.temp_promotion_state, qualifier.promotion_candidates)
+            };
 
-                // Do the actual promotion, now that we know what's viable.
-                promote_consts::promote_candidates(mir, tcx, temps, candidates);
-            } else {
-                let mut qualifier = Qualifier::new(tcx, param_env, &mut qualif_map,
-                                                   None, def_id, mir, mode);
-                qualifier.qualify_const();
-            }
+            // Do the actual promotion, now that we know what's viable.
+            promote_consts::promote_candidates(mir, tcx, temps, candidates);
+        } else {
+            let mut qualifier = Qualifier::new(tcx, param_env,
+                                               &mut self.qualif_map,
+                                               def_id, mir, mode);
+            let qualif = qualifier.qualify_const();
 
-            for hook in &mut *hooks {
-                hook.on_mir_pass(tcx, src, mir, self, true);
+            if mode == Mode::Const {
+                qualifier.qualif_map.insert(def_id, qualif);
             }
+        }
 
-            // Statics must be Sync.
-            if mode == Mode::Static {
-                let ty = mir.return_ty;
-                tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
-                    let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
-                    let mut fulfillment_cx = traits::FulfillmentContext::new();
-                    fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
-                    if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
-                        infcx.report_fulfillment_errors(&err);
-                    }
-                });
-            }
+        // Statics must be Sync.
+        if mode == Mode::Static {
+            let ty = mir.return_ty;
+            tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|infcx| {
+                let cause = traits::ObligationCause::new(mir.span, id, traits::SharedStatic);
+                let mut fulfillment_cx = traits::FulfillmentContext::new();
+                fulfillment_cx.register_builtin_bound(&infcx, ty, ty::BoundSync, cause);
+                if let Err(err) = fulfillment_cx.select_all_or_error(&infcx) {
+                    infcx.report_fulfillment_errors(&err);
+                }
+            });
         }
     }
 }
diff --git a/src/librustc_mir/transform/simplify_branches.rs b/src/librustc_mir/transform/simplify_branches.rs
index 407e2161610..8759a340d7e 100644
--- a/src/librustc_mir/transform/simplify_branches.rs
+++ b/src/librustc_mir/transform/simplify_branches.rs
@@ -13,7 +13,7 @@
 use rustc::ty::TyCtxt;
 use rustc::middle::const_val::ConstVal;
 use rustc::mir::transform::{MirPass, MirSource, Pass};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 
 use std::fmt;
 
diff --git a/src/librustc_mir/transform/simplify_cfg.rs b/src/librustc_mir/transform/simplify_cfg.rs
index ca8556496fa..1a8a5fa18cf 100644
--- a/src/librustc_mir/transform/simplify_cfg.rs
+++ b/src/librustc_mir/transform/simplify_cfg.rs
@@ -35,9 +35,8 @@
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc::ty::TyCtxt;
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::transform::{MirPass, MirSource, Pass};
-use rustc::mir::traversal;
 use std::fmt;
 
 pub struct SimplifyCfg<'a> { label: &'a str }
diff --git a/src/librustc_mir/transform/type_check.rs b/src/librustc_mir/transform/type_check.rs
index 7a682292429..9d3afe541cc 100644
--- a/src/librustc_mir/transform/type_check.rs
+++ b/src/librustc_mir/transform/type_check.rs
@@ -15,10 +15,10 @@ use rustc::infer::{self, InferCtxt, InferOk};
 use rustc::traits::{self, Reveal};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::{self, Ty, TyCtxt, TypeVariants};
-use rustc::mir::repr::*;
+use rustc::mir::*;
 use rustc::mir::tcx::LvalueTy;
 use rustc::mir::transform::{MirPass, MirSource, Pass};
-use rustc::mir::visit::{self, Visitor};
+use rustc::mir::visit::Visitor;
 use std::fmt;
 use syntax::ast;
 use syntax_pos::{Span, DUMMY_SP};
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index 5096a574e2b..828efbf3731 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -190,8 +190,16 @@ impl<'a> Visitor for AstValidator<'a> {
             }
             ItemKind::Trait(.., ref trait_items) => {
                 for trait_item in trait_items {
-                    if let TraitItemKind::Method(ref sig, _) = trait_item.node {
+                    if let TraitItemKind::Method(ref sig, ref block) = trait_item.node {
                         self.check_trait_fn_not_const(sig.constness);
+                        if block.is_none() {
+                            self.check_decl_no_pat(&sig.decl, |span, _| {
+                                self.session.add_lint(lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY,
+                                                      trait_item.id, span,
+                                                      "patterns aren't allowed in methods \
+                                                       without bodies".to_string());
+                            });
+                        }
                     }
                 }
             }
diff --git a/src/librustc_passes/consts.rs b/src/librustc_passes/consts.rs
index ee731dd042e..8ad4d7f57a6 100644
--- a/src/librustc_passes/consts.rs
+++ b/src/librustc_passes/consts.rs
@@ -565,9 +565,11 @@ fn check_expr<'a, 'tcx>(v: &mut CheckCrateVisitor<'a, 'tcx>, e: &hir::Expr, node
             }
         }
         hir::ExprStruct(..) => {
-            // unsafe_cell_type doesn't necessarily exist with no_core
-            if Some(v.tcx.expect_def(e.id).def_id()) == v.tcx.lang_items.unsafe_cell_type() {
-                v.add_qualif(ConstQualif::MUTABLE_MEM);
+            if let ty::TyAdt(adt, ..) = v.tcx.expr_ty(e).sty {
+                // unsafe_cell_type doesn't necessarily exist with no_core
+                if Some(adt.did) == v.tcx.lang_items.unsafe_cell_type() {
+                    v.add_qualif(ConstQualif::MUTABLE_MEM);
+                }
             }
         }
 
diff --git a/src/librustc_plugin/load.rs b/src/librustc_plugin/load.rs
index 669df3ad950..4438241999a 100644
--- a/src/librustc_plugin/load.rs
+++ b/src/librustc_plugin/load.rs
@@ -47,7 +47,7 @@ pub fn load_plugins(sess: &Session,
                     krate: &ast::Crate,
                     crate_name: &str,
                     addl_plugins: Option<Vec<String>>) -> Vec<PluginRegistrar> {
-    let mut loader = PluginLoader::new(sess, cstore, crate_name, krate.config.clone());
+    let mut loader = PluginLoader::new(sess, cstore, crate_name);
 
     // do not report any error now. since crate attributes are
     // not touched by expansion, every use of plugin without
@@ -89,14 +89,10 @@ pub fn load_plugins(sess: &Session,
 }
 
 impl<'a> PluginLoader<'a> {
-    fn new(sess: &'a Session,
-           cstore: &'a CStore,
-           crate_name: &str,
-           crate_config: ast::CrateConfig)
-            -> PluginLoader<'a> {
+    fn new(sess: &'a Session, cstore: &'a CStore, crate_name: &str) -> Self {
         PluginLoader {
             sess: sess,
-            reader: CrateLoader::new(sess, cstore, crate_name, crate_config),
+            reader: CrateLoader::new(sess, cstore, crate_name),
             plugins: vec![],
         }
     }
diff --git a/src/librustc_resolve/diagnostics.rs b/src/librustc_resolve/diagnostics.rs
index f2a5aedbb3a..1fb5db05dd5 100644
--- a/src/librustc_resolve/diagnostics.rs
+++ b/src/librustc_resolve/diagnostics.rs
@@ -860,31 +860,6 @@ match (A, B, C) {
 ```
 "##,
 
-E0422: r##"
-You are trying to use an identifier that is either undefined or not a struct.
-
-Erroneous code example:
-
-``` compile_fail,E0422
-fn main () {
-    let x = Foo { x: 1, y: 2 };
-}
-```
-
-In this case, `Foo` is undefined, so it inherently isn't anything, and
-definitely not a struct.
-
-```compile_fail,E0422
-fn main () {
-    let foo = 1;
-    let x = foo { x: 1, y: 2 };
-}
-```
-
-In this case, `foo` is defined, but is not a struct, so Rust can't use it as
-one.
-"##,
-
 E0423: r##"
 A `struct` variant name was used like a function name.
 
@@ -1503,6 +1478,7 @@ register_diagnostics! {
 //  E0419, merged into 531
 //  E0420, merged into 532
 //  E0421, merged into 531
+//  E0422, merged into 531/532
     E0531, // unresolved pattern path kind `name`
     E0532, // expected pattern path kind, found another pattern path kind
 //  E0427, merged into 530
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 856eb348eae..0b382fcbfdd 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -129,8 +129,6 @@ enum ResolutionError<'a> {
     IdentifierBoundMoreThanOnceInParameterList(&'a str),
     /// error E0416: identifier is bound more than once in the same pattern
     IdentifierBoundMoreThanOnceInSamePattern(&'a str),
-    /// error E0422: does not name a struct
-    DoesNotNameAStruct(&'a str),
     /// error E0423: is a struct variant name, but this expression uses it like a function name
     StructVariantUsedAsFunction(&'a str),
     /// error E0424: `self` is not available in a static method
@@ -336,15 +334,6 @@ fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
             err.span_label(span, &format!("used in a pattern more than once"));
             err
         }
-        ResolutionError::DoesNotNameAStruct(name) => {
-            let mut err = struct_span_err!(resolver.session,
-                             span,
-                             E0422,
-                             "`{}` does not name a structure",
-                             name);
-            err.span_label(span, &format!("not a structure"));
-            err
-        }
         ResolutionError::StructVariantUsedAsFunction(path_name) => {
             let mut err = struct_span_err!(resolver.session,
                              span,
@@ -1412,7 +1401,7 @@ impl<'a> Resolver<'a> {
 
                                 format!("Did you mean `{}{}`?", prefix, path_str)
                             }
-                            None => format!("Maybe a missing `extern crate {}`?", segment_name),
+                            None => format!("Maybe a missing `extern crate {};`?", segment_name),
                         }
                     } else {
                         format!("Could not find `{}` in `{}`", segment_name, module_name)
@@ -2383,6 +2372,18 @@ impl<'a> Resolver<'a> {
         self.record_def(pat_id, resolution);
     }
 
+    fn resolve_struct_path(&mut self, node_id: NodeId, path: &Path) {
+        // Resolution logic is equivalent for expressions and patterns,
+        // reuse `resolve_pattern_path` for both.
+        self.resolve_pattern_path(node_id, None, path, TypeNS, |def| {
+            match def {
+                Def::Struct(..) | Def::Union(..) | Def::Variant(..) |
+                Def::TyAlias(..) | Def::AssociatedTy(..) | Def::SelfTy(..) => true,
+                _ => false,
+            }
+        }, "struct, variant or union type");
+    }
+
     fn resolve_pattern(&mut self,
                        pat: &Pat,
                        pat_src: PatternSource,
@@ -2460,13 +2461,7 @@ impl<'a> Resolver<'a> {
                 }
 
                 PatKind::Struct(ref path, ..) => {
-                    self.resolve_pattern_path(pat.id, None, path, TypeNS, |def| {
-                        match def {
-                            Def::Struct(..) | Def::Union(..) | Def::Variant(..) |
-                            Def::TyAlias(..) | Def::AssociatedTy(..) => true,
-                            _ => false,
-                        }
-                    }, "variant, struct or type alias");
+                    self.resolve_struct_path(pat.id, path);
                 }
 
                 _ => {}
@@ -3024,23 +3019,7 @@ impl<'a> Resolver<'a> {
             }
 
             ExprKind::Struct(ref path, ..) => {
-                // Resolve the path to the structure it goes to. We don't
-                // check to ensure that the path is actually a structure; that
-                // is checked later during typeck.
-                match self.resolve_path(expr.id, path, 0, TypeNS) {
-                    Ok(definition) => self.record_def(expr.id, definition),
-                    Err(true) => self.record_def(expr.id, err_path_resolution()),
-                    Err(false) => {
-                        debug!("(resolving expression) didn't find struct def",);
-
-                        resolve_error(self,
-                                      path.span,
-                                      ResolutionError::DoesNotNameAStruct(
-                                                                &path_names_to_string(path, 0))
-                                     );
-                        self.record_def(expr.id, err_path_resolution());
-                    }
-                }
+                self.resolve_struct_path(expr.id, path);
 
                 visit::walk_expr(self, expr);
             }
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 1c60ccb9765..73d0e5e50c6 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -166,6 +166,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> {
                        loc.file.name,
                        loc.line);
             }
+            error!("    master span: {:?}: `{}`", path.span, self.span.snippet(path.span));
             return vec!();
         }
 
@@ -1493,7 +1494,8 @@ impl<'l, 'tcx: 'l, 'll, D: Dump +'ll> Visitor for DumpVisitor<'l, 'tcx, 'll, D>
                 Def::StructCtor(..) | Def::VariantCtor(..) |
                 Def::Const(..) | Def::AssociatedConst(..) |
                 Def::Struct(..) | Def::Variant(..) |
-                Def::TyAlias(..) | Def::AssociatedTy(..) => {
+                Def::TyAlias(..) | Def::AssociatedTy(..) |
+                Def::SelfTy(..) => {
                     paths_to_process.push((id, p.clone(), Some(ref_kind)))
                 }
                 def => error!("unexpected definition kind when processing collected paths: {:?}",
diff --git a/src/librustc_save_analysis/json_dumper.rs b/src/librustc_save_analysis/json_dumper.rs
index 0378d75cc6e..eb613c3afda 100644
--- a/src/librustc_save_analysis/json_dumper.rs
+++ b/src/librustc_save_analysis/json_dumper.rs
@@ -129,7 +129,7 @@ impl From<DefId> for Id {
 #[derive(Debug, RustcEncodable)]
 struct Import {
     kind: ImportKind,
-    id: Id,
+    ref_id: Option<Id>,
     span: SpanData,
     name: String,
     value: String,
@@ -146,7 +146,7 @@ impl From<ExternCrateData> for Import {
     fn from(data: ExternCrateData) -> Import {
         Import {
             kind: ImportKind::ExternCrate,
-            id: From::from(data.id),
+            ref_id: None,
             span: data.span,
             name: data.name,
             value: String::new(),
@@ -157,7 +157,7 @@ impl From<UseData> for Import {
     fn from(data: UseData) -> Import {
         Import {
             kind: ImportKind::Use,
-            id: From::from(data.id),
+            ref_id: data.mod_id.map(|id| From::from(id)),
             span: data.span,
             name: data.name,
             value: String::new(),
@@ -168,7 +168,7 @@ impl From<UseGlobData> for Import {
     fn from(data: UseGlobData) -> Import {
         Import {
             kind: ImportKind::GlobUse,
-            id: From::from(data.id),
+            ref_id: None,
             span: data.span,
             name: "*".to_owned(),
             value: data.names.join(", "),
diff --git a/src/librustc_trans/assert_module_sources.rs b/src/librustc_trans/assert_module_sources.rs
index 7fe6d2bbfe2..264ed4cd12f 100644
--- a/src/librustc_trans/assert_module_sources.rs
+++ b/src/librustc_trans/assert_module_sources.rs
@@ -134,7 +134,7 @@ impl<'a, 'tcx> AssertModuleSource<'a, 'tcx> {
     /// Scan for a `cfg="foo"` attribute and check whether we have a
     /// cfg flag called `foo`.
     fn check_config(&self, attr: &ast::Attribute) -> bool {
-        let config = &self.tcx.map.krate().config;
+        let config = &self.tcx.sess.parse_sess.config;
         let value = self.field(attr, CFG);
         debug!("check_config(config={:?}, value={:?})", config, value);
         if config.iter().any(|c| c.check_name(&value[..])) {
diff --git a/src/librustc_trans/back/symbol_names.rs b/src/librustc_trans/back/symbol_names.rs
index f0661e03bc8..bf2a5d76c10 100644
--- a/src/librustc_trans/back/symbol_names.rs
+++ b/src/librustc_trans/back/symbol_names.rs
@@ -99,7 +99,8 @@
 
 use common::SharedCrateContext;
 use monomorphize::Instance;
-use util::sha2::{Digest, Sha256};
+use rustc_data_structures::fmt_wrap::FmtWrap;
+use rustc_data_structures::blake2b::Blake2bHasher;
 
 use rustc::middle::weak_lang_items;
 use rustc::hir::def_id::LOCAL_CRATE;
@@ -113,21 +114,6 @@ use rustc::util::common::record_time;
 
 use syntax::attr;
 use syntax::parse::token::{self, InternedString};
-use serialize::hex::ToHex;
-
-use std::hash::Hasher;
-
-struct Sha256Hasher<'a>(&'a mut Sha256);
-
-impl<'a> Hasher for Sha256Hasher<'a> {
-    fn write(&mut self, msg: &[u8]) {
-        self.0.input(msg)
-    }
-
-    fn finish(&self) -> u64 {
-        bug!("Sha256Hasher::finish should not be called");
-    }
-}
 
 fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
 
@@ -149,12 +135,9 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
 
     let tcx = scx.tcx();
 
-    let mut hash_state = scx.symbol_hasher().borrow_mut();
-    record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
-        hash_state.reset();
-        let hasher = Sha256Hasher(&mut hash_state);
-        let mut hasher = ty::util::TypeIdHasher::new(tcx, hasher);
+    let mut hasher = ty::util::TypeIdHasher::new(tcx, Blake2bHasher::new(8, &[]));
 
+    record_time(&tcx.sess.perf_stats.symbol_hash_time, || {
         // the main symbol name is not necessarily unique; hash in the
         // compiler's internal def-path, guaranteeing each symbol has a
         // truly unique path
@@ -175,8 +158,9 @@ fn get_symbol_hash<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
     });
 
     // 64 bits should be enough to avoid collisions.
-    let output = hash_state.result_bytes();
-    format!("h{}", output[..8].to_hex())
+    let mut hasher = hasher.into_inner();
+    let hash_bytes = hasher.finalize();
+    format!("h{:x}", FmtWrap(hash_bytes))
 }
 
 impl<'a, 'tcx> Instance<'tcx> {
diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs
index d4d4f883e7b..977ababbf56 100644
--- a/src/librustc_trans/base.rs
+++ b/src/librustc_trans/base.rs
@@ -35,6 +35,7 @@ use back::link;
 use back::linker::LinkerInfo;
 use llvm::{Linkage, ValueRef, Vector, get_param};
 use llvm;
+use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
 use middle::lang_items::{LangItem, ExchangeMallocFnLangItem, StartFnLangItem};
 use rustc::ty::subst::Substs;
@@ -44,7 +45,6 @@ use rustc::ty::adjustment::CustomCoerceUnsized;
 use rustc::dep_graph::{DepNode, WorkProduct};
 use rustc::hir::map as hir_map;
 use rustc::util::common::time;
-use rustc::mir::mir_map::MirMap;
 use session::config::{self, NoDebugInfo};
 use rustc_incremental::IncrementalHashesMap;
 use session::Session;
@@ -79,7 +79,6 @@ use type_::Type;
 use type_of;
 use value::Value;
 use Disr;
-use util::sha2::Sha256;
 use util::nodemap::{NodeSet, FnvHashMap, FnvHashSet};
 
 use arena::TypedArena;
@@ -866,7 +865,7 @@ impl<'blk, 'tcx> FunctionContext<'blk, 'tcx> {
             false
         };
 
-        let mir = def_id.and_then(|id| ccx.get_mir(id));
+        let mir = def_id.map(|id| ccx.tcx().item_mir(id));
 
         let debug_context = if let (false, Some((instance, sig, abi)), &Some(ref mir)) =
                 (no_debug, definition, &mir) {
@@ -1278,8 +1277,7 @@ fn write_metadata(cx: &SharedCrateContext,
     let metadata = cstore.encode_metadata(cx.tcx(),
                                           cx.export_map(),
                                           cx.link_meta(),
-                                          reachable_ids,
-                                          cx.mir_map());
+                                          reachable_ids);
     if kind == MetadataKind::Uncompressed {
         return metadata;
     }
@@ -1527,7 +1525,6 @@ pub fn filter_reachable_ids(tcx: TyCtxt, reachable: NodeSet) -> NodeSet {
 }
 
 pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                             mir_map: &MirMap<'tcx>,
                              analysis: ty::CrateAnalysis,
                              incremental_hashes_map: &IncrementalHashesMap)
                              -> CrateTranslation {
@@ -1551,9 +1548,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     let link_meta = link::build_link_meta(incremental_hashes_map, name);
 
     let shared_ccx = SharedCrateContext::new(tcx,
-                                             &mir_map,
                                              export_map,
-                                             Sha256::new(),
                                              link_meta.clone(),
                                              reachable,
                                              check_overflow);
@@ -1716,8 +1711,21 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // `reachable_symbols` list later on so it should be ok.
     for cnum in sess.cstore.crates() {
         let syms = sess.cstore.reachable_ids(cnum);
-        reachable_symbols.extend(syms.into_iter().filter(|did| {
-            sess.cstore.is_extern_item(shared_ccx.tcx(), *did)
+        reachable_symbols.extend(syms.into_iter().filter(|&def_id| {
+            let applicable = match sess.cstore.describe_def(def_id) {
+                Some(Def::Static(..)) => true,
+                Some(Def::Fn(_)) => {
+                    shared_ccx.tcx().lookup_generics(def_id).types.is_empty()
+                }
+                _ => false
+            };
+
+            if applicable {
+                let attrs = shared_ccx.tcx().get_attrs(def_id);
+                attr::contains_extern_indicator(sess.diagnostic(), &attrs)
+            } else {
+                false
+            }
         }).map(|did| {
             symbol_for_def_id(did, &shared_ccx, &symbol_map)
         }));
diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs
index 8a7919d01f5..8348da9f7b7 100644
--- a/src/librustc_trans/collector.rs
+++ b/src/librustc_trans/collector.rs
@@ -198,15 +198,13 @@ use rustc::traits;
 use rustc::ty::subst::{Substs, Subst};
 use rustc::ty::{self, TypeFoldable, TyCtxt};
 use rustc::ty::adjustment::CustomCoerceUnsized;
-use rustc::mir::repr as mir;
+use rustc::mir::{self, Location};
 use rustc::mir::visit as mir_visit;
 use rustc::mir::visit::Visitor as MirVisitor;
-use rustc::mir::repr::Location;
 
 use rustc_const_eval as const_eval;
 
 use syntax::abi::Abi;
-use errors;
 use syntax_pos::DUMMY_SP;
 use base::custom_coerce_unsize_info;
 use context::SharedCrateContext;
@@ -347,8 +345,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
 
             // Scan the MIR in order to find function calls, closures, and
             // drop-glue
-            let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
-                || format!("Could not find MIR for static: {:?}", def_id));
+            let mir = scx.tcx().item_mir(def_id);
 
             let empty_substs = scx.empty_substs_for_def_id(def_id);
             let visitor = MirNeighborCollector {
@@ -368,8 +365,7 @@ fn collect_items_rec<'a, 'tcx: 'a>(scx: &SharedCrateContext<'a, 'tcx>,
 
             // Scan the MIR in order to find function calls, closures, and
             // drop-glue
-            let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(instance.def),
-                || format!("Could not find MIR for function: {}", instance));
+            let mir = scx.tcx().item_mir(instance.def);
 
             let visitor = MirNeighborCollector {
                 scx: scx,
@@ -452,11 +448,7 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> {
         match *rvalue {
             mir::Rvalue::Aggregate(mir::AggregateKind::Closure(def_id,
                                                                ref substs), _) => {
-                let mir = errors::expect(self.scx.sess().diagnostic(),
-                                         self.scx.get_mir(def_id),
-                                         || {
-                    format!("Could not find MIR for closure: {:?}", def_id)
-                });
+                let mir = self.scx.tcx().item_mir(def_id);
 
                 let concrete_substs = monomorphize::apply_param_substs(self.scx,
                                                                        self.param_substs,
@@ -1249,8 +1241,7 @@ fn collect_const_item_neighbours<'a, 'tcx>(scx: &SharedCrateContext<'a, 'tcx>,
 {
     // Scan the MIR in order to find function calls, closures, and
     // drop-glue
-    let mir = errors::expect(scx.sess().diagnostic(), scx.get_mir(def_id),
-        || format!("Could not find MIR for const: {:?}", def_id));
+    let mir = scx.tcx().item_mir(def_id);
 
     let visitor = MirNeighborCollector {
         scx: scx,
diff --git a/src/librustc_trans/common.rs b/src/librustc_trans/common.rs
index e1223221262..464b261b08e 100644
--- a/src/librustc_trans/common.rs
+++ b/src/librustc_trans/common.rs
@@ -19,6 +19,7 @@ use llvm::{True, False, Bool, OperandBundleDef};
 use rustc::hir::def::Def;
 use rustc::hir::def_id::DefId;
 use rustc::infer::TransNormalize;
+use rustc::mir::Mir;
 use rustc::util::common::MemoizationMap;
 use middle::lang_items::LangItem;
 use rustc::ty::subst::Substs;
@@ -32,7 +33,6 @@ use consts;
 use debuginfo::{self, DebugLoc};
 use declare;
 use machine;
-use mir::CachedMir;
 use monomorphize;
 use type_::Type;
 use value::Value;
@@ -46,7 +46,7 @@ use arena::TypedArena;
 use libc::{c_uint, c_char};
 use std::ops::Deref;
 use std::ffi::CString;
-use std::cell::{Cell, RefCell};
+use std::cell::{Cell, RefCell, Ref};
 
 use syntax::ast;
 use syntax::parse::token::InternedString;
@@ -250,10 +250,8 @@ pub fn validate_substs(substs: &Substs) {
 // Function context.  Every LLVM function we create will have one of
 // these.
 pub struct FunctionContext<'a, 'tcx: 'a> {
-    // The MIR for this function. At present, this is optional because
-    // we only have MIR available for things that are local to the
-    // crate.
-    pub mir: Option<CachedMir<'a, 'tcx>>,
+    // The MIR for this function.
+    pub mir: Option<Ref<'tcx, Mir<'tcx>>>,
 
     // The ValueRef returned from a call to llvm::LLVMAddFunction; the
     // address of the first instruction in the sequence of
@@ -313,8 +311,8 @@ pub struct FunctionContext<'a, 'tcx: 'a> {
 }
 
 impl<'a, 'tcx> FunctionContext<'a, 'tcx> {
-    pub fn mir(&self) -> CachedMir<'a, 'tcx> {
-        self.mir.clone().expect("fcx.mir was empty")
+    pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
+        self.mir.as_ref().map(Ref::clone).expect("fcx.mir was empty")
     }
 
     pub fn cleanup(&self) {
@@ -490,7 +488,7 @@ impl<'blk, 'tcx> BlockS<'blk, 'tcx> {
         self.set_lpad_ref(lpad.map(|p| &*self.fcx().lpad_arena.alloc(p)))
     }
 
-    pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
+    pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
         self.fcx.mir()
     }
 
@@ -609,7 +607,7 @@ impl<'blk, 'tcx> BlockAndBuilder<'blk, 'tcx> {
         self.bcx.llbb
     }
 
-    pub fn mir(&self) -> CachedMir<'blk, 'tcx> {
+    pub fn mir(&self) -> Ref<'tcx, Mir<'tcx>> {
         self.bcx.mir()
     }
 
diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs
index 2a72d42296d..fc75b1018ec 100644
--- a/src/librustc_trans/context.rs
+++ b/src/librustc_trans/context.rs
@@ -15,15 +15,12 @@ use middle::cstore::LinkMeta;
 use rustc::hir::def::ExportMap;
 use rustc::hir::def_id::DefId;
 use rustc::traits;
-use rustc::mir::mir_map::MirMap;
-use rustc::mir::repr as mir;
 use base;
 use builder::Builder;
 use common::BuilderRef_res;
 use debuginfo;
 use declare;
 use glue::DropGlueKind;
-use mir::CachedMir;
 use monomorphize::Instance;
 
 use partitioning::CodegenUnit;
@@ -35,7 +32,6 @@ use session::config::NoDebugInfo;
 use session::Session;
 use session::config;
 use symbol_map::SymbolMap;
-use util::sha2::Sha256;
 use util::nodemap::{NodeSet, DefIdMap, FnvHashMap, FnvHashSet};
 
 use std::ffi::{CStr, CString};
@@ -72,12 +68,9 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
     export_map: ExportMap,
     reachable: NodeSet,
     link_meta: LinkMeta,
-    symbol_hasher: RefCell<Sha256>,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     stats: Stats,
     check_overflow: bool,
-    mir_map: &'a MirMap<'tcx>,
-    mir_cache: RefCell<DepTrackingMap<MirCache<'tcx>>>,
 
     use_dll_storage_attrs: bool,
 
@@ -184,19 +177,6 @@ impl<'tcx> DepTrackingMapConfig for TraitSelectionCache<'tcx> {
     }
 }
 
-// Cache for mir loaded from metadata
-struct MirCache<'tcx> {
-    data: PhantomData<&'tcx ()>
-}
-
-impl<'tcx> DepTrackingMapConfig for MirCache<'tcx> {
-    type Key = DefId;
-    type Value = Rc<mir::Mir<'tcx>>;
-    fn to_dep_node(key: &DefId) -> DepNode<DefId> {
-        DepNode::Mir(*key)
-    }
-}
-
 // # Global Cache
 
 pub struct ProjectionCache<'gcx> {
@@ -453,9 +433,7 @@ unsafe fn create_context_and_module(sess: &Session, mod_name: &str) -> (ContextR
 
 impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
     pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
-               mir_map: &'b MirMap<'tcx>,
                export_map: ExportMap,
-               symbol_hasher: Sha256,
                link_meta: LinkMeta,
                reachable: NodeSet,
                check_overflow: bool)
@@ -515,10 +493,7 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
             export_map: export_map,
             reachable: reachable,
             link_meta: link_meta,
-            symbol_hasher: RefCell::new(symbol_hasher),
             tcx: tcx,
-            mir_map: mir_map,
-            mir_cache: RefCell::new(DepTrackingMap::new(tcx.dep_graph.clone())),
             stats: Stats {
                 n_glues_created: Cell::new(0),
                 n_null_glues: Cell::new(0),
@@ -582,23 +557,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
         self.use_dll_storage_attrs
     }
 
-    pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
-        if def_id.is_local() {
-            self.mir_map.map.get(&def_id).map(CachedMir::Ref)
-        } else {
-            if let Some(mir) = self.mir_cache.borrow().get(&def_id).cloned() {
-                return Some(CachedMir::Owned(mir));
-            }
-
-            let mir = self.sess().cstore.maybe_get_item_mir(self.tcx, def_id);
-            let cached = mir.map(Rc::new);
-            if let Some(ref mir) = cached {
-                self.mir_cache.borrow_mut().insert(def_id, mir.clone());
-            }
-            cached.map(CachedMir::Owned)
-        }
-    }
-
     pub fn translation_items(&self) -> &RefCell<FnvHashSet<TransItem<'tcx>>> {
         &self.translation_items
     }
@@ -613,14 +571,6 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
         })
     }
 
-    pub fn symbol_hasher(&self) -> &RefCell<Sha256> {
-        &self.symbol_hasher
-    }
-
-    pub fn mir_map(&self) -> &MirMap<'tcx> {
-        &self.mir_map
-    }
-
     pub fn metadata_symbol_name(&self) -> String {
         format!("rust_metadata_{}_{}",
                 self.link_meta().crate_name,
@@ -919,10 +869,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         &self.local().llsizingtypes
     }
 
-    pub fn symbol_hasher<'a>(&'a self) -> &'a RefCell<Sha256> {
-        &self.shared.symbol_hasher
-    }
-
     pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<FnvHashMap<Ty<'tcx>, String>> {
         &self.local().type_hashcodes
     }
@@ -1008,10 +954,6 @@ impl<'b, 'tcx> CrateContext<'b, 'tcx> {
         self.shared.use_dll_storage_attrs()
     }
 
-    pub fn get_mir(&self, def_id: DefId) -> Option<CachedMir<'b, 'tcx>> {
-        self.shared.get_mir(def_id)
-    }
-
     pub fn symbol_map(&self) -> &SymbolMap<'tcx> {
         &*self.local().symbol_map
     }
diff --git a/src/librustc_trans/debuginfo/create_scope_map.rs b/src/librustc_trans/debuginfo/create_scope_map.rs
index 1d7e4991aa8..e0c1a80be39 100644
--- a/src/librustc_trans/debuginfo/create_scope_map.rs
+++ b/src/librustc_trans/debuginfo/create_scope_map.rs
@@ -15,7 +15,7 @@ use super::utils::{DIB, span_start};
 use llvm;
 use llvm::debuginfo::{DIScope, DISubprogram};
 use common::{CrateContext, FunctionContext};
-use rustc::mir::repr::{Mir, VisibilityScope};
+use rustc::mir::{Mir, VisibilityScope};
 
 use libc::c_uint;
 use std::ptr;
@@ -45,7 +45,7 @@ impl MirDebugScope {
 /// Produce DIScope DIEs for each MIR Scope which has variables defined in it.
 /// If debuginfo is disabled, the returned vector is empty.
 pub fn create_mir_scopes(fcx: &FunctionContext) -> IndexVec<VisibilityScope, MirDebugScope> {
-    let mir = fcx.mir.clone().expect("create_mir_scopes: missing MIR for fn");
+    let mir = fcx.mir();
     let null_scope = MirDebugScope {
         scope_metadata: ptr::null_mut(),
         file_start_pos: BytePos(0),
diff --git a/src/librustc_trans/debuginfo/metadata.rs b/src/librustc_trans/debuginfo/metadata.rs
index 2804e3ffe37..863aecc8244 100644
--- a/src/librustc_trans/debuginfo/metadata.rs
+++ b/src/librustc_trans/debuginfo/metadata.rs
@@ -30,7 +30,7 @@ use rustc::ty::fold::TypeVisitor;
 use rustc::ty::subst::Substs;
 use rustc::ty::util::TypeIdHasher;
 use rustc::hir;
-use rustc_data_structures::blake2b;
+use rustc_data_structures::blake2b::Blake2bHasher;
 use {type_of, machine, monomorphize};
 use common::CrateContext;
 use type_::Type;
@@ -149,10 +149,16 @@ impl<'tcx> TypeMap<'tcx> {
             None => { /* generate one */}
         };
 
+        // The hasher we are using to generate the UniqueTypeId. We want
+        // something that provides more than the 64 bits of the DefaultHasher.
+        const TYPE_ID_HASH_LENGTH: usize = 20;
+
         let mut type_id_hasher = TypeIdHasher::new(cx.tcx(),
-                                                   DebugInfoTypeIdHasher::new());
+                                                   Blake2bHasher::new(TYPE_ID_HASH_LENGTH, &[]));
         type_id_hasher.visit_ty(type_);
-        let hash = type_id_hasher.into_inner().into_hash();
+        let mut hash_state = type_id_hasher.into_inner();
+        let hash: &[u8] = hash_state.finalize();
+        debug_assert!(hash.len() == TYPE_ID_HASH_LENGTH);
 
         let mut unique_type_id = String::with_capacity(TYPE_ID_HASH_LENGTH * 2);
 
@@ -164,39 +170,6 @@ impl<'tcx> TypeMap<'tcx> {
         self.type_to_unique_id.insert(type_, UniqueTypeId(key));
 
         return UniqueTypeId(key);
-
-        // The hasher we are using to generate the UniqueTypeId. We want
-        // something that provides more than the 64 bits of the DefaultHasher.
-        const TYPE_ID_HASH_LENGTH: usize = 20;
-
-        struct DebugInfoTypeIdHasher {
-            state: blake2b::Blake2bCtx
-        }
-
-        impl ::std::hash::Hasher for DebugInfoTypeIdHasher {
-            fn finish(&self) -> u64 {
-                unimplemented!()
-            }
-
-            #[inline]
-            fn write(&mut self, bytes: &[u8]) {
-                blake2b::blake2b_update(&mut self.state, bytes);
-            }
-        }
-
-        impl DebugInfoTypeIdHasher {
-            fn new() -> DebugInfoTypeIdHasher {
-                DebugInfoTypeIdHasher {
-                    state: blake2b::blake2b_new(TYPE_ID_HASH_LENGTH, &[])
-                }
-            }
-
-            fn into_hash(self) -> [u8; TYPE_ID_HASH_LENGTH] {
-                let mut hash = [0u8; TYPE_ID_HASH_LENGTH];
-                blake2b::blake2b_final(self.state, &mut hash);
-                hash
-            }
-        }
     }
 
     // Get the UniqueTypeId for an enum variant. Enum variants are not really
diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs
index 813915bfd6e..3bc5f4f3dbc 100644
--- a/src/librustc_trans/debuginfo/mod.rs
+++ b/src/librustc_trans/debuginfo/mod.rs
@@ -32,7 +32,7 @@ use abi::Abi;
 use common::{CrateContext, FunctionContext, Block, BlockAndBuilder};
 use monomorphize::{self, Instance};
 use rustc::ty::{self, Ty};
-use rustc::mir::repr as mir;
+use rustc::mir;
 use session::config::{self, FullDebugInfo, LimitedDebugInfo, NoDebugInfo};
 use util::nodemap::{DefIdMap, FnvHashMap, FnvHashSet};
 
diff --git a/src/librustc_trans/lib.rs b/src/librustc_trans/lib.rs
index 81c0c184f66..07acc54962b 100644
--- a/src/librustc_trans/lib.rs
+++ b/src/librustc_trans/lib.rs
@@ -25,6 +25,7 @@
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
+#![feature(cell_extras)]
 #![feature(const_fn)]
 #![feature(custom_attribute)]
 #![feature(dotdot_in_tuple_patterns)]
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs
index 455cf4eb455..a934da12b9e 100644
--- a/src/librustc_trans/mir/analyze.rs
+++ b/src/librustc_trans/mir/analyze.rs
@@ -13,9 +13,7 @@
 
 use rustc_data_structures::bitvec::BitVector;
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
-use rustc::mir::repr as mir;
-use rustc::mir::repr::TerminatorKind;
-use rustc::mir::repr::Location;
+use rustc::mir::{self, Location, TerminatorKind};
 use rustc::mir::visit::{Visitor, LvalueContext};
 use rustc::mir::traversal;
 use common::{self, Block, BlockAndBuilder};
diff --git a/src/librustc_trans/mir/block.rs b/src/librustc_trans/mir/block.rs
index d60dc3fe843..8bf27b4babf 100644
--- a/src/librustc_trans/mir/block.rs
+++ b/src/librustc_trans/mir/block.rs
@@ -12,7 +12,7 @@ use llvm::{self, ValueRef};
 use rustc_const_eval::{ErrKind, ConstEvalErr, note_const_eval_err};
 use rustc::middle::lang_items;
 use rustc::ty;
-use rustc::mir::repr as mir;
+use rustc::mir;
 use abi::{Abi, FnType, ArgType};
 use adt;
 use base;
@@ -37,13 +37,14 @@ use super::analyze::CleanupKind;
 use super::constant::Const;
 use super::lvalue::{LvalueRef};
 use super::operand::OperandRef;
-use super::operand::OperandValue::*;
+use super::operand::OperandValue::{Pair, Ref, Immediate};
+
+use std::cell::Ref as CellRef;
 
 impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
     pub fn trans_block(&mut self, bb: mir::BasicBlock) {
         let mut bcx = self.bcx(bb);
-        let mir = self.mir.clone();
-        let data = &mir[bb];
+        let data = &CellRef::clone(&self.mir)[bb];
 
         debug!("trans_block({:?}={:?})", bb, data);
 
@@ -228,7 +229,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> {
             }
 
             mir::TerminatorKind::Drop { ref location, target, unwind } => {
-                let ty = location.ty(&mir, bcx.tcx()).to_ty(bcx.tcx());
+                let ty = location.ty(&self.mir, bcx.tcx()).to_ty(bcx.tcx());
                 let ty = bcx.monomorphize(&ty);
 
                 // Double check for necessity to drop
diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs
index 3e7d8acf610..3d0d8897609 100644
--- a/src/librustc_trans/mir/constant.rs
+++ b/src/librustc_trans/mir/constant.rs
@@ -16,7 +16,7 @@ use rustc_const_math::ConstFloat::*;
 use rustc_const_math::{ConstInt, ConstIsize, ConstUsize, ConstMathErr};
 use rustc::hir::def_id::DefId;
 use rustc::infer::TransNormalize;
-use rustc::mir::repr as mir;
+use rustc::mir;
 use rustc::mir::tcx::LvalueTy;
 use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable};
@@ -261,9 +261,7 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> {
             }
         }
 
-        let mir = ccx.get_mir(instance.def).unwrap_or_else(|| {
-            bug!("missing constant MIR for {}", instance)
-        });
+        let mir = ccx.tcx().item_mir(instance.def);
         MirConstContext::new(ccx, &mir, instance.substs, args).trans()
     }
 
diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs
index 8e65eac2e80..d28c466e230 100644
--- a/src/librustc_trans/mir/lvalue.rs
+++ b/src/librustc_trans/mir/lvalue.rs
@@ -10,7 +10,7 @@
 
 use llvm::ValueRef;
 use rustc::ty::{self, Ty, TypeFoldable};
-use rustc::mir::repr as mir;
+use rustc::mir;
 use rustc::mir::tcx::LvalueTy;
 use rustc_data_structures::indexed_vec::Idx;
 use adt;
diff --git a/src/librustc_trans/mir/mod.rs b/src/librustc_trans/mir/mod.rs
index b0c7d26c47e..d2adf88c916 100644
--- a/src/librustc_trans/mir/mod.rs
+++ b/src/librustc_trans/mir/mod.rs
@@ -11,7 +11,7 @@
 use libc::c_uint;
 use llvm::{self, ValueRef};
 use rustc::ty;
-use rustc::mir::repr as mir;
+use rustc::mir;
 use rustc::mir::tcx::LvalueTy;
 use session::config::FullDebugInfo;
 use base;
@@ -23,8 +23,7 @@ use type_of;
 use syntax_pos::{DUMMY_SP, NO_EXPANSION, COMMAND_LINE_EXPN, BytePos};
 use syntax::parse::token::keywords;
 
-use std::ops::Deref;
-use std::rc::Rc;
+use std::cell::Ref;
 use std::iter;
 
 use basic_block::BasicBlock;
@@ -39,25 +38,9 @@ use rustc::mir::traversal;
 
 use self::operand::{OperandRef, OperandValue};
 
-#[derive(Clone)]
-pub enum CachedMir<'mir, 'tcx: 'mir> {
-    Ref(&'mir mir::Mir<'tcx>),
-    Owned(Rc<mir::Mir<'tcx>>)
-}
-
-impl<'mir, 'tcx: 'mir> Deref for CachedMir<'mir, 'tcx> {
-    type Target = mir::Mir<'tcx>;
-    fn deref(&self) -> &mir::Mir<'tcx> {
-        match *self {
-            CachedMir::Ref(r) => r,
-            CachedMir::Owned(ref rc) => rc
-        }
-    }
-}
-
 /// Master context for translating MIR.
 pub struct MirContext<'bcx, 'tcx:'bcx> {
-    mir: CachedMir<'bcx, 'tcx>,
+    mir: Ref<'tcx, mir::Mir<'tcx>>,
 
     /// Function context
     fcx: &'bcx common::FunctionContext<'bcx, 'tcx>,
@@ -223,7 +206,7 @@ pub fn trans_mir<'blk, 'tcx: 'blk>(fcx: &'blk FunctionContext<'blk, 'tcx>) {
     let scopes = debuginfo::create_mir_scopes(fcx);
 
     let mut mircx = MirContext {
-        mir: mir.clone(),
+        mir: Ref::clone(&mir),
         fcx: fcx,
         llpersonalityslot: None,
         blocks: block_bcxs,
diff --git a/src/librustc_trans/mir/operand.rs b/src/librustc_trans/mir/operand.rs
index c9d83a33752..62eda56e2e1 100644
--- a/src/librustc_trans/mir/operand.rs
+++ b/src/librustc_trans/mir/operand.rs
@@ -10,7 +10,7 @@
 
 use llvm::ValueRef;
 use rustc::ty::Ty;
-use rustc::mir::repr as mir;
+use rustc::mir;
 use rustc_data_structures::indexed_vec::Idx;
 
 use base;
diff --git a/src/librustc_trans/mir/rvalue.rs b/src/librustc_trans/mir/rvalue.rs
index b6172fa2a90..f25877b1de1 100644
--- a/src/librustc_trans/mir/rvalue.rs
+++ b/src/librustc_trans/mir/rvalue.rs
@@ -12,7 +12,7 @@ use llvm::{self, ValueRef};
 use rustc::ty::{self, Ty};
 use rustc::ty::cast::{CastTy, IntTy};
 use rustc::ty::layout::Layout;
-use rustc::mir::repr as mir;
+use rustc::mir;
 
 use asm;
 use base;
diff --git a/src/librustc_trans/mir/statement.rs b/src/librustc_trans/mir/statement.rs
index 3d6aad37ed5..296a0e8049e 100644
--- a/src/librustc_trans/mir/statement.rs
+++ b/src/librustc_trans/mir/statement.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::mir::repr as mir;
+use rustc::mir;
 
 use base;
 use common::{self, BlockAndBuilder};
diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs
index ab2a3986433..270ce79620f 100644
--- a/src/librustc_trans/monomorphize.rs
+++ b/src/librustc_trans/monomorphize.rs
@@ -26,7 +26,7 @@ pub struct Instance<'tcx> {
 
 impl<'tcx> fmt::Display for Instance<'tcx> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        ppaux::parameterized(f, &self.substs, self.def, ppaux::Ns::Value, &[])
+        ppaux::parameterized(f, &self.substs, self.def, &[])
     }
 }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index c137fca58af..8799050b1b9 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -1484,7 +1484,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                       def: Def,
                       opt_self_ty: Option<Ty<'tcx>>,
                       base_path_ref_id: ast::NodeId,
-                      base_segments: &[hir::PathSegment])
+                      base_segments: &[hir::PathSegment],
+                      permit_variants: bool)
                       -> Ty<'tcx> {
         let tcx = self.tcx();
 
@@ -1515,6 +1516,16 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                                     did,
                                     base_segments.last().unwrap())
             }
+            Def::Variant(did) if permit_variants => {
+                // Convert "variant type" as if it were a real type.
+                // The resulting `Ty` is type of the variant's enum for now.
+                tcx.prohibit_type_params(base_segments.split_last().unwrap().1);
+                self.ast_path_to_ty(rscope,
+                                    span,
+                                    param_mode,
+                                    tcx.parent_def_id(did).unwrap(),
+                                    base_segments.last().unwrap())
+            }
             Def::TyParam(did) => {
                 tcx.prohibit_type_params(base_segments);
 
@@ -1604,7 +1615,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                                       opt_self_ty: Option<Ty<'tcx>>,
                                       base_path_ref_id: ast::NodeId,
                                       base_segments: &[hir::PathSegment],
-                                      assoc_segments: &[hir::PathSegment])
+                                      assoc_segments: &[hir::PathSegment],
+                                      permit_variants: bool)
                                       -> (Ty<'tcx>, Def) {
         // Convert the base type.
         debug!("finish_resolving_def_to_ty(base_def={:?}, \
@@ -1619,7 +1631,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                                           base_def,
                                           opt_self_ty,
                                           base_path_ref_id,
-                                          base_segments);
+                                          base_segments,
+                                          permit_variants);
         debug!("finish_resolving_def_to_ty: base_def_to_ty returned {:?}", base_ty);
 
         // If any associated type segments remain, attempt to resolve them.
@@ -1775,7 +1788,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
                                                                 opt_self_ty,
                                                                 ast_ty.id,
                                                                 &path.segments[..base_ty_end],
-                                                                &path.segments[base_ty_end..]);
+                                                                &path.segments[base_ty_end..],
+                                                                false);
 
                 // Write back the new resolution.
                 if path_res.depth != 0 {
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index d3fef0711b2..c842514227c 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -489,8 +489,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                         expected: Ty<'tcx>) -> Ty<'tcx>
     {
         // Resolve the path and check the definition for errors.
-        let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(path, pat.id,
-                                                                                 pat.span) {
+        let (variant, pat_ty) = if let Some(variant_ty) = self.check_struct_path(path, pat.id) {
             variant_ty
         } else {
             for field in fields {
diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs
index 5be77cb12e9..ccc944813ff 100644
--- a/src/librustc_typeck/check/coercion.rs
+++ b/src/librustc_typeck/check/coercion.rs
@@ -196,6 +196,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
                 // Function items are coercible to any closure
                 // type; function pointers are not (that would
                 // require double indirection).
+                // Additionally, we permit coercion of function
+                // items to drop the unsafe qualifier.
                 self.coerce_from_fn_item(a, a_f, b)
             }
             ty::TyFnPtr(a_f) => {
@@ -504,6 +506,24 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
         Ok((target, AdjustDerefRef(adjustment)))
     }
 
+    fn coerce_from_safe_fn(&self,
+                           a: Ty<'tcx>,
+                           fn_ty_a: &'tcx ty::BareFnTy<'tcx>,
+                           b: Ty<'tcx>)
+                           -> CoerceResult<'tcx> {
+        if let ty::TyFnPtr(fn_ty_b) = b.sty {
+            match (fn_ty_a.unsafety, fn_ty_b.unsafety) {
+                (hir::Unsafety::Normal, hir::Unsafety::Unsafe) => {
+                    let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
+                    return self.unify_and_identity(unsafe_a, b)
+                        .map(|(ty, _)| (ty, AdjustUnsafeFnPointer));
+                }
+                _ => {}
+            }
+        }
+        self.unify_and_identity(a, b)
+    }
+
     fn coerce_from_fn_pointer(&self,
                               a: Ty<'tcx>,
                               fn_ty_a: &'tcx ty::BareFnTy<'tcx>,
@@ -516,17 +536,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
         let b = self.shallow_resolve(b);
         debug!("coerce_from_fn_pointer(a={:?}, b={:?})", a, b);
 
-        if let ty::TyFnPtr(fn_ty_b) = b.sty {
-            match (fn_ty_a.unsafety, fn_ty_b.unsafety) {
-                (hir::Unsafety::Normal, hir::Unsafety::Unsafe) => {
-                    let unsafe_a = self.tcx.safe_to_unsafe_fn_ty(fn_ty_a);
-                    return self.unify_and_identity(unsafe_a, b)
-                        .map(|(ty, _)| (ty, AdjustUnsafeFnPointer));
-                }
-                _ => {}
-            }
-        }
-        self.unify_and_identity(a, b)
+        self.coerce_from_safe_fn(a, fn_ty_a, b)
     }
 
     fn coerce_from_fn_item(&self,
@@ -544,7 +554,8 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
         match b.sty {
             ty::TyFnPtr(_) => {
                 let a_fn_pointer = self.tcx.mk_fn_ptr(fn_ty_a);
-                self.unify_and_identity(a_fn_pointer, b).map(|(ty, _)| (ty, AdjustReifyFnPointer))
+                self.coerce_from_safe_fn(a_fn_pointer, fn_ty_a, b)
+                    .map(|(ty, _)| (ty, AdjustReifyFnPointer))
             }
             _ => self.unify_and_identity(a, b),
         }
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 21da8cd388c..75a14bb3db9 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1686,41 +1686,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                        cause)
     }
 
-    /// Instantiates the type in `did` with the generics in `path` and returns
-    /// it (registering the necessary trait obligations along the way).
-    ///
-    /// Note that this function is only intended to be used with type-paths,
-    /// not with value-paths.
-    pub fn instantiate_type_path(&self,
-                                 did: DefId,
-                                 path: &hir::Path,
-                                 node_id: ast::NodeId)
-                                 -> Ty<'tcx> {
-        debug!("instantiate_type_path(did={:?}, path={:?})", did, path);
-        let mut ty = self.tcx.lookup_item_type(did).ty;
-        if ty.is_fn() {
-            // Tuple variants have fn type even in type namespace, extract true variant type from it
-            ty = self.tcx.no_late_bound_regions(&ty.fn_ret()).unwrap();
-        }
-        let type_predicates = self.tcx.lookup_predicates(did);
-        let substs = AstConv::ast_path_substs_for_ty(self, self,
-                                                     path.span,
-                                                     PathParamMode::Optional,
-                                                     did,
-                                                     path.segments.last().unwrap());
-        debug!("instantiate_type_path: ty={:?} substs={:?}", ty, substs);
-        let bounds = self.instantiate_bounds(path.span, substs, &type_predicates);
-        let cause = traits::ObligationCause::new(path.span, self.body_id,
-                                                 traits::ItemObligation(did));
-        self.add_obligations_for_parameters(cause, &bounds);
-
-        let ty_substituted = self.instantiate_type_scheme(path.span, substs, &ty);
-        self.write_substs(node_id, ty::ItemSubsts {
-            substs: substs
-        });
-        ty_substituted
-    }
-
     pub fn write_nil(&self, node_id: ast::NodeId) {
         self.write_ty(node_id, self.tcx.mk_nil());
     }
@@ -3251,47 +3216,55 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
     }
 
     pub fn check_struct_path(&self,
-                         path: &hir::Path,
-                         node_id: ast::NodeId,
-                         span: Span)
-                         -> Option<(ty::VariantDef<'tcx>,  Ty<'tcx>)> {
-        let def = self.finish_resolving_struct_path(path, node_id, span);
+                             path: &hir::Path,
+                             node_id: ast::NodeId)
+                             -> Option<(ty::VariantDef<'tcx>,  Ty<'tcx>)> {
+        let (def, ty) = self.finish_resolving_struct_path(path, node_id);
         let variant = match def {
             Def::Err => {
                 self.set_tainted_by_errors();
                 return None;
             }
-            Def::Variant(did) => {
-                let type_did = self.tcx.parent_def_id(did).unwrap();
-                Some((type_did, self.tcx.expect_variant_def(def)))
-            }
-            Def::Struct(type_did) | Def::Union(type_did) => {
-                Some((type_did, self.tcx.expect_variant_def(def)))
+            Def::Variant(..) => {
+                match ty.sty {
+                    ty::TyAdt(adt, substs) => {
+                        Some((adt.variant_of_def(def), adt.did, substs))
+                    }
+                    _ => bug!("unexpected type: {:?}", ty.sty)
+                }
             }
-            Def::TyAlias(did) | Def::AssociatedTy(did) => {
-                match self.tcx.opt_lookup_item_type(did).map(|scheme| &scheme.ty.sty) {
-                    Some(&ty::TyAdt(adt, _)) if !adt.is_enum() => {
-                        Some((did, adt.struct_variant()))
+            Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) |
+            Def::AssociatedTy(..) | Def::SelfTy(..) => {
+                match ty.sty {
+                    ty::TyAdt(adt, substs) if !adt.is_enum() => {
+                        Some((adt.struct_variant(), adt.did, substs))
                     }
                     _ => None,
                 }
             }
-            _ => None
+            _ => bug!("unexpected definition: {:?}", def)
         };
 
-        if let Some((def_id, variant)) = variant {
+        if let Some((variant, did, substs)) = variant {
             if variant.ctor_kind == CtorKind::Fn &&
                     !self.tcx.sess.features.borrow().relaxed_adts {
                 emit_feature_err(&self.tcx.sess.parse_sess,
-                                 "relaxed_adts", span, GateIssue::Language,
+                                 "relaxed_adts", path.span, GateIssue::Language,
                                  "tuple structs and variants in struct patterns are unstable");
             }
-            let ty = self.instantiate_type_path(def_id, path, node_id);
+
+            // Check bounds on type arguments used in the path.
+            let type_predicates = self.tcx.lookup_predicates(did);
+            let bounds = self.instantiate_bounds(path.span, substs, &type_predicates);
+            let cause = traits::ObligationCause::new(path.span, self.body_id,
+                                                     traits::ItemObligation(did));
+            self.add_obligations_for_parameters(cause, &bounds);
+
             Some((variant, ty))
         } else {
             struct_span_err!(self.tcx.sess, path.span, E0071,
-                             "`{}` does not name a struct or a struct variant",
-                             pprust::path_to_string(path))
+                             "expected struct, variant or union type, found {}",
+                             ty.sort_string(self.tcx))
                 .span_label(path.span, &format!("not a struct"))
                 .emit();
             None
@@ -3305,12 +3278,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                          base_expr: &'gcx Option<P<hir::Expr>>) -> Ty<'tcx>
     {
         // Find the relevant variant
-        let (variant, struct_ty) = if let Some(variant_ty) = self.check_struct_path(path, expr.id,
-                                                                                    expr.span) {
+        let (variant, struct_ty) = if let Some(variant_ty) = self.check_struct_path(path, expr.id) {
             variant_ty
         } else {
             self.check_struct_fields_on_error(fields, base_expr);
-            return self.tcx().types.err;
+            return self.tcx.types.err;
         };
 
         self.check_expr_struct_fields(struct_ty, path.span, variant, fields,
@@ -3805,7 +3777,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                               }
                           }
                           err.emit();
-                          self.tcx().types.err
+                          self.tcx.types.err
                       }
                   }
               }
@@ -3815,29 +3787,26 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
 
     // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary.
     // The newly resolved definition is written into `def_map`.
-    pub fn finish_resolving_struct_path(&self,
-                                        path: &hir::Path,
-                                        node_id: ast::NodeId,
-                                        span: Span)
-                                        -> Def
+    fn finish_resolving_struct_path(&self,
+                                    path: &hir::Path,
+                                    node_id: ast::NodeId)
+                                    -> (Def, Ty<'tcx>)
     {
-        let path_res = self.tcx().expect_resolution(node_id);
-        if path_res.depth == 0 {
-            // If fully resolved already, we don't have to do anything.
-            path_res.base_def
-        } else {
-            let base_ty_end = path.segments.len() - path_res.depth;
-            let (_ty, def) = AstConv::finish_resolving_def_to_ty(self, self, span,
-                                                                 PathParamMode::Optional,
-                                                                 path_res.base_def,
-                                                                 None,
-                                                                 node_id,
-                                                                 &path.segments[..base_ty_end],
-                                                                 &path.segments[base_ty_end..]);
-            // Write back the new resolution.
-            self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def));
-            def
+        let path_res = self.tcx.expect_resolution(node_id);
+        let base_ty_end = path.segments.len() - path_res.depth;
+        let (ty, def) = AstConv::finish_resolving_def_to_ty(self, self, path.span,
+                                                            PathParamMode::Optional,
+                                                            path_res.base_def,
+                                                            None,
+                                                            node_id,
+                                                            &path.segments[..base_ty_end],
+                                                            &path.segments[base_ty_end..],
+                                                            true);
+        // Write back the new resolution.
+        if path_res.depth != 0 {
+            self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def));
         }
+        (def, ty)
     }
 
     // Resolve associated value path into a base type and associated constant or method definition.
@@ -3849,7 +3818,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                        span: Span)
                                        -> (Def, Option<Ty<'tcx>>, &'b [hir::PathSegment])
     {
-        let path_res = self.tcx().expect_resolution(node_id);
+        let path_res = self.tcx.expect_resolution(node_id);
         if path_res.depth == 0 {
             // If fully resolved already, we don't have to do anything.
             (path_res.base_def, opt_self_ty, &path.segments)
@@ -3863,7 +3832,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                                                                  opt_self_ty,
                                                                  node_id,
                                                                  &ty_segments[..base_ty_end],
-                                                                 &ty_segments[base_ty_end..]);
+                                                                 &ty_segments[base_ty_end..],
+                                                                 false);
 
             // Resolve an associated constant or method on the previously resolved type.
             let item_segment = path.segments.last().unwrap();
@@ -3883,7 +3853,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
             };
 
             // Write back the new resolution.
-            self.tcx().def_map.borrow_mut().insert(node_id, PathResolution::new(def));
+            self.tcx.def_map.borrow_mut().insert(node_id, PathResolution::new(def));
             (def, Some(ty), slice::ref_slice(item_segment))
         }
     }
@@ -4308,7 +4278,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
         // the referenced item.
         let ty_substituted = self.instantiate_type_scheme(span, &substs, &scheme.ty);
 
-
         if let Some((ty::ImplContainer(impl_def_id), self_ty)) = ufcs_associated {
             // In the case of `Foo<T>::method` and `<Foo<T>>::method`, if `method`
             // is inherent, there is no `Self` parameter, instead, the impl needs
diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs
index 189f8490f6c..7dd850180d4 100644
--- a/src/librustc_typeck/diagnostics.rs
+++ b/src/librustc_typeck/diagnostics.rs
@@ -895,17 +895,14 @@ fn some_func(x: &mut i32) {
 
 E0071: r##"
 You tried to use structure-literal syntax to create an item that is
-not a struct-style structure or enum variant.
+not a structure or enum variant.
 
 Example of erroneous code:
 
 ```compile_fail,E0071
-enum Foo { FirstValue(i32) };
-
-let u = Foo::FirstValue { value: 0 }; // error: Foo::FirstValue
-                                         // isn't a structure!
-// or even simpler, if the name doesn't refer to a structure at all.
-let t = u32 { value: 4 }; // error: `u32` does not name a structure.
+type U32 = u32;
+let t = U32 { value: 4 }; // error: expected struct, variant or union type,
+                          // found builtin type `u32`
 ```
 
 To fix this, ensure that the name was correctly spelled, and that
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 208819a4a0b..5ce75810006 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -163,14 +163,16 @@ pub fn run_core(search_paths: SearchPaths,
     let dep_graph = DepGraph::new(false);
     let _ignore = dep_graph.in_ignore();
     let cstore = Rc::new(CStore::new(&dep_graph));
-    let sess = session::build_session_(sessopts, &dep_graph, cpath, diagnostic_handler,
-                                       codemap, cstore.clone());
+    let mut sess = session::build_session_(
+        sessopts, &dep_graph, cpath, diagnostic_handler, codemap, cstore.clone()
+    );
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let mut cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs));
     target_features::add_configuration(&mut cfg, &sess);
+    sess.parse_sess.config = cfg;
 
-    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
+    let krate = panictry!(driver::phase_1_parse_input(&sess, &input));
 
     let name = link::find_crate_name(Some(&sess), &krate.attrs, &input);
 
@@ -189,7 +191,7 @@ pub fn run_core(search_paths: SearchPaths,
                                                      resolutions,
                                                      &arenas,
                                                      &name,
-                                                     |tcx, _, analysis, _, result| {
+                                                     |tcx, analysis, _, result| {
         if let Err(_) = result {
             sess.fatal("Compilation failed, aborting rustdoc");
         }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index d1d2b14806f..45c3d413500 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -73,24 +73,20 @@ pub fn run(input: &str,
     };
 
     let codemap = Rc::new(CodeMap::new());
-    let diagnostic_handler = errors::Handler::with_tty_emitter(ColorConfig::Auto,
-                                                               true,
-                                                               false,
-                                                               Some(codemap.clone()));
+    let handler =
+        errors::Handler::with_tty_emitter(ColorConfig::Auto, true, false, Some(codemap.clone()));
 
     let dep_graph = DepGraph::new(false);
     let _ignore = dep_graph.in_ignore();
     let cstore = Rc::new(CStore::new(&dep_graph));
-    let sess = session::build_session_(sessopts,
-                                       &dep_graph,
-                                       Some(input_path.clone()),
-                                       diagnostic_handler,
-                                       codemap,
-                                       cstore.clone());
+    let mut sess = session::build_session_(
+        sessopts, &dep_graph, Some(input_path.clone()), handler, codemap, cstore.clone(),
+    );
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
+    sess.parse_sess.config =
+        config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
 
-    let cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
-    let krate = panictry!(driver::phase_1_parse_input(&sess, cfg, &input));
+    let krate = panictry!(driver::phase_1_parse_input(&sess, &input));
     let driver::ExpansionResult { defs, mut hir_forest, .. } = {
         phase_2_configure_and_expand(
             &sess, &cstore, krate, None, "rustdoc-test", None, MakeGlobMap::No, |_| Ok(())
@@ -236,18 +232,16 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
 
     let dep_graph = DepGraph::new(false);
     let cstore = Rc::new(CStore::new(&dep_graph));
-    let sess = session::build_session_(sessopts,
-                                       &dep_graph,
-                                       None,
-                                       diagnostic_handler,
-                                       codemap,
-                                       cstore.clone());
+    let mut sess = session::build_session_(
+        sessopts, &dep_graph, None, diagnostic_handler, codemap, cstore.clone(),
+    );
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
 
     let outdir = Mutex::new(TempDir::new("rustdoctest").ok().expect("rustdoc needs a tempdir"));
     let libdir = sess.target_filesearch(PathKind::All).get_lib_path();
     let mut control = driver::CompileController::basic();
-    let cfg = config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
+    sess.parse_sess.config =
+        config::build_configuration(&sess, config::parse_cfgspecs(cfgs.clone()));
     let out = Some(outdir.lock().unwrap().path().to_path_buf());
 
     if no_run {
@@ -255,9 +249,7 @@ fn runtest(test: &str, cratename: &str, cfgs: Vec<String>, libs: SearchPaths,
     }
 
     let res = panic::catch_unwind(AssertUnwindSafe(|| {
-        driver::compile_input(&sess, &cstore, cfg.clone(),
-                              &input, &out,
-                              &None, None, &control)
+        driver::compile_input(&sess, &cstore, &input, &out, &None, None, &control)
     }));
 
     match res {
diff --git a/src/libstd/build.rs b/src/libstd/build.rs
index c811ed3bded..72cd6e4830b 100644
--- a/src/libstd/build.rs
+++ b/src/libstd/build.rs
@@ -58,6 +58,8 @@ fn main() {
         println!("cargo:rustc-link-lib=ws2_32");
         println!("cargo:rustc-link-lib=userenv");
         println!("cargo:rustc-link-lib=shell32");
+    } else if target.contains("fuchsia") {
+        println!("cargo:rustc-link-lib=magenta");
     }
 }
 
diff --git a/src/libstd/io/impls.rs b/src/libstd/io/impls.rs
index cd05e6b5de9..6b26c016638 100644
--- a/src/libstd/io/impls.rs
+++ b/src/libstd/io/impls.rs
@@ -147,6 +147,10 @@ impl<B: BufRead + ?Sized> BufRead for Box<B> {
 // =============================================================================
 // In-memory buffer implementations
 
+/// Read is implemented for `&[u8]` by copying from the slice.
+///
+/// Note that reading updates the slice to point to the yet unread part.
+/// The slice will be empty when EOF is reached.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Read for &'a [u8] {
     #[inline]
@@ -180,6 +184,11 @@ impl<'a> BufRead for &'a [u8] {
     fn consume(&mut self, amt: usize) { *self = &self[amt..]; }
 }
 
+/// Write is implemented for `&mut [u8]` by copying into the slice, overwriting
+/// its data.
+///
+/// Note that writing updates the slice to point to the yet unwritten part.
+/// The slice will be empty when it has been completely overwritten.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a> Write for &'a mut [u8] {
     #[inline]
@@ -204,6 +213,8 @@ impl<'a> Write for &'a mut [u8] {
     fn flush(&mut self) -> io::Result<()> { Ok(()) }
 }
 
+/// Write is implemented for `Vec<u8>` by appending to the vector.
+/// The vector will grow as needed.
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Write for Vec<u8> {
     #[inline]
diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs
index d801fa028cc..0ce6b0a9431 100644
--- a/src/libstd/macros.rs
+++ b/src/libstd/macros.rs
@@ -286,7 +286,7 @@ pub mod builtin {
     /// // fn concat_idents!(new, fun, name) { } // not usable in this way!
     /// # }
     /// ```
-    #[unstable(feature = "concat_idents", issue = "29599")]
+    #[unstable(feature = "concat_idents_macro", issue = "29599")]
     #[macro_export]
     macro_rules! concat_idents {
         ($($e:ident),*) => ({ /* compiler built-in */ })
diff --git a/src/libstd/os/raw.rs b/src/libstd/os/raw.rs
index 6c5c1b90a4a..2a918d8aeb7 100644
--- a/src/libstd/os/raw.rs
+++ b/src/libstd/os/raw.rs
@@ -18,7 +18,8 @@
                                        target_arch = "arm",
                                        target_arch = "powerpc",
                                        target_arch = "powerpc64",
-                                       target_arch = "s390x"))))]
+                                       target_arch = "s390x")),
+          all(target_os = "fuchsia", target_arch = "aarch64")))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
 #[cfg(not(any(target_os = "android",
               target_os = "emscripten",
@@ -26,7 +27,8 @@
                                            target_arch = "arm",
                                            target_arch = "powerpc",
                                            target_arch = "powerpc64",
-                                           target_arch = "s390x")))))]
+                                           target_arch = "s390x")),
+              all(target_os = "fuchsia", target_arch = "aarch64"))))]
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
 #[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8;
diff --git a/src/libstd/sys/unix/rand.rs b/src/libstd/sys/unix/rand.rs
index f28a6ad3375..3aebb8c18ec 100644
--- a/src/libstd/sys/unix/rand.rs
+++ b/src/libstd/sys/unix/rand.rs
@@ -27,7 +27,8 @@ fn next_u64(mut fill_buf: &mut FnMut(&mut [u8])) -> u64 {
 #[cfg(all(unix,
           not(target_os = "ios"),
           not(target_os = "openbsd"),
-          not(target_os = "freebsd")))]
+          not(target_os = "freebsd"),
+          not(target_os = "fuchsia")))]
 mod imp {
     use self::OsRngInner::*;
     use super::{next_u32, next_u64};
@@ -339,3 +340,54 @@ mod imp {
         }
     }
 }
+
+#[cfg(target_os = "fuchsia")]
+mod imp {
+    use super::{next_u32, next_u64};
+
+    use io;
+    use rand::Rng;
+
+    #[link(name = "magenta")]
+    extern {
+        fn mx_cprng_draw(buffer: *mut u8, len: usize) -> isize;
+    }
+
+    fn getrandom(buf: &mut [u8]) -> isize {
+        unsafe { mx_cprng_draw(buf.as_mut_ptr(), buf.len()) }
+    }
+
+    pub struct OsRng {
+        // dummy field to ensure that this struct cannot be constructed outside
+        // of this module
+        _dummy: (),
+    }
+
+    impl OsRng {
+        /// Create a new `OsRng`.
+        pub fn new() -> io::Result<OsRng> {
+            Ok(OsRng { _dummy: () })
+        }
+    }
+
+    impl Rng for OsRng {
+        fn next_u32(&mut self) -> u32 {
+            next_u32(&mut |v| self.fill_bytes(v))
+        }
+        fn next_u64(&mut self) -> u64 {
+            next_u64(&mut |v| self.fill_bytes(v))
+        }
+        fn fill_bytes(&mut self, v: &mut [u8]) {
+            let mut buf = v;
+            while !buf.is_empty() {
+                let ret = getrandom(buf);
+                if ret < 0 {
+                    panic!("kernel mx_cprng_draw call failed! (returned {}, buf.len() {})",
+                        ret, buf.len());
+                }
+                let move_buf = buf;
+                buf = &mut move_buf[(ret as usize)..];
+            }
+        }
+    }
+}
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 37e306de325..8864694c932 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -477,7 +477,6 @@ pub type CrateConfig = Vec<P<MetaItem>>;
 pub struct Crate {
     pub module: Mod,
     pub attrs: Vec<Attribute>,
-    pub config: CrateConfig,
     pub span: Span,
     pub exported_macros: Vec<MacroDef>,
 }
diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs
index dc02c26039c..0335f210347 100644
--- a/src/libsyntax/attr.rs
+++ b/src/libsyntax/attr.rs
@@ -501,10 +501,7 @@ pub fn requests_inline(attrs: &[Attribute]) -> bool {
 }
 
 /// Tests if a cfg-pattern matches the cfg set
-pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem,
-                   sess: &ParseSess,
-                   features: Option<&Features>)
-                   -> bool {
+pub fn cfg_matches(cfg: &ast::MetaItem, sess: &ParseSess, features: Option<&Features>) -> bool {
     match cfg.node {
         ast::MetaItemKind::List(ref pred, ref mis) => {
             for mi in mis.iter() {
@@ -518,10 +515,10 @@ pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem,
             // that they won't fail with the loop above.
             match &pred[..] {
                 "any" => mis.iter().any(|mi| {
-                    cfg_matches(cfgs, mi.meta_item().unwrap(), sess, features)
+                    cfg_matches(mi.meta_item().unwrap(), sess, features)
                 }),
                 "all" => mis.iter().all(|mi| {
-                    cfg_matches(cfgs, mi.meta_item().unwrap(), sess, features)
+                    cfg_matches(mi.meta_item().unwrap(), sess, features)
                 }),
                 "not" => {
                     if mis.len() != 1 {
@@ -529,7 +526,7 @@ pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem,
                         return false;
                     }
 
-                    !cfg_matches(cfgs, mis[0].meta_item().unwrap(), sess, features)
+                    !cfg_matches(mis[0].meta_item().unwrap(), sess, features)
                 },
                 p => {
                     span_err!(sess.span_diagnostic, cfg.span, E0537, "invalid predicate `{}`", p);
@@ -541,7 +538,7 @@ pub fn cfg_matches(cfgs: &[P<MetaItem>], cfg: &ast::MetaItem,
             if let (Some(feats), Some(gated_cfg)) = (features, GatedCfg::gate(cfg)) {
                 gated_cfg.check_and_emit(sess, feats);
             }
-            contains(cfgs, cfg)
+            contains(&sess.config, cfg)
         }
     }
 }
diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs
index 01f81e5e2de..946257a16d5 100644
--- a/src/libsyntax/config.rs
+++ b/src/libsyntax/config.rs
@@ -20,7 +20,6 @@ use util::small_vector::SmallVector;
 
 /// A folder that strips out items that do not belong in the current configuration.
 pub struct StripUnconfigured<'a> {
-    pub config: &'a ast::CrateConfig,
     pub should_test: bool,
     pub sess: &'a ParseSess,
     pub features: Option<&'a Features>,
@@ -32,7 +31,6 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, should_test: bool)
     let features;
     {
         let mut strip_unconfigured = StripUnconfigured {
-            config: &krate.config.clone(),
             should_test: should_test,
             sess: sess,
             features: None,
@@ -107,7 +105,7 @@ impl<'a> StripUnconfigured<'a> {
         use attr::cfg_matches;
         match (cfg.meta_item(), mi.meta_item()) {
             (Some(cfg), Some(mi)) =>
-                if cfg_matches(self.config, &cfg, self.sess, self.features) {
+                if cfg_matches(&cfg, self.sess, self.features) {
                     self.process_cfg_attr(respan(mi.span, ast::Attribute_ {
                         id: attr::mk_attr_id(),
                         style: attr.node.style,
@@ -148,7 +146,7 @@ impl<'a> StripUnconfigured<'a> {
                 return true;
             }
 
-            attr::cfg_matches(self.config, mis[0].meta_item().unwrap(), self.sess, self.features)
+            attr::cfg_matches(mis[0].meta_item().unwrap(), self.sess, self.features)
         })
     }
 
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index c404c6d1162..cc097ab0efa 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -574,7 +574,6 @@ pub struct ExpansionData {
 /// -> expn_info of their expansion context stored into their span.
 pub struct ExtCtxt<'a> {
     pub parse_sess: &'a parse::ParseSess,
-    pub cfg: ast::CrateConfig,
     pub ecfg: expand::ExpansionConfig<'a>,
     pub crate_root: Option<&'static str>,
     pub resolver: &'a mut Resolver,
@@ -583,13 +582,12 @@ pub struct ExtCtxt<'a> {
 }
 
 impl<'a> ExtCtxt<'a> {
-    pub fn new(parse_sess: &'a parse::ParseSess, cfg: ast::CrateConfig,
+    pub fn new(parse_sess: &'a parse::ParseSess,
                ecfg: expand::ExpansionConfig<'a>,
                resolver: &'a mut Resolver)
                -> ExtCtxt<'a> {
         ExtCtxt {
             parse_sess: parse_sess,
-            cfg: cfg,
             ecfg: ecfg,
             crate_root: None,
             resolver: resolver,
@@ -617,11 +615,11 @@ impl<'a> ExtCtxt<'a> {
 
     pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree])
         -> parser::Parser<'a> {
-        parse::tts_to_parser(self.parse_sess, tts.to_vec(), self.cfg().clone())
+        parse::tts_to_parser(self.parse_sess, tts.to_vec())
     }
     pub fn codemap(&self) -> &'a CodeMap { self.parse_sess.codemap() }
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
-    pub fn cfg(&self) -> &ast::CrateConfig { &self.cfg }
+    pub fn cfg(&self) -> &ast::CrateConfig { &self.parse_sess.config }
     pub fn call_site(&self) -> Span {
         self.codemap().with_expn_info(self.backtrace(), |ei| match ei {
             Some(expn_info) => expn_info.call_site,
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index e84a9208029..e3b23e239f9 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -293,11 +293,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
     }
 
     fn collect_invocations(&mut self, expansion: Expansion) -> (Expansion, Vec<Invocation>) {
-        let crate_config = mem::replace(&mut self.cx.cfg, Vec::new());
         let result = {
             let mut collector = InvocationCollector {
                 cfg: StripUnconfigured {
-                    config: &crate_config,
                     should_test: self.cx.ecfg.should_test,
                     sess: self.cx.parse_sess,
                     features: self.cx.ecfg.features,
@@ -308,7 +306,6 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
             };
             (expansion.fold_with(&mut collector), collector.invocations)
         };
-        self.cx.cfg = crate_config;
 
         if self.monotonic {
             let err_count = self.cx.parse_sess.span_diagnostic.err_count();
@@ -646,7 +643,7 @@ fn string_to_tts(text: String, parse_sess: &ParseSess) -> Vec<TokenTree> {
                             .new_filemap(String::from("<macro expansion>"), None, text);
 
     let lexer = lexer::StringReader::new(&parse_sess.span_diagnostic, filemap);
-    let mut parser = Parser::new(parse_sess, Vec::new(), Box::new(lexer));
+    let mut parser = Parser::new(parse_sess, Box::new(lexer));
     panictry!(parser.parse_all_token_trees())
 }
 
diff --git a/src/libsyntax/ext/quote.rs b/src/libsyntax/ext/quote.rs
index 7f002d28166..f3497c130bf 100644
--- a/src/libsyntax/ext/quote.rs
+++ b/src/libsyntax/ext/quote.rs
@@ -331,7 +331,6 @@ pub mod rt {
             panictry!(parse::parse_item_from_source_str(
                 "<quote expansion>".to_string(),
                 s,
-                self.cfg().clone(),
                 self.parse_sess())).expect("parse error")
         }
 
@@ -339,7 +338,6 @@ pub mod rt {
             panictry!(parse::parse_stmt_from_source_str(
                 "<quote expansion>".to_string(),
                 s,
-                self.cfg().clone(),
                 self.parse_sess())).expect("parse error")
         }
 
@@ -347,7 +345,6 @@ pub mod rt {
             panictry!(parse::parse_expr_from_source_str(
                 "<quote expansion>".to_string(),
                 s,
-                self.cfg().clone(),
                 self.parse_sess()))
         }
 
@@ -355,7 +352,6 @@ pub mod rt {
             panictry!(parse::parse_tts_from_source_str(
                 "<quote expansion>".to_string(),
                 s,
-                self.cfg().clone(),
                 self.parse_sess()))
         }
     }
@@ -920,14 +916,6 @@ fn expand_parse_call(cx: &ExtCtxt,
                      tts: &[TokenTree]) -> P<ast::Expr> {
     let (cx_expr, tts_expr) = expand_tts(cx, sp, tts);
 
-    let cfg_call = || cx.expr_method_call(
-        sp, cx.expr_ident(sp, id_ext("ext_cx")),
-        id_ext("cfg"), Vec::new());
-
-    let cfg_clone_call = || cx.expr_method_call(
-        sp, cfg_call(),
-        id_ext("clone"), Vec::new());
-
     let parse_sess_call = || cx.expr_method_call(
         sp, cx.expr_ident(sp, id_ext("ext_cx")),
         id_ext("parse_sess"), Vec::new());
@@ -935,7 +923,7 @@ fn expand_parse_call(cx: &ExtCtxt,
     let new_parser_call =
         cx.expr_call(sp,
                      cx.expr_ident(sp, id_ext("new_parser_from_tts")),
-                     vec!(parse_sess_call(), cfg_clone_call(), tts_expr));
+                     vec!(parse_sess_call(), tts_expr));
 
     let path = vec![id_ext("syntax"), id_ext("ext"), id_ext("quote"), id_ext(parse_method)];
     let mut args = vec![cx.expr_mut_addr_of(sp, new_parser_call)];
diff --git a/src/libsyntax/ext/source_util.rs b/src/libsyntax/ext/source_util.rs
index 30dc1823b37..ec48cae3f76 100644
--- a/src/libsyntax/ext/source_util.rs
+++ b/src/libsyntax/ext/source_util.rs
@@ -92,15 +92,8 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt, sp: Span, tts: &[tokenstream::T
         None => return DummyResult::expr(sp),
     };
     // The file will be added to the code map by the parser
-    let p =
-        parse::new_sub_parser_from_file(cx.parse_sess(),
-                                        cx.cfg().clone(),
-                                        &res_rel_file(cx,
-                                                      sp,
-                                                      Path::new(&file)),
-                                        true,
-                                        None,
-                                        sp);
+    let path = res_rel_file(cx, sp, Path::new(&file));
+    let p = parse::new_sub_parser_from_file(cx.parse_sess(), &path, true, None, sp);
 
     struct ExpandResult<'a> {
         p: parse::parser::Parser<'a>,
diff --git a/src/libsyntax/ext/tt/macro_parser.rs b/src/libsyntax/ext/tt/macro_parser.rs
index 74def68b185..7e3fe328569 100644
--- a/src/libsyntax/ext/tt/macro_parser.rs
+++ b/src/libsyntax/ext/tt/macro_parser.rs
@@ -78,7 +78,6 @@ pub use self::NamedMatch::*;
 pub use self::ParseResult::*;
 use self::TokenTreeOrTokenTreeVec::*;
 
-use ast;
 use ast::Ident;
 use syntax_pos::{self, BytePos, mk_sp, Span};
 use codemap::Spanned;
@@ -92,6 +91,7 @@ use parse::token;
 use print::pprust;
 use ptr::P;
 use tokenstream::{self, TokenTree};
+use util::small_vector::SmallVector;
 
 use std::mem;
 use std::rc::Rc;
@@ -104,7 +104,7 @@ use std::collections::hash_map::Entry::{Vacant, Occupied};
 #[derive(Clone)]
 enum TokenTreeOrTokenTreeVec {
     Tt(tokenstream::TokenTree),
-    TtSeq(Rc<Vec<tokenstream::TokenTree>>),
+    TtSeq(Vec<tokenstream::TokenTree>),
 }
 
 impl TokenTreeOrTokenTreeVec {
@@ -161,7 +161,7 @@ pub fn count_names(ms: &[TokenTree]) -> usize {
     })
 }
 
-pub fn initial_matcher_pos(ms: Rc<Vec<TokenTree>>, sep: Option<Token>, lo: BytePos)
+pub fn initial_matcher_pos(ms: Vec<TokenTree>, sep: Option<Token>, lo: BytePos)
                            -> Box<MatcherPos> {
     let match_idx_hi = count_names(&ms[..]);
     let matches: Vec<_> = (0..match_idx_hi).map(|_| Vec::new()).collect();
@@ -279,17 +279,10 @@ pub fn token_name_eq(t1 : &Token, t2 : &Token) -> bool {
     }
 }
 
-pub fn parse(sess: &ParseSess,
-             cfg: &ast::CrateConfig,
-             mut rdr: TtReader,
-             ms: &[TokenTree])
-             -> NamedParseResult {
-    let mut cur_eis = Vec::new();
-    cur_eis.push(initial_matcher_pos(Rc::new(ms.iter()
-                                                .cloned()
-                                                .collect()),
-                                     None,
-                                     rdr.peek().sp.lo));
+pub fn parse(sess: &ParseSess, mut rdr: TtReader, ms: &[TokenTree]) -> NamedParseResult {
+    let mut cur_eis = SmallVector::one(initial_matcher_pos(ms.to_owned(),
+                                                           None,
+                                                           rdr.peek().sp.lo));
 
     loop {
         let mut bb_eis = Vec::new(); // black-box parsed by parser.rs
@@ -484,7 +477,7 @@ pub fn parse(sess: &ParseSess,
                 rdr.next_token();
             } else /* bb_eis.len() == 1 */ {
                 rdr.next_tok = {
-                    let mut rust_parser = Parser::new(sess, cfg.clone(), Box::new(&mut rdr));
+                    let mut rust_parser = Parser::new(sess, Box::new(&mut rdr));
                     let mut ei = bb_eis.pop().unwrap();
                     if let TokenTree::Token(span, MatchNt(_, ident)) = ei.top_elts.get_tt(ei.idx) {
                         let match_cur = ei.match_cur;
diff --git a/src/libsyntax/ext/tt/macro_rules.rs b/src/libsyntax/ext/tt/macro_rules.rs
index ceca698f479..431e757368c 100644
--- a/src/libsyntax/ext/tt/macro_rules.rs
+++ b/src/libsyntax/ext/tt/macro_rules.rs
@@ -115,7 +115,7 @@ fn generic_extension<'cx>(cx: &'cx ExtCtxt,
                 // rhs has holes ( `$id` and `$(...)` that need filled)
                 let trncbr =
                     new_tt_reader(&cx.parse_sess.span_diagnostic, Some(named_matches), rhs);
-                let mut p = Parser::new(cx.parse_sess(), cx.cfg().clone(), Box::new(trncbr));
+                let mut p = Parser::new(cx.parse_sess(), Box::new(trncbr));
                 p.directory = cx.current_expansion.module.directory.clone();
                 p.restrictions = match cx.current_expansion.no_noninline_mod {
                     true => Restrictions::NO_NONINLINE_MOD,
@@ -220,7 +220,7 @@ pub fn compile(sess: &ParseSess, def: &ast::MacroDef) -> SyntaxExtension {
     // Parse the macro_rules! invocation (`none` is for no interpolations):
     let arg_reader = new_tt_reader(&sess.span_diagnostic, None, def.body.clone());
 
-    let argument_map = match parse(sess, &Vec::new(), arg_reader, &argument_gram) {
+    let argument_map = match parse(sess, arg_reader, &argument_gram) {
         Success(m) => m,
         Failure(sp, tok) => {
             let s = parse_failure_msg(tok);
diff --git a/src/libsyntax/ext/tt/transcribe.rs b/src/libsyntax/ext/tt/transcribe.rs
index 38a926b6e87..8a6a8e53a3e 100644
--- a/src/libsyntax/ext/tt/transcribe.rs
+++ b/src/libsyntax/ext/tt/transcribe.rs
@@ -10,14 +10,15 @@
 use self::LockstepIterSize::*;
 
 use ast::Ident;
-use syntax_pos::{Span, DUMMY_SP};
 use errors::{Handler, DiagnosticBuilder};
 use ext::tt::macro_parser::{NamedMatch, MatchedSeq, MatchedNonterminal};
 use parse::token::{DocComment, MatchNt, SubstNt};
 use parse::token::{Token, Interpolated, NtIdent, NtTT};
 use parse::token;
 use parse::lexer::TokenAndSpan;
+use syntax_pos::{Span, DUMMY_SP};
 use tokenstream::{self, TokenTree};
+use util::small_vector::SmallVector;
 
 use std::rc::Rc;
 use std::ops::Add;
@@ -36,7 +37,7 @@ struct TtFrame {
 pub struct TtReader<'a> {
     pub sp_diag: &'a Handler,
     /// the unzipped tree:
-    stack: Vec<TtFrame>,
+    stack: SmallVector<TtFrame>,
     /* for MBE-style macro transcription */
     interpolations: HashMap<Ident, Rc<NamedMatch>>,
 
@@ -74,7 +75,7 @@ pub fn new_tt_reader_with_doc_flag(sp_diag: &Handler,
                                    -> TtReader {
     let mut r = TtReader {
         sp_diag: sp_diag,
-        stack: vec!(TtFrame {
+        stack: SmallVector::one(TtFrame {
             forest: TokenTree::Sequence(DUMMY_SP, Rc::new(tokenstream::SequenceRepetition {
                 tts: src,
                 // doesn't matter. This merely holds the root unzipping.
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 16916ddd5d6..4bf6e55d674 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -972,10 +972,8 @@ pub fn noop_fold_mod<T: Folder>(Mod {inner, items}: Mod, folder: &mut T) -> Mod
     }
 }
 
-pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_macros, span}: Crate,
+pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, mut exported_macros, span}: Crate,
                                   folder: &mut T) -> Crate {
-    let config = folder.fold_meta_items(config);
-
     let mut items = folder.fold_item(P(ast::Item {
         ident: keywords::Invalid.ident(),
         attrs: attrs,
@@ -1009,7 +1007,6 @@ pub fn noop_fold_crate<T: Folder>(Crate {module, attrs, config, mut exported_mac
     Crate {
         module: module,
         attrs: attrs,
-        config: config,
         exported_macros: exported_macros,
         span: span,
     }
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index b2f27878993..b86e508d899 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -36,6 +36,7 @@
 #![feature(specialization)]
 #![feature(dotdot_in_tuple_patterns)]
 
+extern crate core;
 extern crate serialize;
 extern crate term;
 extern crate libc;
diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs
index 1a84a750463..7b67c23e102 100644
--- a/src/libsyntax/parse/mod.rs
+++ b/src/libsyntax/parse/mod.rs
@@ -10,7 +10,7 @@
 
 //! The main parser interface
 
-use ast;
+use ast::{self, CrateConfig};
 use codemap::CodeMap;
 use syntax_pos::{self, Span, FileMap};
 use errors::{Handler, ColorConfig, DiagnosticBuilder};
@@ -44,13 +44,14 @@ pub mod obsolete;
 pub struct ParseSess {
     pub span_diagnostic: Handler, // better be the same as the one in the reader!
     pub unstable_features: UnstableFeatures,
+    pub config: CrateConfig,
     /// Used to determine and report recursive mod inclusions
     included_mod_stack: RefCell<Vec<PathBuf>>,
     code_map: Rc<CodeMap>,
 }
 
 impl ParseSess {
-    pub fn new() -> ParseSess {
+    pub fn new() -> Self {
         let cm = Rc::new(CodeMap::new());
         let handler = Handler::with_tty_emitter(ColorConfig::Auto,
                                                 true,
@@ -63,6 +64,7 @@ impl ParseSess {
         ParseSess {
             span_diagnostic: handler,
             unstable_features: UnstableFeatures::from_environment(),
+            config: Vec::new(),
             included_mod_stack: RefCell::new(vec![]),
             code_map: code_map
         }
@@ -78,146 +80,90 @@ impl ParseSess {
 // uses a HOF to parse anything, and <source> includes file and
 // source_str.
 
-pub fn parse_crate_from_file<'a>(input: &Path,
-                                 cfg: ast::CrateConfig,
-                                 sess: &'a ParseSess)
-                                 -> PResult<'a, ast::Crate> {
-    let mut parser = new_parser_from_file(sess, cfg, input);
+pub fn parse_crate_from_file<'a>(input: &Path, sess: &'a ParseSess) -> PResult<'a, ast::Crate> {
+    let mut parser = new_parser_from_file(sess, input);
     parser.parse_crate_mod()
 }
 
-pub fn parse_crate_attrs_from_file<'a>(input: &Path,
-                                       cfg: ast::CrateConfig,
-                                       sess: &'a ParseSess)
+pub fn parse_crate_attrs_from_file<'a>(input: &Path, sess: &'a ParseSess)
                                        -> PResult<'a, Vec<ast::Attribute>> {
-    let mut parser = new_parser_from_file(sess, cfg, input);
+    let mut parser = new_parser_from_file(sess, input);
     parser.parse_inner_attributes()
 }
 
-pub fn parse_crate_from_source_str<'a>(name: String,
-                                       source: String,
-                                       cfg: ast::CrateConfig,
-                                       sess: &'a ParseSess)
+pub fn parse_crate_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
                                        -> PResult<'a, ast::Crate> {
-    let mut p = new_parser_from_source_str(sess,
-                                           cfg,
-                                           name,
-                                           source);
-    p.parse_crate_mod()
+    new_parser_from_source_str(sess, name, source).parse_crate_mod()
 }
 
-pub fn parse_crate_attrs_from_source_str<'a>(name: String,
-                                             source: String,
-                                             cfg: ast::CrateConfig,
-                                             sess: &'a ParseSess)
+pub fn parse_crate_attrs_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
                                              -> PResult<'a, Vec<ast::Attribute>> {
-    let mut p = new_parser_from_source_str(sess,
-                                           cfg,
-                                           name,
-                                           source);
-    p.parse_inner_attributes()
+    new_parser_from_source_str(sess, name, source).parse_inner_attributes()
 }
 
-pub fn parse_expr_from_source_str<'a>(name: String,
-                                      source: String,
-                                      cfg: ast::CrateConfig,
-                                      sess: &'a ParseSess)
+pub fn parse_expr_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
                                       -> PResult<'a, P<ast::Expr>> {
-    let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    p.parse_expr()
+    new_parser_from_source_str(sess, name, source).parse_expr()
 }
 
 /// Parses an item.
 ///
 /// Returns `Ok(Some(item))` when successful, `Ok(None)` when no item was found, and`Err`
 /// when a syntax error occurred.
-pub fn parse_item_from_source_str<'a>(name: String,
-                                      source: String,
-                                      cfg: ast::CrateConfig,
-                                      sess: &'a ParseSess)
+pub fn parse_item_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
                                       -> PResult<'a, Option<P<ast::Item>>> {
-    let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    p.parse_item()
+    new_parser_from_source_str(sess, name, source).parse_item()
 }
 
-pub fn parse_meta_from_source_str<'a>(name: String,
-                                      source: String,
-                                      cfg: ast::CrateConfig,
-                                      sess: &'a ParseSess)
+pub fn parse_meta_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
                                       -> PResult<'a, P<ast::MetaItem>> {
-    let mut p = new_parser_from_source_str(sess, cfg, name, source);
-    p.parse_meta_item()
+    new_parser_from_source_str(sess, name, source).parse_meta_item()
 }
 
-pub fn parse_stmt_from_source_str<'a>(name: String,
-                                      source: String,
-                                      cfg: ast::CrateConfig,
-                                      sess: &'a ParseSess)
+pub fn parse_stmt_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
                                       -> PResult<'a, Option<ast::Stmt>> {
-    let mut p = new_parser_from_source_str(
-        sess,
-        cfg,
-        name,
-        source
-    );
-    p.parse_stmt()
+    new_parser_from_source_str(sess, name, source).parse_stmt()
 }
 
 // Warning: This parses with quote_depth > 0, which is not the default.
-pub fn parse_tts_from_source_str<'a>(name: String,
-                                     source: String,
-                                     cfg: ast::CrateConfig,
-                                     sess: &'a ParseSess)
+pub fn parse_tts_from_source_str<'a>(name: String, source: String, sess: &'a ParseSess)
                                      -> PResult<'a, Vec<tokenstream::TokenTree>> {
-    let mut p = new_parser_from_source_str(
-        sess,
-        cfg,
-        name,
-        source
-    );
+    let mut p = new_parser_from_source_str(sess, name, source);
     p.quote_depth += 1;
     // right now this is re-creating the token trees from ... token trees.
     p.parse_all_token_trees()
 }
 
 // Create a new parser from a source string
-pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess,
-                                      cfg: ast::CrateConfig,
-                                      name: String,
-                                      source: String)
+pub fn new_parser_from_source_str<'a>(sess: &'a ParseSess, name: String, source: String)
                                       -> Parser<'a> {
-    filemap_to_parser(sess, sess.codemap().new_filemap(name, None, source), cfg)
+    filemap_to_parser(sess, sess.codemap().new_filemap(name, None, source))
 }
 
 /// Create a new parser, handling errors as appropriate
 /// if the file doesn't exist
-pub fn new_parser_from_file<'a>(sess: &'a ParseSess,
-                                cfg: ast::CrateConfig,
-                                path: &Path) -> Parser<'a> {
-    filemap_to_parser(sess, file_to_filemap(sess, path, None), cfg)
+pub fn new_parser_from_file<'a>(sess: &'a ParseSess, path: &Path) -> Parser<'a> {
+    filemap_to_parser(sess, file_to_filemap(sess, path, None))
 }
 
 /// Given a session, a crate config, a path, and a span, add
 /// the file at the given path to the codemap, and return a parser.
 /// On an error, use the given span as the source of the problem.
 pub fn new_sub_parser_from_file<'a>(sess: &'a ParseSess,
-                                    cfg: ast::CrateConfig,
                                     path: &Path,
                                     owns_directory: bool,
                                     module_name: Option<String>,
                                     sp: Span) -> Parser<'a> {
-    let mut p = filemap_to_parser(sess, file_to_filemap(sess, path, Some(sp)), cfg);
+    let mut p = filemap_to_parser(sess, file_to_filemap(sess, path, Some(sp)));
     p.owns_directory = owns_directory;
     p.root_module_name = module_name;
     p
 }
 
 /// Given a filemap and config, return a parser
-pub fn filemap_to_parser<'a>(sess: &'a ParseSess,
-                             filemap: Rc<FileMap>,
-                             cfg: ast::CrateConfig) -> Parser<'a> {
+pub fn filemap_to_parser<'a>(sess: &'a ParseSess, filemap: Rc<FileMap>, ) -> Parser<'a> {
     let end_pos = filemap.end_pos;
-    let mut parser = tts_to_parser(sess, filemap_to_tts(sess, filemap), cfg);
+    let mut parser = tts_to_parser(sess, filemap_to_tts(sess, filemap));
 
     if parser.token == token::Eof && parser.span == syntax_pos::DUMMY_SP {
         parser.span = syntax_pos::mk_sp(end_pos, end_pos);
@@ -228,18 +174,13 @@ pub fn filemap_to_parser<'a>(sess: &'a ParseSess,
 
 // must preserve old name for now, because quote! from the *existing*
 // compiler expands into it
-pub fn new_parser_from_tts<'a>(sess: &'a ParseSess,
-                               cfg: ast::CrateConfig,
-                               tts: Vec<tokenstream::TokenTree>)
+pub fn new_parser_from_tts<'a>(sess: &'a ParseSess, tts: Vec<tokenstream::TokenTree>)
                                -> Parser<'a> {
-    tts_to_parser(sess, tts, cfg)
+    tts_to_parser(sess, tts)
 }
 
-pub fn new_parser_from_ts<'a>(sess: &'a ParseSess,
-                              cfg: ast::CrateConfig,
-                              ts: tokenstream::TokenStream)
-                              -> Parser<'a> {
-    tts_to_parser(sess, ts.to_tts(), cfg)
+pub fn new_parser_from_ts<'a>(sess: &'a ParseSess, ts: tokenstream::TokenStream) -> Parser<'a> {
+    tts_to_parser(sess, ts.to_tts())
 }
 
 
@@ -266,18 +207,15 @@ pub fn filemap_to_tts(sess: &ParseSess, filemap: Rc<FileMap>)
     -> Vec<tokenstream::TokenTree> {
     // it appears to me that the cfg doesn't matter here... indeed,
     // parsing tt's probably shouldn't require a parser at all.
-    let cfg = Vec::new();
     let srdr = lexer::StringReader::new(&sess.span_diagnostic, filemap);
-    let mut p1 = Parser::new(sess, cfg, Box::new(srdr));
+    let mut p1 = Parser::new(sess, Box::new(srdr));
     panictry!(p1.parse_all_token_trees())
 }
 
-/// Given tts and cfg, produce a parser
-pub fn tts_to_parser<'a>(sess: &'a ParseSess,
-                         tts: Vec<tokenstream::TokenTree>,
-                         cfg: ast::CrateConfig) -> Parser<'a> {
+/// Given tts and the ParseSess, produce a parser
+pub fn tts_to_parser<'a>(sess: &'a ParseSess, tts: Vec<tokenstream::TokenTree>) -> Parser<'a> {
     let trdr = lexer::new_tt_reader(&sess.span_diagnostic, None, tts);
-    let mut p = Parser::new(sess, cfg, Box::new(trdr));
+    let mut p = Parser::new(sess, Box::new(trdr));
     p.check_unknown_macro_variable();
     p
 }
@@ -1057,13 +995,13 @@ mod tests {
 
         let name = "<source>".to_string();
         let source = "/// doc comment\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess)
+        let item = parse_item_from_source_str(name.clone(), source, &sess)
             .unwrap().unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
         assert_eq!(&doc[..], "/// doc comment");
 
         let source = "/// doc comment\r\n/// line 2\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name.clone(), source, Vec::new(), &sess)
+        let item = parse_item_from_source_str(name.clone(), source, &sess)
             .unwrap().unwrap();
         let docs = item.attrs.iter().filter(|a| &*a.name() == "doc")
                     .map(|a| a.value_str().unwrap().to_string()).collect::<Vec<_>>();
@@ -1071,7 +1009,7 @@ mod tests {
         assert_eq!(&docs[..], b);
 
         let source = "/** doc comment\r\n *  with CRLF */\r\nfn foo() {}".to_string();
-        let item = parse_item_from_source_str(name, source, Vec::new(), &sess).unwrap().unwrap();
+        let item = parse_item_from_source_str(name, source, &sess).unwrap().unwrap();
         let doc = first_attr_value_str_by_name(&item.attrs, "doc").unwrap();
         assert_eq!(&doc[..], "/** doc comment\n *  with CRLF */");
     }
@@ -1080,7 +1018,7 @@ mod tests {
     fn ttdelim_span() {
         let sess = ParseSess::new();
         let expr = parse::parse_expr_from_source_str("foo".to_string(),
-            "foo!( fn main() { body } )".to_string(), vec![], &sess).unwrap();
+            "foo!( fn main() { body } )".to_string(), &sess).unwrap();
 
         let tts = match expr.node {
             ast::ExprKind::Mac(ref mac) => mac.node.tts.clone(),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index d8dff6b4aa0..a75937759a2 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -15,7 +15,7 @@ use ast::Unsafety;
 use ast::{Mod, Arg, Arm, Attribute, BindingMode, TraitItemKind};
 use ast::Block;
 use ast::{BlockCheckMode, CaptureBy};
-use ast::{Constness, Crate, CrateConfig};
+use ast::{Constness, Crate};
 use ast::Defaultness;
 use ast::EnumDef;
 use ast::{Expr, ExprKind, RangeLimits};
@@ -271,7 +271,6 @@ pub struct Parser<'a> {
     pub span: Span,
     /// the span of the previous token:
     pub prev_span: Span,
-    pub cfg: CrateConfig,
     /// the previous token kind
     prev_token_kind: PrevTokenKind,
     lookahead_buffer: LookaheadBuffer,
@@ -358,11 +357,7 @@ impl From<P<Expr>> for LhsExpr {
 }
 
 impl<'a> Parser<'a> {
-    pub fn new(sess: &'a ParseSess,
-               cfg: ast::CrateConfig,
-               mut rdr: Box<Reader+'a>)
-               -> Parser<'a>
-    {
+    pub fn new(sess: &'a ParseSess, mut rdr: Box<Reader+'a>) -> Self {
         let tok0 = rdr.real_token();
         let span = tok0.sp;
         let mut directory = match span {
@@ -374,7 +369,6 @@ impl<'a> Parser<'a> {
         Parser {
             reader: rdr,
             sess: sess,
-            cfg: cfg,
             token: tok0.tok,
             span: span,
             prev_span: span,
@@ -1757,6 +1751,17 @@ impl<'a> Parser<'a> {
             // First, parse an identifier.
             let identifier = self.parse_path_segment_ident()?;
 
+            if self.check(&token::ModSep) && self.look_ahead(1, |t| *t == token::Lt) {
+                self.bump();
+                let prev_span = self.prev_span;
+
+                let mut err = self.diagnostic().struct_span_err(prev_span,
+                    "unexpected token: `::`");
+                err.help(
+                    "use `<...>` instead of `::<...>` if you meant to specify type arguments");
+                err.emit();
+            }
+
             // Parse types, optionally.
             let parameters = if self.eat_lt() {
                 let (lifetimes, types, bindings) = self.parse_generic_values_after_lt()?;
@@ -5317,7 +5322,6 @@ impl<'a> Parser<'a> {
     fn parse_item_mod(&mut self, outer_attrs: &[Attribute]) -> PResult<'a, ItemInfo> {
         let (in_cfg, outer_attrs) = {
             let mut strip_unconfigured = ::config::StripUnconfigured {
-                config: &self.cfg,
                 sess: self.sess,
                 should_test: false, // irrelevant
                 features: None, // don't perform gated feature checking
@@ -5485,12 +5489,7 @@ impl<'a> Parser<'a> {
         included_mod_stack.push(path.clone());
         drop(included_mod_stack);
 
-        let mut p0 = new_sub_parser_from_file(self.sess,
-                                              self.cfg.clone(),
-                                              &path,
-                                              owns_directory,
-                                              Some(name),
-                                              id_sp);
+        let mut p0 = new_sub_parser_from_file(self.sess, &path, owns_directory, Some(name), id_sp);
         let mod_inner_lo = p0.span.lo;
         let mod_attrs = p0.parse_inner_attributes()?;
         let m0 = p0.parse_mod_items(&token::Eof, mod_inner_lo)?;
@@ -6134,15 +6133,20 @@ impl<'a> Parser<'a> {
     /// MOD_SEP? LBRACE item_seq RBRACE
     fn parse_view_path(&mut self) -> PResult<'a, P<ViewPath>> {
         let lo = self.span.lo;
-        if self.check(&token::OpenDelim(token::Brace)) || self.is_import_coupler() {
-            // `{foo, bar}` or `::{foo, bar}`
+        if self.check(&token::OpenDelim(token::Brace)) || self.check(&token::BinOp(token::Star)) ||
+           self.is_import_coupler() {
+            // `{foo, bar}`, `::{foo, bar}`, `*`, or `::*`.
             let prefix = ast::Path {
                 global: self.eat(&token::ModSep),
                 segments: Vec::new(),
                 span: mk_sp(lo, self.span.hi),
             };
-            let items = self.parse_path_list_items()?;
-            Ok(P(spanned(lo, self.span.hi, ViewPathList(prefix, items))))
+            let view_path_kind = if self.eat(&token::BinOp(token::Star)) {
+                ViewPathGlob(prefix)
+            } else {
+                ViewPathList(prefix, self.parse_path_list_items()?)
+            };
+            Ok(P(spanned(lo, self.span.hi, view_path_kind)))
         } else {
             let prefix = self.parse_path(PathStyle::Mod)?;
             if self.is_import_coupler() {
@@ -6179,7 +6183,6 @@ impl<'a> Parser<'a> {
         Ok(ast::Crate {
             attrs: self.parse_inner_attributes()?,
             module: self.parse_mod_items(&token::Eof, lo)?,
-            config: self.cfg.clone(),
             span: mk_sp(lo, self.span.lo),
             exported_macros: Vec::new(),
         })
diff --git a/src/libsyntax/test.rs b/src/libsyntax/test.rs
index 8faad77859e..fdc1f45623d 100644
--- a/src/libsyntax/test.rs
+++ b/src/libsyntax/test.rs
@@ -274,7 +274,7 @@ fn generate_test_harness(sess: &ParseSess,
     let mut cx: TestCtxt = TestCtxt {
         sess: sess,
         span_diagnostic: sd,
-        ext_cx: ExtCtxt::new(sess, vec![], ExpansionConfig::default("test".to_string()), resolver),
+        ext_cx: ExtCtxt::new(sess, ExpansionConfig::default("test".to_string()), resolver),
         path: Vec::new(),
         testfns: Vec::new(),
         reexport_test_harness_main: reexport_test_harness_main,
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index f22f920a7fa..9e644e59e86 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -220,7 +220,7 @@ impl TokenTree {
                                                          None,
                                                          tts.iter().cloned().collect(),
                                                          true);
-        macro_parser::parse(cx.parse_sess(), cx.cfg(), arg_rdr, mtch)
+        macro_parser::parse(cx.parse_sess(), arg_rdr, mtch)
     }
 
     /// Check if this TokenTree is equal to the other, regardless of span information.
diff --git a/src/libsyntax/util/parser_testing.rs b/src/libsyntax/util/parser_testing.rs
index f59428bf536..76d3f2a063c 100644
--- a/src/libsyntax/util/parser_testing.rs
+++ b/src/libsyntax/util/parser_testing.rs
@@ -25,10 +25,7 @@ pub fn string_to_tts(source_str: String) -> Vec<tokenstream::TokenTree> {
 
 /// Map string to parser (via tts)
 pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> {
-    new_parser_from_source_str(ps,
-                               Vec::new(),
-                               "bogofile".to_string(),
-                               source_str)
+    new_parser_from_source_str(ps, "bogofile".to_string(), source_str)
 }
 
 fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> T where
diff --git a/src/libsyntax/util/small_vector.rs b/src/libsyntax/util/small_vector.rs
index 373dfc4ddfa..57258c76335 100644
--- a/src/libsyntax/util/small_vector.rs
+++ b/src/libsyntax/util/small_vector.rs
@@ -11,6 +11,7 @@
 use self::SmallVectorRepr::*;
 use self::IntoIterRepr::*;
 
+use core::ops;
 use std::iter::{IntoIterator, FromIterator};
 use std::mem;
 use std::slice;
@@ -19,10 +20,12 @@ use std::vec;
 use util::move_map::MoveMap;
 
 /// A vector type optimized for cases where the size is almost always 0 or 1
+#[derive(Clone)]
 pub struct SmallVector<T> {
     repr: SmallVectorRepr<T>,
 }
 
+#[derive(Clone)]
 enum SmallVectorRepr<T> {
     Zero,
     One(T),
@@ -75,16 +78,11 @@ impl<T> SmallVector<T> {
     }
 
     pub fn as_slice(&self) -> &[T] {
-        match self.repr {
-            Zero => {
-                let result: &[T] = &[];
-                result
-            }
-            One(ref v) => {
-                unsafe { slice::from_raw_parts(v, 1) }
-            }
-            Many(ref vs) => vs
-        }
+        self
+    }
+
+    pub fn as_mut_slice(&mut self) -> &mut [T] {
+        self
     }
 
     pub fn pop(&mut self) -> Option<T> {
@@ -163,6 +161,38 @@ impl<T> SmallVector<T> {
     }
 }
 
+impl<T> ops::Deref for SmallVector<T> {
+    type Target = [T];
+
+    fn deref(&self) -> &[T] {
+        match self.repr {
+            Zero => {
+                let result: &[T] = &[];
+                result
+            }
+            One(ref v) => {
+                unsafe { slice::from_raw_parts(v, 1) }
+            }
+            Many(ref vs) => vs
+        }
+    }
+}
+
+impl<T> ops::DerefMut for SmallVector<T> {
+    fn deref_mut(&mut self) -> &mut [T] {
+        match self.repr {
+            Zero => {
+                let result: &mut [T] = &mut [];
+                result
+            }
+            One(ref mut v) => {
+                unsafe { slice::from_raw_parts_mut(v, 1) }
+            }
+            Many(ref mut vs) => vs
+        }
+    }
+}
+
 impl<T> IntoIterator for SmallVector<T> {
     type Item = T;
     type IntoIter = IntoIter<T>;
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 1c97099d387..24c515e5028 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -107,7 +107,7 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt,
                 if p2.token != token::Eof {
                     let mut extra_tts = panictry!(p2.parse_all_token_trees());
                     extra_tts.extend(tts[first_colon..].iter().cloned());
-                    p = parse::tts_to_parser(cx.parse_sess, extra_tts, cx.cfg().clone());
+                    p = parse::tts_to_parser(cx.parse_sess, extra_tts);
                 }
 
                 asm = s;
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 169ef9ab7d6..98da49545f9 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -32,6 +32,6 @@ pub fn expand_cfg<'cx>(cx: &mut ExtCtxt,
         return DummyResult::expr(sp);
     }
 
-    let matches_cfg = attr::cfg_matches(&cx.cfg, &cfg, cx.parse_sess, cx.ecfg.features);
+    let matches_cfg = attr::cfg_matches(&cfg, cx.parse_sess, cx.ecfg.features);
     MacEager::expr(cx.expr_bool(sp, matches_cfg))
 }
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index bc47d8f4e61..687f8c902f2 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -1460,8 +1460,9 @@ impl<'a> MethodDef<'a> {
             .iter()
             .map(|v| {
                 let ident = v.node.name;
+                let sp = Span { expn_id: trait_.span.expn_id, ..v.span };
                 let summary = trait_.summarise_struct(cx, &v.node.data);
-                (ident, v.span, summary)
+                (ident, sp, summary)
             })
             .collect();
         self.call_substructure_method(cx,
diff --git a/src/libsyntax_ext/proc_macro_registrar.rs b/src/libsyntax_ext/proc_macro_registrar.rs
index b96fb08e59e..f49a5f0e070 100644
--- a/src/libsyntax_ext/proc_macro_registrar.rs
+++ b/src/libsyntax_ext/proc_macro_registrar.rs
@@ -47,7 +47,7 @@ pub fn modify(sess: &ParseSess,
               handler: &errors::Handler,
               features: &Features) -> ast::Crate {
     let ecfg = ExpansionConfig::default("proc_macro".to_string());
-    let mut cx = ExtCtxt::new(sess, Vec::new(), ecfg, resolver);
+    let mut cx = ExtCtxt::new(sess, ecfg, resolver);
 
     let mut collect = CollectCustomDerives {
         derives: Vec::new(),
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index e3feaee5369..d83d3a6c5cf 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -481,6 +481,9 @@ impl FileMap {
         self.src.is_none()
     }
 
+    pub fn byte_length(&self) -> u32 {
+        self.end_pos.0 - self.start_pos.0
+    }
     pub fn count_lines(&self) -> usize {
         self.lines.borrow().len()
     }
diff --git a/src/llvm b/src/llvm
-Subproject 8c9961a9cc406c9bcb29a8752a4a2ad9f5f98b1
+Subproject c1d962263bf76a10bea0c761621fcd98d6214b2
diff --git a/src/rustllvm/llvm-auto-clean-trigger b/src/rustllvm/llvm-auto-clean-trigger
index 0f63d70af9d..37fded948e1 100644
--- a/src/rustllvm/llvm-auto-clean-trigger
+++ b/src/rustllvm/llvm-auto-clean-trigger
@@ -1,4 +1,4 @@
 # If this file is modified, then llvm will be forcibly cleaned and then rebuilt.
 # The actual contents of this file do not matter, but to trigger a change on the
 # build bots then the contents should be changed so git updates the mtime.
-2016-10-18
+2016-10-29
diff --git a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
index 2041abcf82c..60697cc8b6a 100644
--- a/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
+++ b/src/test/compile-fail-fulldeps/auxiliary/macro_crate_test.rs
@@ -56,8 +56,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree])
 fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree])
                    -> Box<MacResult+'static> {
     // Parse an expression and emit it unchanged.
-    let mut parser = parse::new_parser_from_tts(cx.parse_sess(),
-        cx.cfg().clone(), tts.to_vec());
+    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), tts.to_vec());
     let expr = parser.parse_expr().unwrap();
     MacEager::expr(quote_expr!(&mut *cx, $expr))
 }
diff --git a/src/test/compile-fail-fulldeps/issue-18986.rs b/src/test/compile-fail-fulldeps/issue-18986.rs
index 3c32cb947b3..95af3760544 100644
--- a/src/test/compile-fail-fulldeps/issue-18986.rs
+++ b/src/test/compile-fail-fulldeps/issue-18986.rs
@@ -15,6 +15,6 @@ pub use use_from_trait_xc::Trait;
 
 fn main() {
     match () {
-        Trait { x: 42 } => () //~ ERROR expected variant, struct or type alias, found trait `Trait`
+        Trait { x: 42 } => () //~ ERROR expected struct, variant or union type, found trait `Trait`
     }
 }
diff --git a/src/test/compile-fail-fulldeps/qquote.rs b/src/test/compile-fail-fulldeps/qquote.rs
index 3e5d17e2ffb..4a7033d44b8 100644
--- a/src/test/compile-fail-fulldeps/qquote.rs
+++ b/src/test/compile-fail-fulldeps/qquote.rs
@@ -24,7 +24,7 @@ fn main() {
     let ps = syntax::parse::ParseSess::new();
     let mut resolver = syntax::ext::base::DummyResolver;
     let mut cx = syntax::ext::base::ExtCtxt::new(
-        &ps, vec![],
+        &ps,
         syntax::ext::expand::ExpansionConfig::default("qquote".to_string()),
         &mut resolver);
     cx.bt_push(syntax::codemap::ExpnInfo {
diff --git a/src/test/compile-fail/E0071.rs b/src/test/compile-fail/E0071.rs
index c13ba7bf136..95653ae83e7 100644
--- a/src/test/compile-fail/E0071.rs
+++ b/src/test/compile-fail/E0071.rs
@@ -9,13 +9,10 @@
 // except according to those terms.
 
 enum Foo {}
+type FooAlias = Foo;
 
 fn main() {
-    let u = Foo { value: 0 };
-    //~^ ERROR `Foo` does not name a struct or a struct variant [E0071]
-    //~| NOTE not a struct
-
-    let t = u32 { value: 4 };
-    //~^ ERROR `u32` does not name a struct or a struct variant [E0071]
+    let u = FooAlias { value: 0 };
+    //~^ ERROR expected struct, variant or union type, found enum `Foo` [E0071]
     //~| NOTE not a struct
 }
diff --git a/src/test/compile-fail/enums-are-namespaced-xc.rs b/src/test/compile-fail/enums-are-namespaced-xc.rs
index 5315e6c834a..02939565f69 100644
--- a/src/test/compile-fail/enums-are-namespaced-xc.rs
+++ b/src/test/compile-fail/enums-are-namespaced-xc.rs
@@ -14,5 +14,6 @@ extern crate namespaced_enums;
 fn main() {
     let _ = namespaced_enums::A; //~ ERROR unresolved name
     let _ = namespaced_enums::B(10); //~ ERROR unresolved name
-    let _ = namespaced_enums::C { a: 10 }; //~ ERROR does not name a structure
+    let _ = namespaced_enums::C { a: 10 };
+    //~^ ERROR unresolved struct, variant or union type `namespaced_enums::C`
 }
diff --git a/src/test/compile-fail/issue-12612.rs b/src/test/compile-fail/issue-12612.rs
index 20943bd0ea0..c6f76ca7887 100644
--- a/src/test/compile-fail/issue-12612.rs
+++ b/src/test/compile-fail/issue-12612.rs
@@ -16,7 +16,7 @@ use foo::bar;
 
 mod test {
     use bar::foo; //~ ERROR unresolved import `bar::foo` [E0432]
-                  //~^ Maybe a missing `extern crate bar`?
+                  //~^ Maybe a missing `extern crate bar;`?
 }
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-16058.rs b/src/test/compile-fail/issue-16058.rs
index 671232e701f..92c1e4b5f50 100644
--- a/src/test/compile-fail/issue-16058.rs
+++ b/src/test/compile-fail/issue-16058.rs
@@ -16,7 +16,7 @@ pub struct GslResult {
 
 impl GslResult {
     pub fn new() -> GslResult {
-        Result { //~ ERROR: `Result` does not name a struct or a struct variant
+        Result { //~ ERROR: expected struct, variant or union type, found enum `Result`
             val: 0f64,
             err: 0f64
         }
diff --git a/src/test/compile-fail/issue-1697.rs b/src/test/compile-fail/issue-1697.rs
index dc09af0ada6..1375200271c 100644
--- a/src/test/compile-fail/issue-1697.rs
+++ b/src/test/compile-fail/issue-1697.rs
@@ -11,6 +11,6 @@
 // Testing that we don't fail abnormally after hitting the errors
 
 use unresolved::*; //~ ERROR unresolved import `unresolved::*` [E0432]
-                   //~^ Maybe a missing `extern crate unresolved`?
+                   //~^ Maybe a missing `extern crate unresolved;`?
 
 fn main() {}
diff --git a/src/test/compile-fail/issue-17001.rs b/src/test/compile-fail/issue-17001.rs
index 218f68714ff..413e8b464ff 100644
--- a/src/test/compile-fail/issue-17001.rs
+++ b/src/test/compile-fail/issue-17001.rs
@@ -11,5 +11,5 @@
 mod foo {}
 
 fn main() {
-    let p = foo { x: () }; //~ ERROR `foo` does not name a struct or a struct variant
+    let p = foo { x: () }; //~ ERROR expected struct, variant or union type, found module `foo`
 }
diff --git a/src/test/compile-fail/issue-17405.rs b/src/test/compile-fail/issue-17405.rs
index 2f2c252b947..5a6bd5ed588 100644
--- a/src/test/compile-fail/issue-17405.rs
+++ b/src/test/compile-fail/issue-17405.rs
@@ -14,6 +14,6 @@ enum Foo {
 
 fn main() {
     match Foo::Bar(1) {
-        Foo { i } => () //~ ERROR expected variant, struct or type alias, found enum `Foo`
+        Foo { i } => () //~ ERROR expected struct, variant or union type, found enum `Foo`
     }
 }
diff --git a/src/test/compile-fail/issue-17518.rs b/src/test/compile-fail/issue-17518.rs
index 0410fadeb78..2113e38c45c 100644
--- a/src/test/compile-fail/issue-17518.rs
+++ b/src/test/compile-fail/issue-17518.rs
@@ -13,5 +13,5 @@ enum SomeEnum {
 }
 
 fn main() {
-    E { name: "foobar" }; //~ ERROR `E` does not name a structure
+    E { name: "foobar" }; //~ ERROR unresolved struct, variant or union type `E`
 }
diff --git a/src/test/compile-fail/issue-21449.rs b/src/test/compile-fail/issue-21449.rs
index 090b8a0d16e..cc44cf88f09 100644
--- a/src/test/compile-fail/issue-21449.rs
+++ b/src/test/compile-fail/issue-21449.rs
@@ -11,5 +11,6 @@
 mod MyMod {}
 
 fn main() {
-    let myVar = MyMod { T: 0 }; //~ ERROR `MyMod` does not name a struct or a struct variant
+    let myVar = MyMod { T: 0 };
+    //~^ ERROR expected struct, variant or union type, found module `MyMod`
 }
diff --git a/src/test/compile-fail/issue-26459.rs b/src/test/compile-fail/issue-26459.rs
index 24b39eeff0f..8be3d88bd5c 100644
--- a/src/test/compile-fail/issue-26459.rs
+++ b/src/test/compile-fail/issue-26459.rs
@@ -11,6 +11,6 @@
 fn main() {
     match 'a' {
         char{ch} => true
-        //~^ ERROR expected variant, struct or type alias, found builtin type `char`
+        //~^ ERROR expected struct, variant or union type, found builtin type `char`
     };
 }
diff --git a/src/test/compile-fail/issue-27815.rs b/src/test/compile-fail/issue-27815.rs
index 33930d1db14..d9840abf0ca 100644
--- a/src/test/compile-fail/issue-27815.rs
+++ b/src/test/compile-fail/issue-27815.rs
@@ -11,12 +11,12 @@
 mod A {}
 
 fn main() {
-    let u = A { x: 1 }; //~ ERROR `A` does not name a struct or a struct variant
-    let v = u32 { x: 1 }; //~ ERROR `u32` does not name a struct or a struct variant
+    let u = A { x: 1 }; //~ ERROR expected struct, variant or union type, found module `A`
+    let v = u32 { x: 1 }; //~ ERROR expected struct, variant or union type, found builtin type `u32`
     match () {
         A { x: 1 } => {}
-        //~^ ERROR expected variant, struct or type alias, found module `A`
+        //~^ ERROR expected struct, variant or union type, found module `A`
         u32 { x: 1 } => {}
-        //~^ ERROR expected variant, struct or type alias, found builtin type `u32`
+        //~^ ERROR expected struct, variant or union type, found builtin type `u32`
     }
 }
diff --git a/src/test/compile-fail/issue-36116.rs b/src/test/compile-fail/issue-36116.rs
new file mode 100644
index 00000000000..9abf2b5ec3a
--- /dev/null
+++ b/src/test/compile-fail/issue-36116.rs
@@ -0,0 +1,23 @@
+// 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.
+
+struct Foo<T> {
+    _a: T,
+}
+
+fn main() {
+    let f = Some(Foo { _a: 42 }).map(|a| a as Foo::<i32>);
+    //~^ ERROR unexpected token: `::`
+    //~| HELP use `<...>` instead of `::<...>` if you meant to specify type arguments
+
+    let g: Foo::<i32> = Foo { _a: 42 };
+    //~^ ERROR unexpected token: `::`
+    //~| HELP use `<...>` instead of `::<...>` if you meant to specify type arguments
+}
diff --git a/src/test/compile-fail/lexical-scopes.rs b/src/test/compile-fail/lexical-scopes.rs
index 505a91f223c..1ab59e790d7 100644
--- a/src/test/compile-fail/lexical-scopes.rs
+++ b/src/test/compile-fail/lexical-scopes.rs
@@ -10,7 +10,7 @@
 
 struct T { i: i32 }
 fn f<T>() {
-    let t = T { i: 0 }; //~ ERROR `T` does not name a struct or a struct variant
+    let t = T { i: 0 }; //~ ERROR expected struct, variant or union type, found type parameter `T`
 }
 
 mod Foo {
diff --git a/src/test/compile-fail/no-patterns-in-args-2.rs b/src/test/compile-fail/no-patterns-in-args-2.rs
new file mode 100644
index 00000000000..385d012cade
--- /dev/null
+++ b/src/test/compile-fail/no-patterns-in-args-2.rs
@@ -0,0 +1,23 @@
+// 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.
+
+#![deny(patterns_in_fns_without_body)]
+
+trait Tr {
+    fn f1(mut arg: u8); //~ ERROR patterns aren't allowed in methods without bodies
+                        //~^ WARN was previously accepted
+    fn f2(&arg: u8); //~ ERROR patterns aren't allowed in methods without bodies
+                     //~^ WARN was previously accepted
+    fn g1(arg: u8); // OK
+    fn g2(_: u8); // OK
+    fn g3(u8); // OK
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/E0422.rs b/src/test/compile-fail/struct-path-alias-bounds.rs
index 61e96b896a6..1b6e51e3703 100644
--- a/src/test/compile-fail/E0422.rs
+++ b/src/test/compile-fail/struct-path-alias-bounds.rs
@@ -8,8 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-fn main () {
-    let x = Foo { x: 1, y: 2 };
-    //~^ ERROR E0422
-    //~| NOTE not a structure
+// issue #36286
+
+struct S<T: Clone> { a: T }
+
+struct NoClone;
+type A = S<NoClone>;
+
+fn main() {
+    let s = A { a: NoClone };
+    //~^ ERROR the trait bound `NoClone: std::clone::Clone` is not satisfied
 }
diff --git a/src/test/compile-fail/struct-path-associated-type.rs b/src/test/compile-fail/struct-path-associated-type.rs
new file mode 100644
index 00000000000..660ac44ce0b
--- /dev/null
+++ b/src/test/compile-fail/struct-path-associated-type.rs
@@ -0,0 +1,48 @@
+// 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.
+
+struct S;
+
+trait Tr {
+    type A;
+}
+
+impl Tr for S {
+    type A = S;
+}
+
+fn f<T: Tr>() {
+    let s = T::A {};
+    //~^ ERROR expected struct, variant or union type, found associated type
+    let z = T::A::<u8> {};
+    //~^ ERROR expected struct, variant or union type, found associated type
+    //~| ERROR type parameters are not allowed on this type
+    match S {
+        T::A {} => {}
+        //~^ ERROR expected struct, variant or union type, found associated type
+    }
+}
+
+fn g<T: Tr<A = S>>() {
+    let s = T::A {}; // OK
+    let z = T::A::<u8> {}; //~ ERROR type parameters are not allowed on this type
+    match S {
+        T::A {} => {} // OK
+    }
+}
+
+fn main() {
+    let s = S::A {}; //~ ERROR ambiguous associated type
+    let z = S::A::<u8> {}; //~ ERROR ambiguous associated type
+    //~^ ERROR type parameters are not allowed on this type
+    match S {
+        S::A {} => {} //~ ERROR ambiguous associated type
+    }
+}
diff --git a/src/test/compile-fail/struct-path-self-type-mismatch.rs b/src/test/compile-fail/struct-path-self-type-mismatch.rs
new file mode 100644
index 00000000000..f694e7d277c
--- /dev/null
+++ b/src/test/compile-fail/struct-path-self-type-mismatch.rs
@@ -0,0 +1,38 @@
+// 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.
+
+struct Foo<A> { inner: A }
+
+trait Bar { fn bar(); }
+
+impl Bar for Foo<i32> {
+    fn bar() {
+        Self { inner: 1.5f32 }; //~ ERROR mismatched types
+                                //~^ NOTE expected i32, found f32
+    }
+}
+
+impl<T> Foo<T> {
+    fn new<U>(u: U) -> Foo<U> {
+        Self {
+        //~^ ERROR mismatched types
+        //~| expected type parameter, found a different type parameter
+        //~| expected type `Foo<U>`
+        //~| found type `Foo<T>`
+            inner: u
+            //~^ ERROR mismatched types
+            //~| expected type parameter, found a different type parameter
+            //~| expected type `T`
+            //~| found type `U`
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/struct-path-self.rs b/src/test/compile-fail/struct-path-self.rs
new file mode 100644
index 00000000000..067d6ac22dc
--- /dev/null
+++ b/src/test/compile-fail/struct-path-self.rs
@@ -0,0 +1,47 @@
+// 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.
+
+struct S;
+
+trait Tr {
+    fn f() {
+        let s = Self {};
+        //~^ ERROR expected struct, variant or union type, found Self
+        let z = Self::<u8> {};
+        //~^ ERROR expected struct, variant or union type, found Self
+        //~| ERROR type parameters are not allowed on this type
+        match s {
+            Self { .. } => {}
+            //~^ ERROR expected struct, variant or union type, found Self
+        }
+    }
+}
+
+impl Tr for S {
+    fn f() {
+        let s = Self {}; // OK
+        let z = Self::<u8> {}; //~ ERROR type parameters are not allowed on this type
+        match s {
+            Self { .. } => {} // OK
+        }
+    }
+}
+
+impl S {
+    fn g() {
+        let s = Self {}; // OK
+        let z = Self::<u8> {}; //~ ERROR type parameters are not allowed on this type
+        match s {
+            Self { .. } => {} // OK
+        }
+    }
+}
+
+fn main() {}
diff --git a/src/test/compile-fail/trait-as-struct-constructor.rs b/src/test/compile-fail/trait-as-struct-constructor.rs
index c78eebddbfd..49d58580da5 100644
--- a/src/test/compile-fail/trait-as-struct-constructor.rs
+++ b/src/test/compile-fail/trait-as-struct-constructor.rs
@@ -12,6 +12,5 @@ trait TraitNotAStruct {}
 
 fn main() {
     TraitNotAStruct{ value: 0 };
-    //~^ ERROR: `TraitNotAStruct` does not name a struct or a struct variant [E0071]
-    //~| NOTE not a struct
+    //~^ ERROR expected struct, variant or union type, found trait `TraitNotAStruct`
 }
diff --git a/src/test/compile-fail/unresolved-import.rs b/src/test/compile-fail/unresolved-import.rs
index 0a9a4375697..47490af0ff3 100644
--- a/src/test/compile-fail/unresolved-import.rs
+++ b/src/test/compile-fail/unresolved-import.rs
@@ -11,7 +11,7 @@
 // ignore-tidy-linelength
 
 use foo::bar; //~ ERROR unresolved import `foo::bar` [E0432]
-              //~^ Maybe a missing `extern crate foo`?
+              //~^ Maybe a missing `extern crate foo;`?
 
 use bar::Baz as x; //~ ERROR unresolved import `bar::Baz` [E0432]
                    //~^ no `Baz` in `bar`. Did you mean to use `Bar`?
diff --git a/src/test/incremental/hashes/trait_defs.rs b/src/test/incremental/hashes/trait_defs.rs
index 937f053e320..391c2e75ba4 100644
--- a/src/test/incremental/hashes/trait_defs.rs
+++ b/src/test/incremental/hashes/trait_defs.rs
@@ -264,8 +264,8 @@ trait TraitChangeModeSelfRefToMut {
 
 
 #[cfg(cfail1)]
-trait TraitChangeModeSelfOwnToMut {
-    fn method(self);
+trait TraitChangeModeSelfOwnToMut: Sized {
+    fn method(self) {}
 }
 
 #[cfg(not(cfail1))]
@@ -273,8 +273,8 @@ trait TraitChangeModeSelfOwnToMut {
 #[rustc_clean(label="Hir", cfg="cfail3")]
 #[rustc_metadata_dirty(cfg="cfail2")]
 #[rustc_metadata_clean(cfg="cfail3")]
-trait TraitChangeModeSelfOwnToMut {
-    fn method(mut self);
+trait TraitChangeModeSelfOwnToMut: Sized {
+    fn method(mut self) {}
 }
 
 
diff --git a/src/test/run-fail-fulldeps/qquote.rs b/src/test/run-fail-fulldeps/qquote.rs
index 1458583ff58..d2a16ac7507 100644
--- a/src/test/run-fail-fulldeps/qquote.rs
+++ b/src/test/run-fail-fulldeps/qquote.rs
@@ -27,7 +27,7 @@ fn main() {
     let ps = syntax::parse::ParseSess::new();
     let mut resolver = syntax::ext::base::DummyResolver;
     let mut cx = syntax::ext::base::ExtCtxt::new(
-        &ps, vec![],
+        &ps,
         syntax::ext::expand::ExpansionConfig::default("qquote".to_string()),
         &mut resolver);
     cx.bt_push(syntax::codemap::ExpnInfo {
diff --git a/src/test/run-make/issue-19371/foo.rs b/src/test/run-make/issue-19371/foo.rs
index 35043bdaddf..ed127b017b6 100644
--- a/src/test/run-make/issue-19371/foo.rs
+++ b/src/test/run-make/issue-19371/foo.rs
@@ -67,12 +67,6 @@ fn compile(code: String, output: PathBuf, sysroot: PathBuf) {
     let (sess, cstore) = basic_sess(sysroot);
     let cfg = build_configuration(&sess, vec![]);
     let control = CompileController::basic();
-
-    compile_input(&sess, &cstore,
-            cfg,
-            &Input::Str { name: anon_src(), input: code },
-            &None,
-            &Some(output),
-            None,
-            &control);
+    let input = Input::Str { name: anon_src(), input: code };
+    compile_input(&sess, &cstore, &input, &None, &Some(output), None, &control);
 }
diff --git a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
index 64747002a65..a41b34f6a53 100644
--- a/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
+++ b/src/test/run-pass-fulldeps/ast_stmt_expr_attr.rs
@@ -31,10 +31,7 @@ use std::fmt;
 // Copied out of syntax::util::parser_testing
 
 pub fn string_to_parser<'a>(ps: &'a ParseSess, source_str: String) -> Parser<'a> {
-    new_parser_from_source_str(ps,
-                               Vec::new(),
-                               "bogofile".to_string(),
-                               source_str)
+    new_parser_from_source_str(ps, "bogofile".to_string(), source_str)
 }
 
 fn with_error_checking_parse<'a, T, F>(s: String, ps: &'a ParseSess, f: F) -> PResult<'a, T> where
diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs
index 78589546084..48919fe876a 100644
--- a/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/cond_noprelude_plugin.rs
@@ -15,10 +15,10 @@
 #![plugin(proc_macro_plugin)]
 
 extern crate rustc_plugin;
-extern crate proc_macro_plugin;
+extern crate proc_macro_tokens;
 extern crate syntax;
 
-use proc_macro_plugin::build::ident_eq;
+use proc_macro_tokens::build::ident_eq;
 
 use syntax::ext::base::{ExtCtxt, MacResult};
 use syntax::ext::proc_macro_shim::build_block_emitter;
diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs
index 11322bf76ff..0ea4cec75cd 100644
--- a/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/cond_plugin.rs
@@ -15,10 +15,10 @@
 #![plugin(proc_macro_plugin)]
 
 extern crate rustc_plugin;
-extern crate proc_macro_plugin;
+extern crate proc_macro_tokens;
 extern crate syntax;
 
-use proc_macro_plugin::prelude::*;
+use proc_macro_tokens::prelude::*;
 
 use rustc_plugin::Registry;
 
diff --git a/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs b/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs
index 232a7166e3b..169c96b4385 100644
--- a/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/cond_prelude_plugin.rs
@@ -15,11 +15,11 @@
 #![plugin(proc_macro_plugin)]
 
 extern crate rustc_plugin;
-extern crate proc_macro_plugin;
+extern crate proc_macro_tokens;
 extern crate syntax;
 
 use syntax::ext::proc_macro_shim::prelude::*;
-use proc_macro_plugin::prelude::*;
+use proc_macro_tokens::prelude::*;
 
 use rustc_plugin::Registry;
 
diff --git a/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs b/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
index f7b046b30ca..3bc4a40a39c 100644
--- a/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/dummy_mir_pass.rs
@@ -19,7 +19,7 @@ extern crate rustc_const_math;
 extern crate syntax;
 
 use rustc::mir::transform::{self, MirPass, MirSource};
-use rustc::mir::repr::{Mir, Literal, Location};
+use rustc::mir::{Mir, Literal, Location};
 use rustc::mir::visit::MutVisitor;
 use rustc::ty::TyCtxt;
 use rustc::middle::const_val::ConstVal;
diff --git a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
index 2c814a5433b..15ec0ccae8f 100644
--- a/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/macro_crate_test.rs
@@ -60,7 +60,7 @@ fn expand_make_a_1(cx: &mut ExtCtxt, sp: Span, tts: &[TokenTree]) -> Box<MacResu
 // See Issue #15750
 fn expand_identity(cx: &mut ExtCtxt, _span: Span, tts: &[TokenTree]) -> Box<MacResult + 'static> {
     // Parse an expression and emit it unchanged.
-    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), cx.cfg().clone(), tts.to_vec());
+    let mut parser = parse::new_parser_from_tts(cx.parse_sess(), tts.to_vec());
     let expr = parser.parse_expr().unwrap();
     MacEager::expr(quote_expr!(&mut *cx, $expr))
 }
diff --git a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs
index 961df6d5c0c..9fce19f46f6 100644
--- a/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs
+++ b/src/test/run-pass-fulldeps/auxiliary/proc_macro_def.rs
@@ -10,11 +10,11 @@
 
 #![feature(plugin, plugin_registrar, rustc_private)]
 
-extern crate proc_macro_plugin;
+extern crate proc_macro_tokens;
 extern crate rustc_plugin;
 extern crate syntax;
 
-use proc_macro_plugin::prelude::*;
+use proc_macro_tokens::prelude::*;
 use rustc_plugin::Registry;
 use syntax::ext::base::SyntaxExtension;
 use syntax::ext::proc_macro_shim::prelude::*;
diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs
index 35e9f3f5c8d..4a397621ceb 100644
--- a/src/test/run-pass-fulldeps/compiler-calls.rs
+++ b/src/test/run-pass-fulldeps/compiler-calls.rs
@@ -47,7 +47,6 @@ impl<'a> CompilerCalls<'a> for TestCalls {
     fn late_callback(&mut self,
                      _: &getopts::Matches,
                      _: &Session,
-                     _: &ast::CrateConfig,
                      _: &Input,
                      _: &Option<PathBuf>,
                      _: &Option<PathBuf>)
diff --git a/src/test/run-pass-fulldeps/macro-quote-1.rs b/src/test/run-pass-fulldeps/macro-quote-1.rs
index a5ac546cba4..914da3f7467 100644
--- a/src/test/run-pass-fulldeps/macro-quote-1.rs
+++ b/src/test/run-pass-fulldeps/macro-quote-1.rs
@@ -14,8 +14,8 @@
 #![feature(rustc_private)]
 #![plugin(proc_macro_plugin)]
 
-extern crate proc_macro_plugin;
-use proc_macro_plugin::prelude::*;
+extern crate proc_macro_tokens;
+use proc_macro_tokens::prelude::*;
 
 extern crate syntax;
 use syntax::ast::Ident;
diff --git a/src/test/run-pass-fulldeps/qquote.rs b/src/test/run-pass-fulldeps/qquote.rs
index 2a53a62a5ab..7c0c24163fe 100644
--- a/src/test/run-pass-fulldeps/qquote.rs
+++ b/src/test/run-pass-fulldeps/qquote.rs
@@ -23,7 +23,7 @@ fn main() {
     let ps = syntax::parse::ParseSess::new();
     let mut resolver = syntax::ext::base::DummyResolver;
     let mut cx = syntax::ext::base::ExtCtxt::new(
-        &ps, vec![],
+        &ps,
         syntax::ext::expand::ExpansionConfig::default("qquote".to_string()),
         &mut resolver);
     cx.bt_push(syntax::codemap::ExpnInfo {
diff --git a/src/test/run-pass/by-value-self-in-mut-slot.rs b/src/test/run-pass/by-value-self-in-mut-slot.rs
index 5bbdec95b15..846b695c35b 100644
--- a/src/test/run-pass/by-value-self-in-mut-slot.rs
+++ b/src/test/run-pass/by-value-self-in-mut-slot.rs
@@ -14,7 +14,7 @@ struct X {
 }
 
 trait Changer {
-    fn change(mut self) -> Self;
+    fn change(self) -> Self;
 }
 
 impl Changer for X {
diff --git a/src/test/run-pass/import-glob-crate.rs b/src/test/run-pass/import-glob-crate.rs
index b2a9b08b01b..fec46c7e1f8 100644
--- a/src/test/run-pass/import-glob-crate.rs
+++ b/src/test/run-pass/import-glob-crate.rs
@@ -8,9 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-
-#![allow(dead_assignment)]
-
 use std::mem::*;
 
 pub fn main() {
@@ -20,3 +17,12 @@ pub fn main() {
     assert_eq!(x, 2);
     assert_eq!(y, 1);
 }
+
+#[allow(unused)]
+fn f() {
+    mod foo { pub use *; }
+    mod bar { pub use ::*; }
+
+    foo::main();
+    bar::main();
+}
diff --git a/src/test/run-pass/issue-22546.rs b/src/test/run-pass/issue-22546.rs
index b3cb8a78213..8516d344e1c 100644
--- a/src/test/run-pass/issue-22546.rs
+++ b/src/test/run-pass/issue-22546.rs
@@ -51,4 +51,10 @@ fn main() {
     if let None::<u8> = Some(8) {
         panic!();
     }
+    if let None::<u8> { .. } = Some(8) {
+        panic!();
+    }
+    if let Option::None::<u8> { .. } = Some(8) {
+        panic!();
+    }
 }
diff --git a/src/test/compile-fail/struct-pat-associated-path.rs b/src/test/run-pass/struct-path-associated-type.rs
index d3f840f4fe9..b033ed5c802 100644
--- a/src/test/compile-fail/struct-pat-associated-path.rs
+++ b/src/test/run-pass/struct-path-associated-type.rs
@@ -8,30 +8,28 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-struct S;
+struct S<T, U = u16> {
+    a: T,
+    b: U,
+}
 
 trait Tr {
     type A;
 }
-
-impl Tr for S {
-    type A = S;
-}
-
-fn f<T: Tr>() {
-    match S {
-        T::A {} => {} //~ ERROR `T::A` does not name a struct or a struct variant
-    }
+impl Tr for u8 {
+    type A = S<u8, u16>;
 }
 
-fn g<T: Tr<A = S>>() {
-    match S {
-        T::A {} => {} //~ ERROR `T::A` does not name a struct or a struct variant
+fn f<T: Tr<A = S<u8>>>() {
+    let s = T::A { a: 0, b: 1 };
+    match s {
+        T::A { a, b } => {
+            assert_eq!(a, 0);
+            assert_eq!(b, 1);
+        }
     }
 }
 
 fn main() {
-    match S {
-        S::A {} => {} //~ ERROR ambiguous associated type
-    }
+    f::<u8>();
 }
diff --git a/src/test/run-pass/struct-path-self.rs b/src/test/run-pass/struct-path-self.rs
new file mode 100644
index 00000000000..c7a282c2a2f
--- /dev/null
+++ b/src/test/run-pass/struct-path-self.rs
@@ -0,0 +1,54 @@
+// 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.
+
+use std::ops::Add;
+
+struct S<T, U = u16> {
+    a: T,
+    b: U,
+}
+
+trait Tr {
+    fn f(&self) -> Self;
+}
+
+impl<T: Default + Add<u8, Output = T>, U: Default> Tr for S<T, U> {
+    fn f(&self) -> Self {
+        let s = Self { a: Default::default(), b: Default::default() };
+        match s {
+            Self { a, b } => Self { a: a + 1, b: b }
+        }
+    }
+}
+
+impl<T: Default, U: Default + Add<u16, Output = U>> S<T, U> {
+    fn g(&self) -> Self {
+        let s = Self { a: Default::default(), b: Default::default() };
+        match s {
+            Self { a, b } => Self { a: a, b: b + 1 }
+        }
+    }
+}
+
+impl S<u8> {
+    fn new() -> Self {
+        Self { a: 0, b: 1 }
+    }
+}
+
+fn main() {
+    let s0 = S::new();
+    let s1 = s0.f();
+    assert_eq!(s1.a, 1);
+    assert_eq!(s1.b, 0);
+    let s2 = s0.g();
+    assert_eq!(s2.a, 0);
+    assert_eq!(s2.b, 1);
+}
diff --git a/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs b/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs
new file mode 100644
index 00000000000..323705f3f95
--- /dev/null
+++ b/src/test/run-pass/typeck-fn-to-unsafe-fn-ptr.rs
@@ -0,0 +1,21 @@
+// 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.
+
+// This tests reification from safe function to `unsafe fn` pointer
+
+fn do_nothing() -> () {}
+
+unsafe fn call_unsafe(func: unsafe fn() -> ()) -> () {
+    func()
+}
+
+pub fn main() {
+    unsafe { call_unsafe(do_nothing); }
+}
diff --git a/src/test/run-pass/uniq-self-in-mut-slot.rs b/src/test/run-pass/uniq-self-in-mut-slot.rs
index baca157a488..7910380abee 100644
--- a/src/test/run-pass/uniq-self-in-mut-slot.rs
+++ b/src/test/run-pass/uniq-self-in-mut-slot.rs
@@ -17,7 +17,7 @@ struct X {
 }
 
 trait Changer {
-    fn change(mut self: Box<Self>) -> Box<Self>;
+    fn change(self: Box<Self>) -> Box<Self>;
 }
 
 impl Changer for X {
diff --git a/src/tools/cargotest/main.rs b/src/tools/cargotest/main.rs
index 978e991d508..800186a926d 100644
--- a/src/tools/cargotest/main.rs
+++ b/src/tools/cargotest/main.rs
@@ -24,7 +24,7 @@ struct Test {
 const TEST_REPOS: &'static [Test] = &[Test {
                                           name: "cargo",
                                           repo: "https://github.com/rust-lang/cargo",
-                                          sha: "d3bad1ab29efae414e9b4c24534b2d02b3a59782",
+                                          sha: "806e3c368a15f618244a3b4e918bf77f9c403fd0",
                                           lock: None,
                                       },
                                       Test {
diff --git a/src/tools/tidy/src/bins.rs b/src/tools/tidy/src/bins.rs
index ea274266f1a..ef93b0858b0 100644
--- a/src/tools/tidy/src/bins.rs
+++ b/src/tools/tidy/src/bins.rs
@@ -44,28 +44,27 @@ pub fn check(path: &Path, bad: &mut bool) {
         let filename = file.file_name().unwrap().to_string_lossy();
         let extensions = [".py", ".sh"];
         if extensions.iter().any(|e| filename.ends_with(e)) {
-            return
+            return;
         }
 
         let metadata = t!(fs::symlink_metadata(&file), &file);
         if metadata.mode() & 0o111 != 0 {
             let rel_path = file.strip_prefix(path).unwrap();
             let git_friendly_path = rel_path.to_str().unwrap().replace("\\", "/");
-            let ret_code = Command::new("git")
-                                        .arg("ls-files")
-                                        .arg(&git_friendly_path)
-                                        .current_dir(path)
-                                        .stdout(Stdio::null())
-                                        .stderr(Stdio::null())
-                                        .status()
-                                        .unwrap_or_else(|e| {
-                                            panic!("could not run git ls-files: {}", e);
-                                        });
-            if ret_code.success() {
+            let output = Command::new("git")
+                .arg("ls-files")
+                .arg(&git_friendly_path)
+                .current_dir(path)
+                .stderr(Stdio::null())
+                .output()
+                .unwrap_or_else(|e| {
+                    panic!("could not run git ls-files: {}", e);
+                });
+            let path_bytes = rel_path.as_os_str().as_bytes();
+            if output.status.success() && output.stdout.starts_with(path_bytes) {
                 println!("binary checked into source: {}", file.display());
                 *bad = true;
             }
         }
     })
 }
-
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index 199e8a77df7..4ef07f7e4b8 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -18,27 +18,42 @@
 //! * Library features have at most one `since` value
 
 use std::collections::HashMap;
+use std::fmt;
 use std::fs::File;
 use std::io::prelude::*;
 use std::path::Path;
 
-const STATUSES: &'static [&'static str] = &[
-    "Active", "Deprecated", "Removed", "Accepted",
-];
+#[derive(PartialEq)]
+enum Status {
+    Stable,
+    Unstable,
+}
+
+impl fmt::Display for Status {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        let as_str = match *self {
+            Status::Stable => "stable",
+            Status::Unstable => "unstable",
+        };
+        fmt::Display::fmt(as_str, f)
+    }
+}
+
 
 struct Feature {
     name: String,
+    level: Status,
     since: String,
-    status: String,
 }
 
 struct LibFeature {
-    level: String,
+    level: Status,
     since: String,
 }
 
 pub fn check(path: &Path, bad: &mut bool) {
     let features = collect_lang_features(&path.join("libsyntax/feature_gate.rs"));
+    assert!(!features.is_empty());
     let mut lib_features = HashMap::<String, LibFeature>::new();
 
     let mut contents = String::new();
@@ -48,7 +63,7 @@ pub fn check(path: &Path, bad: &mut bool) {
         let filename = file.file_name().unwrap().to_string_lossy();
         if !filename.ends_with(".rs") || filename == "features.rs" ||
            filename == "diagnostic_list.rs" {
-            return
+            return;
         }
 
         contents.truncate(0);
@@ -60,24 +75,24 @@ pub fn check(path: &Path, bad: &mut bool) {
                 *bad = true;
             };
             let level = if line.contains("[unstable(") {
-                "unstable"
+                Status::Unstable
             } else if line.contains("[stable(") {
-                "stable"
+                Status::Stable
             } else {
-                continue
+                continue;
             };
             let feature_name = match find_attr_val(line, "feature") {
                 Some(name) => name,
                 None => {
                     err("malformed stability attribute");
-                    continue
+                    continue;
                 }
             };
             let since = match find_attr_val(line, "since") {
                 Some(name) => name,
-                None if level == "stable" => {
+                None if level == Status::Stable => {
                     err("malformed stability attribute");
-                    continue
+                    continue;
                 }
                 None => "None",
             };
@@ -92,27 +107,34 @@ pub fn check(path: &Path, bad: &mut bool) {
                 if s.since != since {
                     err("different `since` than before");
                 }
-                continue
+                continue;
             }
-            lib_features.insert(feature_name.to_owned(), LibFeature {
-                level: level.to_owned(),
-                since: since.to_owned(),
-            });
+            lib_features.insert(feature_name.to_owned(),
+                                LibFeature {
+                                    level: level,
+                                    since: since.to_owned(),
+                                });
         }
     });
 
     if *bad {
-        return
+        return;
     }
 
     let mut lines = Vec::new();
     for feature in features {
         lines.push(format!("{:<32} {:<8} {:<12} {:<8}",
-                           feature.name, "lang", feature.status, feature.since));
+                           feature.name,
+                           "lang",
+                           feature.level,
+                           feature.since));
     }
     for (name, feature) in lib_features {
         lines.push(format!("{:<32} {:<8} {:<12} {:<8}",
-                           name, "lib", feature.level, feature.since));
+                           name,
+                           "lib",
+                           feature.level,
+                           feature.since));
     }
 
     lines.sort();
@@ -122,39 +144,32 @@ pub fn check(path: &Path, bad: &mut bool) {
 }
 
 fn find_attr_val<'a>(line: &'a str, attr: &str) -> Option<&'a str> {
-    line.find(attr).and_then(|i| {
-        line[i..].find("\"").map(|j| i + j + 1)
-    }).and_then(|i| {
-        line[i..].find("\"").map(|j| (i, i + j))
-    }).map(|(i, j)| {
-        &line[i..j]
-    })
+    line.find(attr)
+        .and_then(|i| line[i..].find('"').map(|j| i + j + 1))
+        .and_then(|i| line[i..].find('"').map(|j| (i, i + j)))
+        .map(|(i, j)| &line[i..j])
 }
 
 fn collect_lang_features(path: &Path) -> Vec<Feature> {
     let mut contents = String::new();
     t!(t!(File::open(path)).read_to_string(&mut contents));
 
-    let mut features = Vec::new();
-    for line in contents.lines().map(|l| l.trim()) {
-        if !STATUSES.iter().any(|s| line.starts_with(&format!("({}", s))) {
-            continue
-        }
-        let mut parts = line.split(",");
-        let status = match &parts.next().unwrap().trim().replace("(", "")[..] {
-            "active"   => "unstable",
-            "removed"  => "unstable",
-            "accepted" => "stable",
-            s => panic!("unknown status: {}", s),
-        };
-        let name = parts.next().unwrap().trim().to_owned();
-        let since = parts.next().unwrap().trim().replace("\"", "");
-
-        features.push(Feature {
-            name: name,
-            since: since,
-            status: status.to_owned(),
-        });
-    }
-    return features
+    contents.lines()
+        .filter_map(|line| {
+            let mut parts = line.trim().split(",");
+            let level = match parts.next().map(|l| l.trim().trim_left_matches('(')) {
+                Some("active") => Status::Unstable,
+                Some("removed") => Status::Unstable,
+                Some("accepted") => Status::Stable,
+                _ => return None,
+            };
+            let name = parts.next().unwrap().trim();
+            let since = parts.next().unwrap().trim().trim_matches('"');
+            Some(Feature {
+                name: name.to_owned(),
+                level: level,
+                since: since.to_owned(),
+            })
+        })
+        .collect()
 }