about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--config.toml.example5
-rw-r--r--src/Cargo.lock56
-rw-r--r--src/bootstrap/builder.rs5
-rw-r--r--src/bootstrap/compile.rs3
-rw-r--r--src/bootstrap/config.rs3
-rw-r--r--src/bootstrap/dist.rs8
-rw-r--r--src/bootstrap/lib.rs3
-rw-r--r--src/bootstrap/test.rs10
-rw-r--r--src/doc/unstable-book/src/language-features/lang-items.md21
-rw-r--r--src/doc/unstable-book/src/language-features/match-beginning-vert.md23
-rw-r--r--src/etc/wasm32-shim.js149
-rw-r--r--src/libcore/fmt/mod.rs2
-rw-r--r--src/libcore/fmt/num.rs1
-rw-r--r--src/libcore/intrinsics.rs2
-rw-r--r--src/libcore/iter/mod.rs44
-rw-r--r--src/libcore/lib.rs1
-rw-r--r--src/libcore/mem.rs1
-rw-r--r--src/libcore/num/f32.rs4
-rw-r--r--src/libcore/num/f64.rs3
-rw-r--r--src/libcore/tests/iter.rs62
-rw-r--r--src/libcore/time.rs (renamed from src/libstd/time/duration.rs)15
-rw-r--r--src/libpanic_abort/lib.rs3
-rw-r--r--src/librustc/README.md1
-rw-r--r--src/librustc/dep_graph/dep_node.rs3
-rw-r--r--src/librustc/infer/error_reporting/mod.rs71
-rw-r--r--src/librustc/infer/error_reporting/note.rs10
-rw-r--r--src/librustc/lib.rs1
-rw-r--r--src/librustc/lint/builtin.rs10
-rw-r--r--src/librustc/lint/context.rs2
-rw-r--r--src/librustc/middle/region.rs9
-rw-r--r--src/librustc/middle/resolve_lifetime.rs16
-rw-r--r--src/librustc/mir/mod.rs2
-rw-r--r--src/librustc/session/config.rs2
-rw-r--r--src/librustc/session/mod.rs25
-rw-r--r--src/librustc/traits/coherence.rs50
-rw-r--r--src/librustc/traits/error_reporting.rs9
-rw-r--r--src/librustc/traits/mod.rs15
-rw-r--r--src/librustc/traits/select.rs104
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs37
-rw-r--r--src/librustc/traits/structural_impls.rs3
-rw-r--r--src/librustc/ty/layout.rs171
-rw-r--r--src/librustc/ty/maps/mod.rs1
-rw-r--r--src/librustc/ty/maps/plumbing.rs2
-rw-r--r--src/librustc/ty/sty.rs13
-rw-r--r--src/librustc_back/target/mod.rs7
-rw-r--r--src/librustc_back/target/msp430_none_elf.rs6
-rw-r--r--src/librustc_back/target/wasm32_unknown_unknown.rs3
-rw-r--r--src/librustc_borrowck/borrowck/unused.rs2
-rw-r--r--src/librustc_const_eval/check_match.rs11
-rw-r--r--src/librustc_const_eval/eval.rs3
-rw-r--r--src/librustc_const_eval/pattern.rs11
-rw-r--r--src/librustc_driver/lib.rs35
-rw-r--r--src/librustc_errors/diagnostic.rs37
-rw-r--r--src/librustc_errors/diagnostic_builder.rs10
-rw-r--r--src/librustc_errors/emitter.rs29
-rw-r--r--src/librustc_errors/lib.rs8
-rw-r--r--src/librustc_errors/snippet.rs24
-rw-r--r--src/librustc_errors/styled_buffer.rs21
-rw-r--r--src/librustc_lint/types.rs4
-rw-r--r--src/librustc_lint/unused.rs37
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs4
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/mod.rs36
-rw-r--r--src/librustc_mir/dataflow/impls/borrowed_locals.rs118
-rw-r--r--src/librustc_mir/dataflow/impls/borrows.rs3
-rw-r--r--src/librustc_mir/dataflow/impls/mod.rs4
-rw-r--r--src/librustc_mir/dataflow/mod.rs1
-rw-r--r--src/librustc_mir/interpret/eval_context.rs2
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs18
-rw-r--r--src/librustc_mir/transform/generator.rs68
-rw-r--r--src/librustc_mir/transform/inline.rs3
-rw-r--r--src/librustc_passes/loops.rs5
-rw-r--r--src/librustc_resolve/lib.rs12
-rw-r--r--src/librustc_trans/allocator.rs4
-rw-r--r--src/librustc_trans/asm.rs5
-rw-r--r--src/librustc_trans/back/symbol_export.rs3
-rw-r--r--src/librustc_trans/back/write.rs6
-rw-r--r--src/librustc_trans/context.rs3
-rw-r--r--src/librustc_trans/type_of.rs4
-rw-r--r--src/librustc_typeck/check/compare_method.rs37
-rw-r--r--src/librustc_typeck/check/generator_interior.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs7
-rw-r--r--src/librustc_typeck/coherence/inherent_impls_overlap.rs46
-rw-r--r--src/librustdoc/clean/mod.rs11
-rw-r--r--src/librustdoc/html/static/rustdoc.css30
-rw-r--r--src/librustdoc/test.rs1
-rw-r--r--src/libstd/Cargo.toml1
-rw-r--r--src/libstd/f32.rs1
-rw-r--r--src/libstd/fs.rs38
-rw-r--r--src/libstd/io/error.rs8
-rw-r--r--src/libstd/sys/cloudabi/thread.rs5
-rw-r--r--src/libstd/sys/redox/thread.rs5
-rw-r--r--src/libstd/sys/unix/stack_overflow.rs9
-rw-r--r--src/libstd/sys/unix/thread.rs115
-rw-r--r--src/libstd/sys/wasm/args.rs38
-rw-r--r--src/libstd/sys/wasm/mod.rs233
-rw-r--r--src/libstd/sys/wasm/os.rs38
-rw-r--r--src/libstd/sys/wasm/stdio.rs35
-rw-r--r--src/libstd/sys/wasm/thread.rs5
-rw-r--r--src/libstd/sys/wasm/time.rs44
-rw-r--r--src/libstd/sys/windows/thread.rs5
-rw-r--r--src/libstd/sys_common/thread_info.rs9
-rw-r--r--src/libstd/time.rs (renamed from src/libstd/time/mod.rs)4
-rw-r--r--src/libsyntax/ast.rs1
-rw-r--r--src/libsyntax/codemap.rs26
-rw-r--r--src/libsyntax/ext/build.rs1
-rw-r--r--src/libsyntax/feature_gate.rs15
-rw-r--r--src/libsyntax/fold.rs3
-rw-r--r--src/libsyntax/json.rs42
-rw-r--r--src/libsyntax/lib.rs1
-rw-r--r--src/libsyntax/parse/lexer/mod.rs32
-rw-r--r--src/libsyntax/parse/parser.rs7
-rw-r--r--src/libsyntax/parse/token.rs1
-rw-r--r--src/libsyntax/test_snippet.rs1
-rw-r--r--src/libsyntax_ext/deriving/encodable.rs16
-rw-r--r--src/libsyntax_pos/lib.rs23
-rw-r--r--src/rustllvm/PassWrapper.cpp11
-rw-r--r--src/test/codegen/function-arguments.rs4
-rw-r--r--src/test/codegen/stack-probes.rs2
-rw-r--r--src/test/compile-fail/E0195.rs3
-rw-r--r--src/test/compile-fail/associated-const-type-parameter-arms.rs7
-rw-r--r--src/test/compile-fail/issue-16048.rs5
-rw-r--r--src/test/compile-fail/nll/do-not-ignore-lifetime-bounds-in-copy.rs23
-rw-r--r--src/test/parse-fail/bad-char-literals.rs2
-rw-r--r--src/test/parse-fail/lex-stray-backslash.rs13
-rw-r--r--src/test/run-make/stdin-non-utf8/Makefile6
-rw-r--r--src/test/run-make/stdin-non-utf8/non-utf81
-rw-r--r--src/test/run-pass/generator/too-live-local-in-immovable-gen.rs28
-rw-r--r--src/test/run-pass/issue-47139-1.rs87
-rw-r--r--src/test/run-pass/issue-47139-2.rs75
-rw-r--r--src/test/run-pass/issue-47638.rs18
-rw-r--r--src/test/run-pass/issue-47789.rs20
-rw-r--r--src/test/run-pass/match-beginning-vert.rs28
-rw-r--r--src/test/run-pass/sse2.rs2
-rw-r--r--src/test/run-pass/stack-probes-lto.rs2
-rw-r--r--src/test/run-pass/stack-probes.rs2
-rw-r--r--src/test/rustdoc/const-evalutation-ice.rs22
-rw-r--r--src/test/ui/associated-const-impl-wrong-lifetime.stderr7
-rw-r--r--src/test/ui/blind-item-item-shadow.stderr4
-rw-r--r--src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs (renamed from src/test/compile-fail/regions-bound-missing-bound-in-impl.rs)0
-rw-r--r--src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr48
-rw-r--r--src/test/ui/closure-expected-type/expect-region-supply-region.stderr20
-rw-r--r--src/test/ui/double-import.stderr4
-rw-r--r--src/test/ui/feature-gate-match_beginning_vert.rs36
-rw-r--r--src/test/ui/feature-gate-match_beginning_vert.stderr26
-rw-r--r--src/test/ui/generator/generator-with-nll.stderr18
-rw-r--r--src/test/ui/generator/pattern-borrow.rs23
-rw-r--r--src/test/ui/generator/pattern-borrow.stderr10
-rw-r--r--src/test/ui/generator/sized-yield.rs21
-rw-r--r--src/test/ui/generator/sized-yield.stderr22
-rw-r--r--src/test/ui/generator/yield-while-local-borrowed.stderr18
-rw-r--r--src/test/ui/impl-trait/trait_type.stderr4
-rw-r--r--src/test/ui/imports/duplicate.stderr4
-rw-r--r--src/test/ui/in-band-lifetimes/ellided-lifetimes.rs19
-rw-r--r--src/test/ui/in-band-lifetimes/ellided-lifetimes.stderr14
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs22
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr22
-rw-r--r--src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr31
-rw-r--r--src/test/ui/issue-26886.stderr4
-rw-r--r--src/test/ui/issue-27942.stderr20
-rw-r--r--src/test/ui/issue-37884.stderr10
-rw-r--r--src/test/ui/issue-46472.stderr16
-rw-r--r--src/test/ui/issue-47706-trait.rs16
-rw-r--r--src/test/ui/issue-47706-trait.stderr12
-rw-r--r--src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs40
-rw-r--r--src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.stderr15
-rw-r--r--src/test/ui/lint/suggestions.rs8
-rw-r--r--src/test/ui/lint/suggestions.stderr68
-rw-r--r--src/test/ui/loop-break-value-no-repeat.stderr4
-rw-r--r--src/test/ui/macros/span-covering-argument-1.rs23
-rw-r--r--src/test/ui/macros/span-covering-argument-1.stderr13
-rw-r--r--src/test/ui/resolve-conflict-item-vs-import.stderr4
-rw-r--r--src/test/ui/span/macro-span-replacement.stderr4
-rw-r--r--src/test/ui/static-lifetime.stderr2
-rw-r--r--src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr2
-rw-r--r--src/test/ui/use-mod.stderr2
-rw-r--r--src/tools/compiletest/src/header.rs2
-rw-r--r--src/tools/compiletest/src/runtest.rs8
m---------src/tools/rls0
m---------src/tools/rustfmt24
179 files changed, 2480 insertions, 981 deletions
diff --git a/config.toml.example b/config.toml.example
index 1d60d8c9494..9ca0f563d0a 100644
--- a/config.toml.example
+++ b/config.toml.example
@@ -312,6 +312,11 @@
 # bootstrap)
 #codegen-backends = ["llvm"]
 
+# Flag indicating whether `libstd` calls an imported function to hande basic IO
+# when targetting WebAssembly. Enable this to debug tests for the `wasm32-unknown-unknown`
+# target, as without this option the test output will not be captured.
+#wasm-syscall = false
+
 # =============================================================================
 # Options for specific targets
 #
diff --git a/src/Cargo.lock b/src/Cargo.lock
index d26098903ee..fc89cc4ea9e 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -1618,7 +1618,7 @@ version = "0.1.0"
 
 [[package]]
 name = "rls"
-version = "0.124.0"
+version = "0.125.0"
 dependencies = [
  "cargo 0.26.0",
  "env_logger 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1635,7 +1635,7 @@ dependencies = [
  "rls-rustc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfmt-nightly 0.3.6",
+ "rustfmt-nightly 0.3.8",
  "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1723,7 +1723,7 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_cratesio_shim"
-version = "12.0.0"
+version = "29.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1732,57 +1732,57 @@ dependencies = [
 
 [[package]]
 name = "rustc-ap-rustc_data_structures"
-version = "12.0.0"
+version = "29.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cfg-if 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "parking_lot_core 0.2.9 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-rustc_errors"
-version = "12.0.0"
+version = "29.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-serialize"
-version = "12.0.0"
+version = "29.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "rustc-ap-syntax"
-version = "12.0.0"
+version = "29.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_cratesio_shim 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
 [[package]]
 name = "rustc-ap-syntax_pos"
-version = "12.0.0"
+version = "29.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -2207,7 +2207,7 @@ dependencies = [
 
 [[package]]
 name = "rustfmt-nightly"
-version = "0.3.6"
+version = "0.3.8"
 dependencies = [
  "cargo_metadata 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "derive-new 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2219,8 +2219,8 @@ dependencies = [
  "libc 0.2.36 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-ap-syntax 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.27 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.9 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -3068,12 +3068,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rls-rustc 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "85cfb9dde19e313da3e47738008f8a472e470cc42d910b71595a9238494701f2"
 "checksum rls-span 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d7c7046dc6a92f2ae02ed302746db4382e75131b9ce20ce967259f6b5867a6a"
 "checksum rls-vfs 0.4.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ffd34691a510938bb67fe0444fb363103c73ffb31c121d1e16bc92d8945ea8ff"
-"checksum rustc-ap-rustc_cratesio_shim 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "f1a51c10af5abd5d698b7e3487e869e6d15f6feb04cbedb5c792e2824f9d845e"
-"checksum rustc-ap-rustc_data_structures 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1aa227490501072780d57f74b1164d361833ff8e172f817da0da2cdf2e4280cc"
-"checksum rustc-ap-rustc_errors 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "21ff6c6e13ac4fc04b7d4d398828b024c4b6577045cb3175b33d35fea35ff6d0"
-"checksum rustc-ap-serialize 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6b4e7f51e298675c2bf830f7265621a8936fb09e63b825b58144cbaac969e604"
-"checksum rustc-ap-syntax 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8bf5639869ba2f7fa581939cd217cb71a85506b82ad0ea520614fb0dceb2386c"
-"checksum rustc-ap-syntax_pos 12.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "1c020cdb7379e1c733ae0a311ae47c748337ba584d2dd7b7f53baaae78de6f8b"
+"checksum rustc-ap-rustc_cratesio_shim 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ad5e562044ea78a6764dd75ae8afe4b21fde49f4548024b5fdf6345c21fb524"
+"checksum rustc-ap-rustc_data_structures 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d4c0d65325492aba7db72899e3edbab34d39af98c42ab7c7e450c9a288ffe4ad"
+"checksum rustc-ap-rustc_errors 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "87d4ab2e06a671b5b5c5b0359dac346f164c99d059dce6a22feb08f2f56bd182"
+"checksum rustc-ap-serialize 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e0745fa445ff41c4b6699936cf35ce3ca49502377dd7b3929c829594772c3a7b"
+"checksum rustc-ap-syntax 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "82efedabe30f393161e11214a9130edfa01ad476372d1c6f3fec1f8d30488c9d"
+"checksum rustc-ap-syntax_pos 29.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "db9de2e927e280c75b8efab9c5f591ad31082d5d2c4c562c68fdba2ee77286b0"
 "checksum rustc-demangle 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "aee45432acc62f7b9a108cc054142dac51f979e69e71ddce7d6fc7adf29e817e"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs
index 1272643edd2..780513dd943 100644
--- a/src/bootstrap/builder.rs
+++ b/src/bootstrap/builder.rs
@@ -377,6 +377,11 @@ impl<'a> Builder<'a> {
         self.ensure(Libdir { compiler, target })
     }
 
+    pub fn sysroot_codegen_backends(&self, compiler: Compiler) -> PathBuf {
+        self.sysroot_libdir(compiler, compiler.host)
+            .with_file_name("codegen-backends")
+    }
+
     /// Returns the compiler's libdir where it stores the dynamic libraries that
     /// it itself links against.
     ///
diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs
index fa289bbd76a..1d5e11c5d6d 100644
--- a/src/bootstrap/compile.rs
+++ b/src/bootstrap/compile.rs
@@ -724,8 +724,7 @@ fn copy_codegen_backends_to_sysroot(builder: &Builder,
     //
     // Here we're looking for the output dylib of the `CodegenBackend` step and
     // we're copying that into the `codegen-backends` folder.
-    let libdir = builder.sysroot_libdir(target_compiler, target);
-    let dst = libdir.join("codegen-backends");
+    let dst = builder.sysroot_codegen_backends(target_compiler);
     t!(fs::create_dir_all(&dst));
 
     for backend in builder.config.rust_codegen_backends.iter() {
diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs
index dbeb27cbfb7..0da04bebac5 100644
--- a/src/bootstrap/config.rs
+++ b/src/bootstrap/config.rs
@@ -107,6 +107,7 @@ pub struct Config {
     pub debug_jemalloc: bool,
     pub use_jemalloc: bool,
     pub backtrace: bool, // support for RUST_BACKTRACE
+    pub wasm_syscall: bool,
 
     // misc
     pub low_priority: bool,
@@ -282,6 +283,7 @@ struct Rust {
     test_miri: Option<bool>,
     save_toolstates: Option<String>,
     codegen_backends: Option<Vec<String>>,
+    wasm_syscall: Option<bool>,
 }
 
 /// TOML representation of how each build target is configured.
@@ -463,6 +465,7 @@ impl Config {
             set(&mut config.rust_dist_src, rust.dist_src);
             set(&mut config.quiet_tests, rust.quiet_tests);
             set(&mut config.test_miri, rust.test_miri);
+            set(&mut config.wasm_syscall, rust.wasm_syscall);
             config.rustc_parallel_queries = rust.experimental_parallel_queries.unwrap_or(false);
             config.rustc_default_linker = rust.default_linker.clone();
             config.musl_root = rust.musl_root.clone().map(PathBuf::from);
diff --git a/src/bootstrap/dist.rs b/src/bootstrap/dist.rs
index 4127239dc49..dbb7d19e432 100644
--- a/src/bootstrap/dist.rs
+++ b/src/bootstrap/dist.rs
@@ -435,11 +435,9 @@ impl Step for Rustc {
             }
 
             // Copy over the codegen backends
-            let backends_src = builder.sysroot_libdir(compiler, host)
-                .join("codegen-backends");
-            let backends_dst = image.join("lib/rustlib")
-                .join(&*host)
-                .join("lib/codegen-backends");
+            let backends_src = builder.sysroot_codegen_backends(compiler);
+            let backends_rel = backends_src.strip_prefix(&src).unwrap();
+            let backends_dst = image.join(&backends_rel);
             t!(fs::create_dir_all(&backends_dst));
             cp_r(&backends_src, &backends_dst);
 
diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs
index aae0a4f056f..f2a7ce30c8a 100644
--- a/src/bootstrap/lib.rs
+++ b/src/bootstrap/lib.rs
@@ -423,6 +423,9 @@ impl Build {
         if self.config.profiler {
             features.push_str(" profiler");
         }
+        if self.config.wasm_syscall {
+            features.push_str(" wasm_syscall");
+        }
         features
     }
 
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index a316b0f7ef9..e4c1cdb79fd 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -610,7 +610,6 @@ static HOST_COMPILETESTS: &[Test] = &[
         mode: "incremental",
         suite: "incremental-fulldeps",
     },
-    Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" },
     Test { path: "src/test/rustdoc", mode: "rustdoc", suite: "rustdoc" },
 
     Test { path: "src/test/pretty", mode: "pretty", suite: "pretty" },
@@ -619,6 +618,7 @@ static HOST_COMPILETESTS: &[Test] = &[
     Test { path: "src/test/run-pass-valgrind/pretty", mode: "pretty", suite: "run-pass-valgrind" },
     Test { path: "src/test/run-pass-fulldeps/pretty", mode: "pretty", suite: "run-pass-fulldeps" },
     Test { path: "src/test/run-fail-fulldeps/pretty", mode: "pretty", suite: "run-fail-fulldeps" },
+    Test { path: "src/test/run-make", mode: "run-make", suite: "run-make" },
 ];
 
 #[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
@@ -1286,6 +1286,14 @@ impl Step for Crate {
             cargo.env(format!("CARGO_TARGET_{}_RUNNER", envify(&target)),
                       build.config.nodejs.as_ref().expect("nodejs not configured"));
         } else if target.starts_with("wasm32") {
+            // Warn about running tests without the `wasm_syscall` feature enabled.
+            // The javascript shim implements the syscall interface so that test
+            // output can be correctly reported.
+            if !build.config.wasm_syscall {
+                println!("Libstd was built without `wasm_syscall` feature enabled: \
+                          test output may not be visible.");
+            }
+
             // On the wasm32-unknown-unknown target we're using LTO which is
             // incompatible with `-C prefer-dynamic`, so disable that here
             cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
diff --git a/src/doc/unstable-book/src/language-features/lang-items.md b/src/doc/unstable-book/src/language-features/lang-items.md
index 0137a052a62..c5167418614 100644
--- a/src/doc/unstable-book/src/language-features/lang-items.md
+++ b/src/doc/unstable-book/src/language-features/lang-items.md
@@ -37,28 +37,23 @@ unsafe fn allocate(size: usize, _align: usize) -> *mut u8 {
     p
 }
 
-#[lang = "exchange_free"]
-unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
-    libc::free(ptr as *mut libc::c_void)
-}
-
 #[lang = "box_free"]
 unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
-    deallocate(ptr as *mut u8, ::core::mem::size_of_val(&*ptr), ::core::mem::align_of_val(&*ptr));
+    libc::free(ptr as *mut libc::c_void)
 }
 
 #[start]
-fn main(argc: isize, argv: *const *const u8) -> isize {
-    let x = box 1;
+fn main(_argc: isize, _argv: *const *const u8) -> isize {
+    let _x = box 1;
 
     0
 }
 
 #[lang = "eh_personality"] extern fn rust_eh_personality() {}
 #[lang = "panic_fmt"] extern fn rust_begin_panic() -> ! { unsafe { intrinsics::abort() } }
-# #[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
-# #[no_mangle] pub extern fn rust_eh_register_frames () {}
-# #[no_mangle] pub extern fn rust_eh_unregister_frames () {}
+#[lang = "eh_unwind_resume"] extern fn rust_eh_unwind_resume() {}
+#[no_mangle] pub extern fn rust_eh_register_frames () {}
+#[no_mangle] pub extern fn rust_eh_unregister_frames () {}
 ```
 
 Note the use of `abort`: the `exchange_malloc` lang item is assumed to
@@ -80,7 +75,7 @@ Other features provided by lang items include:
 
 Lang items are loaded lazily by the compiler; e.g. if one never uses
 `Box` then there is no need to define functions for `exchange_malloc`
-and `exchange_free`. `rustc` will emit an error when an item is needed
+and `box_free`. `rustc` will emit an error when an item is needed
 but not found in the current crate or any that it depends on.
 
 Most lang items are defined by `libcore`, but if you're trying to build
@@ -318,4 +313,4 @@ the source code.
   - `phantom_data`: `libcore/marker.rs`
   - `freeze`: `libcore/marker.rs`
   - `debug_trait`: `libcore/fmt/mod.rs`
-  - `non_zero`: `libcore/nonzero.rs`
\ No newline at end of file
+  - `non_zero`: `libcore/nonzero.rs`
diff --git a/src/doc/unstable-book/src/language-features/match-beginning-vert.md b/src/doc/unstable-book/src/language-features/match-beginning-vert.md
deleted file mode 100644
index f0a51af7fd1..00000000000
--- a/src/doc/unstable-book/src/language-features/match-beginning-vert.md
+++ /dev/null
@@ -1,23 +0,0 @@
-# `match_beginning_vert`
-
-The tracking issue for this feature is [#44101].
-
-With this feature enabled, you are allowed to add a '|' to the beginning of a
-match arm:
-
-```rust
-#![feature(match_beginning_vert)]
-
-enum Foo { A, B, C }
-
-fn main() {
-    let x = Foo::A;
-    match x {
-        | Foo::A 
-        | Foo::B => println!("AB"),
-        | Foo::C => println!("C"),
-    }
-}
-```
-
-[#44101]: https://github.com/rust-lang/rust/issues/44101
\ No newline at end of file
diff --git a/src/etc/wasm32-shim.js b/src/etc/wasm32-shim.js
index d55083e0f8e..69647f37eec 100644
--- a/src/etc/wasm32-shim.js
+++ b/src/etc/wasm32-shim.js
@@ -28,14 +28,76 @@ let m = new WebAssembly.Module(buffer);
 
 let memory = null;
 
+function viewstruct(data, fields) {
+  return new Uint32Array(memory.buffer).subarray(data/4, data/4 + fields);
+}
+
 function copystr(a, b) {
-  if (memory === null) {
-    return null
-  }
-  let view = new Uint8Array(memory.buffer).slice(a, a + b);
+  let view = new Uint8Array(memory.buffer).subarray(a, a + b);
   return String.fromCharCode.apply(null, view);
 }
 
+function syscall_write([fd, ptr, len]) {
+  let s = copystr(ptr, len);
+  switch (fd) {
+    case 1: process.stdout.write(s); break;
+    case 2: process.stderr.write(s); break;
+  }
+}
+
+function syscall_exit([code]) {
+  process.exit(code);
+}
+
+function syscall_args(params) {
+  let [ptr, len] = params;
+
+  // Calculate total required buffer size
+  let totalLen = -1;
+  for (let i = 2; i < process.argv.length; ++i) {
+    totalLen += Buffer.byteLength(process.argv[i]) + 1;
+  }
+  if (totalLen < 0) { totalLen = 0; }
+  params[2] = totalLen;
+
+  // If buffer is large enough, copy data
+  if (len >= totalLen) {
+    let view = new Uint8Array(memory.buffer);
+    for (let i = 2; i < process.argv.length; ++i) {
+      let value = process.argv[i];
+      Buffer.from(value).copy(view, ptr);
+      ptr += Buffer.byteLength(process.argv[i]) + 1;
+    }
+  }
+}
+
+function syscall_getenv(params) {
+  let [keyPtr, keyLen, valuePtr, valueLen] = params;
+
+  let key = copystr(keyPtr, keyLen);
+  let value = process.env[key];
+
+  if (value == null) {
+    params[4] = 0xFFFFFFFF;
+  } else {
+    let view = new Uint8Array(memory.buffer);
+    let totalLen = Buffer.byteLength(value);
+    params[4] = totalLen;
+    if (valueLen >= totalLen) {
+      Buffer.from(value).copy(view, valuePtr);
+    }
+  }
+}
+
+function syscall_time(params) {
+  let t = Date.now();
+  let secs = Math.floor(t / 1000);
+  let millis = t % 1000;
+  params[1] = Math.floor(secs / 0x100000000);
+  params[2] = secs % 0x100000000;
+  params[3] = Math.floor(millis * 1000000);
+}
+
 let imports = {};
 imports.env = {
   // These are generated by LLVM itself for various intrinsic calls. Hopefully
@@ -48,68 +110,25 @@ imports.env = {
   log10: Math.log10,
   log10f: Math.log10,
 
-  // These are called in src/libstd/sys/wasm/stdio.rs and are used when
-  // debugging is enabled.
-  rust_wasm_write_stdout: function(a, b) {
-    let s = copystr(a, b);
-    if (s !== null) {
-      process.stdout.write(s);
-    }
-  },
-  rust_wasm_write_stderr: function(a, b) {
-    let s = copystr(a, b);
-    if (s !== null) {
-      process.stderr.write(s);
-    }
-  },
-
-  // These are called in src/libstd/sys/wasm/args.rs and are used when
-  // debugging is enabled.
-  rust_wasm_args_count: function() {
-    if (memory === null)
-      return 0;
-    return process.argv.length - 2;
-  },
-  rust_wasm_args_arg_size: function(i) {
-    return Buffer.byteLength(process.argv[i + 2]);
-  },
-  rust_wasm_args_arg_fill: function(idx, ptr) {
-    let arg = process.argv[idx + 2];
-    let view = new Uint8Array(memory.buffer);
-    Buffer.from(arg).copy(view, ptr);
-  },
-
-  // These are called in src/libstd/sys/wasm/os.rs and are used when
-  // debugging is enabled.
-  rust_wasm_getenv_len: function(a, b) {
-    let key = copystr(a, b);
-    if (key === null) {
-      return -1;
+  rust_wasm_syscall: function(index, data) {
+    switch (index) {
+      case 1: syscall_write(viewstruct(data, 3)); return true;
+      case 2: syscall_exit(viewstruct(data, 1)); return true;
+      case 3: syscall_args(viewstruct(data, 3)); return true;
+      case 4: syscall_getenv(viewstruct(data, 5)); return true;
+      case 6: syscall_time(viewstruct(data, 4)); return true;
+      default:
+        console.log("Unsupported syscall: " + index);
+        return false;
     }
-    if (!(key in process.env)) {
-      return -1;
-    }
-    return Buffer.byteLength(process.env[key]);
-  },
-  rust_wasm_getenv_data: function(a, b, ptr) {
-    let key = copystr(a, b);
-    let value = process.env[key];
-    let view = new Uint8Array(memory.buffer);
-    Buffer.from(value).copy(view, ptr);
-  },
-};
-
-let module_imports = WebAssembly.Module.imports(m);
-
-for (var i = 0; i < module_imports.length; i++) {
-  let imp = module_imports[i];
-  if (imp.module != 'env') {
-    continue
   }
-  if (imp.name == 'memory' && imp.kind == 'memory') {
-    memory = new WebAssembly.Memory({initial: 20});
-    imports.env.memory = memory;
-  }
-}
+};
 
 let instance = new WebAssembly.Instance(m, imports);
+memory = instance.exports.memory;
+try {
+  instance.exports.main();
+} catch (e) {
+  console.error(e);
+  process.exit(101);
+}
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index 65aacb23bd7..6c8a1c3062b 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -1586,6 +1586,7 @@ impl Display for ! {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Debug for bool {
+    #[inline]
     fn fmt(&self, f: &mut Formatter) -> Result {
         Display::fmt(self, f)
     }
@@ -1748,6 +1749,7 @@ impl<T: Debug> Debug for [T] {
 
 #[stable(feature = "rust1", since = "1.0.0")]
 impl Debug for () {
+    #[inline]
     fn fmt(&self, f: &mut Formatter) -> Result {
         f.pad("()")
     }
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index ee989854a37..2992e7cf8db 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -157,6 +157,7 @@ macro_rules! debug {
     ($T:ident) => {
         #[stable(feature = "rust1", since = "1.0.0")]
         impl fmt::Debug for $T {
+            #[inline]
             fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                 fmt::Display::fmt(self, f)
             }
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index a611dc02469..a05d67a304f 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -992,7 +992,7 @@ extern "rust-intrinsic" {
     ///         ptr::copy_nonoverlapping(y, x, 1);
     ///         ptr::copy_nonoverlapping(&t, y, 1);
     ///
-    ///         // y and t now point to the same thing, but we need to completely forget `tmp`
+    ///         // y and t now point to the same thing, but we need to completely forget `t`
     ///         // because it's no longer relevant.
     ///         mem::forget(t);
     ///     }
diff --git a/src/libcore/iter/mod.rs b/src/libcore/iter/mod.rs
index 06c29b47bf9..7314fac282b 100644
--- a/src/libcore/iter/mod.rs
+++ b/src/libcore/iter/mod.rs
@@ -307,6 +307,7 @@ use fmt;
 use iter_private::TrustedRandomAccess;
 use ops::Try;
 use usize;
+use intrinsics;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use self::iterator::Iterator;
@@ -694,6 +695,49 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
             (f(inner_hint.0), inner_hint.1.map(f))
         }
     }
+
+    #[inline]
+    fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
+        if self.first_take {
+            self.first_take = false;
+            let first = self.iter.next();
+            if n == 0 {
+                return first;
+            }
+            n -= 1;
+        }
+        // n and self.step are indices, we need to add 1 to get the amount of elements
+        // When calling `.nth`, we need to subtract 1 again to convert back to an index
+        // step + 1 can't overflow because `.step_by` sets `self.step` to `step - 1`
+        let mut step = self.step + 1;
+        // n + 1 could overflow
+        // thus, if n is usize::MAX, instead of adding one, we call .nth(step)
+        if n == usize::MAX {
+            self.iter.nth(step - 1);
+        } else {
+            n += 1;
+        }
+
+        // overflow handling
+        loop {
+            let mul = n.checked_mul(step);
+            if unsafe { intrinsics::likely(mul.is_some()) } {
+                return self.iter.nth(mul.unwrap() - 1);
+            }
+            let div_n = usize::MAX / n;
+            let div_step = usize::MAX / step;
+            let nth_n = div_n * n;
+            let nth_step = div_step * step;
+            let nth = if nth_n > nth_step {
+                step -= div_n;
+                nth_n
+            } else {
+                n -= div_step;
+                nth_step
+            };
+            self.iter.nth(nth - 1);
+        }
+    }
 }
 
 // StepBy can only make the iterator shorter, so the len will still fit.
diff --git a/src/libcore/lib.rs b/src/libcore/lib.rs
index 7f094e580ab..59a296c2a76 100644
--- a/src/libcore/lib.rs
+++ b/src/libcore/lib.rs
@@ -169,6 +169,7 @@ pub mod slice;
 pub mod str;
 pub mod hash;
 pub mod fmt;
+pub mod time;
 
 // note: does not need to be public
 mod char_private;
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index 93f6a0214d7..21a0beccbf6 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -189,6 +189,7 @@ pub fn forget<T>(t: T) {
 /// Type | size_of::\<Type>()
 /// ---- | ---------------
 /// () | 0
+/// bool | 1
 /// u8 | 1
 /// u16 | 2
 /// u32 | 4
diff --git a/src/libcore/num/f32.rs b/src/libcore/num/f32.rs
index 207df84d080..3586fa5442f 100644
--- a/src/libcore/num/f32.rs
+++ b/src/libcore/num/f32.rs
@@ -239,7 +239,9 @@ impl Float for f32 {
     /// Converts to degrees, assuming the number is in radians.
     #[inline]
     fn to_degrees(self) -> f32 {
-        self * (180.0f32 / consts::PI)
+        // Use a constant for better precision.
+        const PIS_IN_180: f32 = 57.2957795130823208767981548141051703_f32;
+        self * PIS_IN_180
     }
 
     /// Converts to radians, assuming the number is in degrees.
diff --git a/src/libcore/num/f64.rs b/src/libcore/num/f64.rs
index 9206132e8b4..64c0d508b38 100644
--- a/src/libcore/num/f64.rs
+++ b/src/libcore/num/f64.rs
@@ -237,6 +237,9 @@ impl Float for f64 {
     /// Converts to degrees, assuming the number is in radians.
     #[inline]
     fn to_degrees(self) -> f64 {
+        // The division here is correctly rounded with respect to the true
+        // value of 180/π. (This differs from f32, where a constant must be
+        // used to ensure a correctly rounded result.)
         self * (180.0f64 / consts::PI)
     }
 
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 8997cf9c6bf..e52e119ff59 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -162,6 +162,68 @@ fn test_iterator_step_by() {
 }
 
 #[test]
+fn test_iterator_step_by_nth() {
+    let mut it = (0..16).step_by(5);
+    assert_eq!(it.nth(0), Some(0));
+    assert_eq!(it.nth(0), Some(5));
+    assert_eq!(it.nth(0), Some(10));
+    assert_eq!(it.nth(0), Some(15));
+    assert_eq!(it.nth(0), None);
+
+    let it = (0..18).step_by(5);
+    assert_eq!(it.clone().nth(0), Some(0));
+    assert_eq!(it.clone().nth(1), Some(5));
+    assert_eq!(it.clone().nth(2), Some(10));
+    assert_eq!(it.clone().nth(3), Some(15));
+    assert_eq!(it.clone().nth(4), None);
+    assert_eq!(it.clone().nth(42), None);
+}
+
+#[test]
+fn test_iterator_step_by_nth_overflow() {
+    #[cfg(target_pointer_width = "8")]
+    type Bigger = u16;
+    #[cfg(target_pointer_width = "16")]
+    type Bigger = u32;
+    #[cfg(target_pointer_width = "32")]
+    type Bigger = u64;
+    #[cfg(target_pointer_width = "64")]
+    type Bigger = u128;
+
+    #[derive(Clone)]
+    struct Test(Bigger);
+    impl<'a> Iterator for &'a mut Test {
+        type Item = i32;
+        fn next(&mut self) -> Option<Self::Item> { Some(21) }
+        fn nth(&mut self, n: usize) -> Option<Self::Item> {
+            self.0 += n as Bigger + 1;
+            Some(42)
+        }
+    }
+
+    let mut it = Test(0);
+    let root = usize::MAX >> (::std::mem::size_of::<usize>() * 8 / 2);
+    let n = root + 20;
+    (&mut it).step_by(n).nth(n);
+    assert_eq!(it.0, n as Bigger * n as Bigger);
+
+    // large step
+    let mut it = Test(0);
+    (&mut it).step_by(usize::MAX).nth(5);
+    assert_eq!(it.0, (usize::MAX as Bigger) * 5);
+
+    // n + 1 overflows
+    let mut it = Test(0);
+    (&mut it).step_by(2).nth(usize::MAX);
+    assert_eq!(it.0, (usize::MAX as Bigger) * 2);
+
+    // n + 1 overflows
+    let mut it = Test(0);
+    (&mut it).step_by(1).nth(usize::MAX);
+    assert_eq!(it.0, (usize::MAX as Bigger) * 1);
+}
+
+#[test]
 #[should_panic]
 fn test_iterator_step_by_zero() {
     let mut it = (0..).step_by(0);
diff --git a/src/libstd/time/duration.rs b/src/libcore/time.rs
index ee444830be4..1a0208d2f25 100644
--- a/src/libstd/time/duration.rs
+++ b/src/libcore/time.rs
@@ -7,6 +7,19 @@
 // <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.
+#![stable(feature = "duration_core", since = "1.24.0")]
+
+//! Temporal quantification.
+//!
+//! Example:
+//!
+//! ```
+//! use std::time::Duration;
+//!
+//! let five_seconds = Duration::new(5, 0);
+//! // both declarations are equivalent
+//! assert_eq!(Duration::new(5, 0), Duration::from_secs(5));
+//! ```
 
 use iter::Sum;
 use ops::{Add, Sub, Mul, Div, AddAssign, SubAssign, MulAssign, DivAssign};
@@ -45,7 +58,7 @@ const MICROS_PER_SEC: u64 = 1_000_000;
 ///
 /// let ten_millis = Duration::from_millis(10);
 /// ```
-#[stable(feature = "duration", since = "1.3.0")]
+#[stable(feature = "duration_core", since = "1.24.0")]
 #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Hash, Default)]
 pub struct Duration {
     secs: u64,
diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs
index c3bd6a2bc18..5f768ef4399 100644
--- a/src/libpanic_abort/lib.rs
+++ b/src/libpanic_abort/lib.rs
@@ -27,10 +27,12 @@
 #![feature(libc)]
 #![feature(panic_runtime)]
 #![feature(staged_api)]
+#![feature(rustc_attrs)]
 
 // Rust's "try" function, but if we're aborting on panics we just call the
 // function as there's nothing else we need to do here.
 #[no_mangle]
+#[rustc_std_internal_symbol]
 pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
                                               data: *mut u8,
                                               _data_ptr: *mut usize,
@@ -50,6 +52,7 @@ pub unsafe extern fn __rust_maybe_catch_panic(f: fn(*mut u8),
 // will kill us with an illegal instruction, which will do a good enough job for
 // now hopefully.
 #[no_mangle]
+#[rustc_std_internal_symbol]
 pub unsafe extern fn __rust_start_panic(_data: usize, _vtable: usize) -> u32 {
     abort();
 
diff --git a/src/librustc/README.md b/src/librustc/README.md
index ddf71a06d60..722456a76ce 100644
--- a/src/librustc/README.md
+++ b/src/librustc/README.md
@@ -176,6 +176,7 @@ pointers for understanding them better.
 - `'gcx` -- the lifetime of the global arena (see `librustc/ty`).
 - generics -- the set of generic type parameters defined on a type or item
 - ICE -- internal compiler error. When the compiler crashes.
+- ICH -- incremental compilation hash.
 - infcx -- the inference context (see `librustc/infer`)
 - MIR -- the **Mid-level IR** that is created after type-checking for use by borrowck and trans.
   Defined in the `src/librustc/mir/` module, but much of the code that manipulates it is
diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs
index 1de9091b5df..4034055d041 100644
--- a/src/librustc/dep_graph/dep_node.rs
+++ b/src/librustc/dep_graph/dep_node.rs
@@ -639,6 +639,9 @@ define_dep_nodes!( <'tcx>
     [] TargetFeaturesEnabled(DefId),
 
     [] InstanceDefSizeEstimate { instance_def: InstanceDef<'tcx> },
+
+    [] GetSymbolExportLevel(DefId),
+
 );
 
 trait DepNodeParams<'a, 'gcx: 'tcx + 'a, 'tcx: 'a> : fmt::Debug {
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index b10e7425957..03fc40b2e39 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -175,25 +175,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
             ty::ReEarlyBound(_) |
             ty::ReFree(_) => {
                 let scope = region.free_region_binding_scope(self);
-                let prefix = match *region {
-                    ty::ReEarlyBound(ref br) => {
-                        format!("the lifetime {} as defined on", br.name)
-                    }
-                    ty::ReFree(ref fr) => {
-                        match fr.bound_region {
-                            ty::BrAnon(idx) => {
-                                format!("the anonymous lifetime #{} defined on", idx + 1)
-                            }
-                            ty::BrFresh(_) => "an anonymous lifetime defined on".to_owned(),
-                            _ => {
-                                format!("the lifetime {} as defined on",
-                                        fr.bound_region)
-                            }
-                        }
-                    }
-                    _ => bug!()
-                };
-
                 let node = self.hir.as_local_node_id(scope)
                                    .unwrap_or(DUMMY_NODE_ID);
                 let unknown;
@@ -218,7 +199,26 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
                         &unknown
                     }
                 };
-                let (msg, opt_span) = explain_span(self, tag, self.hir.span(node));
+                let (prefix, span) = match *region {
+                    ty::ReEarlyBound(ref br) => {
+                        (format!("the lifetime {} as defined on", br.name),
+                         self.sess.codemap().def_span(self.hir.span(node)))
+                    }
+                    ty::ReFree(ref fr) => {
+                        match fr.bound_region {
+                            ty::BrAnon(idx) => {
+                                (format!("the anonymous lifetime #{} defined on", idx + 1),
+                                 self.hir.span(node))
+                            }
+                            ty::BrFresh(_) => ("an anonymous lifetime defined on".to_owned(),
+                                               self.hir.span(node)),
+                            _ => (format!("the lifetime {} as defined on", fr.bound_region),
+                                  self.sess.codemap().def_span(self.hir.span(node))),
+                        }
+                    }
+                    _ => bug!()
+                };
+                let (msg, opt_span) = explain_span(self, tag, span);
                 (format!("{} {}", prefix, msg), opt_span)
             }
 
@@ -807,7 +807,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             }
         };
 
-        let span = cause.span;
+        let span = cause.span(&self.tcx);
 
         diag.span_label(span, terr.to_string());
         if let Some((sp, msg)) = secondary_span {
@@ -842,7 +842,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                                     "did you mean `{}(/* fields */)`?",
                                     self.tcx.item_path_str(def_id)
                                 );
-                                diag.span_label(cause.span, message);
+                                diag.span_label(span, message);
                             }
                         }
                     }
@@ -870,7 +870,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                trace,
                terr);
 
-        let span = trace.cause.span;
+        let span = trace.cause.span(&self.tcx);
         let failure_code = trace.cause.as_failure_code(terr);
         let mut diag = match failure_code {
             FailureCode::Error0317(failure_str) => {
@@ -1076,6 +1076,31 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
             sup_region,
             "...");
 
+        match (&sup_origin, &sub_origin) {
+            (&infer::Subtype(ref sup_trace), &infer::Subtype(ref sub_trace)) => {
+                if let (Some((sup_expected, sup_found)),
+                        Some((sub_expected, sub_found))) = (self.values_str(&sup_trace.values),
+                                                            self.values_str(&sub_trace.values)) {
+                    if sub_expected == sup_expected && sub_found == sup_found {
+                        self.tcx.note_and_explain_region(
+                            region_scope_tree,
+                            &mut err,
+                            "...but the lifetime must also be valid for ",
+                            sub_region,
+                            "...",
+                        );
+                        err.note(&format!("...so that the {}:\nexpected {}\n   found {}",
+                                          sup_trace.cause.as_requirement_str(),
+                                          sup_expected.content(),
+                                          sup_found.content()));
+                        err.emit();
+                        return;
+                    }
+                }
+            }
+            _ => {}
+        }
+
         self.note_region_origin(&mut err, &sup_origin);
 
         self.tcx.note_and_explain_region(region_scope_tree, &mut err,
diff --git a/src/librustc/infer/error_reporting/note.rs b/src/librustc/infer/error_reporting/note.rs
index e46613b3e4d..02ec9fe74c1 100644
--- a/src/librustc/infer/error_reporting/note.rs
+++ b/src/librustc/infer/error_reporting/note.rs
@@ -23,12 +23,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 if let Some((expected, found)) = self.values_str(&trace.values) {
                     let expected = expected.content();
                     let found = found.content();
-                    // FIXME: do we want a "the" here?
-                    err.span_note(trace.cause.span,
-                                  &format!("...so that {} (expected {}, found {})",
-                                           trace.cause.as_requirement_str(),
-                                           expected,
-                                           found));
+                    err.note(&format!("...so that the {}:\nexpected {}\n   found {}",
+                                      trace.cause.as_requirement_str(),
+                                      expected,
+                                      found));
                 } else {
                     // FIXME: this really should be handled at some earlier stage. Our
                     // handling of region checking when type errors are present is
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index d727dfb0c4b..db6863d6dad 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -66,6 +66,7 @@
 #![feature(specialization)]
 #![feature(unboxed_closures)]
 #![feature(underscore_lifetimes)]
+#![feature(universal_impl_trait)]
 #![feature(trace_macros)]
 #![feature(catch_expr)]
 #![feature(test)]
diff --git a/src/librustc/lint/builtin.rs b/src/librustc/lint/builtin.rs
index 143d2c2ea28..0577800f3f4 100644
--- a/src/librustc/lint/builtin.rs
+++ b/src/librustc/lint/builtin.rs
@@ -246,6 +246,12 @@ declare_lint! {
     "raw pointer to an inference variable"
 }
 
+declare_lint! {
+    pub ELIDED_LIFETIME_IN_PATH,
+    Allow,
+    "hidden lifetime parameters are deprecated, try `Foo<'_>`"
+}
+
 /// Does nothing as a lint pass, but registers some `Lint`s
 /// which are used by other parts of the compiler.
 #[derive(Copy, Clone)]
@@ -291,7 +297,9 @@ impl LintPass for HardwiredLints {
             UNUSED_MUT,
             COERCE_NEVER,
             SINGLE_USE_LIFETIME,
-            TYVAR_BEHIND_RAW_POINTER
+            TYVAR_BEHIND_RAW_POINTER,
+            ELIDED_LIFETIME_IN_PATH
+
         )
     }
 }
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 5336c1944e8..929d5e7ec62 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -631,7 +631,7 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a LateContext<'a, 'tcx> {
     type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
 
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
-        (self.tcx, self.param_env.reveal_all()).layout_of(ty)
+        self.tcx.layout_of(self.param_env.and(ty))
     }
 }
 
diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs
index dad2d7a7c90..e5619f469e7 100644
--- a/src/librustc/middle/region.rs
+++ b/src/librustc/middle/region.rs
@@ -467,9 +467,13 @@ impl<'tcx> Visitor<'tcx> for ExprLocatorVisitor {
     }
 
     fn visit_pat(&mut self, pat: &'tcx Pat) {
+        intravisit::walk_pat(self, pat);
+
         self.expr_and_pat_count += 1;
 
-        intravisit::walk_pat(self, pat);
+        if pat.id == self.id {
+            self.result = Some(self.expr_and_pat_count);
+        }
     }
 
     fn visit_expr(&mut self, expr: &'tcx Expr) {
@@ -814,7 +818,8 @@ impl<'tcx> ScopeTree {
 
     /// Checks whether the given scope contains a `yield`. If so,
     /// returns `Some((span, expr_count))` with the span of a yield we found and
-    /// the number of expressions appearing before the `yield` in the body.
+    /// the number of expressions and patterns appearing before the `yield` in the body + 1.
+    /// If there a are multiple yields in a scope, the one with the highest number is returned.
     pub fn yield_in_scope(&self, scope: Scope) -> Option<(Span, usize)> {
         self.yield_in_scope.get(&scope).cloned()
     }
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 944d7705163..59460141166 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -737,7 +737,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
 
     fn visit_lifetime(&mut self, lifetime_ref: &'tcx hir::Lifetime) {
         if lifetime_ref.is_elided() {
-            self.resolve_elided_lifetimes(slice::from_ref(lifetime_ref));
+            self.resolve_elided_lifetimes(slice::from_ref(lifetime_ref), false);
             return;
         }
         if lifetime_ref.is_static() {
@@ -1444,7 +1444,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         }
 
         if params.lifetimes.iter().all(|l| l.is_elided()) {
-            self.resolve_elided_lifetimes(&params.lifetimes);
+            self.resolve_elided_lifetimes(&params.lifetimes, true);
         } else {
             for l in &params.lifetimes {
                 self.visit_lifetime(l);
@@ -1803,14 +1803,24 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         }
     }
 
-    fn resolve_elided_lifetimes(&mut self, lifetime_refs: &'tcx [hir::Lifetime]) {
+    fn resolve_elided_lifetimes(&mut self, lifetime_refs: &'tcx [hir::Lifetime], deprecated: bool) {
         if lifetime_refs.is_empty() {
             return;
         }
 
         let span = lifetime_refs[0].span;
+        let id = lifetime_refs[0].id;
         let mut late_depth = 0;
         let mut scope = self.scope;
+        if deprecated {
+            self.tcx
+                .struct_span_lint_node(
+                    lint::builtin::ELIDED_LIFETIME_IN_PATH,
+                    id,
+                    span,
+                    &format!("hidden lifetime parameters are deprecated, try `Foo<'_>`"))
+                .emit();
+        }
         let error = loop {
             match *scope {
                 // Do not assign any resolution, it will be inferred.
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 3b644aa13f3..c0feb8ad020 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1825,7 +1825,7 @@ pub struct Location {
     /// the location is within this block
     pub block: BasicBlock,
 
-    /// the location is the start of the this statement; or, if `statement_index`
+    /// the location is the start of the statement; or, if `statement_index`
     /// == num-statements, then the start of the terminator.
     pub statement_index: usize,
 }
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index b9546143a05..9543d01597d 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -1288,6 +1288,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     dep_info_omit_d_target: bool = (false, parse_bool, [TRACKED],
         "in dep-info output, omit targets for tracking dependencies of the dep-info files \
          themselves"),
+    approximate_suggestions: bool = (false, parse_bool, [UNTRACKED],
+        "include machine-applicability of suggestions in JSON output"),
     unpretty: Option<String> = (None, parse_unpretty, [UNTRACKED],
         "Present the input source, unstable (and less-pretty) variants;
         valid types are any of the types for `--pretty`, as well as:
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 2765239d5e6..f4a00a43d8d 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -904,22 +904,27 @@ pub fn build_session_with_codemap(sopts: config::Options,
 
     let emitter: Box<Emitter> = match (sopts.error_format, emitter_dest) {
         (config::ErrorOutputType::HumanReadable(color_config), None) => {
-            Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), false))
+            Box::new(EmitterWriter::stderr(color_config,
+                                           Some(codemap.clone()),
+                                           false,
+                                           sopts.debugging_opts.teach))
         }
         (config::ErrorOutputType::HumanReadable(_), Some(dst)) => {
-            Box::new(EmitterWriter::new(dst, Some(codemap.clone()), false))
+            Box::new(EmitterWriter::new(dst, Some(codemap.clone()), false, false))
         }
         (config::ErrorOutputType::Json(pretty), None) => {
-            Box::new(JsonEmitter::stderr(Some(registry), codemap.clone(), pretty))
+            Box::new(JsonEmitter::stderr(Some(registry), codemap.clone(),
+                     pretty, sopts.debugging_opts.approximate_suggestions))
         }
         (config::ErrorOutputType::Json(pretty), Some(dst)) => {
-            Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone(), pretty))
+            Box::new(JsonEmitter::new(dst, Some(registry), codemap.clone(),
+                     pretty, sopts.debugging_opts.approximate_suggestions))
         }
         (config::ErrorOutputType::Short(color_config), None) => {
-            Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), true))
+            Box::new(EmitterWriter::stderr(color_config, Some(codemap.clone()), true, false))
         }
         (config::ErrorOutputType::Short(_), Some(dst)) => {
-            Box::new(EmitterWriter::new(dst, Some(codemap.clone()), true))
+            Box::new(EmitterWriter::new(dst, Some(codemap.clone()), true, false))
         }
     };
 
@@ -1095,11 +1100,11 @@ pub enum IncrCompSession {
 pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
     let emitter: Box<Emitter> = match output {
         config::ErrorOutputType::HumanReadable(color_config) => {
-            Box::new(EmitterWriter::stderr(color_config, None, false))
+            Box::new(EmitterWriter::stderr(color_config, None, false, false))
         }
         config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
         config::ErrorOutputType::Short(color_config) => {
-            Box::new(EmitterWriter::stderr(color_config, None, true))
+            Box::new(EmitterWriter::stderr(color_config, None, true, false))
         }
     };
     let handler = errors::Handler::with_emitter(true, false, emitter);
@@ -1110,11 +1115,11 @@ pub fn early_error(output: config::ErrorOutputType, msg: &str) -> ! {
 pub fn early_warn(output: config::ErrorOutputType, msg: &str) {
     let emitter: Box<Emitter> = match output {
         config::ErrorOutputType::HumanReadable(color_config) => {
-            Box::new(EmitterWriter::stderr(color_config, None, false))
+            Box::new(EmitterWriter::stderr(color_config, None, false, false))
         }
         config::ErrorOutputType::Json(pretty) => Box::new(JsonEmitter::basic(pretty)),
         config::ErrorOutputType::Short(color_config) => {
-            Box::new(EmitterWriter::stderr(color_config, None, true))
+            Box::new(EmitterWriter::stderr(color_config, None, true, false))
         }
     };
     let handler = errors::Handler::with_emitter(true, false, emitter);
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index ae68e3fe8d0..9de18612d81 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -19,7 +19,7 @@ use ty::{self, Ty, TyCtxt};
 use ty::fold::TypeFoldable;
 use ty::subst::Subst;
 
-use infer::{InferCtxt, InferOk};
+use infer::{InferOk};
 
 /// Whether we do the orphan check relative to this crate or
 /// to some remote crate.
@@ -40,13 +40,20 @@ pub struct OverlapResult<'tcx> {
     pub intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
 }
 
-/// If there are types that satisfy both impls, returns a suitably-freshened
-/// `ImplHeader` with those types substituted
-pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
-                                          impl1_def_id: DefId,
-                                          impl2_def_id: DefId,
-                                          intercrate_mode: IntercrateMode)
-                                          -> Option<OverlapResult<'tcx>>
+/// If there are types that satisfy both impls, invokes `on_overlap`
+/// with a suitably-freshened `ImplHeader` with those types
+/// substituted. Otherwise, invokes `no_overlap`.
+pub fn overlapping_impls<'gcx, F1, F2, R>(
+    tcx: TyCtxt<'_, 'gcx, 'gcx>,
+    impl1_def_id: DefId,
+    impl2_def_id: DefId,
+    intercrate_mode: IntercrateMode,
+    on_overlap: F1,
+    no_overlap: F2,
+) -> R
+where
+    F1: FnOnce(OverlapResult<'_>) -> R,
+    F2: FnOnce() -> R,
 {
     debug!("impl_can_satisfy(\
            impl1_def_id={:?}, \
@@ -56,8 +63,23 @@ pub fn overlapping_impls<'cx, 'gcx, 'tcx>(infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
            impl2_def_id,
            intercrate_mode);
 
-    let selcx = &mut SelectionContext::intercrate(infcx, intercrate_mode);
-    overlap(selcx, impl1_def_id, impl2_def_id)
+    let overlaps = tcx.infer_ctxt().enter(|infcx| {
+        let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
+        overlap(selcx, impl1_def_id, impl2_def_id).is_some()
+    });
+
+    if !overlaps {
+        return no_overlap();
+    }
+
+    // In the case where we detect an error, run the check again, but
+    // this time tracking intercrate ambuiguity causes for better
+    // diagnostics. (These take time and can lead to false errors.)
+    tcx.infer_ctxt().enter(|infcx| {
+        let selcx = &mut SelectionContext::intercrate(&infcx, intercrate_mode);
+        selcx.enable_tracking_intercrate_ambiguity_causes();
+        on_overlap(overlap(selcx, impl1_def_id, impl2_def_id).unwrap())
+    })
 }
 
 fn with_fresh_ty_vars<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
@@ -135,10 +157,10 @@ fn overlap<'cx, 'gcx, 'tcx>(selcx: &mut SelectionContext<'cx, 'gcx, 'tcx>,
         return None
     }
 
-    Some(OverlapResult {
-        impl_header: selcx.infcx().resolve_type_vars_if_possible(&a_impl_header),
-        intercrate_ambiguity_causes: selcx.intercrate_ambiguity_causes().to_vec(),
-    })
+    let impl_header =  selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
+    let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
+    debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);
+    Some(OverlapResult { impl_header, intercrate_ambiguity_causes })
 }
 
 pub fn trait_ref_is_knowable<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>,
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 42200a3a447..7b86791026b 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -831,6 +831,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 span,
                 node: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _),
                 ..
+            }) |
+            hir::map::NodeTraitItem(&hir::TraitItem {
+                span,
+                node: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, _),
+                ..
             }) => {
                 (self.tcx.sess.codemap().def_span(span), decl.inputs.iter()
                         .map(|arg| match arg.clone().into_inner().node {
@@ -1261,6 +1266,10 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                 err.note("the return type of a function must have a \
                           statically known size");
             }
+            ObligationCauseCode::SizedYieldType => {
+                err.note("the yield type of a generator must have a \
+                          statically known size");
+            }
             ObligationCauseCode::AssignmentLhsSized => {
                 err.note("the left-hand-side of an assignment must have a statically known size");
             }
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index fd47e09aad7..80819a86b7c 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -100,6 +100,19 @@ pub struct ObligationCause<'tcx> {
     pub code: ObligationCauseCode<'tcx>
 }
 
+impl<'tcx> ObligationCause<'tcx> {
+    pub fn span<'a, 'gcx>(&self, tcx: &TyCtxt<'a, 'gcx, 'tcx>) -> Span {
+        match self.code {
+            ObligationCauseCode::CompareImplMethodObligation { .. } |
+            ObligationCauseCode::MainFunctionType |
+            ObligationCauseCode::StartFunctionType => {
+                tcx.sess.codemap().def_span(self.span)
+            }
+            _ => self.span,
+        }
+    }
+}
+
 #[derive(Clone, Debug, PartialEq, Eq)]
 pub enum ObligationCauseCode<'tcx> {
     /// Not well classified or should be obvious from span.
@@ -138,6 +151,8 @@ pub enum ObligationCauseCode<'tcx> {
     VariableType(ast::NodeId),
     /// Return type must be Sized
     SizedReturnType,
+    /// Yield type must be Sized
+    SizedYieldType,
     /// [T,..n] --> T must be Copy
     RepeatVec,
 
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index 55cbc890e1e..4ed25646d43 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -92,10 +92,10 @@ pub struct SelectionContext<'cx, 'gcx: 'cx+'tcx, 'tcx: 'cx> {
 
     inferred_obligations: SnapshotVec<InferredObligationsSnapshotVecDelegate<'tcx>>,
 
-    intercrate_ambiguity_causes: Vec<IntercrateAmbiguityCause>,
+    intercrate_ambiguity_causes: Option<Vec<IntercrateAmbiguityCause>>,
 }
 
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub enum IntercrateAmbiguityCause {
     DownstreamCrate {
         trait_desc: String,
@@ -423,7 +423,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             freshener: infcx.freshener(),
             intercrate: None,
             inferred_obligations: SnapshotVec::new(),
-            intercrate_ambiguity_causes: Vec::new(),
+            intercrate_ambiguity_causes: None,
         }
     }
 
@@ -435,10 +435,30 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             freshener: infcx.freshener(),
             intercrate: Some(mode),
             inferred_obligations: SnapshotVec::new(),
-            intercrate_ambiguity_causes: Vec::new(),
+            intercrate_ambiguity_causes: None,
         }
     }
 
+    /// Enables tracking of intercrate ambiguity causes. These are
+    /// used in coherence to give improved diagnostics. We don't do
+    /// this until we detect a coherence error because it can lead to
+    /// false overflow results (#47139) and because it costs
+    /// computation time.
+    pub fn enable_tracking_intercrate_ambiguity_causes(&mut self) {
+        assert!(self.intercrate.is_some());
+        assert!(self.intercrate_ambiguity_causes.is_none());
+        self.intercrate_ambiguity_causes = Some(vec![]);
+        debug!("selcx: enable_tracking_intercrate_ambiguity_causes");
+    }
+
+    /// Gets the intercrate ambiguity causes collected since tracking
+    /// was enabled and disables tracking at the same time. If
+    /// tracking is not enabled, just returns an empty vector.
+    pub fn take_intercrate_ambiguity_causes(&mut self) -> Vec<IntercrateAmbiguityCause> {
+        assert!(self.intercrate.is_some());
+        self.intercrate_ambiguity_causes.take().unwrap_or(vec![])
+    }
+
     pub fn infcx(&self) -> &'cx InferCtxt<'cx, 'gcx, 'tcx> {
         self.infcx
     }
@@ -451,10 +471,6 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
         self.infcx
     }
 
-    pub fn intercrate_ambiguity_causes(&self) -> &[IntercrateAmbiguityCause] {
-        &self.intercrate_ambiguity_causes
-    }
-
     /// Wraps the inference context's in_snapshot s.t. snapshot handling is only from the selection
     /// context's self.
     fn in_snapshot<R, F>(&mut self, f: F) -> R
@@ -828,19 +844,23 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             debug!("evaluate_stack({:?}) --> unbound argument, intercrate -->  ambiguous",
                    stack.fresh_trait_ref);
             // Heuristics: show the diagnostics when there are no candidates in crate.
-            if let Ok(candidate_set) = self.assemble_candidates(stack) {
-                if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
-                    let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
-                    let self_ty = trait_ref.self_ty();
-                    let cause = IntercrateAmbiguityCause::DownstreamCrate {
-                        trait_desc: trait_ref.to_string(),
-                        self_desc: if self_ty.has_concrete_skeleton() {
-                            Some(self_ty.to_string())
-                        } else {
-                            None
-                        },
-                    };
-                    self.intercrate_ambiguity_causes.push(cause);
+            if self.intercrate_ambiguity_causes.is_some() {
+                debug!("evaluate_stack: intercrate_ambiguity_causes is some");
+                if let Ok(candidate_set) = self.assemble_candidates(stack) {
+                    if !candidate_set.ambiguous && candidate_set.vec.is_empty() {
+                        let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
+                        let self_ty = trait_ref.self_ty();
+                        let cause = IntercrateAmbiguityCause::DownstreamCrate {
+                            trait_desc: trait_ref.to_string(),
+                            self_desc: if self_ty.has_concrete_skeleton() {
+                                Some(self_ty.to_string())
+                            } else {
+                                None
+                            },
+                        };
+                        debug!("evaluate_stack: pushing cause = {:?}", cause);
+                        self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
+                    }
                 }
             }
             return EvaluatedToAmbig;
@@ -1092,25 +1112,29 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
             None => {}
             Some(conflict) => {
                 debug!("coherence stage: not knowable");
-                // Heuristics: show the diagnostics when there are no candidates in crate.
-                let candidate_set = self.assemble_candidates(stack)?;
-                if !candidate_set.ambiguous && candidate_set.vec.iter().all(|c| {
-                    !self.evaluate_candidate(stack, &c).may_apply()
-                }) {
-                    let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
-                    let self_ty = trait_ref.self_ty();
-                    let trait_desc = trait_ref.to_string();
-                    let self_desc = if self_ty.has_concrete_skeleton() {
-                        Some(self_ty.to_string())
-                    } else {
-                        None
-                    };
-                    let cause = if let Conflict::Upstream = conflict {
-                        IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc }
-                    } else {
-                        IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
-                    };
-                    self.intercrate_ambiguity_causes.push(cause);
+                if self.intercrate_ambiguity_causes.is_some() {
+                    debug!("evaluate_stack: intercrate_ambiguity_causes is some");
+                    // Heuristics: show the diagnostics when there are no candidates in crate.
+                    let candidate_set = self.assemble_candidates(stack)?;
+                    if !candidate_set.ambiguous && candidate_set.vec.iter().all(|c| {
+                        !self.evaluate_candidate(stack, &c).may_apply()
+                    }) {
+                        let trait_ref = stack.obligation.predicate.skip_binder().trait_ref;
+                        let self_ty = trait_ref.self_ty();
+                        let trait_desc = trait_ref.to_string();
+                        let self_desc = if self_ty.has_concrete_skeleton() {
+                            Some(self_ty.to_string())
+                        } else {
+                            None
+                        };
+                        let cause = if let Conflict::Upstream = conflict {
+                            IntercrateAmbiguityCause::UpstreamCrateUpdate { trait_desc, self_desc }
+                        } else {
+                            IntercrateAmbiguityCause::DownstreamCrate { trait_desc, self_desc }
+                        };
+                        debug!("evaluate_stack: pushing cause = {:?}", cause);
+                        self.intercrate_ambiguity_causes.as_mut().unwrap().push(cause);
+                    }
                 }
                 return Ok(None);
             }
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index 834389e5d00..a10169e13e6 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -133,12 +133,12 @@ impl<'a, 'gcx, 'tcx> Children {
             };
 
             let tcx = tcx.global_tcx();
-            let (le, ge) = tcx.infer_ctxt().enter(|infcx| {
-                let overlap = traits::overlapping_impls(&infcx,
-                                                        possible_sibling,
-                                                        impl_def_id,
-                                                        traits::IntercrateMode::Issue43355);
-                if let Some(overlap) = overlap {
+            let (le, ge) = traits::overlapping_impls(
+                tcx,
+                possible_sibling,
+                impl_def_id,
+                traits::IntercrateMode::Issue43355,
+                |overlap| {
                     if tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
                         return Ok((false, false));
                     }
@@ -151,10 +151,9 @@ impl<'a, 'gcx, 'tcx> Children {
                     } else {
                         Ok((le, ge))
                     }
-                } else {
-                    Ok((false, false))
-                }
-            })?;
+                },
+                || Ok((false, false)),
+            )?;
 
             if le && !ge {
                 debug!("descending as child of TraitRef {:?}",
@@ -171,16 +170,14 @@ impl<'a, 'gcx, 'tcx> Children {
                 return Ok(Inserted::Replaced(possible_sibling));
             } else {
                 if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
-                    tcx.infer_ctxt().enter(|infcx| {
-                        if let Some(overlap) = traits::overlapping_impls(
-                            &infcx,
-                            possible_sibling,
-                            impl_def_id,
-                            traits::IntercrateMode::Fixed)
-                        {
-                            last_lint = Some(overlap_error(overlap));
-                        }
-                    });
+                    traits::overlapping_impls(
+                        tcx,
+                        possible_sibling,
+                        impl_def_id,
+                        traits::IntercrateMode::Fixed,
+                        |overlap| last_lint = Some(overlap_error(overlap)),
+                        || (),
+                    );
                 }
 
                 // no overlap (error bailed already via ?)
diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs
index e1e2798ecb5..1eb14a22278 100644
--- a/src/librustc/traits/structural_impls.rs
+++ b/src/librustc/traits/structural_impls.rs
@@ -209,6 +209,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::ObligationCauseCode<'a> {
             super::VariableType(id) => Some(super::VariableType(id)),
             super::ReturnType(id) => Some(super::ReturnType(id)),
             super::SizedReturnType => Some(super::SizedReturnType),
+            super::SizedYieldType => Some(super::SizedYieldType),
             super::RepeatVec => Some(super::RepeatVec),
             super::FieldSized(item) => Some(super::FieldSized(item)),
             super::ConstSized => Some(super::ConstSized),
@@ -526,6 +527,7 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
             super::VariableType(_) |
             super::ReturnType(_) |
             super::SizedReturnType |
+            super::SizedYieldType |
             super::ReturnNoExpression |
             super::RepeatVec |
             super::FieldSized(_) |
@@ -574,6 +576,7 @@ impl<'tcx> TypeFoldable<'tcx> for traits::ObligationCauseCode<'tcx> {
             super::VariableType(_) |
             super::ReturnType(_) |
             super::SizedReturnType |
+            super::SizedYieldType |
             super::ReturnNoExpression |
             super::RepeatVec |
             super::FieldSized(_) |
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index 69d07eafdca..63b91ff1101 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -895,7 +895,8 @@ fn layout_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     }
 
     tcx.layout_depth.set(depth+1);
-    let layout = LayoutDetails::compute_uncached(tcx, param_env, ty);
+    let cx = LayoutCx { tcx, param_env };
+    let layout = cx.layout_raw_uncached(ty);
     tcx.layout_depth.set(depth);
 
     layout
@@ -908,13 +909,18 @@ pub fn provide(providers: &mut ty::maps::Providers) {
     };
 }
 
-impl<'a, 'tcx> LayoutDetails {
-    fn compute_uncached(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                        param_env: ty::ParamEnv<'tcx>,
-                        ty: Ty<'tcx>)
-                        -> Result<&'tcx Self, LayoutError<'tcx>> {
-        let cx = (tcx, param_env);
-        let dl = cx.data_layout();
+#[derive(Copy, Clone)]
+pub struct LayoutCx<'tcx, C> {
+    pub tcx: C,
+    pub param_env: ty::ParamEnv<'tcx>
+}
+
+impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
+    fn layout_raw_uncached(self, ty: Ty<'tcx>)
+                           -> Result<&'tcx LayoutDetails, LayoutError<'tcx>> {
+        let tcx = self.tcx;
+        let param_env = self.param_env;
+        let dl = self.data_layout();
         let scalar_unit = |value: Primitive| {
             let bits = value.size(dl).bits();
             assert!(bits <= 128);
@@ -924,7 +930,7 @@ impl<'a, 'tcx> LayoutDetails {
             }
         };
         let scalar = |value: Primitive| {
-            tcx.intern_layout(LayoutDetails::scalar(cx, scalar_unit(value)))
+            tcx.intern_layout(LayoutDetails::scalar(self, scalar_unit(value)))
         };
         let scalar_pair = |a: Scalar, b: Scalar| {
             let align = a.value.align(dl).max(b.value.align(dl)).max(dl.aggregate_align);
@@ -1158,13 +1164,13 @@ impl<'a, 'tcx> LayoutDetails {
         Ok(match ty.sty {
             // Basic scalars.
             ty::TyBool => {
-                tcx.intern_layout(LayoutDetails::scalar(cx, Scalar {
+                tcx.intern_layout(LayoutDetails::scalar(self, Scalar {
                     value: Int(I8, false),
                     valid_range: 0..=1
                 }))
             }
             ty::TyChar => {
-                tcx.intern_layout(LayoutDetails::scalar(cx, Scalar {
+                tcx.intern_layout(LayoutDetails::scalar(self, Scalar {
                     value: Int(I32, false),
                     valid_range: 0..=0x10FFFF
                 }))
@@ -1180,7 +1186,7 @@ impl<'a, 'tcx> LayoutDetails {
             ty::TyFnPtr(_) => {
                 let mut ptr = scalar_unit(Pointer);
                 ptr.valid_range.start = 1;
-                tcx.intern_layout(LayoutDetails::scalar(cx, ptr))
+                tcx.intern_layout(LayoutDetails::scalar(self, ptr))
             }
 
             // The never type.
@@ -1198,13 +1204,13 @@ impl<'a, 'tcx> LayoutDetails {
 
                 let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
                 if pointee.is_sized(tcx, param_env, DUMMY_SP) {
-                    return Ok(tcx.intern_layout(LayoutDetails::scalar(cx, data_ptr)));
+                    return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
                 }
 
                 let unsized_part = tcx.struct_tail(pointee);
                 let metadata = match unsized_part.sty {
                     ty::TyForeign(..) => {
-                        return Ok(tcx.intern_layout(LayoutDetails::scalar(cx, data_ptr)));
+                        return Ok(tcx.intern_layout(LayoutDetails::scalar(self, data_ptr)));
                     }
                     ty::TySlice(_) | ty::TyStr => {
                         scalar_unit(Int(dl.ptr_sized_integer(), false))
@@ -1230,7 +1236,7 @@ impl<'a, 'tcx> LayoutDetails {
                     }
                 }
 
-                let element = cx.layout_of(element)?;
+                let element = self.layout_of(element)?;
                 let count = count.val.to_const_int().unwrap().to_u64().unwrap();
                 let size = element.size.checked_mul(count, dl)
                     .ok_or(LayoutError::SizeOverflow(ty))?;
@@ -1247,7 +1253,7 @@ impl<'a, 'tcx> LayoutDetails {
                 })
             }
             ty::TySlice(element) => {
-                let element = cx.layout_of(element)?;
+                let element = self.layout_of(element)?;
                 tcx.intern_layout(LayoutDetails {
                     variants: Variants::Single { index: 0 },
                     fields: FieldPlacement::Array {
@@ -1289,14 +1295,14 @@ impl<'a, 'tcx> LayoutDetails {
             // Tuples, generators and closures.
             ty::TyGenerator(def_id, ref substs, _) => {
                 let tys = substs.field_tys(def_id, tcx);
-                univariant(&tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
+                univariant(&tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
                     &ReprOptions::default(),
                     StructKind::AlwaysSized)?
             }
 
             ty::TyClosure(def_id, ref substs) => {
                 let tys = substs.upvar_tys(def_id, tcx);
-                univariant(&tys.map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
+                univariant(&tys.map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
                     &ReprOptions::default(),
                     StructKind::AlwaysSized)?
             }
@@ -1308,13 +1314,13 @@ impl<'a, 'tcx> LayoutDetails {
                     StructKind::MaybeUnsized
                 };
 
-                univariant(&tys.iter().map(|ty| cx.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
+                univariant(&tys.iter().map(|ty| self.layout_of(ty)).collect::<Result<Vec<_>, _>>()?,
                     &ReprOptions::default(), kind)?
             }
 
             // SIMD vector types.
             ty::TyAdt(def, ..) if def.repr.simd() => {
-                let element = cx.layout_of(ty.simd_type(tcx))?;
+                let element = self.layout_of(ty.simd_type(tcx))?;
                 let count = ty.simd_size(tcx) as u64;
                 assert!(count > 0);
                 let scalar = match element.abi {
@@ -1350,7 +1356,7 @@ impl<'a, 'tcx> LayoutDetails {
                 // Cache the field layouts.
                 let variants = def.variants.iter().map(|v| {
                     v.fields.iter().map(|field| {
-                        cx.layout_of(field.ty(tcx, substs))
+                        self.layout_of(field.ty(tcx, substs))
                     }).collect::<Result<Vec<_>, _>>()
                 }).collect::<Result<Vec<_>, _>>()?;
 
@@ -1430,7 +1436,7 @@ impl<'a, 'tcx> LayoutDetails {
                     let mut st = univariant_uninterned(&variants[v], &def.repr, kind)?;
                     st.variants = Variants::Single { index: v };
                     // Exclude 0 from the range of a newtype ABI NonZero<T>.
-                    if Some(def.did) == cx.tcx().lang_items().non_zero() {
+                    if Some(def.did) == self.tcx.lang_items().non_zero() {
                         match st.abi {
                             Abi::Scalar(ref mut scalar) |
                             Abi::ScalarPair(ref mut scalar, _) => {
@@ -1482,7 +1488,7 @@ impl<'a, 'tcx> LayoutDetails {
                         let count = (niche_variants.end - niche_variants.start + 1) as u128;
                         for (field_index, field) in variants[i].iter().enumerate() {
                             let (offset, niche, niche_start) =
-                                match field.find_niche(cx, count)? {
+                                match field.find_niche(self, count)? {
                                     Some(niche) => niche,
                                     None => continue
                                 };
@@ -1687,56 +1693,49 @@ impl<'a, 'tcx> LayoutDetails {
     /// This is invoked by the `layout_raw` query to record the final
     /// layout of each type.
     #[inline]
-    fn record_layout_for_printing(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                  ty: Ty<'tcx>,
-                                  param_env: ty::ParamEnv<'tcx>,
-                                  layout: TyLayout<'tcx>) {
+    fn record_layout_for_printing(self, layout: TyLayout<'tcx>) {
         // If we are running with `-Zprint-type-sizes`, record layouts for
         // dumping later. Ignore layouts that are done with non-empty
         // environments or non-monomorphic layouts, as the user only wants
         // to see the stuff resulting from the final trans session.
         if
-            !tcx.sess.opts.debugging_opts.print_type_sizes ||
-            ty.has_param_types() ||
-            ty.has_self_ty() ||
-            !param_env.caller_bounds.is_empty()
+            !self.tcx.sess.opts.debugging_opts.print_type_sizes ||
+            layout.ty.has_param_types() ||
+            layout.ty.has_self_ty() ||
+            !self.param_env.caller_bounds.is_empty()
         {
             return;
         }
 
-        Self::record_layout_for_printing_outlined(tcx, ty, param_env, layout)
+        self.record_layout_for_printing_outlined(layout)
     }
 
-    fn record_layout_for_printing_outlined(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                           ty: Ty<'tcx>,
-                                           param_env: ty::ParamEnv<'tcx>,
-                                           layout: TyLayout<'tcx>) {
-        let cx = (tcx, param_env);
+    fn record_layout_for_printing_outlined(self, layout: TyLayout<'tcx>) {
         // (delay format until we actually need it)
         let record = |kind, opt_discr_size, variants| {
-            let type_desc = format!("{:?}", ty);
-            tcx.sess.code_stats.borrow_mut().record_type_size(kind,
-                                                              type_desc,
-                                                              layout.align,
-                                                              layout.size,
-                                                              opt_discr_size,
-                                                              variants);
+            let type_desc = format!("{:?}", layout.ty);
+            self.tcx.sess.code_stats.borrow_mut().record_type_size(kind,
+                                                                   type_desc,
+                                                                   layout.align,
+                                                                   layout.size,
+                                                                   opt_discr_size,
+                                                                   variants);
         };
 
-        let adt_def = match ty.sty {
+        let adt_def = match layout.ty.sty {
             ty::TyAdt(ref adt_def, _) => {
-                debug!("print-type-size t: `{:?}` process adt", ty);
+                debug!("print-type-size t: `{:?}` process adt", layout.ty);
                 adt_def
             }
 
             ty::TyClosure(..) => {
-                debug!("print-type-size t: `{:?}` record closure", ty);
+                debug!("print-type-size t: `{:?}` record closure", layout.ty);
                 record(DataTypeKind::Closure, None, vec![]);
                 return;
             }
 
             _ => {
-                debug!("print-type-size t: `{:?}` skip non-nominal", ty);
+                debug!("print-type-size t: `{:?}` skip non-nominal", layout.ty);
                 return;
             }
         };
@@ -1748,7 +1747,7 @@ impl<'a, 'tcx> LayoutDetails {
                                   layout: TyLayout<'tcx>| {
             let mut min_size = Size::from_bytes(0);
             let field_info: Vec<_> = flds.iter().enumerate().map(|(i, &name)| {
-                match layout.field(cx, i) {
+                match layout.field(self, i) {
                     Err(err) => {
                         bug!("no layout found for field {}: `{:?}`", name, err);
                     }
@@ -1808,18 +1807,18 @@ impl<'a, 'tcx> LayoutDetails {
             Variants::NicheFilling { .. } |
             Variants::Tagged { .. } => {
                 debug!("print-type-size `{:#?}` adt general variants def {}",
-                       ty, adt_def.variants.len());
+                       layout.ty, adt_def.variants.len());
                 let variant_infos: Vec<_> =
                     adt_def.variants.iter().enumerate().map(|(i, variant_def)| {
                         let fields: Vec<_> =
                             variant_def.fields.iter().map(|f| f.name).collect();
                         build_variant_info(Some(variant_def.name),
                                             &fields,
-                                            layout.for_variant(cx, i))
+                                            layout.for_variant(self, i))
                     })
                     .collect();
                 record(adt_kind.into(), match layout.variants {
-                    Variants::Tagged { ref discr, .. } => Some(discr.value.size(tcx)),
+                    Variants::Tagged { ref discr, .. } => Some(discr.value.size(self)),
                     _ => None
                 }, variant_infos);
             }
@@ -1855,7 +1854,7 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
         assert!(!ty.has_infer_types());
 
         // First try computing a static layout.
-        let err = match (tcx, param_env).layout_of(ty) {
+        let err = match tcx.layout_of(param_env.and(ty)) {
             Ok(layout) => {
                 return Ok(SizeSkeleton::Known(layout.size));
             }
@@ -2001,15 +2000,15 @@ impl<'a, 'gcx, 'tcx> HasTyCtxt<'gcx> for TyCtxt<'a, 'gcx, 'tcx> {
     }
 }
 
-impl<'a, 'gcx, 'tcx, T: Copy> HasDataLayout for (TyCtxt<'a, 'gcx, 'tcx>, T) {
+impl<'tcx, T: HasDataLayout> HasDataLayout for LayoutCx<'tcx, T> {
     fn data_layout(&self) -> &TargetDataLayout {
-        self.0.data_layout()
+        self.tcx.data_layout()
     }
 }
 
-impl<'a, 'gcx, 'tcx, T: Copy> HasTyCtxt<'gcx> for (TyCtxt<'a, 'gcx, 'tcx>, T) {
+impl<'gcx, 'tcx, T: HasTyCtxt<'gcx>> HasTyCtxt<'gcx> for LayoutCx<'tcx, T> {
     fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'gcx> {
-        self.0.tcx()
+        self.tcx.tcx()
     }
 }
 
@@ -2042,17 +2041,15 @@ pub trait LayoutOf<T> {
     fn layout_of(self, ty: T) -> Self::TyLayout;
 }
 
-impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv<'tcx>) {
+impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> {
     type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
 
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
-    #[inline]
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
-        let (tcx, param_env) = self;
-
-        let ty = tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all());
-        let details = tcx.layout_raw(param_env.reveal_all().and(ty))?;
+        let param_env = self.param_env.reveal_all();
+        let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env);
+        let details = self.tcx.layout_raw(param_env.and(ty))?;
         let layout = TyLayout {
             ty,
             details
@@ -2064,24 +2061,21 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (TyCtxt<'a, 'tcx, 'tcx>, ty::ParamEnv<'tcx
         // completed, to avoid problems around recursive structures
         // and the like. (Admitedly, I wasn't able to reproduce a problem
         // here, but it seems like the right thing to do. -nmatsakis)
-        LayoutDetails::record_layout_for_printing(tcx, ty, param_env, layout);
+        self.record_layout_for_printing(layout);
 
         Ok(layout)
     }
 }
 
-impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>,
-                                       ty::ParamEnv<'tcx>) {
+impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for LayoutCx<'tcx, ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>> {
     type TyLayout = Result<TyLayout<'tcx>, LayoutError<'tcx>>;
 
     /// Computes the layout of a type. Note that this implicitly
     /// executes in "reveal all" mode.
-    #[inline]
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
-        let (tcx_at, param_env) = self;
-
-        let ty = tcx_at.tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all());
-        let details = tcx_at.layout_raw(param_env.reveal_all().and(ty))?;
+        let param_env = self.param_env.reveal_all();
+        let ty = self.tcx.normalize_associated_type_in_env(&ty, param_env.reveal_all());
+        let details = self.tcx.layout_raw(param_env.reveal_all().and(ty))?;
         let layout = TyLayout {
             ty,
             details
@@ -2093,12 +2087,45 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for (ty::maps::TyCtxtAt<'a, 'tcx, 'tcx>,
         // completed, to avoid problems around recursive structures
         // and the like. (Admitedly, I wasn't able to reproduce a problem
         // here, but it seems like the right thing to do. -nmatsakis)
-        LayoutDetails::record_layout_for_printing(tcx_at.tcx, ty, param_env, layout);
+        let cx = LayoutCx {
+            tcx: *self.tcx,
+            param_env: self.param_env
+        };
+        cx.record_layout_for_printing(layout);
 
         Ok(layout)
     }
 }
 
+// Helper (inherent) `layout_of` methods to avoid pushing `LayoutCx` to users.
+impl<'a, 'tcx> TyCtxt<'a, 'tcx, 'tcx> {
+    /// Computes the layout of a type. Note that this implicitly
+    /// executes in "reveal all" mode.
+    #[inline]
+    pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                     -> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
+        let cx = LayoutCx {
+            tcx: self,
+            param_env: param_env_and_ty.param_env
+        };
+        cx.layout_of(param_env_and_ty.value)
+    }
+}
+
+impl<'a, 'tcx> ty::maps::TyCtxtAt<'a, 'tcx, 'tcx> {
+    /// Computes the layout of a type. Note that this implicitly
+    /// executes in "reveal all" mode.
+    #[inline]
+    pub fn layout_of(self, param_env_and_ty: ty::ParamEnvAnd<'tcx, Ty<'tcx>>)
+                     -> Result<TyLayout<'tcx>, LayoutError<'tcx>> {
+        let cx = LayoutCx {
+            tcx: self,
+            param_env: param_env_and_ty.param_env
+        };
+        cx.layout_of(param_env_and_ty.value)
+    }
+}
+
 impl<'a, 'tcx> TyLayout<'tcx> {
     pub fn for_variant<C>(&self, cx: C, variant_index: usize) -> Self
         where C: LayoutOf<Ty<'tcx>> + HasTyCtxt<'tcx>,
diff --git a/src/librustc/ty/maps/mod.rs b/src/librustc/ty/maps/mod.rs
index 6c79f6a62fa..85fca68187f 100644
--- a/src/librustc/ty/maps/mod.rs
+++ b/src/librustc/ty/maps/mod.rs
@@ -343,6 +343,7 @@ define_maps! { <'tcx>
         -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>),
     [] fn export_name: ExportName(DefId) -> Option<Symbol>,
     [] fn contains_extern_indicator: ContainsExternIndicator(DefId) -> bool,
+    [] fn symbol_export_level: GetSymbolExportLevel(DefId) -> SymbolExportLevel,
     [] fn is_translated_function: IsTranslatedFunction(DefId) -> bool,
     [] fn codegen_unit: CodegenUnit(InternedString) -> Arc<CodegenUnit<'tcx>>,
     [] fn compile_codegen_unit: CompileCodegenUnit(InternedString) -> Stats,
diff --git a/src/librustc/ty/maps/plumbing.rs b/src/librustc/ty/maps/plumbing.rs
index c9eebc3d2a0..0ab6ee1a54a 100644
--- a/src/librustc/ty/maps/plumbing.rs
+++ b/src/librustc/ty/maps/plumbing.rs
@@ -921,6 +921,8 @@ pub fn force_from_dep_node<'a, 'gcx, 'lcx>(tcx: TyCtxt<'a, 'gcx, 'lcx>,
 
         DepKind::TargetFeaturesWhitelist => { force!(target_features_whitelist, LOCAL_CRATE); }
         DepKind::TargetFeaturesEnabled => { force!(target_features_enabled, def_id!()); }
+
+        DepKind::GetSymbolExportLevel => { force!(symbol_export_level, def_id!()); }
     }
 
     true
diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs
index 0c1ebd1a2ba..1593b452cdf 100644
--- a/src/librustc/ty/sty.rs
+++ b/src/librustc/ty/sty.rs
@@ -390,14 +390,21 @@ impl<'a, 'gcx, 'tcx> ClosureSubsts<'tcx> {
         state.map(move |d| d.ty.subst(tcx, self.substs))
     }
 
+    /// This is the types of the fields of a generate which
+    /// is available before the generator transformation.
+    /// It includes the upvars and the state discriminant which is u32.
+    pub fn pre_transforms_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
+        impl Iterator<Item=Ty<'tcx>> + 'a
+    {
+        self.upvar_tys(def_id, tcx).chain(iter::once(tcx.types.u32))
+    }
+
     /// This is the types of all the fields stored in a generator.
     /// It includes the upvars, state types and the state discriminant which is u32.
     pub fn field_tys(self, def_id: DefId, tcx: TyCtxt<'a, 'gcx, 'tcx>) ->
         impl Iterator<Item=Ty<'tcx>> + 'a
     {
-        let upvars = self.upvar_tys(def_id, tcx);
-        let state = self.state_tys(def_id, tcx);
-        upvars.chain(iter::once(tcx.types.u32)).chain(state)
+        self.pre_transforms_tys(def_id, tcx).chain(self.state_tys(def_id, tcx))
     }
 }
 
diff --git a/src/librustc_back/target/mod.rs b/src/librustc_back/target/mod.rs
index 3c8a676dcc2..2872c59157d 100644
--- a/src/librustc_back/target/mod.rs
+++ b/src/librustc_back/target/mod.rs
@@ -468,6 +468,10 @@ pub struct TargetOptions {
 
     /// The codegen backend to use for this target, typically "llvm"
     pub codegen_backend: String,
+
+    /// The default visibility for symbols in this target should be "hidden"
+    /// rather than "default"
+    pub default_hidden_visibility: bool,
 }
 
 impl Default for TargetOptions {
@@ -538,6 +542,7 @@ impl Default for TargetOptions {
             no_builtins: false,
             i128_lowering: false,
             codegen_backend: "llvm".to_string(),
+            default_hidden_visibility: false,
         }
     }
 }
@@ -785,6 +790,7 @@ impl Target {
         key!(singlethread, bool);
         key!(no_builtins, bool);
         key!(codegen_backend);
+        key!(default_hidden_visibility, bool);
 
         if let Some(array) = obj.find("abi-blacklist").and_then(Json::as_array) {
             for name in array.iter().filter_map(|abi| abi.as_string()) {
@@ -982,6 +988,7 @@ impl ToJson for Target {
         target_option_val!(singlethread);
         target_option_val!(no_builtins);
         target_option_val!(codegen_backend);
+        target_option_val!(default_hidden_visibility);
 
         if default.abi_blacklist != self.options.abi_blacklist {
             d.insert("abi-blacklist".to_string(), self.options.abi_blacklist.iter()
diff --git a/src/librustc_back/target/msp430_none_elf.rs b/src/librustc_back/target/msp430_none_elf.rs
index 509a7cf5e03..966df897f01 100644
--- a/src/librustc_back/target/msp430_none_elf.rs
+++ b/src/librustc_back/target/msp430_none_elf.rs
@@ -53,6 +53,12 @@ pub fn target() -> TargetResult {
             // don't want to invoke that many gcc instances.
             default_codegen_units: Some(1),
 
+            // Since MSP430 doesn't meaningfully support faulting on illegal
+            // instructions, LLVM generates a call to abort() function instead
+            // of a trap instruction. Such calls are 4 bytes long, and that is
+            // too much overhead for such small target.
+            trap_unreachable: false,
+
             .. Default::default( )
         }
     })
diff --git a/src/librustc_back/target/wasm32_unknown_unknown.rs b/src/librustc_back/target/wasm32_unknown_unknown.rs
index 7e1011ab8af..242860e5c6e 100644
--- a/src/librustc_back/target/wasm32_unknown_unknown.rs
+++ b/src/librustc_back/target/wasm32_unknown_unknown.rs
@@ -83,6 +83,9 @@ pub fn target() -> Result<Target, String> {
         // performing LTO with compiler-builtins.
         no_builtins: true,
 
+        // no dynamic linking, no need for default visibility!
+        default_hidden_visibility: true,
+
         .. Default::default()
     };
     Ok(Target {
diff --git a/src/librustc_borrowck/borrowck/unused.rs b/src/librustc_borrowck/borrowck/unused.rs
index ddee122d0a6..7bcd8a18545 100644
--- a/src/librustc_borrowck/borrowck/unused.rs
+++ b/src/librustc_borrowck/borrowck/unused.rs
@@ -77,7 +77,7 @@ impl<'a, 'tcx> UnusedMutCx<'a, 'tcx> {
                 continue
             }
 
-            let mut_span = tcx.sess.codemap().span_until_char(ids[0].2, ' ');
+            let mut_span = tcx.sess.codemap().span_until_non_whitespace(ids[0].2);
 
             // Ok, every name wasn't used mutably, so issue a warning that this
             // didn't need to be mutable.
diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs
index fd171b89924..ae53ed0e114 100644
--- a/src/librustc_const_eval/check_match.rs
+++ b/src/librustc_const_eval/check_match.rs
@@ -127,13 +127,16 @@ impl<'a, 'tcx> Visitor<'tcx> for MatchVisitor<'a, 'tcx> {
     }
 }
 
+
 impl<'a, 'tcx> PatternContext<'a, 'tcx> {
     fn report_inlining_errors(&self, pat_span: Span) {
         for error in &self.errors {
             match *error {
                 PatternError::StaticInPattern(span) => {
-                    span_err!(self.tcx.sess, span, E0158,
-                              "statics cannot be referenced in patterns");
+                    self.span_e0158(span, "statics cannot be referenced in patterns")
+                }
+                PatternError::AssociatedConstInPattern(span) => {
+                    self.span_e0158(span, "associated consts cannot be referenced in patterns")
                 }
                 PatternError::ConstEval(ref err) => {
                     err.report(self.tcx, pat_span, "pattern");
@@ -141,6 +144,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
             }
         }
     }
+
+    fn span_e0158(&self, span: Span, text: &str) {
+        span_err!(self.tcx.sess, span, E0158, "{}", text)
+    }
 }
 
 impl<'a, 'tcx> MatchVisitor<'a, 'tcx> {
diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs
index 17a9454e9d4..8e4ec93c14b 100644
--- a/src/librustc_const_eval/eval.rs
+++ b/src/librustc_const_eval/eval.rs
@@ -17,7 +17,6 @@ use rustc::hir::map::blocks::FnLikeNode;
 use rustc::hir::def::{Def, CtorKind};
 use rustc::hir::def_id::DefId;
 use rustc::ty::{self, Ty, TyCtxt};
-use rustc::ty::layout::LayoutOf;
 use rustc::ty::util::IntTypeExt;
 use rustc::ty::subst::{Substs, Subst};
 use rustc::util::common::ErrorReported;
@@ -313,7 +312,7 @@ fn eval_const_expr_partial<'a, 'tcx>(cx: &ConstContext<'a, 'tcx>,
           if tcx.fn_sig(def_id).abi() == Abi::RustIntrinsic {
             let layout_of = |ty: Ty<'tcx>| {
                 let ty = tcx.erase_regions(&ty);
-                (tcx.at(e.span), cx.param_env).layout_of(ty).map_err(|err| {
+                tcx.at(e.span).layout_of(cx.param_env.and(ty)).map_err(|err| {
                     ConstEvalErr { span: e.span, kind: LayoutError(err) }
                 })
             };
diff --git a/src/librustc_const_eval/pattern.rs b/src/librustc_const_eval/pattern.rs
index 3577feaf90c..e0b3929e32a 100644
--- a/src/librustc_const_eval/pattern.rs
+++ b/src/librustc_const_eval/pattern.rs
@@ -27,6 +27,7 @@ use syntax_pos::Span;
 
 #[derive(Clone, Debug)]
 pub enum PatternError<'tcx> {
+    AssociatedConstInPattern(Span),
     StaticInPattern(Span),
     ConstEval(ConstEvalErr<'tcx>),
 }
@@ -635,6 +636,10 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                   -> Pattern<'tcx> {
         let ty = self.tables.node_id_to_type(id);
         let def = self.tables.qpath_def(qpath, id);
+        let is_associated_const = match def {
+            Def::AssociatedConst(_) => true,
+            _ => false,
+        };
         let kind = match def {
             Def::Const(def_id) | Def::AssociatedConst(def_id) => {
                 let substs = self.tables.node_substs(id);
@@ -656,7 +661,11 @@ impl<'a, 'tcx> PatternContext<'a, 'tcx> {
                         return pat;
                     }
                     None => {
-                        self.errors.push(PatternError::StaticInPattern(span));
+                        self.errors.push(if is_associated_const {
+                            PatternError::AssociatedConstInPattern(span)
+                        } else {
+                            PatternError::StaticInPattern(span)
+                        });
                         PatternKind::Wild
                     }
                 }
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 6118ee94c84..05dcaf73135 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -167,7 +167,8 @@ pub fn run<F>(run_compiler: F) -> isize
                     let emitter =
                         errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
                                                                None,
-                                                               true);
+                                                               true,
+                                                               false);
                     let handler = errors::Handler::with_emitter(true, false, Box::new(emitter));
                     handler.emit(&MultiSpan::new(),
                                  "aborting due to previous error(s)",
@@ -289,7 +290,7 @@ fn get_trans_sysroot(backend_name: &str) -> fn() -> Box<TransCrate> {
     let sysroot = sysroot_candidates.iter()
         .map(|sysroot| {
             let libdir = filesearch::relative_target_lib_path(&sysroot, &target);
-            sysroot.join(&libdir).join("codegen-backends")
+            sysroot.join(libdir).with_file_name("codegen-backends")
         })
         .filter(|f| {
             info!("codegen backend candidate: {}", f.display());
@@ -456,10 +457,13 @@ pub fn run_compiler<'a>(args: &[String],
                                            None);
 
     let (odir, ofile) = make_output(&matches);
-    let (input, input_file_path) = match make_input(&matches.free) {
-        Some((input, input_file_path)) => callbacks.some_input(input, input_file_path),
+    let (input, input_file_path, input_err) = match make_input(&matches.free) {
+        Some((input, input_file_path, input_err)) => {
+            let (input, input_file_path) = callbacks.some_input(input, input_file_path);
+            (input, input_file_path, input_err)
+        },
         None => match callbacks.no_input(&matches, &sopts, &cfg, &odir, &ofile, &descriptions) {
-            Some((input, input_file_path)) => (input, input_file_path),
+            Some((input, input_file_path)) => (input, input_file_path, None),
             None => return (Ok(()), None),
         },
     };
@@ -470,6 +474,13 @@ pub fn run_compiler<'a>(args: &[String],
         sopts, input_file_path.clone(), descriptions, codemap, emitter_dest,
     );
 
+    if let Some(err) = input_err {
+        // Immediately stop compilation if there was an issue reading
+        // the input (for example if the input stream is not UTF-8).
+        sess.err(&format!("{}", err));
+        return (Err(CompileIncomplete::Stopped), Some(sess));
+    }
+
     let trans = get_trans(&sess);
 
     rustc_lint::register_builtins(&mut sess.lint_store.borrow_mut(), Some(&sess));
@@ -512,17 +523,22 @@ fn make_output(matches: &getopts::Matches) -> (Option<PathBuf>, Option<PathBuf>)
 }
 
 // Extract input (string or file and optional path) from matches.
-fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>)> {
+fn make_input(free_matches: &[String]) -> Option<(Input, Option<PathBuf>, Option<io::Error>)> {
     if free_matches.len() == 1 {
         let ifile = &free_matches[0];
         if ifile == "-" {
             let mut src = String::new();
-            io::stdin().read_to_string(&mut src).unwrap();
+            let err = if io::stdin().read_to_string(&mut src).is_err() {
+                Some(io::Error::new(io::ErrorKind::InvalidData,
+                                    "couldn't read from stdin, as it did not contain valid UTF-8"))
+            } else {
+                None
+            };
             Some((Input::Str { name: FileName::Anon, input: src },
-                  None))
+                  None, err))
         } else {
             Some((Input::File(PathBuf::from(ifile)),
-                  Some(PathBuf::from(ifile))))
+                  Some(PathBuf::from(ifile)), None))
         }
     } else {
         None
@@ -1434,6 +1450,7 @@ pub fn monitor<F: FnOnce() + Send + 'static>(f: F) {
             let emitter =
                 Box::new(errors::emitter::EmitterWriter::stderr(errors::ColorConfig::Auto,
                                                                 None,
+                                                                false,
                                                                 false));
             let handler = errors::Handler::with_emitter(true, false, emitter);
 
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index 2e654fe9929..40e4efb397d 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -222,6 +222,7 @@ impl Diagnostic {
             }],
             msg: msg.to_owned(),
             show_code_when_inline: false,
+            approximate: false,
         });
         self
     }
@@ -252,6 +253,7 @@ impl Diagnostic {
             }],
             msg: msg.to_owned(),
             show_code_when_inline: true,
+            approximate: false,
         });
         self
     }
@@ -267,6 +269,41 @@ impl Diagnostic {
             }).collect(),
             msg: msg.to_owned(),
             show_code_when_inline: true,
+            approximate: false,
+        });
+        self
+    }
+
+    /// This is a suggestion that may contain mistakes or fillers and should
+    /// be read and understood by a human.
+    pub fn span_approximate_suggestion(&mut self, sp: Span, msg: &str,
+                                       suggestion: String) -> &mut Self {
+        self.suggestions.push(CodeSuggestion {
+            substitutions: vec![Substitution {
+                parts: vec![SubstitutionPart {
+                    snippet: suggestion,
+                    span: sp,
+                }],
+            }],
+            msg: msg.to_owned(),
+            show_code_when_inline: true,
+            approximate: true,
+        });
+        self
+    }
+
+    pub fn span_approximate_suggestions(&mut self, sp: Span, msg: &str,
+                                        suggestions: Vec<String>) -> &mut Self {
+        self.suggestions.push(CodeSuggestion {
+            substitutions: suggestions.into_iter().map(|snippet| Substitution {
+                parts: vec![SubstitutionPart {
+                    snippet,
+                    span: sp,
+                }],
+            }).collect(),
+            msg: msg.to_owned(),
+            show_code_when_inline: true,
+            approximate: true,
         });
         self
     }
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 61674ada6fa..2536fc648c7 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -186,6 +186,16 @@ impl<'a> DiagnosticBuilder<'a> {
                                      msg: &str,
                                      suggestions: Vec<String>)
                                      -> &mut Self);
+    forward!(pub fn span_approximate_suggestion(&mut self,
+                                                sp: Span,
+                                                msg: &str,
+                                                suggestion: String)
+                                                -> &mut Self);
+    forward!(pub fn span_approximate_suggestions(&mut self,
+                                                 sp: Span,
+                                                 msg: &str,
+                                                 suggestions: Vec<String>)
+                                                 -> &mut Self);
     forward!(pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self);
     forward!(pub fn code(&mut self, s: DiagnosticId) -> &mut Self);
 
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index ffb5efd93ed..a49284eb55a 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -106,6 +106,7 @@ pub struct EmitterWriter {
     dst: Destination,
     cm: Option<Rc<CodeMapper>>,
     short_message: bool,
+    teach: bool,
 }
 
 struct FileWithAnnotatedLines {
@@ -117,32 +118,37 @@ struct FileWithAnnotatedLines {
 impl EmitterWriter {
     pub fn stderr(color_config: ColorConfig,
                   code_map: Option<Rc<CodeMapper>>,
-                  short_message: bool)
+                  short_message: bool,
+                  teach: bool)
                   -> EmitterWriter {
         if color_config.use_color() {
             let dst = Destination::from_stderr();
             EmitterWriter {
                 dst,
                 cm: code_map,
-                short_message: short_message,
+                short_message,
+                teach,
             }
         } else {
             EmitterWriter {
                 dst: Raw(Box::new(io::stderr())),
                 cm: code_map,
-                short_message: short_message,
+                short_message,
+                teach,
             }
         }
     }
 
     pub fn new(dst: Box<Write + Send>,
                code_map: Option<Rc<CodeMapper>>,
-               short_message: bool)
+               short_message: bool,
+               teach: bool)
                -> EmitterWriter {
         EmitterWriter {
             dst: Raw(dst),
             cm: code_map,
-            short_message: short_message,
+            short_message,
+            teach,
         }
     }
 
@@ -284,6 +290,10 @@ impl EmitterWriter {
                           line: &Line,
                           width_offset: usize,
                           code_offset: usize) -> Vec<(usize, Style)> {
+        if line.line_index == 0 {
+            return Vec::new();
+        }
+
         let source_string = match file.get_line(line.line_index - 1) {
             Some(s) => s,
             None => return Vec::new(),
@@ -551,7 +561,14 @@ impl EmitterWriter {
                                code_offset + annotation.start_col,
                                style);
                 }
-                _ => (),
+                _ if self.teach => {
+                    buffer.set_style_range(line_offset,
+                                           code_offset + annotation.start_col,
+                                           code_offset + annotation.end_col,
+                                           style,
+                                           annotation.is_primary);
+                }
+                _ => {}
             }
         }
 
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 3d50c95d3f4..236698ed2d4 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -83,6 +83,12 @@ pub struct CodeSuggestion {
     pub substitutions: Vec<Substitution>,
     pub msg: String,
     pub show_code_when_inline: bool,
+    /// Whether or not the suggestion is approximate
+    ///
+    /// Sometimes we may show suggestions with placeholders,
+    /// which are useful for users but not useful for
+    /// tools like rustfix
+    pub approximate: bool,
 }
 
 #[derive(Clone, Debug, PartialEq, Hash, RustcEncodable, RustcDecodable)]
@@ -297,7 +303,7 @@ impl Handler {
                                       cm: Option<Rc<CodeMapper>>,
                                       flags: HandlerFlags)
                                       -> Handler {
-        let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false));
+        let emitter = Box::new(EmitterWriter::stderr(color_config, cm, false, false));
         Handler::with_emitter_and_flags(emitter, flags)
     }
 
diff --git a/src/librustc_errors/snippet.rs b/src/librustc_errors/snippet.rs
index 6035f33c822..7d416f13ffc 100644
--- a/src/librustc_errors/snippet.rs
+++ b/src/librustc_errors/snippet.rs
@@ -10,32 +10,8 @@
 
 // Code for annotating snippets.
 
-use syntax_pos::{Span, FileMap};
-use CodeMapper;
-use std::rc::Rc;
 use Level;
 
-#[derive(Clone)]
-pub struct SnippetData {
-    codemap: Rc<CodeMapper>,
-    files: Vec<FileInfo>,
-}
-
-#[derive(Clone)]
-pub struct FileInfo {
-    file: Rc<FileMap>,
-
-    /// The "primary file", if any, gets a `-->` marker instead of
-    /// `>>>`, and has a line-number/column printed and not just a
-    /// filename (other files are not guaranteed to have line numbers
-    /// or columns). It appears first in the listing. It is known to
-    /// contain at least one primary span, though primary spans (which
-    /// are designated with `^^^`) may also occur in other files.
-    primary_span: Option<Span>,
-
-    lines: Vec<Line>,
-}
-
 #[derive(Clone, Debug, PartialOrd, Ord, PartialEq, Eq)]
 pub struct Line {
     pub line_index: usize,
diff --git a/src/librustc_errors/styled_buffer.rs b/src/librustc_errors/styled_buffer.rs
index 2c33f805203..2c736ec22c3 100644
--- a/src/librustc_errors/styled_buffer.rs
+++ b/src/librustc_errors/styled_buffer.rs
@@ -144,4 +144,25 @@ impl StyledBuffer {
     pub fn num_lines(&self) -> usize {
         self.text.len()
     }
+
+    pub fn set_style_range(&mut self,
+                           line: usize,
+                           col_start: usize,
+                           col_end: usize,
+                           style: Style,
+                           overwrite: bool) {
+        for col in col_start..col_end {
+            self.set_style(line, col, style, overwrite);
+        }
+    }
+
+    pub fn set_style(&mut self, line: usize, col: usize, style: Style, overwrite: bool) {
+        if let Some(ref mut line) = self.styles.get_mut(line) {
+            if let Some(s) = line.get_mut(col) {
+                if *s == Style::NoStyle || *s == Style::Quotation || overwrite {
+                    *s = style;
+                }
+            }
+        }
+    }
 }
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index e0999db6e3e..e7e4119b999 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -437,8 +437,8 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
                             // repr(transparent) types are allowed to have arbitrary ZSTs, not just
                             // PhantomData -- skip checking all ZST fields
                             if def.repr.transparent() {
-                                let is_zst = (cx, cx.param_env(field.did))
-                                    .layout_of(field_ty)
+                                let is_zst = cx
+                                    .layout_of(cx.param_env(field.did).and(field_ty))
                                     .map(|layout| layout.is_zst())
                                     .unwrap_or(false);
                                 if is_zst {
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index ef6475f9ee4..56f863ab3aa 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -302,19 +302,38 @@ impl EarlyLintPass for UnusedParens {
             Assign(_, ref value) => (value, "assigned value", false),
             AssignOp(.., ref value) => (value, "assigned value", false),
             InPlace(_, ref value) => (value, "emplacement value", false),
-            Call(_, ref args) => {
-                for arg in args {
-                    self.check_unused_parens_core(cx, arg, "function argument", false)
+            // either function/method call, or something this lint doesn't care about
+            ref call_or_other => {
+                let args_to_check;
+                let call_kind;
+                match *call_or_other {
+                    Call(_, ref args) => {
+                        call_kind = "function";
+                        args_to_check = &args[..];
+                    },
+                    MethodCall(_, ref args) => {
+                        call_kind = "method";
+                        // first "argument" is self (which sometimes needs parens)
+                        args_to_check = &args[1..];
+                    }
+                    // actual catch-all arm
+                    _ => { return; }
                 }
-                return;
-            },
-            MethodCall(_, ref args) => {
-                for arg in &args[1..] { // first "argument" is self (which sometimes needs parens)
-                    self.check_unused_parens_core(cx, arg, "method argument", false)
+                // Don't lint if this is a nested macro expansion: otherwise, the lint could
+                // trigger in situations that macro authors shouldn't have to care about, e.g.,
+                // when a parenthesized token tree matched in one macro expansion is matched as
+                // an expression in another and used as a fn/method argument (Issue #47775)
+                if e.span.ctxt().outer().expn_info()
+                    .map_or(false, |info| info.call_site.ctxt().outer()
+                            .expn_info().is_some()) {
+                        return;
+                }
+                let msg = format!("{} argument", call_kind);
+                for arg in args_to_check {
+                    self.check_unused_parens_core(cx, arg, &msg, false);
                 }
                 return;
             }
-            _ => return,
         };
         self.check_unused_parens_core(cx, &value, msg, struct_lit_needs_parens);
     }
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 7bd3b6e39f0..7fadc4b36e4 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -746,12 +746,12 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                     self.describe_field_from_ty(&tnm.ty, field)
                 }
                 ty::TyArray(ty, _) | ty::TySlice(ty) => self.describe_field_from_ty(&ty, field),
-                ty::TyClosure(closure_def_id, _) => {
+                ty::TyClosure(def_id, _) | ty::TyGenerator(def_id, _, _) => {
                     // Convert the def-id into a node-id. node-ids are only valid for
                     // the local code in the current crate, so this returns an `Option` in case
                     // the closure comes from another crate. But in that case we wouldn't
                     // be borrowck'ing it, so we can just unwrap:
-                    let node_id = self.tcx.hir.as_local_node_id(closure_def_id).unwrap();
+                    let node_id = self.tcx.hir.as_local_node_id(def_id).unwrap();
                     let freevar = self.tcx.with_freevars(node_id, |fv| fv[field.index()]);
 
                     self.tcx.hir.name(freevar.var_id()).to_string()
diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
index 015eb8a3b66..c0c680a4ddc 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs
@@ -374,13 +374,20 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
             }
         };
         if let PlaceContext::Copy = context {
-            let ty = place_ty.to_ty(self.tcx());
-            if self.cx
-                .infcx
-                .type_moves_by_default(self.cx.param_env, ty, DUMMY_SP)
-            {
-                span_mirbug!(self, place, "attempted copy of non-Copy type ({:?})", ty);
-            }
+            let tcx = self.tcx();
+            let trait_ref = ty::TraitRef {
+                def_id: tcx.lang_items().copy_trait().unwrap(),
+                substs: tcx.mk_substs_trait(place_ty.to_ty(tcx), &[]),
+            };
+
+            // In order to have a Copy operand, the type T of the value must be Copy. Note that we
+            // prove that T: Copy, rather than using the type_moves_by_default test. This is
+            // important because type_moves_by_default ignores the resulting region obligations and
+            // assumes they pass. This can result in bounds from Copy impls being unsoundly ignored
+            // (e.g., #29149). Note that we decide to use Copy before knowing whether the bounds
+            // fully apply: in effect, the rule is that if a value of some type could implement
+            // Copy, then it must.
+            self.cx.prove_trait_ref(trait_ref, location);
         }
         place_ty
     }
@@ -533,15 +540,17 @@ impl<'a, 'b, 'gcx, 'tcx> TypeVerifier<'a, 'b, 'gcx, 'tcx> {
                     }
                 }
                 ty::TyGenerator(def_id, substs, _) => {
-                    // Try upvars first. `field_tys` requires final optimized MIR.
-                    if let Some(ty) = substs.upvar_tys(def_id, tcx).nth(field.index()) {
+                    // Try pre-transform fields first (upvars and current state)
+                    if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field.index()) {
                         return Ok(ty);
                     }
 
+                    // Then try `field_tys` which contains all the fields, but it
+                    // requires the final optimized MIR.
                     return match substs.field_tys(def_id, tcx).nth(field.index()) {
                         Some(ty) => Ok(ty),
                         None => Err(FieldAccessError::OutOfRange {
-                            field_count: substs.field_tys(def_id, tcx).count() + 1,
+                            field_count: substs.field_tys(def_id, tcx).count(),
                         }),
                     };
                 }
@@ -1233,13 +1242,16 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
                 }
             }
             AggregateKind::Generator(def_id, substs, _) => {
-                if let Some(ty) = substs.upvar_tys(def_id, tcx).nth(field_index) {
+                // Try pre-transform fields first (upvars and current state)
+                if let Some(ty) = substs.pre_transforms_tys(def_id, tcx).nth(field_index) {
                     Ok(ty)
                 } else {
+                    // Then try `field_tys` which contains all the fields, but it
+                    // requires the final optimized MIR.
                     match substs.field_tys(def_id, tcx).nth(field_index) {
                         Some(ty) => Ok(ty),
                         None => Err(FieldAccessError::OutOfRange {
-                            field_count: substs.field_tys(def_id, tcx).count() + 1,
+                            field_count: substs.field_tys(def_id, tcx).count(),
                         }),
                     }
                 }
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
new file mode 100644
index 00000000000..244e8b5ccd7
--- /dev/null
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -0,0 +1,118 @@
+// Copyright 2017 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.
+
+pub use super::*;
+
+use rustc::mir::*;
+use rustc::mir::visit::Visitor;
+use dataflow::BitDenotation;
+
+/// This calculates if any part of a MIR local could have previously been borrowed.
+/// This means that once a local has been borrowed, its bit will always be set
+/// from that point and onwards, even if the borrow ends. You could also think of this
+/// as computing the lifetimes of infinite borrows.
+/// This is used to compute which locals are live during a yield expression for
+/// immovable generators.
+#[derive(Copy, Clone)]
+pub struct HaveBeenBorrowedLocals<'a, 'tcx: 'a> {
+    mir: &'a Mir<'tcx>,
+}
+
+impl<'a, 'tcx: 'a> HaveBeenBorrowedLocals<'a, 'tcx> {
+    pub fn new(mir: &'a Mir<'tcx>)
+               -> Self {
+        HaveBeenBorrowedLocals { mir: mir }
+    }
+
+    pub fn mir(&self) -> &Mir<'tcx> {
+        self.mir
+    }
+}
+
+impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> {
+    type Idx = Local;
+    fn name() -> &'static str { "has_been_borrowed_locals" }
+    fn bits_per_block(&self) -> usize {
+        self.mir.local_decls.len()
+    }
+
+    fn start_block_effect(&self, _sets: &mut IdxSet<Local>) {
+        // Nothing is borrowed on function entry
+    }
+
+    fn statement_effect(&self,
+                        sets: &mut BlockSets<Local>,
+                        loc: Location) {
+        BorrowedLocalsVisitor {
+            sets,
+        }.visit_statement(loc.block, &self.mir[loc.block].statements[loc.statement_index], loc);
+    }
+
+    fn terminator_effect(&self,
+                         sets: &mut BlockSets<Local>,
+                         loc: Location) {
+        BorrowedLocalsVisitor {
+            sets,
+        }.visit_terminator(loc.block, self.mir[loc.block].terminator(), loc);
+    }
+
+    fn propagate_call_return(&self,
+                             _in_out: &mut IdxSet<Local>,
+                             _call_bb: mir::BasicBlock,
+                             _dest_bb: mir::BasicBlock,
+                             _dest_place: &mir::Place) {
+        // Nothing to do when a call returns successfully
+    }
+}
+
+impl<'a, 'tcx> BitwiseOperator for HaveBeenBorrowedLocals<'a, 'tcx> {
+    #[inline]
+    fn join(&self, pred1: usize, pred2: usize) -> usize {
+        pred1 | pred2 // "maybe" means we union effects of both preds
+    }
+}
+
+impl<'a, 'tcx> InitialFlow for HaveBeenBorrowedLocals<'a, 'tcx> {
+    #[inline]
+    fn bottom_value() -> bool {
+        false // bottom = unborrowed
+    }
+}
+
+struct BorrowedLocalsVisitor<'b, 'c: 'b> {
+    sets: &'b mut BlockSets<'c, Local>,
+}
+
+fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
+    match *place {
+        Place::Local(l) => Some(l),
+        Place::Static(..) => None,
+        Place::Projection(ref proj) => {
+            match proj.elem {
+                ProjectionElem::Deref => None,
+                _ => find_local(&proj.base)
+            }
+        }
+    }
+}
+
+impl<'tcx, 'b, 'c> Visitor<'tcx> for BorrowedLocalsVisitor<'b, 'c> {
+    fn visit_rvalue(&mut self,
+                    rvalue: &Rvalue<'tcx>,
+                    location: Location) {
+        if let Rvalue::Ref(_, _, ref place) = *rvalue {
+            if let Some(local) = find_local(place) {
+                self.sets.gen(&local);
+            }
+        }
+
+        self.super_rvalue(rvalue, location)
+    }
+}
diff --git a/src/librustc_mir/dataflow/impls/borrows.rs b/src/librustc_mir/dataflow/impls/borrows.rs
index 632bb5b3428..80990bcc080 100644
--- a/src/librustc_mir/dataflow/impls/borrows.rs
+++ b/src/librustc_mir/dataflow/impls/borrows.rs
@@ -396,8 +396,7 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
                         // Issue #46746: Two-phase borrows handles
                         // stmts of form `Tmp = &mut Borrow` ...
                         match lhs {
-                            Place::Local(..) => {} // okay
-                            Place::Static(..) => unreachable!(), // (filtered by is_unsafe_place)
+                            Place::Local(..) | Place::Static(..) => {} // okay
                             Place::Projection(..) => {
                                 // ... can assign into projections,
                                 // e.g. `box (&mut _)`. Current
diff --git a/src/librustc_mir/dataflow/impls/mod.rs b/src/librustc_mir/dataflow/impls/mod.rs
index e7c15625cbe..c5f5492cd2c 100644
--- a/src/librustc_mir/dataflow/impls/mod.rs
+++ b/src/librustc_mir/dataflow/impls/mod.rs
@@ -33,6 +33,10 @@ mod storage_liveness;
 
 pub use self::storage_liveness::*;
 
+mod borrowed_locals;
+
+pub use self::borrowed_locals::*;
+
 #[allow(dead_code)]
 pub(super) mod borrows;
 
diff --git a/src/librustc_mir/dataflow/mod.rs b/src/librustc_mir/dataflow/mod.rs
index bd63198ecd0..291c22b5e1e 100644
--- a/src/librustc_mir/dataflow/mod.rs
+++ b/src/librustc_mir/dataflow/mod.rs
@@ -30,6 +30,7 @@ pub use self::impls::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
 pub use self::impls::{DefinitelyInitializedPlaces, MovingOutStatements};
 pub use self::impls::EverInitializedPlaces;
 pub use self::impls::borrows::{Borrows, BorrowData};
+pub use self::impls::HaveBeenBorrowedLocals;
 pub(crate) use self::impls::borrows::{ActiveBorrows, Reservations, ReserveOrActivateIndex};
 pub use self::at_location::{FlowAtLocation, FlowsAtLocation};
 pub(crate) use self::drop_flag_effects::*;
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs
index baec0fea50f..02fcb69fef5 100644
--- a/src/librustc_mir/interpret/eval_context.rs
+++ b/src/librustc_mir/interpret/eval_context.rs
@@ -172,7 +172,7 @@ impl<'a, 'tcx, M: Machine<'tcx>> LayoutOf<Ty<'tcx>> for &'a EvalContext<'a, 'tcx
     type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>;
 
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
-        (self.tcx, self.param_env).layout_of(ty)
+        self.tcx.layout_of(self.param_env.and(ty))
             .map_err(|layout| EvalErrorKind::Layout(layout).into())
     }
 }
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index 806d787c845..e9471cdb4f9 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -107,6 +107,7 @@ use rustc::dep_graph::WorkProductId;
 use rustc::hir::def_id::DefId;
 use rustc::hir::map::DefPathData;
 use rustc::mir::mono::{Linkage, Visibility};
+use rustc::middle::exported_symbols::SymbolExportLevel;
 use rustc::ty::{self, TyCtxt, InstanceDef};
 use rustc::ty::item_path::characteristic_def_id_of_type;
 use rustc::util::nodemap::{FxHashMap, FxHashSet};
@@ -322,7 +323,16 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                             .or_insert_with(make_codegen_unit);
 
         let mut can_be_internalized = true;
-        let (linkage, visibility) = match trans_item.explicit_linkage(tcx) {
+        let default_visibility = |id: DefId| {
+            if tcx.sess.target.target.options.default_hidden_visibility &&
+                tcx.symbol_export_level(id) != SymbolExportLevel::C
+            {
+                Visibility::Hidden
+            } else {
+                Visibility::Default
+            }
+        };
+        let (linkage, mut visibility) = match trans_item.explicit_linkage(tcx) {
             Some(explicit_linkage) => (explicit_linkage, Visibility::Default),
             None => {
                 match trans_item {
@@ -352,7 +362,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                     Visibility::Hidden
                                 } else if def_id.is_local() {
                                     if tcx.is_exported_symbol(def_id) {
-                                        Visibility::Default
+                                        can_be_internalized = false;
+                                        default_visibility(def_id)
                                     } else {
                                         Visibility::Hidden
                                     }
@@ -375,7 +386,8 @@ fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     MonoItem::GlobalAsm(node_id) => {
                         let def_id = tcx.hir.local_def_id(node_id);
                         let visibility = if tcx.is_exported_symbol(def_id) {
-                            Visibility::Default
+                            can_be_internalized = false;
+                            default_visibility(def_id)
                         } else {
                             Visibility::Hidden
                         };
diff --git a/src/librustc_mir/transform/generator.rs b/src/librustc_mir/transform/generator.rs
index ebd34f81deb..812665f5fa4 100644
--- a/src/librustc_mir/transform/generator.rs
+++ b/src/librustc_mir/transform/generator.rs
@@ -78,7 +78,8 @@ use std::mem;
 use transform::{MirPass, MirSource};
 use transform::simplify;
 use transform::no_landing_pads::no_landing_pads;
-use dataflow::{do_dataflow, DebugFormatted, MaybeStorageLive, state_for_location};
+use dataflow::{do_dataflow, DebugFormatted, state_for_location};
+use dataflow::{MaybeStorageLive, HaveBeenBorrowedLocals};
 
 pub struct StateTransform;
 
@@ -369,17 +370,33 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 HashMap<BasicBlock, liveness::LocalSet>) {
     let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
     let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap();
-    let analysis = MaybeStorageLive::new(mir);
+
+    // Calculate when MIR locals have live storage. This gives us an upper bound of their
+    // lifetimes.
+    let storage_live_analysis = MaybeStorageLive::new(mir);
     let storage_live =
-        do_dataflow(tcx, mir, node_id, &[], &dead_unwinds, analysis,
+        do_dataflow(tcx, mir, node_id, &[], &dead_unwinds, storage_live_analysis,
                     |bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
 
+    // Find the MIR locals which do not use StorageLive/StorageDead statements.
+    // The storage of these locals are always live.
     let mut ignored = StorageIgnored(IdxSetBuf::new_filled(mir.local_decls.len()));
     ignored.visit_mir(mir);
 
-    let mut borrowed_locals = BorrowedLocals(IdxSetBuf::new_empty(mir.local_decls.len()));
-    borrowed_locals.visit_mir(mir);
+    // Calculate the MIR locals which have been previously
+    // borrowed (even if they are still active).
+    // This is only used for immovable generators.
+    let borrowed_locals = if !movable {
+        let analysis = HaveBeenBorrowedLocals::new(mir);
+        let result =
+            do_dataflow(tcx, mir, node_id, &[], &dead_unwinds, analysis,
+                        |bd, p| DebugFormatted::new(&bd.mir().local_decls[p]));
+        Some((analysis, result))
+    } else {
+        None
+    };
 
+    // Calculate the liveness of MIR locals ignoring borrows.
     let mut set = liveness::LocalSet::new_empty(mir.local_decls.len());
     let mut liveness = liveness::liveness_of_locals(mir, LivenessMode {
         include_regular_use: true,
@@ -396,24 +413,41 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 statement_index: data.statements.len(),
             };
 
-            let storage_liveness = state_for_location(loc, &analysis, &storage_live, mir);
+            if let Some((ref analysis, ref result)) = borrowed_locals {
+                let borrowed_locals = state_for_location(loc,
+                                                         analysis,
+                                                         result,
+                                                         mir);
+                // The `liveness` variable contains the liveness of MIR locals ignoring borrows.
+                // This is correct for movable generators since borrows cannot live across
+                // suspension points. However for immovable generators we need to account for
+                // borrows, so we conseratively assume that all borrowed locals live forever.
+                // To do this we just union our `liveness` result with `borrowed_locals`, which
+                // contains all the locals which has been borrowed before this suspension point.
+                // If a borrow is converted to a raw reference, we must also assume that it lives
+                // forever. Note that the final liveness is still bounded by the storage liveness
+                // of the local, which happens using the `intersect` operation below.
+                liveness.outs[block].union(&borrowed_locals);
+            }
+
+            let mut storage_liveness = state_for_location(loc,
+                                                          &storage_live_analysis,
+                                                          &storage_live,
+                                                          mir);
 
+            // Store the storage liveness for later use so we can restore the state
+            // after a suspension point
             storage_liveness_map.insert(block, storage_liveness.clone());
 
-            let mut live_locals = storage_liveness;
-
             // Mark locals without storage statements as always having live storage
-            live_locals.union(&ignored.0);
+            storage_liveness.union(&ignored.0);
 
-            if !movable {
-                // For immovable generators we consider borrowed locals to always be live.
-                // This effectively makes those locals use just the storage liveness.
-                liveness.outs[block].union(&borrowed_locals.0);
-            }
+            // Locals live are live at this point only if they are used across
+            // suspension points (the `liveness` variable)
+            // and their storage is live (the `storage_liveness` variable)
+            storage_liveness.intersect(&liveness.outs[block]);
 
-            // Locals live are live at this point only if they are used across suspension points
-            // and their storage is live
-            live_locals.intersect(&liveness.outs[block]);
+            let live_locals = storage_liveness;
 
             // Add the locals life at this suspension point to the set of locals which live across
             // any suspension points
diff --git a/src/librustc_mir/transform/inline.rs b/src/librustc_mir/transform/inline.rs
index 43ee75d1e2b..ceea97e3ed3 100644
--- a/src/librustc_mir/transform/inline.rs
+++ b/src/librustc_mir/transform/inline.rs
@@ -19,7 +19,6 @@ use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc::mir::*;
 use rustc::mir::visit::*;
 use rustc::ty::{self, Instance, Ty, TyCtxt, TypeFoldable};
-use rustc::ty::layout::LayoutOf;
 use rustc::ty::subst::{Subst,Substs};
 
 use std::collections::VecDeque;
@@ -655,7 +654,7 @@ impl<'a, 'tcx> Inliner<'a, 'tcx> {
 fn type_size_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                           param_env: ty::ParamEnv<'tcx>,
                           ty: Ty<'tcx>) -> Option<u64> {
-    (tcx, param_env).layout_of(ty).ok().map(|layout| layout.size.bytes())
+    tcx.layout_of(param_env.and(ty)).ok().map(|layout| layout.size.bytes())
 }
 
 fn subst_and_normalize<'a, 'tcx: 'a>(
diff --git a/src/librustc_passes/loops.rs b/src/librustc_passes/loops.rs
index c23f28fe220..008c71cc9ce 100644
--- a/src/librustc_passes/loops.rs
+++ b/src/librustc_passes/loops.rs
@@ -119,6 +119,11 @@ impl<'a, 'hir> Visitor<'hir> for CheckLoopVisitor<'a, 'hir> {
                                              kind.name())
                                 .span_label(e.span,
                                             "can only break with a value inside `loop`")
+                                .span_suggestion(e.span,
+                                                 &format!("instead, use `break` on its own \
+                                                           without a value inside this `{}` loop",
+                                                          kind.name()),
+                                                 "break".to_string())
                                 .emit();
                         }
                     }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index ecf3c9e42d5..2da4bfedd3a 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -3998,14 +3998,20 @@ impl<'a> Resolver<'a> {
 
             if let (Ok(snippet), false) = (cm.span_to_snippet(binding.span),
                                            binding.is_renamed_extern_crate()) {
+                let suggested_name = if name.as_str().chars().next().unwrap().is_uppercase() {
+                    format!("Other{}", name)
+                } else {
+                    format!("other_{}", name)
+                };
+
                 err.span_suggestion(binding.span,
                                     rename_msg,
                                     if snippet.ends_with(';') {
-                                        format!("{} as Other{};",
+                                        format!("{} as {};",
                                                 &snippet[..snippet.len()-1],
-                                                name)
+                                                suggested_name)
                                     } else {
-                                        format!("{} as Other{}", snippet, name)
+                                        format!("{} as {}", snippet, suggested_name)
                                     });
             } else {
                 err.span_label(binding.span, rename_msg);
diff --git a/src/librustc_trans/allocator.rs b/src/librustc_trans/allocator.rs
index fd5aa1364d3..e1c145b122d 100644
--- a/src/librustc_trans/allocator.rs
+++ b/src/librustc_trans/allocator.rs
@@ -86,6 +86,10 @@ pub(crate) unsafe fn trans(tcx: TyCtxt, mods: &ModuleLlvm, kind: AllocatorKind)
                                                      name.as_ptr(),
                                                      ty);
 
+        if tcx.sess.target.target.options.default_hidden_visibility {
+            llvm::LLVMRustSetVisibility(llfn, llvm::Visibility::Hidden);
+        }
+
         let callee = CString::new(kind.fn_name(method.name)).unwrap();
         let callee = llvm::LLVMRustGetOrInsertFunction(llmod,
                                                        callee.as_ptr(),
diff --git a/src/librustc_trans/asm.rs b/src/librustc_trans/asm.rs
index c7be0c4e67d..751f8148a2a 100644
--- a/src/librustc_trans/asm.rs
+++ b/src/librustc_trans/asm.rs
@@ -59,8 +59,9 @@ pub fn trans_inline_asm<'a, 'tcx>(
     // Default per-arch clobbers
     // Basically what clang does
     let arch_clobbers = match &bx.sess().target.target.arch[..] {
-        "x86" | "x86_64" => vec!["~{dirflag}", "~{fpsr}", "~{flags}"],
-        _                => Vec::new()
+        "x86" | "x86_64"  => vec!["~{dirflag}", "~{fpsr}", "~{flags}"],
+        "mips" | "mips64" => vec!["~{$1}"],
+        _                 => Vec::new()
     };
 
     let all_constraints =
diff --git a/src/librustc_trans/back/symbol_export.rs b/src/librustc_trans/back/symbol_export.rs
index 15ff59c7df9..989ef8a9537 100644
--- a/src/librustc_trans/back/symbol_export.rs
+++ b/src/librustc_trans/back/symbol_export.rs
@@ -133,6 +133,8 @@ pub fn provide(providers: &mut Providers) {
 
         Arc::new(local_crate)
     };
+
+    providers.symbol_export_level = export_level;
 }
 
 pub fn provide_extern(providers: &mut Providers) {
@@ -203,6 +205,7 @@ pub fn provide_extern(providers: &mut Providers) {
 
         Arc::new(crate_exports)
     };
+    providers.symbol_export_level = export_level;
 }
 
 fn export_level(tcx: TyCtxt, sym_def_id: DefId) -> SymbolExportLevel {
diff --git a/src/librustc_trans/back/write.rs b/src/librustc_trans/back/write.rs
index 8afa63a5e97..206c73b0174 100644
--- a/src/librustc_trans/back/write.rs
+++ b/src/librustc_trans/back/write.rs
@@ -824,9 +824,7 @@ fn binaryen_assemble(cgcx: &CodegenContext,
     if cgcx.debuginfo != config::NoDebugInfo {
         options.debuginfo(true);
     }
-    if cgcx.crate_types.contains(&config::CrateTypeExecutable) {
-        options.start("main");
-    }
+
     options.stack(1024 * 1024);
     options.import_memory(cgcx.wasm_import_memory);
     let assembled = input.and_then(|input| {
@@ -1452,7 +1450,7 @@ fn start_executing_work(tcx: TyCtxt,
         target_pointer_width: tcx.sess.target.target.target_pointer_width.clone(),
         binaryen_linker: tcx.sess.linker_flavor() == LinkerFlavor::Binaryen,
         debuginfo: tcx.sess.opts.debuginfo,
-        wasm_import_memory: wasm_import_memory,
+        wasm_import_memory,
         assembler_cmd,
     };
 
diff --git a/src/librustc_trans/context.rs b/src/librustc_trans/context.rs
index 06b8d9ff7b3..a285e5f263a 100644
--- a/src/librustc_trans/context.rs
+++ b/src/librustc_trans/context.rs
@@ -464,8 +464,7 @@ impl<'a, 'tcx> LayoutOf<Ty<'tcx>> for &'a CodegenCx<'a, 'tcx> {
     type TyLayout = TyLayout<'tcx>;
 
     fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout {
-        (self.tcx, ty::ParamEnv::empty(traits::Reveal::All))
-            .layout_of(ty)
+        self.tcx.layout_of(ty::ParamEnv::empty(traits::Reveal::All).and(ty))
             .unwrap_or_else(|e| match e {
                 LayoutError::SizeOverflow(_) => self.sess().fatal(&e.to_string()),
                 _ => bug!("failed to get layout for `{}`: {}", ty, e)
diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs
index b1533cfad19..af957500f70 100644
--- a/src/librustc_trans/type_of.rs
+++ b/src/librustc_trans/type_of.rs
@@ -57,7 +57,9 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>,
         ty::TyClosure(..) |
         ty::TyGenerator(..) |
         ty::TyAdt(..) |
-        ty::TyDynamic(..) |
+        // FIXME(eddyb) producing readable type names for trait objects can result
+        // in problematically distinct types due to HRTB and subtyping (see #47638).
+        // ty::TyDynamic(..) |
         ty::TyForeign(..) |
         ty::TyStr => {
             let mut name = String::with_capacity(32);
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 570eecfc267..4c10f28eb8e 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -40,6 +40,8 @@ pub fn compare_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     debug!("compare_impl_method(impl_trait_ref={:?})",
            impl_trait_ref);
 
+    let impl_m_span = tcx.sess.codemap().def_span(impl_m_span);
+
     if let Err(ErrorReported) = compare_self_type(tcx,
                                                   impl_m,
                                                   impl_m_span,
@@ -186,6 +188,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     check_region_bounds_on_impl_method(tcx,
                                        impl_m_span,
                                        impl_m,
+                                       trait_m,
                                        &trait_m_generics,
                                        &impl_m_generics,
                                        trait_to_skol_substs)?;
@@ -310,7 +313,7 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             };
 
             let mut diag = struct_span_err!(tcx.sess,
-                                            cause.span,
+                                            cause.span(&tcx),
                                             E0053,
                                             "method `{}` has an incompatible type for trait",
                                             trait_m.name);
@@ -346,10 +349,12 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 span: Span,
                                                 impl_m: &ty::AssociatedItem,
+                                                trait_m: &ty::AssociatedItem,
                                                 trait_generics: &ty::Generics,
                                                 impl_generics: &ty::Generics,
                                                 trait_to_skol_substs: &Substs<'tcx>)
                                                 -> Result<(), ErrorReported> {
+    let span = tcx.sess.codemap().def_span(span);
     let trait_params = &trait_generics.regions[..];
     let impl_params = &impl_generics.regions[..];
 
@@ -371,14 +376,18 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // are zero. Since I don't quite know how to phrase things at
     // the moment, give a kind of vague error message.
     if trait_params.len() != impl_params.len() {
-        struct_span_err!(tcx.sess,
-                         span,
-                         E0195,
-                         "lifetime parameters or bounds on method `{}` do not match the \
-                          trait declaration",
-                         impl_m.name)
-            .span_label(span, "lifetimes do not match trait")
-            .emit();
+        let mut err = struct_span_err!(tcx.sess,
+                                       span,
+                                       E0195,
+                                       "lifetime parameters or bounds on method `{}` do not match \
+                                        the trait declaration",
+                                       impl_m.name);
+        err.span_label(span, "lifetimes do not match method in trait");
+        if let Some(sp) = tcx.hir.span_if_local(trait_m.def_id) {
+            err.span_label(tcx.sess.codemap().def_span(sp),
+                           "lifetimes in impl do not match this method in trait");
+        }
+        err.emit();
         return Err(ErrorReported);
     }
 
@@ -424,9 +433,9 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
                 }).map(|(ref impl_arg, ref trait_arg)| {
                     (impl_arg.span, Some(trait_arg.span))
                 })
-                .unwrap_or_else(|| (cause.span, tcx.hir.span_if_local(trait_m.def_id)))
+                .unwrap_or_else(|| (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)))
             } else {
-                (cause.span, tcx.hir.span_if_local(trait_m.def_id))
+                (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
             }
         }
         TypeError::Sorts(ExpectedFound { .. }) => {
@@ -459,14 +468,14 @@ fn extract_spans_for_error_reporting<'a, 'gcx, 'tcx>(infcx: &infer::InferCtxt<'a
                              {
                                  (impl_m_output.span(), Some(trait_m_output.span()))
                              } else {
-                                 (cause.span, tcx.hir.span_if_local(trait_m.def_id))
+                                 (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
                              }
                          })
             } else {
-                (cause.span, tcx.hir.span_if_local(trait_m.def_id))
+                (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id))
             }
         }
-        _ => (cause.span, tcx.hir.span_if_local(trait_m.def_id)),
+        _ => (cause.span(&tcx), tcx.hir.span_if_local(trait_m.def_id)),
     }
 }
 
diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs
index 781eeaef248..2e45e3b1f35 100644
--- a/src/librustc_typeck/check/generator_interior.rs
+++ b/src/librustc_typeck/check/generator_interior.rs
@@ -150,15 +150,15 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for InteriorVisitor<'a, 'gcx, 'tcx> {
     }
 
     fn visit_pat(&mut self, pat: &'tcx Pat) {
+        intravisit::walk_pat(self, pat);
+
+        self.expr_count += 1;
+
         if let PatKind::Binding(..) = pat.node {
             let scope = self.region_scope_tree.var_scope(pat.hir_id.local_id);
             let ty = self.fcx.tables.borrow().pat_ty(pat);
             self.record(ty, Some(scope), None, pat.span);
         }
-
-        self.expr_count += 1;
-
-        intravisit::walk_pat(self, pat);
     }
 
     fn visit_expr(&mut self, expr: &'tcx Expr) {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 483dd345286..363d4a9dc0c 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -100,7 +100,6 @@ use rustc::ty::adjustment::{Adjust, Adjustment, AutoBorrow};
 use rustc::ty::fold::TypeFoldable;
 use rustc::ty::maps::Providers;
 use rustc::ty::util::{Representability, IntTypeExt};
-use rustc::ty::layout::LayoutOf;
 use errors::{DiagnosticBuilder, DiagnosticId};
 
 use require_c_abi_if_variadic;
@@ -1015,7 +1014,9 @@ fn check_fn<'a, 'gcx, 'tcx>(inherited: &'a Inherited<'a, 'gcx, 'tcx>,
     let span = body.value.span;
 
     if body.is_generator && can_be_generator.is_some() {
-        fcx.yield_ty = Some(fcx.next_ty_var(TypeVariableOrigin::TypeInference(span)));
+        let yield_ty = fcx.next_ty_var(TypeVariableOrigin::TypeInference(span));
+        fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
+        fcx.yield_ty = Some(yield_ty);
     }
 
     GatherLocalsVisitor { fcx: &fcx, }.visit_body(body);
@@ -1551,7 +1552,7 @@ fn check_transparent<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, sp: Span, def_id: De
     let field_infos: Vec<_> = adt.non_enum_variant().fields.iter().map(|field| {
         let ty = field.ty(tcx, Substs::identity_for_item(tcx, field.did));
         let param_env = tcx.param_env(field.did);
-        let layout = (tcx, param_env).layout_of(ty);
+        let layout = tcx.layout_of(param_env.and(ty));
         // We are currently checking the type this field came from, so it must be local
         let span = tcx.hir.span_if_local(field.did).unwrap();
         let zst = layout.map(|layout| layout.is_zst()).unwrap_or(false);
diff --git a/src/librustc_typeck/coherence/inherent_impls_overlap.rs b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
index 07d5f813cbb..88a2dc817ae 100644
--- a/src/librustc_typeck/coherence/inherent_impls_overlap.rs
+++ b/src/librustc_typeck/coherence/inherent_impls_overlap.rs
@@ -82,29 +82,37 @@ impl<'a, 'tcx> InherentOverlapChecker<'a, 'tcx> {
 
         for (i, &impl1_def_id) in impls.iter().enumerate() {
             for &impl2_def_id in &impls[(i + 1)..] {
-                let used_to_be_allowed = self.tcx.infer_ctxt().enter(|infcx| {
-                    if let Some(overlap) =
-                        traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id,
-                                                  IntercrateMode::Issue43355)
-                    {
+                let used_to_be_allowed = traits::overlapping_impls(
+                    self.tcx,
+                    impl1_def_id,
+                    impl2_def_id,
+                    IntercrateMode::Issue43355,
+                    |overlap| {
                         self.check_for_common_items_in_impls(
-                            impl1_def_id, impl2_def_id, overlap, false);
+                            impl1_def_id,
+                            impl2_def_id,
+                            overlap,
+                            false,
+                        );
                         false
-                    } else {
-                        true
-                    }
-                });
+                    },
+                    || true,
+                );
 
                 if used_to_be_allowed {
-                    self.tcx.infer_ctxt().enter(|infcx| {
-                        if let Some(overlap) =
-                            traits::overlapping_impls(&infcx, impl1_def_id, impl2_def_id,
-                                                      IntercrateMode::Fixed)
-                        {
-                            self.check_for_common_items_in_impls(
-                                impl1_def_id, impl2_def_id, overlap, true);
-                        }
-                    });
+                    traits::overlapping_impls(
+                        self.tcx,
+                        impl1_def_id,
+                        impl2_def_id,
+                        IntercrateMode::Fixed,
+                        |overlap| self.check_for_common_items_in_impls(
+                            impl1_def_id,
+                            impl2_def_id,
+                            overlap,
+                            true,
+                        ),
+                        || (),
+                    );
                 }
             }
         }
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 0929b833c19..7c9a49c82a9 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -2447,7 +2447,12 @@ impl Clean<Type> for hir::Ty {
                 let def_id = cx.tcx.hir.body_owner_def_id(n);
                 let param_env = cx.tcx.param_env(def_id);
                 let substs = Substs::identity_for_item(cx.tcx, def_id);
-                let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap();
+                let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap_or_else(|_| {
+                    cx.tcx.mk_const(ty::Const {
+                        val: ConstVal::Unevaluated(def_id, substs),
+                        ty: cx.tcx.types.usize
+                    })
+                });
                 let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
                     n.to_string()
                 } else if let ConstVal::Unevaluated(def_id, _) = n.val {
@@ -2577,7 +2582,9 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 let mut n = cx.tcx.lift(&n).unwrap();
                 if let ConstVal::Unevaluated(def_id, substs) = n.val {
                     let param_env = cx.tcx.param_env(def_id);
-                    n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap()
+                    if let Ok(new_n) = cx.tcx.const_eval(param_env.and((def_id, substs))) {
+                        n = new_n;
+                    }
                 };
                 let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
                     n.to_string()
diff --git a/src/librustdoc/html/static/rustdoc.css b/src/librustdoc/html/static/rustdoc.css
index d2eeb2e15b3..2b1f920bba0 100644
--- a/src/librustdoc/html/static/rustdoc.css
+++ b/src/librustdoc/html/static/rustdoc.css
@@ -181,15 +181,19 @@ nav.sub {
 	overflow: auto;
 }
 
-.sidebar .current {
+.sidebar .block > ul > li {
 	margin-right: -20px;
 }
 
-.content, nav { max-width: 960px; }
+.content, nav {
+	max-width: 960px;
+}
 
 /* Everything else */
 
-.js-only, .hidden { display: none !important; }
+.js-only, .hidden {
+	display: none !important;
+}
 
 .sidebar img {
 	margin: 20px auto;
@@ -218,7 +222,9 @@ nav.sub {
 	border: none;
 }
 
-.location a:first-child { font-weight: 500; }
+.location a:first-child {
+	font-weight: 500;
+}
 
 .block {
 	padding: 0;
@@ -299,7 +305,9 @@ nav.sub {
 	-ms-user-select: none;
 	user-select: none;
 }
-.line-numbers span { cursor: pointer; }
+.line-numbers span {
+	cursor: pointer;
+}
 
 .docblock-short p {
 	display: inline;
@@ -317,7 +325,9 @@ nav.sub {
 	text-overflow: ellipsis;
 	margin: 0;
 }
-.docblock-short code { white-space: nowrap; }
+.docblock-short code {
+	white-space: nowrap;
+}
 
 .docblock h1, .docblock h2, .docblock h3, .docblock h4, .docblock h5 {
 	border-bottom: 1px solid;
@@ -384,7 +394,9 @@ h4 > code, h3 > code, .invisible > code {
 	display: inline-block;
 }
 
-#main { position: relative; }
+#main {
+	position: relative;
+}
 #main > .since {
 	top: inherit;
 	font-family: "Fira Sans", "Helvetica Neue", Helvetica, Arial, sans-serif;
@@ -428,7 +440,9 @@ h4 > code, h3 > code, .invisible > code {
 	padding: 0;
 }
 
-.content .item-list li { margin-bottom: 1em; }
+.content .item-list li {
+	margin-bottom: 1em;
+}
 
 .content .multi-column {
 	-moz-column-count: 5;
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index d61b80c9aa0..087d88419bc 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -238,6 +238,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
     ));
     let emitter = errors::emitter::EmitterWriter::new(box Sink(data.clone()),
                                                       Some(codemap.clone()),
+                                                      false,
                                                       false);
     let old = io::set_panic(Some(box Sink(data.clone())));
     let _bomb = Bomb(data.clone(), old.unwrap_or(box io::stdout()));
diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml
index 3430ecabcbe..c1fe4a89d6a 100644
--- a/src/libstd/Cargo.toml
+++ b/src/libstd/Cargo.toml
@@ -48,3 +48,4 @@ jemalloc = ["alloc_jemalloc"]
 force_alloc_system = []
 panic-unwind = ["panic_unwind"]
 profiler = ["profiler_builtins"]
+wasm_syscall = []
diff --git a/src/libstd/f32.rs b/src/libstd/f32.rs
index 9810dede618..ecf68f29d6f 100644
--- a/src/libstd/f32.rs
+++ b/src/libstd/f32.rs
@@ -1531,6 +1531,7 @@ mod tests {
         assert!(nan.to_degrees().is_nan());
         assert_eq!(inf.to_degrees(), inf);
         assert_eq!(neg_inf.to_degrees(), neg_inf);
+        assert_eq!(1_f32.to_degrees(), 57.2957795130823208767981548141051703);
     }
 
     #[test]
diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs
index d1f3ccbd2c6..5cea389531f 100644
--- a/src/libstd/fs.rs
+++ b/src/libstd/fs.rs
@@ -482,20 +482,42 @@ impl File {
         self.inner.file_attr().map(Metadata)
     }
 
-    /// Creates a new independently owned handle to the underlying file.
-    ///
-    /// The returned `File` is a reference to the same state that this object
-    /// references. Both handles will read and write with the same cursor
-    /// position.
+    /// Create a new `File` instance that shares the same underlying file handle
+    /// as the existing `File` instance. Reads, writes, and seeks will affect
+    /// both `File` instances simultaneously.
     ///
     /// # Examples
     ///
+    /// Create two handles for a file named `foo.txt`:
+    ///
     /// ```no_run
     /// use std::fs::File;
     ///
     /// # fn foo() -> std::io::Result<()> {
-    /// let mut f = File::open("foo.txt")?;
-    /// let file_copy = f.try_clone()?;
+    /// let mut file = File::open("foo.txt")?;
+    /// let file_copy = file.try_clone()?;
+    /// # Ok(())
+    /// # }
+    /// ```
+    ///
+    /// Assuming there’s a file named `foo.txt` with contents `abcdef\n`, create
+    /// two handles, seek one of them, and read the remaining bytes from the
+    /// other handle:
+    ///
+    /// ```no_run
+    /// use std::fs::File;
+    /// use std::io::SeekFrom;
+    /// use std::io::prelude::*;
+    ///
+    /// # fn foo() -> std::io::Result<()> {
+    /// let mut file = File::open("foo.txt")?;
+    /// let mut file_copy = file.try_clone()?;
+    ///
+    /// file.seek(SeekFrom::Start(3))?;
+    ///
+    /// let mut contents = vec![];
+    /// file_copy.read_to_end(&mut contents)?;
+    /// assert_eq!(contents, b"def\n");
     /// # Ok(())
     /// # }
     /// ```
@@ -1001,7 +1023,7 @@ impl Metadata {
         self.0.accessed().map(FromInner::from_inner)
     }
 
-    /// Returns the creation time listed in the this metadata.
+    /// Returns the creation time listed in this metadata.
     ///
     /// The returned value corresponds to the `birthtime` field of `stat` on
     /// Unix platforms and the `ftCreationTime` field on Windows platforms.
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index f0b41f30251..bdd675e6e2b 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -292,8 +292,8 @@ impl Error {
     /// # if cfg!(target_os = "linux") {
     /// use std::io;
     ///
-    /// let error = io::Error::from_raw_os_error(98);
-    /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
+    /// let error = io::Error::from_raw_os_error(22);
+    /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
     /// # }
     /// ```
     ///
@@ -303,8 +303,8 @@ impl Error {
     /// # if cfg!(windows) {
     /// use std::io;
     ///
-    /// let error = io::Error::from_raw_os_error(10048);
-    /// assert_eq!(error.kind(), io::ErrorKind::AddrInUse);
+    /// let error = io::Error::from_raw_os_error(10022);
+    /// assert_eq!(error.kind(), io::ErrorKind::InvalidInput);
     /// # }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index c980ae75261..78a3b82546e 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -111,10 +111,11 @@ impl Drop for Thread {
 
 #[cfg_attr(test, allow(dead_code))]
 pub mod guard {
-    pub unsafe fn current() -> Option<usize> {
+    pub type Guard = !;
+    pub unsafe fn current() -> Option<Guard> {
         None
     }
-    pub unsafe fn init() -> Option<usize> {
+    pub unsafe fn init() -> Option<Guard> {
         None
     }
 }
diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs
index c4aad8d86f8..c4719a94c7e 100644
--- a/src/libstd/sys/redox/thread.rs
+++ b/src/libstd/sys/redox/thread.rs
@@ -88,6 +88,7 @@ impl Thread {
 }
 
 pub mod guard {
-    pub unsafe fn current() -> Option<usize> { None }
-    pub unsafe fn init() -> Option<usize> { None }
+    pub type Guard = !;
+    pub unsafe fn current() -> Option<Guard> { None }
+    pub unsafe fn init() -> Option<Guard> { None }
 }
diff --git a/src/libstd/sys/unix/stack_overflow.rs b/src/libstd/sys/unix/stack_overflow.rs
index 51adbc24ae0..40453f9b8a1 100644
--- a/src/libstd/sys/unix/stack_overflow.rs
+++ b/src/libstd/sys/unix/stack_overflow.rs
@@ -57,9 +57,6 @@ mod imp {
     use sys_common::thread_info;
 
 
-    // This is initialized in init() and only read from after
-    static mut PAGE_SIZE: usize = 0;
-
     #[cfg(any(target_os = "linux", target_os = "android"))]
     unsafe fn siginfo_si_addr(info: *mut libc::siginfo_t) -> usize {
         #[repr(C)]
@@ -102,12 +99,12 @@ mod imp {
                                     _data: *mut libc::c_void) {
         use sys_common::util::report_overflow;
 
-        let guard = thread_info::stack_guard().unwrap_or(0);
+        let guard = thread_info::stack_guard().unwrap_or(0..0);
         let addr = siginfo_si_addr(info);
 
         // If the faulting address is within the guard page, then we print a
         // message saying so and abort.
-        if guard != 0 && guard - PAGE_SIZE <= addr && addr < guard {
+        if guard.start <= addr && addr < guard.end {
             report_overflow();
             rtabort!("stack overflow");
         } else {
@@ -123,8 +120,6 @@ mod imp {
     static mut MAIN_ALTSTACK: *mut libc::c_void = ptr::null_mut();
 
     pub unsafe fn init() {
-        PAGE_SIZE = ::sys::os::page_size();
-
         let mut action: sigaction = mem::zeroed();
         action.sa_flags = SA_SIGINFO | SA_ONSTACK;
         action.sa_sigaction = signal_handler as sighandler_t;
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 525882c1e1e..72cdb9440b8 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -205,8 +205,10 @@ impl Drop for Thread {
           not(target_os = "solaris")))]
 #[cfg_attr(test, allow(dead_code))]
 pub mod guard {
-    pub unsafe fn current() -> Option<usize> { None }
-    pub unsafe fn init() -> Option<usize> { None }
+    use ops::Range;
+    pub type Guard = Range<usize>;
+    pub unsafe fn current() -> Option<Guard> { None }
+    pub unsafe fn init() -> Option<Guard> { None }
 }
 
 
@@ -222,14 +224,43 @@ pub mod guard {
     use libc;
     use libc::mmap;
     use libc::{PROT_NONE, MAP_PRIVATE, MAP_ANON, MAP_FAILED, MAP_FIXED};
+    use ops::Range;
     use sys::os;
 
-    #[cfg(any(target_os = "macos",
-              target_os = "bitrig",
-              target_os = "openbsd",
-              target_os = "solaris"))]
+    // This is initialized in init() and only read from after
+    static mut PAGE_SIZE: usize = 0;
+
+    pub type Guard = Range<usize>;
+
+    #[cfg(target_os = "solaris")]
+    unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
+        let mut current_stack: libc::stack_t = ::mem::zeroed();
+        assert_eq!(libc::stack_getbounds(&mut current_stack), 0);
+        Some(current_stack.ss_sp)
+    }
+
+    #[cfg(target_os = "macos")]
     unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
-        current().map(|s| s as *mut libc::c_void)
+        let stackaddr = libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize -
+             libc::pthread_get_stacksize_np(libc::pthread_self());
+        Some(stackaddr as *mut libc::c_void)
+    }
+
+    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
+    unsafe fn get_stack_start() -> Option<*mut libc::c_void> {
+        let mut current_stack: libc::stack_t = ::mem::zeroed();
+        assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
+                                             &mut current_stack), 0);
+
+        let extra = if cfg!(target_os = "bitrig") {3} else {1} * PAGE_SIZE;
+        let stackaddr = if libc::pthread_main_np() == 1 {
+            // main thread
+            current_stack.ss_sp as usize - current_stack.ss_size + extra
+        } else {
+            // new thread
+            current_stack.ss_sp as usize - current_stack.ss_size
+        };
+        Some(stackaddr as *mut libc::c_void)
     }
 
     #[cfg(any(target_os = "android", target_os = "freebsd",
@@ -253,8 +284,9 @@ pub mod guard {
         ret
     }
 
-    pub unsafe fn init() -> Option<usize> {
-        let psize = os::page_size();
+    pub unsafe fn init() -> Option<Guard> {
+        PAGE_SIZE = os::page_size();
+
         let mut stackaddr = get_stack_start()?;
 
         // Ensure stackaddr is page aligned! A parent process might
@@ -263,9 +295,9 @@ pub mod guard {
         // stackaddr < stackaddr + stacksize, so if stackaddr is not
         // page-aligned, calculate the fix such that stackaddr <
         // new_page_aligned_stackaddr < stackaddr + stacksize
-        let remainder = (stackaddr as usize) % psize;
+        let remainder = (stackaddr as usize) % PAGE_SIZE;
         if remainder != 0 {
-            stackaddr = ((stackaddr as usize) + psize - remainder)
+            stackaddr = ((stackaddr as usize) + PAGE_SIZE - remainder)
                 as *mut libc::c_void;
         }
 
@@ -280,60 +312,42 @@ pub mod guard {
             // Instead, we'll just note where we expect rlimit to start
             // faulting, so our handler can report "stack overflow", and
             // trust that the kernel's own stack guard will work.
-            Some(stackaddr as usize)
+            let stackaddr = stackaddr as usize;
+            Some(stackaddr - PAGE_SIZE..stackaddr)
         } else {
             // Reallocate the last page of the stack.
             // This ensures SIGBUS will be raised on
             // stack overflow.
-            let result = mmap(stackaddr, psize, PROT_NONE,
+            let result = mmap(stackaddr, PAGE_SIZE, PROT_NONE,
                               MAP_PRIVATE | MAP_ANON | MAP_FIXED, -1, 0);
 
             if result != stackaddr || result == MAP_FAILED {
                 panic!("failed to allocate a guard page");
             }
 
+            let guardaddr = stackaddr as usize;
             let offset = if cfg!(target_os = "freebsd") {
                 2
             } else {
                 1
             };
 
-            Some(stackaddr as usize + offset * psize)
+            Some(guardaddr..guardaddr + offset * PAGE_SIZE)
         }
     }
 
-    #[cfg(target_os = "solaris")]
-    pub unsafe fn current() -> Option<usize> {
-        let mut current_stack: libc::stack_t = ::mem::zeroed();
-        assert_eq!(libc::stack_getbounds(&mut current_stack), 0);
-        Some(current_stack.ss_sp as usize)
-    }
-
-    #[cfg(target_os = "macos")]
-    pub unsafe fn current() -> Option<usize> {
-        Some(libc::pthread_get_stackaddr_np(libc::pthread_self()) as usize -
-             libc::pthread_get_stacksize_np(libc::pthread_self()))
-    }
-
-    #[cfg(any(target_os = "openbsd", target_os = "bitrig"))]
-    pub unsafe fn current() -> Option<usize> {
-        let mut current_stack: libc::stack_t = ::mem::zeroed();
-        assert_eq!(libc::pthread_stackseg_np(libc::pthread_self(),
-                                             &mut current_stack), 0);
-
-        let extra = if cfg!(target_os = "bitrig") {3} else {1} * os::page_size();
-        Some(if libc::pthread_main_np() == 1 {
-            // main thread
-            current_stack.ss_sp as usize - current_stack.ss_size + extra
-        } else {
-            // new thread
-            current_stack.ss_sp as usize - current_stack.ss_size
-        })
+    #[cfg(any(target_os = "macos",
+              target_os = "bitrig",
+              target_os = "openbsd",
+              target_os = "solaris"))]
+    pub unsafe fn current() -> Option<Guard> {
+        let stackaddr = get_stack_start()? as usize;
+        Some(stackaddr - PAGE_SIZE..stackaddr)
     }
 
     #[cfg(any(target_os = "android", target_os = "freebsd",
               target_os = "linux", target_os = "netbsd", target_os = "l4re"))]
-    pub unsafe fn current() -> Option<usize> {
+    pub unsafe fn current() -> Option<Guard> {
         let mut ret = None;
         let mut attr: libc::pthread_attr_t = ::mem::zeroed();
         assert_eq!(libc::pthread_attr_init(&mut attr), 0);
@@ -352,12 +366,23 @@ pub mod guard {
             assert_eq!(libc::pthread_attr_getstack(&attr, &mut stackaddr,
                                                    &mut size), 0);
 
+            let stackaddr = stackaddr as usize;
             ret = if cfg!(target_os = "freebsd") {
-                Some(stackaddr as usize - guardsize)
+                // FIXME does freebsd really fault *below* the guard addr?
+                let guardaddr = stackaddr - guardsize;
+                Some(guardaddr - PAGE_SIZE..guardaddr)
             } else if cfg!(target_os = "netbsd") {
-                Some(stackaddr as usize)
+                Some(stackaddr - guardsize..stackaddr)
+            } else if cfg!(all(target_os = "linux", target_env = "gnu")) {
+                // glibc used to include the guard area within the stack, as noted in the BUGS
+                // section of `man pthread_attr_getguardsize`.  This has been corrected starting
+                // with glibc 2.27, and in some distro backports, so the guard is now placed at the
+                // end (below) the stack.  There's no easy way for us to know which we have at
+                // runtime, so we'll just match any fault in the range right above or below the
+                // stack base to call that fault a stack overflow.
+                Some(stackaddr - guardsize..stackaddr + guardsize)
             } else {
-                Some(stackaddr as usize + guardsize)
+                Some(stackaddr..stackaddr + guardsize)
             };
         }
         assert_eq!(libc::pthread_attr_destroy(&mut attr), 0);
diff --git a/src/libstd/sys/wasm/args.rs b/src/libstd/sys/wasm/args.rs
index d2a4a7b19d5..b3c6b671e80 100644
--- a/src/libstd/sys/wasm/args.rs
+++ b/src/libstd/sys/wasm/args.rs
@@ -10,8 +10,8 @@
 
 use ffi::OsString;
 use marker::PhantomData;
-use mem;
 use vec;
+use sys::ArgsSysCall;
 
 pub unsafe fn init(_argc: isize, _argv: *const *const u8) {
     // On wasm these should always be null, so there's nothing for us to do here
@@ -21,38 +21,10 @@ pub unsafe fn cleanup() {
 }
 
 pub fn args() -> Args {
-    // When the runtime debugging is enabled we'll link to some extra runtime
-    // functions to actually implement this. These are for now just implemented
-    // in a node.js script but they're off by default as they're sort of weird
-    // in a web-wasm world.
-    if !super::DEBUG {
-        return Args {
-            iter: Vec::new().into_iter(),
-            _dont_send_or_sync_me: PhantomData,
-        }
-    }
-
-    // You'll find the definitions of these in `src/etc/wasm32-shim.js`. These
-    // are just meant for debugging and should not be relied on.
-    extern {
-        fn rust_wasm_args_count() -> usize;
-        fn rust_wasm_args_arg_size(a: usize) -> usize;
-        fn rust_wasm_args_arg_fill(a: usize, ptr: *mut u8);
-    }
-
-    unsafe {
-        let cnt = rust_wasm_args_count();
-        let mut v = Vec::with_capacity(cnt);
-        for i in 0..cnt {
-            let n = rust_wasm_args_arg_size(i);
-            let mut data = vec![0; n];
-            rust_wasm_args_arg_fill(i, data.as_mut_ptr());
-            v.push(mem::transmute::<Vec<u8>, OsString>(data));
-        }
-        Args {
-            iter: v.into_iter(),
-            _dont_send_or_sync_me: PhantomData,
-        }
+    let v = ArgsSysCall::perform();
+    Args {
+        iter: v.into_iter(),
+        _dont_send_or_sync_me: PhantomData,
     }
 }
 
diff --git a/src/libstd/sys/wasm/mod.rs b/src/libstd/sys/wasm/mod.rs
index ba3d6a2813a..c02e5e809c8 100644
--- a/src/libstd/sys/wasm/mod.rs
+++ b/src/libstd/sys/wasm/mod.rs
@@ -26,17 +26,11 @@
 
 use io;
 use os::raw::c_char;
-
-// Right now the wasm backend doesn't even have the ability to print to the
-// console by default. Wasm can't import anything from JS! (you have to
-// explicitly provide it).
-//
-// Sometimes that's a real bummer, though, so this flag can be set to `true` to
-// enable calling various shims defined in `src/etc/wasm32-shim.js` which should
-// help receive debug output and see what's going on. In general this flag
-// currently controls "will we call out to our own defined shims in node.js",
-// and this flag should always be `false` for release builds.
-const DEBUG: bool = false;
+use ptr;
+use sys::os_str::Buf;
+use sys_common::{AsInner, FromInner};
+use ffi::{OsString, OsStr};
+use time::Duration;
 
 pub mod args;
 #[cfg(feature = "backtrace")]
@@ -92,7 +86,7 @@ pub unsafe fn strlen(mut s: *const c_char) -> usize {
 }
 
 pub unsafe fn abort_internal() -> ! {
-    ::intrinsics::abort();
+    ExitSysCall::perform(1)
 }
 
 // We don't have randomness yet, but I totally used a random number generator to
@@ -103,3 +97,218 @@ pub unsafe fn abort_internal() -> ! {
 pub fn hashmap_random_keys() -> (u64, u64) {
     (1, 2)
 }
+
+// Implement a minimal set of system calls to enable basic IO
+pub enum SysCallIndex {
+    Read = 0,
+    Write = 1,
+    Exit = 2,
+    Args = 3,
+    GetEnv = 4,
+    SetEnv = 5,
+    Time = 6,
+}
+
+#[repr(C)]
+pub struct ReadSysCall {
+    fd: usize,
+    ptr: *mut u8,
+    len: usize,
+    result: usize,
+}
+
+impl ReadSysCall {
+    pub fn perform(fd: usize, buffer: &mut [u8]) -> usize {
+        let mut call_record = ReadSysCall {
+            fd,
+            len: buffer.len(),
+            ptr: buffer.as_mut_ptr(),
+            result: 0
+        };
+        if unsafe { syscall(SysCallIndex::Read, &mut call_record) } {
+            call_record.result
+        } else {
+            0
+        }
+    }
+}
+
+#[repr(C)]
+pub struct WriteSysCall {
+    fd: usize,
+    ptr: *const u8,
+    len: usize,
+}
+
+impl WriteSysCall {
+    pub fn perform(fd: usize, buffer: &[u8]) {
+        let mut call_record = WriteSysCall {
+            fd,
+            len: buffer.len(),
+            ptr: buffer.as_ptr()
+        };
+        unsafe { syscall(SysCallIndex::Write, &mut call_record); }
+    }
+}
+
+#[repr(C)]
+pub struct ExitSysCall {
+    code: usize,
+}
+
+impl ExitSysCall {
+    pub fn perform(code: usize) -> ! {
+        let mut call_record = ExitSysCall {
+            code
+        };
+        unsafe {
+            syscall(SysCallIndex::Exit, &mut call_record);
+            ::intrinsics::abort();
+        }
+    }
+}
+
+fn receive_buffer<E, F: FnMut(&mut [u8]) -> Result<usize, E>>(estimate: usize, mut f: F)
+    -> Result<Vec<u8>, E>
+{
+    let mut buffer = vec![0; estimate];
+    loop {
+        let result = f(&mut buffer)?;
+        if result <= buffer.len() {
+            buffer.truncate(result);
+            break;
+        }
+        buffer.resize(result, 0);
+    }
+    Ok(buffer)
+}
+
+#[repr(C)]
+pub struct ArgsSysCall {
+    ptr: *mut u8,
+    len: usize,
+    result: usize
+}
+
+impl ArgsSysCall {
+    pub fn perform() -> Vec<OsString> {
+        receive_buffer(1024, |buffer| -> Result<usize, !> {
+            let mut call_record = ArgsSysCall {
+                len: buffer.len(),
+                ptr: buffer.as_mut_ptr(),
+                result: 0
+            };
+            if unsafe { syscall(SysCallIndex::Args, &mut call_record) } {
+                Ok(call_record.result)
+            } else {
+                Ok(0)
+            }
+        })
+            .unwrap()
+            .split(|b| *b == 0)
+            .map(|s| FromInner::from_inner(Buf { inner: s.to_owned() }))
+            .collect()
+    }
+}
+
+#[repr(C)]
+pub struct GetEnvSysCall {
+    key_ptr: *const u8,
+    key_len: usize,
+    value_ptr: *mut u8,
+    value_len: usize,
+    result: usize
+}
+
+impl GetEnvSysCall {
+    pub fn perform(key: &OsStr) -> Option<OsString> {
+        let key_buf = &AsInner::as_inner(key).inner;
+        receive_buffer(64, |buffer| {
+            let mut call_record = GetEnvSysCall {
+                key_len: key_buf.len(),
+                key_ptr: key_buf.as_ptr(),
+                value_len: buffer.len(),
+                value_ptr: buffer.as_mut_ptr(),
+                result: !0usize
+            };
+            if unsafe { syscall(SysCallIndex::GetEnv, &mut call_record) } {
+                if call_record.result == !0usize {
+                    Err(())
+                } else {
+                    Ok(call_record.result)
+                }
+            } else {
+                Err(())
+            }
+        }).ok().map(|s| {
+            FromInner::from_inner(Buf { inner: s })
+        })
+    }
+}
+
+#[repr(C)]
+pub struct SetEnvSysCall {
+    key_ptr: *const u8,
+    key_len: usize,
+    value_ptr: *const u8,
+    value_len: usize
+}
+
+impl SetEnvSysCall {
+    pub fn perform(key: &OsStr, value: Option<&OsStr>) {
+        let key_buf = &AsInner::as_inner(key).inner;
+        let value_buf = value.map(|v| &AsInner::as_inner(v).inner);
+        let mut call_record = SetEnvSysCall {
+            key_len: key_buf.len(),
+            key_ptr: key_buf.as_ptr(),
+            value_len: value_buf.map(|v| v.len()).unwrap_or(!0usize),
+            value_ptr: value_buf.map(|v| v.as_ptr()).unwrap_or(ptr::null())
+        };
+        unsafe { syscall(SysCallIndex::SetEnv, &mut call_record); }
+    }
+}
+
+pub enum TimeClock {
+    Monotonic = 0,
+    System = 1,
+}
+
+#[repr(C)]
+pub struct TimeSysCall {
+    clock: usize,
+    secs_hi: usize,
+    secs_lo: usize,
+    nanos: usize
+}
+
+impl TimeSysCall {
+    pub fn perform(clock: TimeClock) -> Duration {
+        let mut call_record = TimeSysCall {
+            clock: clock as usize,
+            secs_hi: 0,
+            secs_lo: 0,
+            nanos: 0
+        };
+        if unsafe { syscall(SysCallIndex::Time, &mut call_record) } {
+            Duration::new(
+                ((call_record.secs_hi as u64) << 32) | (call_record.secs_lo as u64),
+                call_record.nanos as u32
+            )
+        } else {
+            panic!("Time system call is not implemented by WebAssembly host");
+        }
+    }
+}
+
+unsafe fn syscall<T>(index: SysCallIndex, data: &mut T) -> bool {
+    #[cfg(feature = "wasm_syscall")]
+    extern {
+        #[no_mangle]
+        fn rust_wasm_syscall(index: usize, data: *mut Void) -> usize;
+    }
+
+    #[cfg(not(feature = "wasm_syscall"))]
+    unsafe fn rust_wasm_syscall(_index: usize, _data: *mut Void) -> usize { 0 }
+
+    rust_wasm_syscall(index as usize, data as *mut T as *mut Void) != 0
+}
diff --git a/src/libstd/sys/wasm/os.rs b/src/libstd/sys/wasm/os.rs
index c98030f7ebf..23ca1754719 100644
--- a/src/libstd/sys/wasm/os.rs
+++ b/src/libstd/sys/wasm/os.rs
@@ -8,16 +8,13 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use core::intrinsics;
-
 use error::Error as StdError;
 use ffi::{OsString, OsStr};
 use fmt;
 use io;
-use mem;
 use path::{self, PathBuf};
 use str;
-use sys::{unsupported, Void};
+use sys::{unsupported, Void, ExitSysCall, GetEnvSysCall, SetEnvSysCall};
 
 pub fn errno() -> i32 {
     0
@@ -87,36 +84,15 @@ pub fn env() -> Env {
 }
 
 pub fn getenv(k: &OsStr) -> io::Result<Option<OsString>> {
-    // If we're debugging the runtime then we actually probe node.js to ask for
-    // the value of environment variables to help provide inputs to programs.
-    // The `extern` shims here are defined in `src/etc/wasm32-shim.js` and are
-    // intended for debugging only, you should not rely on them.
-    if !super::DEBUG {
-        return Ok(None)
-    }
-
-    extern {
-        fn rust_wasm_getenv_len(k: *const u8, kl: usize) -> isize;
-        fn rust_wasm_getenv_data(k: *const u8, kl: usize, v: *mut u8);
-    }
-    unsafe {
-        let k: &[u8] = mem::transmute(k);
-        let n = rust_wasm_getenv_len(k.as_ptr(), k.len());
-        if n == -1 {
-            return Ok(None)
-        }
-        let mut data = vec![0; n as usize];
-        rust_wasm_getenv_data(k.as_ptr(), k.len(), data.as_mut_ptr());
-        Ok(Some(mem::transmute(data)))
-    }
+    Ok(GetEnvSysCall::perform(k))
 }
 
-pub fn setenv(_k: &OsStr, _v: &OsStr) -> io::Result<()> {
-    unsupported()
+pub fn setenv(k: &OsStr, v: &OsStr) -> io::Result<()> {
+    Ok(SetEnvSysCall::perform(k, Some(v)))
 }
 
-pub fn unsetenv(_n: &OsStr) -> io::Result<()> {
-    unsupported()
+pub fn unsetenv(k: &OsStr) -> io::Result<()> {
+    Ok(SetEnvSysCall::perform(k, None))
 }
 
 pub fn temp_dir() -> PathBuf {
@@ -128,7 +104,7 @@ pub fn home_dir() -> Option<PathBuf> {
 }
 
 pub fn exit(_code: i32) -> ! {
-    unsafe { intrinsics::abort() }
+    ExitSysCall::perform(_code as isize as usize)
 }
 
 pub fn getpid() -> u32 {
diff --git a/src/libstd/sys/wasm/stdio.rs b/src/libstd/sys/wasm/stdio.rs
index 0f75f240251..beb19c0ed2c 100644
--- a/src/libstd/sys/wasm/stdio.rs
+++ b/src/libstd/sys/wasm/stdio.rs
@@ -9,19 +9,19 @@
 // except according to those terms.
 
 use io;
-use sys::{Void, unsupported};
+use sys::{ReadSysCall, WriteSysCall};
 
-pub struct Stdin(Void);
+pub struct Stdin;
 pub struct Stdout;
 pub struct Stderr;
 
 impl Stdin {
     pub fn new() -> io::Result<Stdin> {
-        unsupported()
+        Ok(Stdin)
     }
 
-    pub fn read(&self, _data: &mut [u8]) -> io::Result<usize> {
-        match self.0 {}
+    pub fn read(&self, data: &mut [u8]) -> io::Result<usize> {
+        Ok(ReadSysCall::perform(0, data))
     }
 }
 
@@ -31,19 +31,7 @@ impl Stdout {
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
-        // If runtime debugging is enabled at compile time we'll invoke some
-        // runtime functions that are defined in our src/etc/wasm32-shim.js
-        // debugging script. Note that this ffi function call is intended
-        // *purely* for debugging only and should not be relied upon.
-        if !super::DEBUG {
-            return unsupported()
-        }
-        extern {
-            fn rust_wasm_write_stdout(data: *const u8, len: usize);
-        }
-        unsafe {
-            rust_wasm_write_stdout(data.as_ptr(), data.len())
-        }
+        WriteSysCall::perform(1, data);
         Ok(data.len())
     }
 
@@ -58,16 +46,7 @@ impl Stderr {
     }
 
     pub fn write(&self, data: &[u8]) -> io::Result<usize> {
-        // See comments in stdout for what's going on here.
-        if !super::DEBUG {
-            return unsupported()
-        }
-        extern {
-            fn rust_wasm_write_stderr(data: *const u8, len: usize);
-        }
-        unsafe {
-            rust_wasm_write_stderr(data.as_ptr(), data.len())
-        }
+        WriteSysCall::perform(2, data);
         Ok(data.len())
     }
 
diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs
index 13980e0cc19..6a066509b49 100644
--- a/src/libstd/sys/wasm/thread.rs
+++ b/src/libstd/sys/wasm/thread.rs
@@ -43,6 +43,7 @@ impl Thread {
 }
 
 pub mod guard {
-    pub unsafe fn current() -> Option<usize> { None }
-    pub unsafe fn init() -> Option<usize> { None }
+    pub type Guard = !;
+    pub unsafe fn current() -> Option<Guard> { None }
+    pub unsafe fn init() -> Option<Guard> { None }
 }
diff --git a/src/libstd/sys/wasm/time.rs b/src/libstd/sys/wasm/time.rs
index c269def98f6..e52435e6339 100644
--- a/src/libstd/sys/wasm/time.rs
+++ b/src/libstd/sys/wasm/time.rs
@@ -8,56 +8,50 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use fmt;
 use time::Duration;
+use sys::{TimeSysCall, TimeClock};
 
 #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
-pub struct Instant;
+pub struct Instant(Duration);
 
-#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
-pub struct SystemTime;
+#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Debug, Hash)]
+pub struct SystemTime(Duration);
 
-pub const UNIX_EPOCH: SystemTime = SystemTime;
+pub const UNIX_EPOCH: SystemTime = SystemTime(Duration::from_secs(0));
 
 impl Instant {
     pub fn now() -> Instant {
-        panic!("not supported on web assembly");
+        Instant(TimeSysCall::perform(TimeClock::Monotonic))
     }
 
-    pub fn sub_instant(&self, _other: &Instant) -> Duration {
-        panic!("can't sub yet");
+    pub fn sub_instant(&self, other: &Instant) -> Duration {
+        self.0 - other.0
     }
 
-    pub fn add_duration(&self, _other: &Duration) -> Instant {
-        panic!("can't add yet");
+    pub fn add_duration(&self, other: &Duration) -> Instant {
+        Instant(self.0 + *other)
     }
 
-    pub fn sub_duration(&self, _other: &Duration) -> Instant {
-        panic!("can't sub yet");
+    pub fn sub_duration(&self, other: &Duration) -> Instant {
+        Instant(self.0 - *other)
     }
 }
 
 impl SystemTime {
     pub fn now() -> SystemTime {
-        panic!("not supported on web assembly");
+        SystemTime(TimeSysCall::perform(TimeClock::System))
     }
 
-    pub fn sub_time(&self, _other: &SystemTime)
+    pub fn sub_time(&self, other: &SystemTime)
                     -> Result<Duration, Duration> {
-        panic!()
-    }
-
-    pub fn add_duration(&self, _other: &Duration) -> SystemTime {
-        panic!()
+        self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0)
     }
 
-    pub fn sub_duration(&self, _other: &Duration) -> SystemTime {
-        panic!()
+    pub fn add_duration(&self, other: &Duration) -> SystemTime {
+        SystemTime(self.0 + *other)
     }
-}
 
-impl fmt::Debug for SystemTime {
-    fn fmt(&self, _f: &mut fmt::Formatter) -> fmt::Result {
-        panic!()
+    pub fn sub_duration(&self, other: &Duration) -> SystemTime {
+        SystemTime(self.0 - *other)
     }
 }
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index 74786d09285..43abfbb1f64 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -93,6 +93,7 @@ impl Thread {
 
 #[cfg_attr(test, allow(dead_code))]
 pub mod guard {
-    pub unsafe fn current() -> Option<usize> { None }
-    pub unsafe fn init() -> Option<usize> { None }
+    pub type Guard = !;
+    pub unsafe fn current() -> Option<Guard> { None }
+    pub unsafe fn init() -> Option<Guard> { None }
 }
diff --git a/src/libstd/sys_common/thread_info.rs b/src/libstd/sys_common/thread_info.rs
index 7970042b1d6..6a2b6742367 100644
--- a/src/libstd/sys_common/thread_info.rs
+++ b/src/libstd/sys_common/thread_info.rs
@@ -11,10 +11,11 @@
 #![allow(dead_code)] // stack_guard isn't used right now on all platforms
 
 use cell::RefCell;
+use sys::thread::guard::Guard;
 use thread::Thread;
 
 struct ThreadInfo {
-    stack_guard: Option<usize>,
+    stack_guard: Option<Guard>,
     thread: Thread,
 }
 
@@ -38,11 +39,11 @@ pub fn current_thread() -> Option<Thread> {
     ThreadInfo::with(|info| info.thread.clone())
 }
 
-pub fn stack_guard() -> Option<usize> {
-    ThreadInfo::with(|info| info.stack_guard).and_then(|o| o)
+pub fn stack_guard() -> Option<Guard> {
+    ThreadInfo::with(|info| info.stack_guard.clone()).and_then(|o| o)
 }
 
-pub fn set(stack_guard: Option<usize>, thread: Thread) {
+pub fn set(stack_guard: Option<Guard>, thread: Thread) {
     THREAD_INFO.with(|c| assert!(c.borrow().is_none()));
     THREAD_INFO.with(move |c| *c.borrow_mut() = Some(ThreadInfo{
         stack_guard,
diff --git a/src/libstd/time/mod.rs b/src/libstd/time.rs
index 6ce3b3e8a00..12f2a9bb85f 100644
--- a/src/libstd/time/mod.rs
+++ b/src/libstd/time.rs
@@ -29,9 +29,7 @@ use sys::time;
 use sys_common::FromInner;
 
 #[stable(feature = "time", since = "1.3.0")]
-pub use self::duration::Duration;
-
-mod duration;
+pub use core::time::Duration;
 
 /// A measurement of a monotonically nondecreasing clock.
 /// Opaque and useful only with `Duration`.
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index 73810b3fe81..c7ab6158256 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -883,7 +883,6 @@ pub struct Arm {
     pub pats: Vec<P<Pat>>,
     pub guard: Option<P<Expr>>,
     pub body: P<Expr>,
-    pub beginning_vert: Option<Span>, // For RFC 1925 feature gate
 }
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
diff --git a/src/libsyntax/codemap.rs b/src/libsyntax/codemap.rs
index a6a7f9e20b3..3601b9ba8a8 100644
--- a/src/libsyntax/codemap.rs
+++ b/src/libsyntax/codemap.rs
@@ -593,8 +593,30 @@ impl CodeMap {
         }
     }
 
-    /// Given a `Span`, try to get a shorter span ending just after the first
-    /// occurrence of `char` `c`.
+    /// Given a `Span`, get a new `Span` covering the first token and all its trailing whitespace or
+    /// the original `Span`.
+    ///
+    /// If `sp` points to `"let mut x"`, then a span pointing at `"let "` will be returned.
+    pub fn span_until_non_whitespace(&self, sp: Span) -> Span {
+        if let Ok(snippet) = self.span_to_snippet(sp) {
+            let mut offset = 0;
+            // get the bytes width of all the non-whitespace characters
+            for c in snippet.chars().take_while(|c| !c.is_whitespace()) {
+                offset += c.len_utf8();
+            }
+            // get the bytes width of all the whitespace characters after that
+            for c in snippet[offset..].chars().take_while(|c| c.is_whitespace()) {
+                offset += c.len_utf8();
+            }
+            if offset > 1 {
+                return sp.with_hi(BytePos(sp.lo().0 + offset as u32));
+            }
+        }
+        sp
+    }
+
+    /// Given a `Span`, try to get a shorter span ending just after the first occurrence of `char`
+    /// `c`.
     pub fn span_through_char(&self, sp: Span, c: char) -> Span {
         if let Ok(snippet) = self.span_to_snippet(sp) {
             if let Some(offset) = snippet.find(c) {
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index cf63592c2ec..2e6de96d65a 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -883,7 +883,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
             pats,
             guard: None,
             body: expr,
-            beginning_vert: None,
         }
     }
 
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 9a2560b0458..3e858c3b923 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -386,9 +386,6 @@ declare_features! (
     // allow `#[must_use]` on functions and comparison operators (RFC 1940)
     (active, fn_must_use, "1.21.0", Some(43302)),
 
-    // allow '|' at beginning of match arms (RFC 1925)
-    (active, match_beginning_vert, "1.21.0", Some(44101)),
-
     // Future-proofing enums/structs with #[non_exhaustive] attribute (RFC 2008)
     (active, non_exhaustive, "1.22.0", Some(44109)),
 
@@ -545,6 +542,8 @@ declare_features! (
     (accepted, abi_sysv64, "1.24.0", Some(36167)),
     // Allows `repr(align(16))` struct attribute (RFC 1358)
     (accepted, repr_align, "1.24.0", Some(33626)),
+    // allow '|' at beginning of match arms (RFC 1925)
+    (accepted, match_beginning_vert, "1.25.0", Some(44101)),
 );
 
 // If you change this, please modify src/doc/unstable-book as well. You must
@@ -788,6 +787,11 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                                        is just used for rustc unit tests \
                                                        and will never be stable",
                                                       cfg_fn!(rustc_attrs))),
+    ("rustc_serialize_exclude_null", Normal, Gated(Stability::Unstable,
+                                             "rustc_attrs",
+                                             "the `#[rustc_serialize_exclude_null]` attribute \
+                                              is an internal-only feature",
+                                             cfg_fn!(rustc_attrs))),
     ("rustc_synthetic", Whitelisted, Gated(Stability::Unstable,
                                                       "rustc_attrs",
                                                       "this attribute \
@@ -1678,11 +1682,6 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
     }
 
     fn visit_arm(&mut self, arm: &'a ast::Arm) {
-        if let Some(span) = arm.beginning_vert {
-            gate_feature_post!(&self, match_beginning_vert,
-                               span,
-                               "Use of a '|' at the beginning of a match arm is experimental")
-        }
         visit::walk_arm(self, arm)
     }
 
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index 0f8fe57e380..921ed3565a4 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -340,14 +340,13 @@ pub fn fold_thin_attrs<T: Folder>(attrs: ThinVec<Attribute>, fld: &mut T) -> Thi
     fold_attrs(attrs.into(), fld).into()
 }
 
-pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body, beginning_vert}: Arm,
+pub fn noop_fold_arm<T: Folder>(Arm {attrs, pats, guard, body}: Arm,
     fld: &mut T) -> Arm {
     Arm {
         attrs: fold_attrs(attrs, fld),
         pats: pats.move_map(|x| fld.fold_pat(x)),
         guard: guard.map(|x| fld.fold_expr(x)),
         body: fld.fold_expr(body),
-        beginning_vert,
     }
 }
 
diff --git a/src/libsyntax/json.rs b/src/libsyntax/json.rs
index 54c726d8462..98d5fa8f797 100644
--- a/src/libsyntax/json.rs
+++ b/src/libsyntax/json.rs
@@ -38,34 +38,41 @@ pub struct JsonEmitter {
     registry: Option<Registry>,
     cm: Rc<CodeMapper + 'static>,
     pretty: bool,
+    /// Whether "approximate suggestions" are enabled in the config
+    approximate_suggestions: bool,
 }
 
 impl JsonEmitter {
     pub fn stderr(registry: Option<Registry>,
                   code_map: Rc<CodeMap>,
-                  pretty: bool) -> JsonEmitter {
+                  pretty: bool,
+                  approximate_suggestions: bool) -> JsonEmitter {
         JsonEmitter {
             dst: Box::new(io::stderr()),
             registry,
             cm: code_map,
             pretty,
+            approximate_suggestions,
         }
     }
 
     pub fn basic(pretty: bool) -> JsonEmitter {
         let file_path_mapping = FilePathMapping::empty();
-        JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping)), pretty)
+        JsonEmitter::stderr(None, Rc::new(CodeMap::new(file_path_mapping)),
+                            pretty, false)
     }
 
     pub fn new(dst: Box<Write + Send>,
                registry: Option<Registry>,
                code_map: Rc<CodeMap>,
-               pretty: bool) -> JsonEmitter {
+               pretty: bool,
+               approximate_suggestions: bool) -> JsonEmitter {
         JsonEmitter {
             dst,
             registry,
             cm: code_map,
             pretty,
+            approximate_suggestions,
         }
     }
 }
@@ -101,6 +108,7 @@ struct Diagnostic {
 }
 
 #[derive(RustcEncodable)]
+#[allow(unused_attributes)]
 struct DiagnosticSpan {
     file_name: String,
     byte_start: u32,
@@ -121,6 +129,9 @@ struct DiagnosticSpan {
     /// If we are suggesting a replacement, this will contain text
     /// that should be sliced in atop this span.
     suggested_replacement: Option<String>,
+    /// If the suggestion is approximate
+    #[rustc_serialize_exclude_null]
+    suggestion_approximate: Option<bool>,
     /// Macro invocations that created the code at this span, if any.
     expansion: Option<Box<DiagnosticSpanMacroExpansion>>,
 }
@@ -188,7 +199,7 @@ impl Diagnostic {
         }
         let buf = BufWriter::default();
         let output = buf.clone();
-        EmitterWriter::new(Box::new(buf), Some(je.cm.clone()), false).emit(db);
+        EmitterWriter::new(Box::new(buf), Some(je.cm.clone()), false, false).emit(db);
         let output = Arc::try_unwrap(output.0).unwrap().into_inner().unwrap();
         let output = String::from_utf8(output).unwrap();
 
@@ -220,7 +231,7 @@ impl Diagnostic {
 
 impl DiagnosticSpan {
     fn from_span_label(span: SpanLabel,
-                       suggestion: Option<&String>,
+                       suggestion: Option<(&String, bool)>,
                        je: &JsonEmitter)
                        -> DiagnosticSpan {
         Self::from_span_etc(span.span,
@@ -233,7 +244,7 @@ impl DiagnosticSpan {
     fn from_span_etc(span: Span,
                      is_primary: bool,
                      label: Option<String>,
-                     suggestion: Option<&String>,
+                     suggestion: Option<(&String, bool)>,
                      je: &JsonEmitter)
                      -> DiagnosticSpan {
         // obtain the full backtrace from the `macro_backtrace`
@@ -253,7 +264,7 @@ impl DiagnosticSpan {
     fn from_span_full(span: Span,
                       is_primary: bool,
                       label: Option<String>,
-                      suggestion: Option<&String>,
+                      suggestion: Option<(&String, bool)>,
                       mut backtrace: vec::IntoIter<MacroBacktrace>,
                       je: &JsonEmitter)
                       -> DiagnosticSpan {
@@ -281,6 +292,13 @@ impl DiagnosticSpan {
                 def_site_span,
             })
         });
+
+        let suggestion_approximate = if je.approximate_suggestions {
+             suggestion.map(|x| x.1)
+        } else {
+            None
+        };
+
         DiagnosticSpan {
             file_name: start.file.name.to_string(),
             byte_start: span.lo().0 - start.file.start_pos.0,
@@ -291,7 +309,8 @@ impl DiagnosticSpan {
             column_end: end.col.0 + 1,
             is_primary,
             text: DiagnosticSpanLine::from_span(span, je),
-            suggested_replacement: suggestion.cloned(),
+            suggested_replacement: suggestion.map(|x| x.0.clone()),
+            suggestion_approximate,
             expansion: backtrace_step,
             label,
         }
@@ -309,14 +328,15 @@ impl DiagnosticSpan {
         suggestion.substitutions
                       .iter()
                       .flat_map(|substitution| {
-                          substitution.parts.iter().map(move |suggestion| {
+                          substitution.parts.iter().map(move |suggestion_inner| {
                               let span_label = SpanLabel {
-                                  span: suggestion.span,
+                                  span: suggestion_inner.span,
                                   is_primary: true,
                                   label: None,
                               };
                               DiagnosticSpan::from_span_label(span_label,
-                                                              Some(&suggestion.snippet),
+                                                              Some((&suggestion_inner.snippet,
+                                                                   suggestion.approximate)),
                                                               je)
                           })
                       })
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index 3b4c5da10f2..9181cca215c 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -25,6 +25,7 @@
 #![feature(match_default_bindings)]
 #![feature(i128_type)]
 #![feature(const_atomic_usize_new)]
+#![feature(rustc_attrs)]
 
 // See librustc_cratesio_shim/Cargo.toml for a comment explaining this.
 #[allow(unused_extern_crates)]
diff --git a/src/libsyntax/parse/lexer/mod.rs b/src/libsyntax/parse/lexer/mod.rs
index b95c91548d0..11ab84a5729 100644
--- a/src/libsyntax/parse/lexer/mod.rs
+++ b/src/libsyntax/parse/lexer/mod.rs
@@ -246,14 +246,27 @@ impl<'a> StringReader<'a> {
         self.err_span(self.mk_sp(from_pos, to_pos), m)
     }
 
+    /// Pushes a character to a message string for error reporting
+    fn push_escaped_char_for_msg(m: &mut String, c: char) {
+        match c {
+            '\u{20}'...'\u{7e}' => {
+                // Don't escape \, ' or " for user-facing messages
+                m.push(c);
+            }
+            _ => {
+                for c in c.escape_default() {
+                    m.push(c);
+                }
+            }
+        }
+    }
+
     /// Report a lexical error spanning [`from_pos`, `to_pos`), appending an
     /// escaped character to the error message
     fn fatal_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) -> FatalError {
         let mut m = m.to_string();
         m.push_str(": ");
-        for c in c.escape_default() {
-            m.push(c)
-        }
+        Self::push_escaped_char_for_msg(&mut m, c);
         self.fatal_span_(from_pos, to_pos, &m[..])
     }
     fn struct_fatal_span_char(&self,
@@ -264,9 +277,7 @@ impl<'a> StringReader<'a> {
                               -> DiagnosticBuilder<'a> {
         let mut m = m.to_string();
         m.push_str(": ");
-        for c in c.escape_default() {
-            m.push(c)
-        }
+        Self::push_escaped_char_for_msg(&mut m, c);
         self.sess.span_diagnostic.struct_span_fatal(self.mk_sp(from_pos, to_pos), &m[..])
     }
 
@@ -275,9 +286,7 @@ impl<'a> StringReader<'a> {
     fn err_span_char(&self, from_pos: BytePos, to_pos: BytePos, m: &str, c: char) {
         let mut m = m.to_string();
         m.push_str(": ");
-        for c in c.escape_default() {
-            m.push(c)
-        }
+        Self::push_escaped_char_for_msg(&mut m, c);
         self.err_span_(from_pos, to_pos, &m[..]);
     }
     fn struct_err_span_char(&self,
@@ -288,9 +297,7 @@ impl<'a> StringReader<'a> {
                             -> DiagnosticBuilder<'a> {
         let mut m = m.to_string();
         m.push_str(": ");
-        for c in c.escape_default() {
-            m.push(c)
-        }
+        Self::push_escaped_char_for_msg(&mut m, c);
         self.sess.span_diagnostic.struct_span_err(self.mk_sp(from_pos, to_pos), &m[..])
     }
 
@@ -1745,6 +1752,7 @@ mod tests {
     fn mk_sess(cm: Rc<CodeMap>) -> ParseSess {
         let emitter = errors::emitter::EmitterWriter::new(Box::new(io::sink()),
                                                           Some(cm.clone()),
+                                                          false,
                                                           false);
         ParseSess {
             span_diagnostic: errors::Handler::with_emitter(true, false, Box::new(emitter)),
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index b3c485a85c0..764b3d0a848 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -3398,11 +3398,7 @@ impl<'a> Parser<'a> {
 
         let attrs = self.parse_outer_attributes()?;
         // Allow a '|' before the pats (RFC 1925)
-        let beginning_vert = if self.eat(&token::BinOp(token::Or)) {
-            Some(self.prev_span)
-        } else {
-            None
-        };
+        self.eat(&token::BinOp(token::Or));
         let pats = self.parse_pats()?;
         let guard = if self.eat_keyword(keywords::If) {
             Some(self.parse_expr()?)
@@ -3426,7 +3422,6 @@ impl<'a> Parser<'a> {
             pats,
             guard,
             body: expr,
-            beginning_vert,
         })
     }
 
diff --git a/src/libsyntax/parse/token.rs b/src/libsyntax/parse/token.rs
index 2be93c07d5a..7fbe781e9a1 100644
--- a/src/libsyntax/parse/token.rs
+++ b/src/libsyntax/parse/token.rs
@@ -112,6 +112,7 @@ fn ident_can_begin_expr(ident: ast::Ident) -> bool {
         keywords::Unsafe.name(),
         keywords::While.name(),
         keywords::Yield.name(),
+        keywords::Static.name(),
     ].contains(&ident.name)
 }
 
diff --git a/src/libsyntax/test_snippet.rs b/src/libsyntax/test_snippet.rs
index 5072f2e2793..3b4bba24d77 100644
--- a/src/libsyntax/test_snippet.rs
+++ b/src/libsyntax/test_snippet.rs
@@ -62,6 +62,7 @@ fn test_harness(file_text: &str, span_labels: Vec<SpanLabel>, expected_output: &
 
     let emitter = EmitterWriter::new(Box::new(Shared { data: output.clone() }),
                                      Some(code_map.clone()),
+                                     false,
                                      false);
     let handler = Handler::with_emitter(true, false, Box::new(emitter));
     handler.span_err(msp, "foo");
diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs
index 0e6e96438d8..743f22b6b31 100644
--- a/src/libsyntax_ext/deriving/encodable.rs
+++ b/src/libsyntax_ext/deriving/encodable.rs
@@ -190,7 +190,7 @@ fn encodable_substructure(cx: &mut ExtCtxt,
         Struct(_, ref fields) => {
             let emit_struct_field = cx.ident_of("emit_struct_field");
             let mut stmts = Vec::new();
-            for (i, &FieldInfo { name, ref self_, span, .. }) in fields.iter().enumerate() {
+            for (i, &FieldInfo { name, ref self_, span, attrs, .. }) in fields.iter().enumerate() {
                 let name = match name {
                     Some(id) => id.name,
                     None => Symbol::intern(&format!("_field{}", i)),
@@ -212,7 +212,19 @@ fn encodable_substructure(cx: &mut ExtCtxt,
                 } else {
                     cx.expr(span, ExprKind::Ret(Some(call)))
                 };
-                stmts.push(cx.stmt_expr(call));
+
+                // This exists for https://github.com/rust-lang/rust/pull/47540
+                //
+                // If we decide to stabilize that flag this can be removed
+                let expr = if attrs.iter().any(|a| a.check_name("rustc_serialize_exclude_null")) {
+                    let is_some = cx.ident_of("is_some");
+                    let condition = cx.expr_method_call(span, self_.clone(), is_some, vec![]);
+                    cx.expr_if(span, condition, call, None)
+                } else {
+                    call
+                };
+                let stmt = cx.stmt_expr(expr);
+                stmts.push(stmt);
             }
 
             // unit structs have no fields and need to return Ok()
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index dd1ec7284f6..294506625bc 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -347,13 +347,24 @@ impl Span {
 
     /// Return a `Span` that would enclose both `self` and `end`.
     pub fn to(self, end: Span) -> Span {
-        let span = self.data();
-        let end = end.data();
+        let span_data = self.data();
+        let end_data = end.data();
+        // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
+        // Return the macro span on its own to avoid weird diagnostic output. It is preferable to
+        // have an incomplete span than a completely nonsensical one.
+        if span_data.ctxt != end_data.ctxt {
+            if span_data.ctxt == SyntaxContext::empty() {
+                return end;
+            } else if end_data.ctxt == SyntaxContext::empty() {
+                return self;
+            }
+            // both span fall within a macro
+            // FIXME(estebank) check if it is the *same* macro
+        }
         Span::new(
-            cmp::min(span.lo, end.lo),
-            cmp::max(span.hi, end.hi),
-            // FIXME(jseyfried): self.ctxt should always equal end.ctxt here (c.f. issue #23480)
-            if span.ctxt == SyntaxContext::empty() { end.ctxt } else { span.ctxt },
+            cmp::min(span_data.lo, end_data.lo),
+            cmp::max(span_data.hi, end_data.hi),
+            if span_data.ctxt == SyntaxContext::empty() { end_data.ctxt } else { span_data.ctxt },
         )
     }
 
diff --git a/src/rustllvm/PassWrapper.cpp b/src/rustllvm/PassWrapper.cpp
index b2f1229891d..06d1301d700 100644
--- a/src/rustllvm/PassWrapper.cpp
+++ b/src/rustllvm/PassWrapper.cpp
@@ -836,6 +836,10 @@ struct LLVMRustThinLTOData {
   StringMap<FunctionImporter::ImportMapTy> ImportLists;
   StringMap<FunctionImporter::ExportSetTy> ExportLists;
   StringMap<GVSummaryMapTy> ModuleToDefinedGVSummaries;
+
+#if LLVM_VERSION_GE(7, 0)
+  LLVMRustThinLTOData() : Index(/* isPerformingAnalysis = */ false) {}
+#endif
 };
 
 // Just an argument to the `LLVMRustCreateThinLTOData` function below.
@@ -918,7 +922,14 @@ LLVMRustCreateThinLTOData(LLVMRustThinLTOModule *modules,
   //
   // This is copied from `lib/LTO/ThinLTOCodeGenerator.cpp`
 #if LLVM_VERSION_GE(5, 0)
+#if LLVM_VERSION_GE(7, 0)
+  auto deadIsPrevailing = [&](GlobalValue::GUID G) {
+    return PrevailingType::Unknown;
+  };
+  computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols, deadIsPrevailing);
+#else
   computeDeadSymbols(Ret->Index, Ret->GUIDPreservedSymbols);
+#endif
   ComputeCrossModuleImport(
     Ret->Index,
     Ret->ModuleToDefinedGVSummaries,
diff --git a/src/test/codegen/function-arguments.rs b/src/test/codegen/function-arguments.rs
index f8945a6ee8d..0e98d3f9050 100644
--- a/src/test/codegen/function-arguments.rs
+++ b/src/test/codegen/function-arguments.rs
@@ -122,13 +122,13 @@ pub fn unsafe_slice(_: &[UnsafeInner]) {
 pub fn str(_: &[u8]) {
 }
 
-// CHECK: @trait_borrow(%"core::ops::drop::Drop"* nonnull %arg0.0, {}* noalias nonnull readonly %arg0.1)
+// CHECK: @trait_borrow({}* nonnull %arg0.0, {}* noalias nonnull readonly %arg0.1)
 // FIXME #25759 This should also have `nocapture`
 #[no_mangle]
 pub fn trait_borrow(_: &Drop) {
 }
 
-// CHECK: @trait_box(%"core::ops::drop::Drop"* noalias nonnull, {}* noalias nonnull readonly)
+// CHECK: @trait_box({}* noalias nonnull, {}* noalias nonnull readonly)
 #[no_mangle]
 pub fn trait_box(_: Box<Drop>) {
 }
diff --git a/src/test/codegen/stack-probes.rs b/src/test/codegen/stack-probes.rs
index 5b26dade9af..4a489f1edb3 100644
--- a/src/test/codegen/stack-probes.rs
+++ b/src/test/codegen/stack-probes.rs
@@ -15,7 +15,7 @@
 // ignore-wasm
 // ignore-emscripten
 // ignore-windows
-// no-system-llvm
+// min-system-llvm-version 5.0
 // compile-flags: -C no-prepopulate-passes
 
 #![crate_type = "lib"]
diff --git a/src/test/compile-fail/E0195.rs b/src/test/compile-fail/E0195.rs
index 06dd903b23d..4f4d7ce0dba 100644
--- a/src/test/compile-fail/E0195.rs
+++ b/src/test/compile-fail/E0195.rs
@@ -10,13 +10,14 @@
 
 trait Trait {
     fn bar<'a,'b:'a>(x: &'a str, y: &'b str);
+    //~^ NOTE lifetimes in impl do not match this method in trait
 }
 
 struct Foo;
 
 impl Trait for Foo {
     fn bar<'a,'b>(x: &'a str, y: &'b str) { //~ ERROR E0195
-                                            //~^ lifetimes do not match trait
+    //~^ NOTE lifetimes do not match method in trait
     }
 }
 
diff --git a/src/test/compile-fail/associated-const-type-parameter-arms.rs b/src/test/compile-fail/associated-const-type-parameter-arms.rs
index 52bb4a1b463..630a234fa66 100644
--- a/src/test/compile-fail/associated-const-type-parameter-arms.rs
+++ b/src/test/compile-fail/associated-const-type-parameter-arms.rs
@@ -16,6 +16,7 @@ pub trait Foo {
 }
 
 struct Abc;
+
 impl Foo for Abc {
     const X: EFoo = EFoo::B;
 }
@@ -27,8 +28,10 @@ impl Foo for Def {
 
 pub fn test<A: Foo, B: Foo>(arg: EFoo) {
     match arg {
-        A::X => println!("A::X"), //~ error: statics cannot be referenced in patterns [E0158]
-        B::X => println!("B::X"), //~ error: statics cannot be referenced in patterns [E0158]
+        A::X => println!("A::X"),
+        //~^ error: associated consts cannot be referenced in patterns [E0158]
+        B::X => println!("B::X"),
+        //~^ error: associated consts cannot be referenced in patterns [E0158]
         _ => (),
     }
 }
diff --git a/src/test/compile-fail/issue-16048.rs b/src/test/compile-fail/issue-16048.rs
index 5012556dedd..cda83fe54b0 100644
--- a/src/test/compile-fail/issue-16048.rs
+++ b/src/test/compile-fail/issue-16048.rs
@@ -10,6 +10,7 @@
 
 trait NoLifetime {
     fn get<'p, T : Test<'p>>(&self) -> T;
+    //~^ NOTE lifetimes in impl do not match this method in trait
 }
 
 trait Test<'p> {
@@ -28,8 +29,8 @@ impl<'a> Test<'a> for Foo<'a> {
 
 impl<'a> NoLifetime for Foo<'a> {
     fn get<'p, T : Test<'a>>(&self) -> T {
-//~^ ERROR E0195
-//~| lifetimes do not match trait
+    //~^ ERROR E0195
+    //~| NOTE lifetimes do not match method in trait
         return *self as T;
     }
 }
diff --git a/src/test/compile-fail/nll/do-not-ignore-lifetime-bounds-in-copy.rs b/src/test/compile-fail/nll/do-not-ignore-lifetime-bounds-in-copy.rs
new file mode 100644
index 00000000000..2a4295fd90a
--- /dev/null
+++ b/src/test/compile-fail/nll/do-not-ignore-lifetime-bounds-in-copy.rs
@@ -0,0 +1,23 @@
+// Copyright 2012 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.
+
+// Test that the 'static bound from the Copy impl is respected. Regression test for #29149.
+
+#![feature(nll)]
+
+#[derive(Clone)] struct Foo<'a>(&'a u32);
+impl Copy for Foo<'static> {}
+
+fn main() {
+    let s = 2;
+    let a = Foo(&s); //~ ERROR `s` does not live long enough [E0597]
+    drop(a);
+    drop(a);
+}
diff --git a/src/test/parse-fail/bad-char-literals.rs b/src/test/parse-fail/bad-char-literals.rs
index 96311d6de17..821015ece77 100644
--- a/src/test/parse-fail/bad-char-literals.rs
+++ b/src/test/parse-fail/bad-char-literals.rs
@@ -15,7 +15,7 @@
 fn main() {
     // these literals are just silly.
     ''';
-    //~^ ERROR: character constant must be escaped: \'
+    //~^ ERROR: character constant must be escaped: '
 
     // note that this is a literal "\n" byte
     '
diff --git a/src/test/parse-fail/lex-stray-backslash.rs b/src/test/parse-fail/lex-stray-backslash.rs
new file mode 100644
index 00000000000..b6042bbdc1a
--- /dev/null
+++ b/src/test/parse-fail/lex-stray-backslash.rs
@@ -0,0 +1,13 @@
+// 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.
+
+// compile-flags: -Z parse-only
+
+\ //~ ERROR: unknown start of token: \
diff --git a/src/test/run-make/stdin-non-utf8/Makefile b/src/test/run-make/stdin-non-utf8/Makefile
new file mode 100644
index 00000000000..7948c442616
--- /dev/null
+++ b/src/test/run-make/stdin-non-utf8/Makefile
@@ -0,0 +1,6 @@
+-include ../tools.mk
+
+all:
+	cp non-utf8 $(TMPDIR)/non-utf.rs
+	cat $(TMPDIR)/non-utf.rs | $(RUSTC) - 2>&1 \
+		| $(CGREP) "error: couldn't read from stdin, as it did not contain valid UTF-8"
diff --git a/src/test/run-make/stdin-non-utf8/non-utf8 b/src/test/run-make/stdin-non-utf8/non-utf8
new file mode 100644
index 00000000000..bc87051a852
--- /dev/null
+++ b/src/test/run-make/stdin-non-utf8/non-utf8
@@ -0,0 +1 @@
+
diff --git a/src/test/run-pass/generator/too-live-local-in-immovable-gen.rs b/src/test/run-pass/generator/too-live-local-in-immovable-gen.rs
new file mode 100644
index 00000000000..2314533a681
--- /dev/null
+++ b/src/test/run-pass/generator/too-live-local-in-immovable-gen.rs
@@ -0,0 +1,28 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(generators)]
+
+fn main() {
+    unsafe {
+        static move || {
+            // Tests that the generator transformation finds out that `a` is not live
+            // during the yield expression. Type checking will also compute liveness
+            // and it should also find out that `a` is not live.
+            // The compiler will panic if the generator transformation finds that
+            // `a` is live and type checking finds it dead.
+            let a = {
+                yield ();
+                4i32
+            };
+            &a;
+        };
+    }
+}
diff --git a/src/test/run-pass/issue-47139-1.rs b/src/test/run-pass/issue-47139-1.rs
new file mode 100644
index 00000000000..cb87991a491
--- /dev/null
+++ b/src/test/run-pass/issue-47139-1.rs
@@ -0,0 +1,87 @@
+// 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.
+
+// Regression test for issue #47139:
+//
+// Coherence was encountering an (unnecessary) overflow trying to
+// decide if the two impls of dummy overlap.
+//
+// The overflow went something like:
+//
+// - `&'a ?T: Insertable` ?
+// - let ?T = Option<?U> ?
+// - `Option<?U>: Insertable` ?
+// - `Option<&'a ?U>: Insertable` ?
+// - `&'a ?U: Insertable` ?
+//
+// While somewhere in the middle, a projection would occur, which
+// broke cycle detection.
+//
+// It turned out that this cycle was being kicked off due to some
+// extended diagnostic attempts in coherence, so removing those
+// sidestepped the issue for now.
+
+#![allow(dead_code)]
+
+pub trait Insertable {
+    type Values;
+
+    fn values(self) -> Self::Values;
+}
+
+impl<T> Insertable for Option<T>
+    where
+    T: Insertable,
+    T::Values: Default,
+{
+    type Values = T::Values;
+
+    fn values(self) -> Self::Values {
+        self.map(Insertable::values).unwrap_or_default()
+    }
+}
+
+impl<'a, T> Insertable for &'a Option<T>
+    where
+    Option<&'a T>: Insertable,
+{
+    type Values = <Option<&'a T> as Insertable>::Values;
+
+    fn values(self) -> Self::Values {
+        self.as_ref().values()
+    }
+}
+
+impl<'a, T> Insertable for &'a [T]
+{
+    type Values = Self;
+
+    fn values(self) -> Self::Values {
+        self
+    }
+}
+
+trait Unimplemented { }
+
+trait Dummy { }
+
+struct Foo<T> { t: T }
+
+impl<'a, U> Dummy for Foo<&'a U>
+    where &'a U: Insertable
+{
+}
+
+impl<T> Dummy for T
+    where T: Unimplemented
+{ }
+
+fn main() {
+}
diff --git a/src/test/run-pass/issue-47139-2.rs b/src/test/run-pass/issue-47139-2.rs
new file mode 100644
index 00000000000..08eaee5acd7
--- /dev/null
+++ b/src/test/run-pass/issue-47139-2.rs
@@ -0,0 +1,75 @@
+// 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.
+
+// Regression test for issue #47139:
+//
+// Same as issue-47139-1.rs, but the impls of dummy are in the
+// opposite order. This influenced the way that coherence ran and in
+// some cases caused the overflow to occur when it wouldn't otherwise.
+// In an effort to make the regr test more robust, I am including both
+// orderings.
+
+#![allow(dead_code)]
+
+pub trait Insertable {
+    type Values;
+
+    fn values(self) -> Self::Values;
+}
+
+impl<T> Insertable for Option<T>
+    where
+    T: Insertable,
+    T::Values: Default,
+{
+    type Values = T::Values;
+
+    fn values(self) -> Self::Values {
+        self.map(Insertable::values).unwrap_or_default()
+    }
+}
+
+impl<'a, T> Insertable for &'a Option<T>
+    where
+    Option<&'a T>: Insertable,
+{
+    type Values = <Option<&'a T> as Insertable>::Values;
+
+    fn values(self) -> Self::Values {
+        self.as_ref().values()
+    }
+}
+
+impl<'a, T> Insertable for &'a [T]
+{
+    type Values = Self;
+
+    fn values(self) -> Self::Values {
+        self
+    }
+}
+
+trait Unimplemented { }
+
+trait Dummy { }
+
+struct Foo<T> { t: T }
+
+impl<T> Dummy for T
+    where T: Unimplemented
+{ }
+
+impl<'a, U> Dummy for Foo<&'a U>
+    where &'a U: Insertable
+{
+}
+
+fn main() {
+}
diff --git a/src/test/run-pass/issue-47638.rs b/src/test/run-pass/issue-47638.rs
new file mode 100644
index 00000000000..6f627b2a3c1
--- /dev/null
+++ b/src/test/run-pass/issue-47638.rs
@@ -0,0 +1,18 @@
+// Copyright 2018 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.
+
+fn id<'c, 'b>(f: &'c &'b Fn(&i32)) -> &'c &'b Fn(&'static i32) {
+    f
+}
+
+fn main() {
+    let f: &Fn(&i32) = &|x| {};
+    id(&f);
+}
diff --git a/src/test/run-pass/issue-47789.rs b/src/test/run-pass/issue-47789.rs
new file mode 100644
index 00000000000..3148939992c
--- /dev/null
+++ b/src/test/run-pass/issue-47789.rs
@@ -0,0 +1,20 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+
+#![feature(nll)]
+
+static mut x: &'static u32 = &0;
+
+fn foo() {
+    unsafe { x = &1; }
+}
+
+fn main() { }
diff --git a/src/test/run-pass/match-beginning-vert.rs b/src/test/run-pass/match-beginning-vert.rs
new file mode 100644
index 00000000000..cdacfb2f057
--- /dev/null
+++ b/src/test/run-pass/match-beginning-vert.rs
@@ -0,0 +1,28 @@
+// Copyright 2018 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.
+
+enum Foo {
+    A,
+    B,
+    C,
+    D,
+    E,
+}
+use Foo::*;
+
+fn main() {
+    for foo in &[A, B, C, D, E] {
+        match *foo {
+            | A => println!("A"),
+            | B | C if 1 < 2 => println!("BC!"),
+            | _ => {},
+        }
+    }
+}
diff --git a/src/test/run-pass/sse2.rs b/src/test/run-pass/sse2.rs
index c2414e5ff5d..22469b2fde0 100644
--- a/src/test/run-pass/sse2.rs
+++ b/src/test/run-pass/sse2.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// min-llvm-version 4.0
+// no-system-llvm -- needs MCSubtargetInfo::getFeatureTable()
 // ignore-cloudabi no std::env
 
 #![feature(cfg_target_feature)]
diff --git a/src/test/run-pass/stack-probes-lto.rs b/src/test/run-pass/stack-probes-lto.rs
index 22555c8d6a7..4deced1297b 100644
--- a/src/test/run-pass/stack-probes-lto.rs
+++ b/src/test/run-pass/stack-probes-lto.rs
@@ -15,7 +15,7 @@
 // ignore-emscripten no processes
 // ignore-musl FIXME #31506
 // ignore-pretty
-// no-system-llvm
+// min-system-llvm-version 5.0
 // compile-flags: -C lto
 // no-prefer-dynamic
 
diff --git a/src/test/run-pass/stack-probes.rs b/src/test/run-pass/stack-probes.rs
index 248ad701926..4224a65ffd7 100644
--- a/src/test/run-pass/stack-probes.rs
+++ b/src/test/run-pass/stack-probes.rs
@@ -14,7 +14,7 @@
 // ignore-cloudabi no processes
 // ignore-emscripten no processes
 // ignore-musl FIXME #31506
-// no-system-llvm
+// min-system-llvm-version 5.0
 
 use std::mem;
 use std::process::Command;
diff --git a/src/test/rustdoc/const-evalutation-ice.rs b/src/test/rustdoc/const-evalutation-ice.rs
new file mode 100644
index 00000000000..9fed67ee583
--- /dev/null
+++ b/src/test/rustdoc/const-evalutation-ice.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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.
+
+// Just check if we don't get an ICE for the _S type.
+
+#![feature(const_size_of)]
+
+use std::cell::Cell;
+use std::mem;
+
+pub struct S {
+    s: Cell<usize>
+}
+
+pub type _S = [usize; 0 - (mem::size_of::<S>() != 4) as usize];
diff --git a/src/test/ui/associated-const-impl-wrong-lifetime.stderr b/src/test/ui/associated-const-impl-wrong-lifetime.stderr
index a7aee9b19f1..ab0e1003a9e 100644
--- a/src/test/ui/associated-const-impl-wrong-lifetime.stderr
+++ b/src/test/ui/associated-const-impl-wrong-lifetime.stderr
@@ -9,11 +9,8 @@ error[E0308]: mismatched types
 note: the lifetime 'a as defined on the impl at 17:1...
   --> $DIR/associated-const-impl-wrong-lifetime.rs:17:1
    |
-17 | / impl<'a> Foo for &'a () {
-18 | |     const NAME: &'a str = "unit";
-19 | |     //~^ ERROR mismatched types [E0308]
-20 | | }
-   | |_^
+17 | impl<'a> Foo for &'a () {
+   | ^^^^^^^^^^^^^^^^^^^^^^^
    = note: ...does not necessarily outlive the static lifetime
 
 error: aborting due to previous error
diff --git a/src/test/ui/blind-item-item-shadow.stderr b/src/test/ui/blind-item-item-shadow.stderr
index 855b3799eb5..d3588be2669 100644
--- a/src/test/ui/blind-item-item-shadow.stderr
+++ b/src/test/ui/blind-item-item-shadow.stderr
@@ -10,8 +10,8 @@ error[E0255]: the name `foo` is defined multiple times
    = note: `foo` must be defined only once in the type namespace of this module
 help: You can use `as` to change the binding name of the import
    |
-13 | use foo::foo as Otherfoo;
-   |     ^^^^^^^^^^^^^^^^^^^^
+13 | use foo::foo as other_foo;
+   |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs
index 617de2c5dfe..617de2c5dfe 100644
--- a/src/test/compile-fail/regions-bound-missing-bound-in-impl.rs
+++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.rs
diff --git a/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
new file mode 100644
index 00000000000..e8323247af9
--- /dev/null
+++ b/src/test/ui/borrowck/regions-bound-missing-bound-in-impl.stderr
@@ -0,0 +1,48 @@
+error[E0195]: lifetime parameters or bounds on method `no_bound` do not match the trait declaration
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:28:5
+   |
+20 |     fn no_bound<'b>(self, b: Inv<'b>);
+   |     ---------------------------------- lifetimes in impl do not match this method in trait
+...
+28 |     fn no_bound<'b:'a>(self, b: Inv<'b>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
+
+error[E0195]: lifetime parameters or bounds on method `has_bound` do not match the trait declaration
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:32:5
+   |
+21 |     fn has_bound<'b:'a>(self, b: Inv<'b>);
+   |     -------------------------------------- lifetimes in impl do not match this method in trait
+...
+32 |     fn has_bound<'b>(self, b: Inv<'b>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetimes do not match method in trait
+
+error[E0308]: method not compatible with trait
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
+   |
+36 |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
+   |
+   = note: expected type `fn(&'a isize, Inv<'c>, Inv<'c>, Inv<'d>)`
+              found type `fn(&'a isize, Inv<'_>, Inv<'c>, Inv<'d>)`
+note: the lifetime 'c as defined on the method body at 36:5...
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
+   |
+36 |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: ...does not necessarily outlive the lifetime 'c as defined on the method body at 36:5
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:36:5
+   |
+36 |     fn wrong_bound1<'b,'c,'d:'a+'c>(self, b: Inv<'b>, c: Inv<'c>, d: Inv<'d>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0276]: impl has stricter requirements than trait
+  --> $DIR/regions-bound-missing-bound-in-impl.rs:53:5
+   |
+24 |     fn another_bound<'x: 'a>(self, x: Inv<'x>, y: Inv<'t>);
+   |     ------------------------------------------------------- definition of `another_bound` from trait
+...
+53 |     fn another_bound<'x: 't>(self, x: Inv<'x>, y: Inv<'t>) {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ impl has extra requirement `'x: 't`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr
index ebb1e561e57..5c612522d9a 100644
--- a/src/test/ui/closure-expected-type/expect-region-supply-region.stderr
+++ b/src/test/ui/closure-expected-type/expect-region-supply-region.stderr
@@ -41,14 +41,8 @@ note: the anonymous lifetime #2 defined on the body at 47:29...
 note: ...does not necessarily outlive the lifetime 'x as defined on the function body at 42:1
   --> $DIR/expect-region-supply-region.rs:42:1
    |
-42 | / fn expect_bound_supply_named<'x>() {
-43 | |     let mut f: Option<&u32> = None;
-44 | |
-45 | |     // Here we give a type annotation that `x` should be free. We get
-...  |
-54 | |     });
-55 | | }
-   | |_^
+42 | fn expect_bound_supply_named<'x>() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/expect-region-supply-region.rs:47:33
@@ -61,14 +55,8 @@ error[E0308]: mismatched types
 note: the lifetime 'x as defined on the function body at 42:1...
   --> $DIR/expect-region-supply-region.rs:42:1
    |
-42 | / fn expect_bound_supply_named<'x>() {
-43 | |     let mut f: Option<&u32> = None;
-44 | |
-45 | |     // Here we give a type annotation that `x` should be free. We get
-...  |
-54 | |     });
-55 | | }
-   | |_^
+42 | fn expect_bound_supply_named<'x>() {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...does not necessarily outlive the anonymous lifetime #2 defined on the body at 47:29
   --> $DIR/expect-region-supply-region.rs:47:29
    |
diff --git a/src/test/ui/double-import.stderr b/src/test/ui/double-import.stderr
index fcd3f2696f2..2a0f9ee34f2 100644
--- a/src/test/ui/double-import.stderr
+++ b/src/test/ui/double-import.stderr
@@ -9,8 +9,8 @@ error[E0252]: the name `foo` is defined multiple times
    = note: `foo` must be defined only once in the value namespace of this module
 help: You can use `as` to change the binding name of the import
    |
-23 | use sub2::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times
-   |     ^^^^^^^^^^^^^^^^^^^^^
+23 | use sub2::foo as other_foo; //~ ERROR the name `foo` is defined multiple times
+   |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/feature-gate-match_beginning_vert.rs b/src/test/ui/feature-gate-match_beginning_vert.rs
deleted file mode 100644
index 9085563c99d..00000000000
--- a/src/test/ui/feature-gate-match_beginning_vert.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2017 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.
-
-#[allow(dead_code)]
-enum Foo {
-    A,
-    B,
-    C,
-    D,
-    E,
-}
-use Foo::*;
-
-fn main() {
-    let x = Foo::A;
-    match x {
-        | A => println!("A"),
-        //~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
-        | B | C => println!("BC!"),
-        //~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
-        | _ => {},
-        //~^ ERROR: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
-    };
-    match x {
-        A | B | C => println!("ABC!"),
-        _ => {},
-    };
-}
-
diff --git a/src/test/ui/feature-gate-match_beginning_vert.stderr b/src/test/ui/feature-gate-match_beginning_vert.stderr
deleted file mode 100644
index 1d45dedb497..00000000000
--- a/src/test/ui/feature-gate-match_beginning_vert.stderr
+++ /dev/null
@@ -1,26 +0,0 @@
-error[E0658]: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
-  --> $DIR/feature-gate-match_beginning_vert.rs:24:9
-   |
-24 |         | A => println!("A"),
-   |         ^
-   |
-   = help: add #![feature(match_beginning_vert)] to the crate attributes to enable
-
-error[E0658]: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
-  --> $DIR/feature-gate-match_beginning_vert.rs:26:9
-   |
-26 |         | B | C => println!("BC!"),
-   |         ^
-   |
-   = help: add #![feature(match_beginning_vert)] to the crate attributes to enable
-
-error[E0658]: Use of a '|' at the beginning of a match arm is experimental (see issue #44101)
-  --> $DIR/feature-gate-match_beginning_vert.rs:28:9
-   |
-28 |         | _ => {},
-   |         ^
-   |
-   = help: add #![feature(match_beginning_vert)] to the crate attributes to enable
-
-error: aborting due to 3 previous errors
-
diff --git a/src/test/ui/generator/generator-with-nll.stderr b/src/test/ui/generator/generator-with-nll.stderr
index 0a52a928f69..0f7d2e540d8 100644
--- a/src/test/ui/generator/generator-with-nll.stderr
+++ b/src/test/ui/generator/generator-with-nll.stderr
@@ -1,12 +1,3 @@
-error[E0626]: borrow may still be in use when generator yields (Mir)
-  --> $DIR/generator-with-nll.rs:20:17
-   |
-20 |         let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
-   |                 ^^^^^^^^^
-21 |         //~^ borrow may still be in use when generator yields (Mir)
-22 |         yield ();
-   |         -------- possible yield occurs here
-
 error[E0626]: borrow may still be in use when generator yields (Ast)
   --> $DIR/generator-with-nll.rs:19:23
    |
@@ -25,5 +16,14 @@ error[E0626]: borrow may still be in use when generator yields (Ast)
 22 |         yield ();
    |         -------- possible yield occurs here
 
+error[E0626]: borrow may still be in use when generator yields (Mir)
+  --> $DIR/generator-with-nll.rs:20:17
+   |
+20 |         let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
+   |                 ^^^^^^^^^
+21 |         //~^ borrow may still be in use when generator yields (Mir)
+22 |         yield ();
+   |         -------- possible yield occurs here
+
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/generator/pattern-borrow.rs b/src/test/ui/generator/pattern-borrow.rs
new file mode 100644
index 00000000000..557a5e62f7e
--- /dev/null
+++ b/src/test/ui/generator/pattern-borrow.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(generators)]
+
+enum Test { A(i32), B, }
+
+fn main() { }
+
+fn fun(test: Test) {
+    move || {
+        if let Test::A(ref _a) = test { //~ ERROR borrow may still be in use when generator yields
+            yield ();
+        }
+    };
+}
diff --git a/src/test/ui/generator/pattern-borrow.stderr b/src/test/ui/generator/pattern-borrow.stderr
new file mode 100644
index 00000000000..6b39b272d0e
--- /dev/null
+++ b/src/test/ui/generator/pattern-borrow.stderr
@@ -0,0 +1,10 @@
+error[E0626]: borrow may still be in use when generator yields
+  --> $DIR/pattern-borrow.rs:19:24
+   |
+19 |         if let Test::A(ref _a) = test { //~ ERROR borrow may still be in use when generator yields
+   |                        ^^^^^^
+20 |             yield ();
+   |             -------- possible yield occurs here
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/generator/sized-yield.rs b/src/test/ui/generator/sized-yield.rs
new file mode 100644
index 00000000000..f38ebf8b946
--- /dev/null
+++ b/src/test/ui/generator/sized-yield.rs
@@ -0,0 +1,21 @@
+// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+#![feature(generators, generator_trait)]
+
+use std::ops::Generator;
+
+fn main() {
+   let s = String::from("foo");
+   let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+       yield s[..];
+   };
+   gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+}
diff --git a/src/test/ui/generator/sized-yield.stderr b/src/test/ui/generator/sized-yield.stderr
new file mode 100644
index 00000000000..7adb2cc5598
--- /dev/null
+++ b/src/test/ui/generator/sized-yield.stderr
@@ -0,0 +1,22 @@
+error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+  --> $DIR/sized-yield.rs:17:26
+   |
+17 |      let mut gen = move || { //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+   |  __________________________^
+18 | |        yield s[..];
+19 | |    };
+   | |____^ `str` does not have a constant size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `str`
+   = note: the yield type of a generator must have a statically known size
+
+error[E0277]: the trait bound `str: std::marker::Sized` is not satisfied
+  --> $DIR/sized-yield.rs:20:8
+   |
+20 |    gen.resume(); //~ ERROR the trait bound `str: std::marker::Sized` is not satisfied
+   |        ^^^^^^ `str` does not have a constant size known at compile-time
+   |
+   = help: the trait `std::marker::Sized` is not implemented for `str`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/generator/yield-while-local-borrowed.stderr b/src/test/ui/generator/yield-while-local-borrowed.stderr
index 7961dd97441..114fe8ffcab 100644
--- a/src/test/ui/generator/yield-while-local-borrowed.stderr
+++ b/src/test/ui/generator/yield-while-local-borrowed.stderr
@@ -1,12 +1,3 @@
-error[E0626]: borrow may still be in use when generator yields (Mir)
-  --> $DIR/yield-while-local-borrowed.rs:24:17
-   |
-24 |         let a = &mut 3;
-   |                 ^^^^^^
-...
-27 |         yield();
-   |         ------- possible yield occurs here
-
 error[E0626]: borrow may still be in use when generator yields (Ast)
   --> $DIR/yield-while-local-borrowed.rs:24:22
    |
@@ -26,6 +17,15 @@ error[E0626]: borrow may still be in use when generator yields (Ast)
    |             ------- possible yield occurs here
 
 error[E0626]: borrow may still be in use when generator yields (Mir)
+  --> $DIR/yield-while-local-borrowed.rs:24:17
+   |
+24 |         let a = &mut 3;
+   |                 ^^^^^^
+...
+27 |         yield();
+   |         ------- possible yield occurs here
+
+error[E0626]: borrow may still be in use when generator yields (Mir)
   --> $DIR/yield-while-local-borrowed.rs:52:21
    |
 52 |             let b = &a;
diff --git a/src/test/ui/impl-trait/trait_type.stderr b/src/test/ui/impl-trait/trait_type.stderr
index 7a0d01a8ec2..1417c71ca12 100644
--- a/src/test/ui/impl-trait/trait_type.stderr
+++ b/src/test/ui/impl-trait/trait_type.stderr
@@ -2,7 +2,7 @@ error[E0053]: method `fmt` has an incompatible type for trait
   --> $DIR/trait_type.rs:17:4
    |
 17 |    fn fmt(&self, x: &str) -> () { }
-   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
+   |    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ types differ in mutability
    |
    = note: expected type `fn(&MyType, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
               found type `fn(&MyType, &str)`
@@ -19,7 +19,7 @@ error[E0186]: method `fmt` has a `&self` declaration in the trait, but not in th
   --> $DIR/trait_type.rs:27:4
    |
 27 |    fn fmt() -> () { }
-   |    ^^^^^^^^^^^^^^^^^^ expected `&self` in impl
+   |    ^^^^^^^^^^^^^^ expected `&self` in impl
    |
    = note: `fmt` from trait: `fn(&Self, &mut std::fmt::Formatter<'_>) -> std::result::Result<(), std::fmt::Error>`
 
diff --git a/src/test/ui/imports/duplicate.stderr b/src/test/ui/imports/duplicate.stderr
index a74401314a1..6e5b91a11c9 100644
--- a/src/test/ui/imports/duplicate.stderr
+++ b/src/test/ui/imports/duplicate.stderr
@@ -9,8 +9,8 @@ error[E0252]: the name `foo` is defined multiple times
    = note: `foo` must be defined only once in the value namespace of this module
 help: You can use `as` to change the binding name of the import
    |
-25 |     use a::foo as Otherfoo; //~ ERROR the name `foo` is defined multiple times
-   |         ^^^^^^^^^^^^^^^^^^
+25 |     use a::foo as other_foo; //~ ERROR the name `foo` is defined multiple times
+   |         ^^^^^^^^^^^^^^^^^^^
 
 error[E0659]: `foo` is ambiguous
   --> $DIR/duplicate.rs:56:9
diff --git a/src/test/ui/in-band-lifetimes/ellided-lifetimes.rs b/src/test/ui/in-band-lifetimes/ellided-lifetimes.rs
new file mode 100644
index 00000000000..5151abd6823
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/ellided-lifetimes.rs
@@ -0,0 +1,19 @@
+// Copyright 2018 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.
+#![allow(warnings)]
+#![allow(unused_variables, dead_code, unused, bad_style)]
+#![deny(elided_lifetime_in_path)]
+
+struct Foo<'a> { x: &'a u32 }
+fn foo(x: &Foo) {
+    //~^ ERROR: hidden lifetime parameters are deprecated, try `Foo<'_>`
+}
+
+fn main() {}
diff --git a/src/test/ui/in-band-lifetimes/ellided-lifetimes.stderr b/src/test/ui/in-band-lifetimes/ellided-lifetimes.stderr
new file mode 100644
index 00000000000..613a7be6ed2
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/ellided-lifetimes.stderr
@@ -0,0 +1,14 @@
+error: hidden lifetime parameters are deprecated, try `Foo<'_>`
+  --> $DIR/ellided-lifetimes.rs:15:12
+   |
+15 | fn foo(x: &Foo) {
+   |            ^^^
+   |
+note: lint level defined here
+  --> $DIR/ellided-lifetimes.rs:12:9
+   |
+12 | #![deny(elided_lifetime_in_path)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
new file mode 100644
index 00000000000..f845762cefd
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.rs
@@ -0,0 +1,22 @@
+// Copyright 2018 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::Deref;
+trait Trait {}
+
+struct Struct;
+
+impl Deref for Struct {
+    type Target = Trait;
+    fn deref(&self) -> &Trait {
+        unimplemented!();
+    }
+}
+//~^^^^ ERROR cannot infer an appropriate lifetime for lifetime parameter
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
new file mode 100644
index 00000000000..7aab31eb909
--- /dev/null
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl-2.stderr
@@ -0,0 +1,22 @@
+error[E0601]: main function not found
+
+error[E0495]: cannot infer an appropriate lifetime for lifetime parameter in generic type due to conflicting requirements
+  --> $DIR/mismatched_trait_impl-2.rs:18:5
+   |
+18 |     fn deref(&self) -> &Trait {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: first, the lifetime cannot outlive the anonymous lifetime #1 defined on the method body at 18:5...
+  --> $DIR/mismatched_trait_impl-2.rs:18:5
+   |
+18 | /     fn deref(&self) -> &Trait {
+19 | |         unimplemented!();
+20 | |     }
+   | |_____^
+   = note: ...but the lifetime must also be valid for the static lifetime...
+   = note: ...so that the method type is compatible with trait:
+           expected fn(&Struct) -> &Trait + 'static
+              found fn(&Struct) -> &Trait
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
index e96f7181a6d..fd6be01da9f 100644
--- a/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
+++ b/src/test/ui/in-band-lifetimes/mismatched_trait_impl.stderr
@@ -1,10 +1,8 @@
 error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 'a in generic type due to conflicting requirements
   --> $DIR/mismatched_trait_impl.rs:19:5
    |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
+19 |     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
 note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on the method body at 19:5...
   --> $DIR/mismatched_trait_impl.rs:19:5
@@ -13,27 +11,14 @@ note: first, the lifetime cannot outlive the anonymous lifetime #2 defined on th
 20 | |         x
 21 | |     }
    | |_____^
-note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32)
-  --> $DIR/mismatched_trait_impl.rs:19:5
-   |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
-note: but, the lifetime must be valid for the lifetime 'a as defined on the method body at 19:5...
+note: ...but the lifetime must also be valid for the lifetime 'a as defined on the method body at 19:5...
   --> $DIR/mismatched_trait_impl.rs:19:5
    |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
-note: ...so that method type is compatible with trait (expected fn(&i32, &'a u32, &u32) -> &'a u32, found fn(&i32, &u32, &u32) -> &u32)
-  --> $DIR/mismatched_trait_impl.rs:19:5
-   |
-19 | /     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
-20 | |         x
-21 | |     }
-   | |_____^
+19 |     fn foo(&self, x: &u32, y: &'a u32) -> &'a u32 { //~ ERROR cannot infer
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   = note: ...so that the method type is compatible with trait:
+           expected fn(&i32, &'a u32, &u32) -> &'a u32
+              found fn(&i32, &u32, &u32) -> &u32
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-26886.stderr b/src/test/ui/issue-26886.stderr
index cb2eca87068..e6424e535ee 100644
--- a/src/test/ui/issue-26886.stderr
+++ b/src/test/ui/issue-26886.stderr
@@ -24,8 +24,8 @@ error[E0252]: the name `sync` is defined multiple times
    = note: `sync` must be defined only once in the type namespace of this module
 help: You can use `as` to change the binding name of the import
    |
-14 | use std::sync as Othersync; //~ ERROR the name `sync` is defined multiple times
-   |     ^^^^^^^^^^^^^^^^^^^^^^
+14 | use std::sync as other_sync; //~ ERROR the name `sync` is defined multiple times
+   |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issue-27942.stderr b/src/test/ui/issue-27942.stderr
index b580b8e7313..b24544743d8 100644
--- a/src/test/ui/issue-27942.stderr
+++ b/src/test/ui/issue-27942.stderr
@@ -14,14 +14,8 @@ note: the anonymous lifetime #1 defined on the method body at 15:5...
 note: ...does not necessarily outlive the lifetime 'a as defined on the trait at 13:1
   --> $DIR/issue-27942.rs:13:1
    |
-13 | / pub trait Buffer<'a, R: Resources<'a>> {
-14 | |
-15 | |     fn select(&self) -> BufferViewHandle<R>;
-16 | |     //~^ ERROR mismatched types
-...  |
-19 | |     //~| lifetime mismatch
-20 | | }
-   | |_^
+13 | pub trait Buffer<'a, R: Resources<'a>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0308]: mismatched types
   --> $DIR/issue-27942.rs:15:5
@@ -34,14 +28,8 @@ error[E0308]: mismatched types
 note: the lifetime 'a as defined on the trait at 13:1...
   --> $DIR/issue-27942.rs:13:1
    |
-13 | / pub trait Buffer<'a, R: Resources<'a>> {
-14 | |
-15 | |     fn select(&self) -> BufferViewHandle<R>;
-16 | |     //~^ ERROR mismatched types
-...  |
-19 | |     //~| lifetime mismatch
-20 | | }
-   | |_^
+13 | pub trait Buffer<'a, R: Resources<'a>> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 note: ...does not necessarily outlive the anonymous lifetime #1 defined on the method body at 15:5
   --> $DIR/issue-27942.rs:15:5
    |
diff --git a/src/test/ui/issue-37884.stderr b/src/test/ui/issue-37884.stderr
index 439b123975f..c4ad232ae7e 100644
--- a/src/test/ui/issue-37884.stderr
+++ b/src/test/ui/issue-37884.stderr
@@ -24,14 +24,8 @@ note: the anonymous lifetime #1 defined on the method body at 16:5...
 note: ...does not necessarily outlive the lifetime 'a as defined on the impl at 13:1
   --> $DIR/issue-37884.rs:13:1
    |
-13 | / impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
-14 | |
-15 | |     type Item = &'a mut T;
-16 | |     fn next(&'a mut self) -> Option<Self::Item>
-...  |
-21 | |     }
-22 | | }
-   | |_^
+13 | impl<'a, T: 'a> Iterator for RepeatMut<'a, T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-46472.stderr b/src/test/ui/issue-46472.stderr
index 2f332a7a558..7b5cce218e9 100644
--- a/src/test/ui/issue-46472.stderr
+++ b/src/test/ui/issue-46472.stderr
@@ -10,12 +10,8 @@ error[E0597]: borrowed value does not live long enough (Ast)
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
   --> $DIR/issue-46472.rs:13:1
    |
-13 | / fn bar<'a>() -> &'a mut u32 {
-14 | |     &mut 4
-15 | |     //~^ ERROR borrowed value does not live long enough (Ast) [E0597]
-16 | |     //~| ERROR borrowed value does not live long enough (Mir) [E0597]
-17 | | }
-   | |_^
+13 | fn bar<'a>() -> &'a mut u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0597]: borrowed value does not live long enough (Mir)
   --> $DIR/issue-46472.rs:14:10
@@ -29,12 +25,8 @@ error[E0597]: borrowed value does not live long enough (Mir)
 note: borrowed value must be valid for the lifetime 'a as defined on the function body at 13:1...
   --> $DIR/issue-46472.rs:13:1
    |
-13 | / fn bar<'a>() -> &'a mut u32 {
-14 | |     &mut 4
-15 | |     //~^ ERROR borrowed value does not live long enough (Ast) [E0597]
-16 | |     //~| ERROR borrowed value does not live long enough (Mir) [E0597]
-17 | | }
-   | |_^
+13 | fn bar<'a>() -> &'a mut u32 {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/issue-47706-trait.rs b/src/test/ui/issue-47706-trait.rs
new file mode 100644
index 00000000000..86a9da49a05
--- /dev/null
+++ b/src/test/ui/issue-47706-trait.rs
@@ -0,0 +1,16 @@
+// Copyright 2018 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.
+
+trait T {
+    fn f(&self, _: ()) {
+        None::<()>.map(Self::f);
+    }
+    //~^^ ERROR function is expected to take a single 0-tuple as argument
+}
diff --git a/src/test/ui/issue-47706-trait.stderr b/src/test/ui/issue-47706-trait.stderr
new file mode 100644
index 00000000000..320e98dee4a
--- /dev/null
+++ b/src/test/ui/issue-47706-trait.stderr
@@ -0,0 +1,12 @@
+error[E0601]: main function not found
+
+error[E0593]: function is expected to take a single 0-tuple as argument, but it takes 2 distinct arguments
+  --> $DIR/issue-47706-trait.rs:13:20
+   |
+12 |     fn f(&self, _: ()) {
+   |     ------------------ takes 2 distinct arguments
+13 |         None::<()>.map(Self::f);
+   |                    ^^^ expected function that takes a single 0-tuple as argument
+
+error: aborting due to 2 previous errors
+
diff --git a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
new file mode 100644
index 00000000000..b4e6c5074e3
--- /dev/null
+++ b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.rs
@@ -0,0 +1,40 @@
+// Copyright 2018 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.
+
+// must-compile-successfully
+
+#![warn(unused_parens)]
+
+macro_rules! the_worship_the_heart_lifts_above {
+    ( @as_expr, $e:expr) => { $e };
+    ( @generate_fn, $name:tt) => {
+        #[allow(dead_code)] fn the_moth_for_the_star<'a>() -> Option<&'a str> {
+            Some(the_worship_the_heart_lifts_above!( @as_expr, $name ))
+        }
+    };
+    ( $name:ident ) => { the_worship_the_heart_lifts_above!( @generate_fn, (stringify!($name))); }
+    // ↑ Notably, this does 𝘯𝘰𝘵 warn: we're declining to lint unused parens in
+    // function/method arguments inside of nested macros because of situations
+    // like those reported in Issue #47775
+}
+
+macro_rules! and_the_heavens_reject_not {
+    () => {
+        // ↓ But let's test that we still lint for unused parens around
+        // function args inside of simple, one-deep macros.
+        #[allow(dead_code)] fn the_night_for_the_morrow() -> Option<isize> { Some((2)) }
+        //~^ WARN unnecessary parentheses around function argument
+    }
+}
+
+the_worship_the_heart_lifts_above!(rah);
+and_the_heavens_reject_not!();
+
+fn main() {}
diff --git a/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.stderr b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.stderr
new file mode 100644
index 00000000000..097ec1b1c80
--- /dev/null
+++ b/src/test/ui/lint/issue-47775-nested-macro-unnecessary-parens-arg.stderr
@@ -0,0 +1,15 @@
+warning: unnecessary parentheses around function argument
+  --> $DIR/issue-47775-nested-macro-unnecessary-parens-arg.rs:32:83
+   |
+32 |         #[allow(dead_code)] fn the_night_for_the_morrow() -> Option<isize> { Some((2)) }
+   |                                                                                   ^^^ help: remove these parentheses
+...
+38 | and_the_heavens_reject_not!();
+   | ------------------------------ in this macro invocation
+   |
+note: lint level defined here
+  --> $DIR/issue-47775-nested-macro-unnecessary-parens-arg.rs:13:9
+   |
+13 | #![warn(unused_parens)]
+   |         ^^^^^^^^^^^^^
+
diff --git a/src/test/ui/lint/suggestions.rs b/src/test/ui/lint/suggestions.rs
index dfcaede1402..e35675eacd8 100644
--- a/src/test/ui/lint/suggestions.rs
+++ b/src/test/ui/lint/suggestions.rs
@@ -8,6 +8,8 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+// ignore-tidy-tab
+
 #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
 #![feature(no_debug)]
 
@@ -46,11 +48,15 @@ fn main() {
         let mut a = (1); // should suggest no `mut`, no parens
         //~^ WARN does not need to be mutable
         //~| WARN unnecessary parentheses
+        // the line after `mut` has a `\t` at the beginning, this is on purpose
+        let mut
+	        b = 1;
+        //~^^ WARN does not need to be mutable
         let d = Equinox { warp_factor: 9.975 };
         match d {
             Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
             //~^ WARN this pattern is redundant
         }
-        println!("{}", a);
+        println!("{} {}", a, b);
     }
 }
diff --git a/src/test/ui/lint/suggestions.stderr b/src/test/ui/lint/suggestions.stderr
index 8b30f552d37..90d6bd312e4 100644
--- a/src/test/ui/lint/suggestions.stderr
+++ b/src/test/ui/lint/suggestions.stderr
@@ -1,41 +1,53 @@
 warning: unnecessary parentheses around assigned value
-  --> $DIR/suggestions.rs:46:21
+  --> $DIR/suggestions.rs:48:21
    |
-46 |         let mut a = (1); // should suggest no `mut`, no parens
+48 |         let mut a = (1); // should suggest no `mut`, no parens
    |                     ^^^ help: remove these parentheses
    |
 note: lint level defined here
-  --> $DIR/suggestions.rs:11:21
+  --> $DIR/suggestions.rs:13:21
    |
-11 | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
+13 | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
    |                     ^^^^^^^^^^^^^
 
 warning: use of deprecated attribute `no_debug`: the `#[no_debug]` attribute was an experimental feature that has been deprecated due to lack of demand. See https://github.com/rust-lang/rust/issues/29721
-  --> $DIR/suggestions.rs:41:1
+  --> $DIR/suggestions.rs:43:1
    |
-41 | #[no_debug] // should suggest removal of deprecated attribute
+43 | #[no_debug] // should suggest removal of deprecated attribute
    | ^^^^^^^^^^^ help: remove this attribute
    |
    = note: #[warn(deprecated)] on by default
 
 warning: variable does not need to be mutable
-  --> $DIR/suggestions.rs:46:13
+  --> $DIR/suggestions.rs:48:13
    |
-46 |         let mut a = (1); // should suggest no `mut`, no parens
-   |             ---^^
+48 |         let mut a = (1); // should suggest no `mut`, no parens
+   |             ----^
    |             |
    |             help: remove this `mut`
    |
 note: lint level defined here
-  --> $DIR/suggestions.rs:11:9
+  --> $DIR/suggestions.rs:13:9
    |
-11 | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
+13 | #![warn(unused_mut, unused_parens)] // UI tests pass `-A unused`—see Issue #43896
    |         ^^^^^^^^^^
 
+warning: variable does not need to be mutable
+  --> $DIR/suggestions.rs:52:13
+   |
+52 |            let mut
+   |   _____________^
+   |  |_____________|
+   | ||
+53 | ||             b = 1;
+   | ||____________-^
+   |  |____________|
+   |               help: remove this `mut`
+
 warning: static is marked #[no_mangle], but not exported
-  --> $DIR/suggestions.rs:14:14
+  --> $DIR/suggestions.rs:16:14
    |
-14 | #[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub`
+16 | #[no_mangle] static SHENZHOU: usize = 1; // should suggest `pub`
    |              -^^^^^^^^^^^^^^^^^^^^^^^^^^
    |              |
    |              help: try making it public: `pub`
@@ -43,9 +55,9 @@ warning: static is marked #[no_mangle], but not exported
    = note: #[warn(private_no_mangle_statics)] on by default
 
 error: const items should never be #[no_mangle]
-  --> $DIR/suggestions.rs:16:14
+  --> $DIR/suggestions.rs:18:14
    |
-16 | #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const`
+18 | #[no_mangle] const DISCOVERY: usize = 1; // should suggest `pub static` rather than `const`
    |              -----^^^^^^^^^^^^^^^^^^^^^^
    |              |
    |              help: try a static value: `pub static`
@@ -53,19 +65,19 @@ error: const items should never be #[no_mangle]
    = note: #[deny(no_mangle_const_items)] on by default
 
 warning: functions generic over types must be mangled
-  --> $DIR/suggestions.rs:20:1
+  --> $DIR/suggestions.rs:22:1
    |
-19 | #[no_mangle] // should suggest removal (generics can't be no-mangle)
+21 | #[no_mangle] // should suggest removal (generics can't be no-mangle)
    | ------------ help: remove this attribute
-20 | pub fn defiant<T>(_t: T) {}
+22 | pub fn defiant<T>(_t: T) {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: #[warn(no_mangle_generic_items)] on by default
 
 warning: function is marked #[no_mangle], but not exported
-  --> $DIR/suggestions.rs:24:1
+  --> $DIR/suggestions.rs:26:1
    |
-24 | fn rio_grande() {} // should suggest `pub`
+26 | fn rio_grande() {} // should suggest `pub`
    | -^^^^^^^^^^^^^^^^^
    | |
    | help: try making it public: `pub`
@@ -73,29 +85,29 @@ warning: function is marked #[no_mangle], but not exported
    = note: #[warn(private_no_mangle_fns)] on by default
 
 warning: static is marked #[no_mangle], but not exported
-  --> $DIR/suggestions.rs:31:18
+  --> $DIR/suggestions.rs:33:18
    |
-31 |     #[no_mangle] pub static DAUNTLESS: bool = true;
+33 |     #[no_mangle] pub static DAUNTLESS: bool = true;
    |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 warning: function is marked #[no_mangle], but not exported
-  --> $DIR/suggestions.rs:33:18
+  --> $DIR/suggestions.rs:35:18
    |
-33 |     #[no_mangle] pub fn val_jean() {}
+35 |     #[no_mangle] pub fn val_jean() {}
    |                  ^^^^^^^^^^^^^^^^^^^^
 
 warning: denote infinite loops with `loop { ... }`
-  --> $DIR/suggestions.rs:44:5
+  --> $DIR/suggestions.rs:46:5
    |
-44 |     while true { // should suggest `loop`
+46 |     while true { // should suggest `loop`
    |     ^^^^^^^^^^ help: use `loop`
    |
    = note: #[warn(while_true)] on by default
 
 warning: the `warp_factor:` in this pattern is redundant
-  --> $DIR/suggestions.rs:51:23
+  --> $DIR/suggestions.rs:57:23
    |
-51 |             Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
+57 |             Equinox { warp_factor: warp_factor } => {} // should suggest shorthand
    |                       ------------^^^^^^^^^^^^
    |                       |
    |                       help: remove this
diff --git a/src/test/ui/loop-break-value-no-repeat.stderr b/src/test/ui/loop-break-value-no-repeat.stderr
index 296b3b191e3..982de00b4fa 100644
--- a/src/test/ui/loop-break-value-no-repeat.stderr
+++ b/src/test/ui/loop-break-value-no-repeat.stderr
@@ -3,6 +3,10 @@ error[E0571]: `break` with value from a `for` loop
    |
 22 |         break 22 //~ ERROR `break` with value from a `for` loop
    |         ^^^^^^^^ can only break with a value inside `loop`
+help: instead, use `break` on its own without a value inside this `for` loop
+   |
+22 |         break //~ ERROR `break` with value from a `for` loop
+   |         ^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/macros/span-covering-argument-1.rs b/src/test/ui/macros/span-covering-argument-1.rs
new file mode 100644
index 00000000000..bfc137fc7b2
--- /dev/null
+++ b/src/test/ui/macros/span-covering-argument-1.rs
@@ -0,0 +1,23 @@
+// Copyright 2018 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.
+
+macro_rules! bad {
+    ($s:ident whatever) => {
+        {
+            let $s = 0;
+            *&mut $s = 0;
+            //~^ ERROR cannot borrow immutable local variable `foo` as mutable [E0596]
+        }
+    }
+}
+
+fn main() {
+    bad!(foo whatever);
+}
diff --git a/src/test/ui/macros/span-covering-argument-1.stderr b/src/test/ui/macros/span-covering-argument-1.stderr
new file mode 100644
index 00000000000..677d2f10fd6
--- /dev/null
+++ b/src/test/ui/macros/span-covering-argument-1.stderr
@@ -0,0 +1,13 @@
+error[E0596]: cannot borrow immutable local variable `foo` as mutable
+  --> $DIR/span-covering-argument-1.rs:15:19
+   |
+14 |             let $s = 0;
+   |                 -- consider changing this to `mut $s`
+15 |             *&mut $s = 0;
+   |                   ^^ cannot borrow mutably
+...
+22 |     bad!(foo whatever);
+   |     ------------------- in this macro invocation
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/resolve-conflict-item-vs-import.stderr b/src/test/ui/resolve-conflict-item-vs-import.stderr
index 03ef66681e4..e2245b8a8b1 100644
--- a/src/test/ui/resolve-conflict-item-vs-import.stderr
+++ b/src/test/ui/resolve-conflict-item-vs-import.stderr
@@ -10,8 +10,8 @@ error[E0255]: the name `transmute` is defined multiple times
    = note: `transmute` must be defined only once in the value namespace of this module
 help: You can use `as` to change the binding name of the import
    |
-11 | use std::mem::transmute as Othertransmute;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+11 | use std::mem::transmute as other_transmute;
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/span/macro-span-replacement.stderr b/src/test/ui/span/macro-span-replacement.stderr
index 2a0e71e192c..728cd12e2c6 100644
--- a/src/test/ui/span/macro-span-replacement.stderr
+++ b/src/test/ui/span/macro-span-replacement.stderr
@@ -1,8 +1,8 @@
 warning: struct is never used: `S`
-  --> $DIR/macro-span-replacement.rs:17:9
+  --> $DIR/macro-span-replacement.rs:17:14
    |
 17 |         $b $a; //~ WARN struct is never used
-   |         ^^^^^^
+   |              ^
 ...
 22 |     m!(S struct);
    |     ------------- in this macro invocation
diff --git a/src/test/ui/static-lifetime.stderr b/src/test/ui/static-lifetime.stderr
index a99dbf21e54..24ba27b27ad 100644
--- a/src/test/ui/static-lifetime.stderr
+++ b/src/test/ui/static-lifetime.stderr
@@ -8,7 +8,7 @@ note: lifetime parameter instantiated with the lifetime 'a as defined on the imp
   --> $DIR/static-lifetime.rs:13:1
    |
 13 | impl<'a, A: Clone> Arbitrary for ::std::borrow::Cow<'a, A> {} //~ ERROR lifetime bound
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    = note: but lifetime parameter must outlive the static lifetime
 
 error: aborting due to previous error
diff --git a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr
index d2ac15f7ffc..01dba62a851 100644
--- a/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr
+++ b/src/test/ui/suggestions/issue-45799-bad-extern-crate-rename-suggestion-formatting.stderr
@@ -7,7 +7,7 @@ error[E0259]: the name `std` is defined multiple times
    = note: `std` must be defined only once in the type namespace of this module
 help: You can use `as` to change the binding name of the import
    |
-11 | extern crate std as Otherstd;
+11 | extern crate std as other_std;
    |
 
 error: aborting due to previous error
diff --git a/src/test/ui/use-mod.stderr b/src/test/ui/use-mod.stderr
index bb64909e64a..1c9f306f493 100644
--- a/src/test/ui/use-mod.stderr
+++ b/src/test/ui/use-mod.stderr
@@ -25,7 +25,7 @@ error[E0252]: the name `bar` is defined multiple times
    = note: `bar` must be defined only once in the type namespace of this module
 help: You can use `as` to change the binding name of the import
    |
-15 |     self as Otherbar
+15 |     self as other_bar
    |
 
 error: aborting due to 3 previous errors
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index ff662736bdd..80750f9a3fe 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -167,7 +167,7 @@ impl EarlyProps {
                         .expect("Malformed llvm version directive");
                     // Ignore if using system LLVM and actual version
                     // is smaller the minimum required version
-                    !(config.system_llvm && &actual_version[..] < min_version)
+                    config.system_llvm && &actual_version[..] < min_version
                 } else {
                     false
                 }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index abf62a060b8..46df211cbaf 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -79,7 +79,7 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
     let mut results = Vec::new();
     let mut mismatch = Mismatch::new(0);
 
-    for result in diff::lines(actual, expected) {
+    for result in diff::lines(expected, actual) {
         match result {
             diff::Result::Left(str) => {
                 if lines_since_mismatch >= context_size && lines_since_mismatch > 0 {
@@ -91,7 +91,8 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
                     mismatch.lines.push(DiffLine::Context(line.to_owned()));
                 }
 
-                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
+                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
+                line_number += 1;
                 lines_since_mismatch = 0;
             }
             diff::Result::Right(str) => {
@@ -104,8 +105,7 @@ pub fn make_diff(expected: &str, actual: &str, context_size: usize) -> Vec<Misma
                     mismatch.lines.push(DiffLine::Context(line.to_owned()));
                 }
 
-                mismatch.lines.push(DiffLine::Expected(str.to_owned()));
-                line_number += 1;
+                mismatch.lines.push(DiffLine::Resulting(str.to_owned()));
                 lines_since_mismatch = 0;
             }
             diff::Result::Both(str, _) => {
diff --git a/src/tools/rls b/src/tools/rls
-Subproject 511321ae1c2fa3f0e334885fecf406dd6c88283
+Subproject dee42bda8156a28ead609080e27b02173bb9c29
diff --git a/src/tools/rustfmt b/src/tools/rustfmt
-Subproject e0e3e22248cd14ebbe0253e9720261a0328bfc5
+Subproject 346238f49740d6c98102a6a59811b1625c73a9d