about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/Cargo.lock98
-rw-r--r--src/bootstrap/bin/rustc.rs4
-rw-r--r--src/bootstrap/check.rs5
-rw-r--r--src/bootstrap/doc.rs3
-rw-r--r--src/bootstrap/test.rs57
-rw-r--r--src/bootstrap/tool.rs65
-rw-r--r--src/build_helper/lib.rs2
-rw-r--r--src/ci/docker/dist-various-2/Dockerfile16
-rwxr-xr-xsrc/ci/docker/dist-various-2/build-fuchsia-toolchain.sh10
m---------src/doc/reference0
-rw-r--r--src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md45
-rw-r--r--src/liballoc/lib.rs1
-rw-r--r--src/liballoc/tests/arc.rs6
-rw-r--r--src/liballoc/tests/btree/set.rs2
-rw-r--r--src/liballoc/tests/lib.rs3
-rw-r--r--src/liballoc/tests/rc.rs6
-rw-r--r--src/liballoc/tests/slice.rs11
-rw-r--r--src/liballoc_jemalloc/lib.rs1
-rw-r--r--src/liballoc_system/lib.rs1
-rw-r--r--src/libarena/lib.rs1
-rw-r--r--src/libcore/any.rs16
-rw-r--r--src/libcore/cell.rs6
-rw-r--r--src/libcore/fmt/builders.rs14
-rw-r--r--src/libcore/fmt/mod.rs10
-rw-r--r--src/libcore/iter/iterator.rs2
-rw-r--r--src/libcore/manually_drop_stage0.rs195
-rw-r--r--src/libcore/mem.rs108
-rw-r--r--src/libcore/panic.rs10
-rw-r--r--src/libcore/ptr.rs4
-rw-r--r--src/libcore/slice/memchr.rs17
-rw-r--r--src/libcore/task/context.rs6
-rw-r--r--src/libcore/task/wake.rs8
-rw-r--r--src/libcore/tests/any.rs16
-rw-r--r--src/libcore/tests/hash/mod.rs2
-rw-r--r--src/libcore/tests/intrinsics.rs2
-rw-r--r--src/libcore/tests/lib.rs1
-rw-r--r--src/libcore/tests/manually_drop.rs24
-rw-r--r--src/libcore/tests/mem.rs4
-rw-r--r--src/libcore/tests/option.rs2
-rw-r--r--src/libcore/tests/ptr.rs20
-rw-r--r--src/libcore/tests/result.rs2
-rw-r--r--src/libfmt_macros/lib.rs2
-rw-r--r--src/libgraphviz/lib.rs2
-rw-r--r--src/libpanic_abort/lib.rs1
-rw-r--r--src/libpanic_unwind/lib.rs1
-rw-r--r--src/libproc_macro/lib.rs1
-rw-r--r--src/libprofiler_builtins/lib.rs1
-rw-r--r--src/librustc/hir/lowering.rs4
-rw-r--r--src/librustc/hir/map/hir_id_validator.rs2
-rw-r--r--src/librustc/ich/hcx.rs2
-rw-r--r--src/librustc/ich/impls_syntax.rs1
-rw-r--r--src/librustc/infer/anon_types/mod.rs52
-rw-r--r--src/librustc/infer/error_reporting/need_type_info.rs2
-rw-r--r--src/librustc/infer/outlives/obligations.rs6
-rw-r--r--src/librustc/lib.rs2
-rw-r--r--src/librustc/lint/context.rs2
-rw-r--r--src/librustc/middle/borrowck.rs8
-rw-r--r--src/librustc/middle/lang_items.rs2
-rw-r--r--src/librustc/session/config.rs25
-rw-r--r--src/librustc/session/mod.rs3
-rw-r--r--src/librustc/traits/coherence.rs2
-rw-r--r--src/librustc/traits/error_reporting.rs4
-rw-r--r--src/librustc/traits/object_safety.rs11
-rw-r--r--src/librustc/traits/project.rs13
-rw-r--r--src/librustc/traits/query/dropck_outlives.rs5
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs115
-rw-r--r--src/librustc/ty/context.rs60
-rw-r--r--src/librustc/ty/util.rs6
-rw-r--r--src/librustc/util/ppaux.rs40
-rw-r--r--src/librustc_allocator/lib.rs1
-rw-r--r--src/librustc_apfloat/lib.rs2
-rw-r--r--src/librustc_asan/lib.rs2
-rw-r--r--src/librustc_borrowck/borrowck/check_loans.rs13
-rw-r--r--src/librustc_borrowck/borrowck/gather_loans/move_error.rs5
-rw-r--r--src/librustc_borrowck/borrowck/mod.rs28
-rw-r--r--src/librustc_borrowck/lib.rs1
-rw-r--r--src/librustc_codegen_llvm/back/link.rs5
-rw-r--r--src/librustc_codegen_llvm/lib.rs1
-rw-r--r--src/librustc_codegen_utils/lib.rs1
-rw-r--r--src/librustc_data_structures/lib.rs2
-rw-r--r--src/librustc_driver/driver.rs14
-rw-r--r--src/librustc_driver/lib.rs2
-rw-r--r--src/librustc_driver/profile/mod.rs2
-rw-r--r--src/librustc_driver/profile/trace.rs8
-rw-r--r--src/librustc_errors/diagnostic.rs19
-rw-r--r--src/librustc_errors/diagnostic_builder.rs19
-rw-r--r--src/librustc_errors/emitter.rs10
-rw-r--r--src/librustc_errors/lib.rs2
-rw-r--r--src/librustc_incremental/lib.rs2
-rw-r--r--src/librustc_lint/lib.rs2
-rw-r--r--src/librustc_llvm/lib.rs1
-rw-r--r--src/librustc_lsan/lib.rs2
-rw-r--r--src/librustc_metadata/dynamic_lib.rs25
-rw-r--r--src/librustc_metadata/lib.rs2
-rw-r--r--src/librustc_mir/borrow_check/borrow_set.rs13
-rw-r--r--src/librustc_mir/borrow_check/mod.rs83
-rw-r--r--src/librustc_mir/borrow_check/move_errors.rs43
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs9
-rw-r--r--src/librustc_mir/borrow_check/nll/facts.rs2
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs142
-rw-r--r--src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs81
-rw-r--r--src/librustc_mir/build/block.rs9
-rw-r--r--src/librustc_mir/build/expr/as_place.rs15
-rw-r--r--src/librustc_mir/build/matches/mod.rs70
-rw-r--r--src/librustc_mir/build/matches/test.rs2
-rw-r--r--src/librustc_mir/build/mod.rs43
-rw-r--r--src/librustc_mir/interpret/terminator/drop.rs2
-rw-r--r--src/librustc_mir/lib.rs2
-rw-r--r--src/librustc_mir/transform/elaborate_drops.rs15
-rw-r--r--src/librustc_mir/transform/uniform_array_move_out.rs2
-rw-r--r--src/librustc_mir/util/elaborate_drops.rs4
-rw-r--r--src/librustc_msan/lib.rs2
-rw-r--r--src/librustc_passes/ast_validation.rs2
-rw-r--r--src/librustc_passes/lib.rs2
-rw-r--r--src/librustc_platform_intrinsics/lib.rs1
-rw-r--r--src/librustc_plugin/lib.rs2
-rw-r--r--src/librustc_privacy/lib.rs2
-rw-r--r--src/librustc_resolve/lib.rs2
-rw-r--r--src/librustc_resolve/macros.rs2
-rw-r--r--src/librustc_save_analysis/lib.rs1
-rw-r--r--src/librustc_target/lib.rs2
-rw-r--r--src/librustc_target/spec/aarch64_fuchsia.rs (renamed from src/librustc_target/spec/aarch64_unknown_fuchsia.rs)4
-rw-r--r--src/librustc_target/spec/fuchsia_base.rs2
-rw-r--r--src/librustc_target/spec/mod.rs4
-rw-r--r--src/librustc_target/spec/x86_64_fuchsia.rs (renamed from src/librustc_target/spec/x86_64_unknown_fuchsia.rs)4
-rw-r--r--src/librustc_traits/lib.rs2
-rw-r--r--src/librustc_tsan/lib.rs2
-rw-r--r--src/librustc_typeck/check/compare_method.rs11
-rw-r--r--src/librustc_typeck/check/wfcheck.rs3
-rw-r--r--src/librustc_typeck/collect.rs28
-rw-r--r--src/librustc_typeck/lib.rs1
-rw-r--r--src/librustc_typeck/outlives/utils.rs31
-rw-r--r--src/librustdoc/clean/auto_trait.rs171
-rw-r--r--src/librustdoc/clean/inline.rs2
-rw-r--r--src/librustdoc/clean/mod.rs5
-rw-r--r--src/librustdoc/core.rs6
-rw-r--r--src/librustdoc/html/format.rs6
-rw-r--r--src/librustdoc/html/highlight.rs4
-rw-r--r--src/librustdoc/html/layout.rs4
-rw-r--r--src/librustdoc/html/render.rs103
-rw-r--r--src/librustdoc/lib.rs49
-rw-r--r--src/librustdoc/passes/mod.rs27
-rw-r--r--src/librustdoc/test.rs2
-rw-r--r--src/libserialize/lib.rs2
-rw-r--r--src/libstd/error.rs90
-rw-r--r--src/libstd/ffi/c_str.rs2
-rw-r--r--src/libstd/io/error.rs14
-rw-r--r--src/libstd/io/mod.rs4
-rw-r--r--src/libstd/io/stdio.rs8
-rw-r--r--src/libstd/io/util.rs2
-rw-r--r--src/libstd/net/parser.rs2
-rw-r--r--src/libstd/net/tcp.rs2
-rw-r--r--src/libstd/net/udp.rs2
-rw-r--r--src/libstd/panic.rs2
-rw-r--r--src/libstd/panicking.rs36
-rw-r--r--src/libstd/process.rs4
-rw-r--r--src/libstd/rt.rs2
-rw-r--r--src/libstd/sync/mpsc/mod.rs10
-rw-r--r--src/libstd/sync/mpsc/select.rs2
-rw-r--r--src/libstd/sync/once.rs2
-rw-r--r--src/libstd/sys/cloudabi/thread.rs2
-rw-r--r--src/libstd/sys/redox/process.rs4
-rw-r--r--src/libstd/sys/redox/thread.rs2
-rw-r--r--src/libstd/sys/unix/process/process_common.rs6
-rw-r--r--src/libstd/sys/unix/thread.rs2
-rw-r--r--src/libstd/sys/wasm/thread.rs2
-rw-r--r--src/libstd/sys/windows/thread.rs2
-rw-r--r--src/libstd/sys_common/at_exit_imp.rs4
-rw-r--r--src/libstd/sys_common/backtrace.rs10
-rw-r--r--src/libstd/sys_common/poison.rs2
-rw-r--r--src/libstd/sys_common/thread.rs2
-rw-r--r--src/libstd/thread/mod.rs15
-rw-r--r--src/libsyntax/attr/mod.rs34
-rw-r--r--src/libsyntax/feature_gate.rs9
-rw-r--r--src/libsyntax/lib.rs2
-rw-r--r--src/libsyntax/parse/parser.rs36
-rw-r--r--src/libsyntax/print/pprust.rs2
-rw-r--r--src/libsyntax_ext/lib.rs2
-rw-r--r--src/libsyntax_pos/lib.rs16
-rw-r--r--src/libterm/lib.rs4
-rw-r--r--src/libterm/terminfo/mod.rs2
-rw-r--r--src/libterm/terminfo/parser/compiled.rs6
-rw-r--r--src/libtest/lib.rs2
-rw-r--r--src/libunwind/lib.rs2
-rw-r--r--src/stage0.txt2
-rw-r--r--src/test/compile-fail/specialization/issue-52050.rs42
-rw-r--r--src/test/run-pass/z-crate-attr.rs21
-rw-r--r--src/test/rustdoc/generic-impl.rs25
-rw-r--r--src/test/rustdoc/manual_impl.rs1
-rw-r--r--src/test/rustdoc/sidebar-items.rs8
-rw-r--r--src/test/ui/bad-crate-name.rs15
-rw-r--r--src/test/ui/bad-crate-name.stderr19
-rw-r--r--src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs40
-rw-r--r--src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr9
-rw-r--r--src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr24
-rw-r--r--src/test/ui/borrowck/borrowck-migrate-to-nll.rs41
-rw-r--r--src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr24
-rw-r--r--src/test/ui/borrowck/issue-41962.stderr24
-rw-r--r--src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs33
-rw-r--r--src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr4
-rw-r--r--src/test/ui/feature-gate-infer_static_outlives_requirements.rs22
-rw-r--r--src/test/ui/feature-gate-infer_static_outlives_requirements.stderr17
-rw-r--r--src/test/ui/generator/generator-with-nll.rs8
-rw-r--r--src/test/ui/generator/generator-with-nll.stderr28
-rw-r--r--src/test/ui/impl-trait/associated-existential-type-generic-trait.rs40
-rw-r--r--src/test/ui/impl-trait/associated-existential-type-trivial.rs30
-rw-r--r--src/test/ui/impl-trait/associated-existential-type.rs34
-rw-r--r--src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr12
-rw-r--r--src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr6
-rw-r--r--src/test/ui/issue-10291.nll.stderr2
-rw-r--r--src/test/ui/issue-13033.stderr4
-rw-r--r--src/test/ui/issue-16683.nll.stderr6
-rw-r--r--src/test/ui/issue-17385.nll.stderr52
-rw-r--r--src/test/ui/issue-17758.nll.stderr6
-rw-r--r--src/test/ui/issue-20801.nll.stderr20
-rw-r--r--src/test/ui/issue-27282-move-match-input-into-guard.stderr23
-rw-r--r--src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr28
-rw-r--r--src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr29
-rw-r--r--src/test/ui/issue-40510-1.nll.stderr2
-rw-r--r--src/test/ui/issue-40510-3.nll.stderr2
-rw-r--r--src/test/ui/issue-47412.stderr8
-rw-r--r--src/test/ui/issue-52213.nll.stderr2
-rw-r--r--src/test/ui/issue-52533-1.nll.stderr17
-rw-r--r--src/test/ui/issue-52533-1.rs (renamed from src/liballoc/repeat-generic-slice.rs)14
-rw-r--r--src/test/ui/issue-52533-1.stderr22
-rw-r--r--src/test/ui/issue-52533.nll.stderr17
-rw-r--r--src/test/ui/issue-52533.rs17
-rw-r--r--src/test/ui/issue-52533.stderr20
-rw-r--r--src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr16
-rw-r--r--src/test/ui/mismatched_types/E0053.stderr4
-rw-r--r--src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr4
-rw-r--r--src/test/ui/nll/borrowed-match-issue-45045.stderr21
-rw-r--r--src/test/ui/nll/cannot-move-block-spans.nll.stderr85
-rw-r--r--src/test/ui/nll/cannot-move-block-spans.rs32
-rw-r--r--src/test/ui/nll/cannot-move-block-spans.stderr58
-rw-r--r--src/test/ui/nll/closure-requirements/escape-argument-callee.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr6
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr4
-rw-r--r--src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr2
-rw-r--r--src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr6
-rw-r--r--src/test/ui/nll/issue-50716.stderr6
-rw-r--r--src/test/ui/nll/mir_check_cast_reify.stderr6
-rw-r--r--src/test/ui/nll/mir_check_cast_unsafe_fn.stderr6
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs29
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr17
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/infer-static.rs24
-rw-r--r--src/test/ui/rfc-2093-infer-outlives/infer-static.stderr12
-rw-r--r--src/test/ui/span/issue-40157.nll.stderr10
-rw-r--r--src/tools/build-manifest/src/main.rs4
m---------src/tools/cargo0
-rw-r--r--src/tools/compiletest/Cargo.toml2
-rw-r--r--src/tools/compiletest/src/header.rs11
-rw-r--r--src/tools/compiletest/src/read2.rs6
-rw-r--r--src/tools/compiletest/src/runtest.rs8
-rw-r--r--src/tools/error_index_generator/main.rs36
-rw-r--r--src/tools/remote-test-client/src/main.rs4
-rw-r--r--src/tools/remote-test-server/src/main.rs4
-rw-r--r--src/tools/tidy/src/deps.rs1
-rw-r--r--src/tools/tidy/src/features.rs2
-rw-r--r--src/tools/tidy/src/lib.rs4
264 files changed, 2820 insertions, 1193 deletions
diff --git a/src/Cargo.lock b/src/Cargo.lock
index 09baaeadaee..747d72e604e 100644
--- a/src/Cargo.lock
+++ b/src/Cargo.lock
@@ -87,7 +87,7 @@ dependencies = [
 
 [[package]]
 name = "atty"
-version = "0.2.10"
+version = "0.2.11"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -187,20 +187,20 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "cargo"
 version = "0.30.0"
 dependencies = [
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bufstream 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "clap 2.32.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "core-foundation 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "crates-io 0.18.0",
  "crossbeam 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "env_logger 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "filetime 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "flate2 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "fs2 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "hex 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -210,12 +210,12 @@ dependencies = [
  "lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libgit2-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "num_cpus 1.8.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustfix 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "semver 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -225,7 +225,7 @@ dependencies = [
  "shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
  "tar 0.4.16 (registry+https://github.com/rust-lang/crates.io-index)",
  "tempfile 3.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "termcolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "toml 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "unicode-width 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -303,7 +303,7 @@ version = "2.32.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "strsim 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -410,7 +410,7 @@ dependencies = [
  "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "miow 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "rustfix 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -464,7 +464,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 name = "crates-io"
 version = "0.18.0"
 dependencies = [
- "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
  "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -521,10 +521,10 @@ dependencies = [
 
 [[package]]
 name = "curl"
-version = "0.4.12"
+version = "0.4.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "curl-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -536,7 +536,7 @@ dependencies = [
 
 [[package]]
 name = "curl-sys"
-version = "0.4.6"
+version = "0.4.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -622,7 +622,7 @@ name = "env_logger"
 version = "0.5.10"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "humantime 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "regex 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -787,12 +787,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "git2"
-version = "0.7.2"
+version = "0.7.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "bitflags 1.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
- "libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "libgit2-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-probe 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "openssl-sys 0.9.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -804,8 +804,8 @@ name = "git2-curl"
 version = "0.8.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)",
- "git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)",
+ "git2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "url 1.7.1 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
@@ -1050,12 +1050,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "libgit2-sys"
-version = "0.7.5"
+version = "0.7.6"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "cc 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
  "cmake 0.1.31 (registry+https://github.com/rust-lang/crates.io-index)",
- "curl-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "curl-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)",
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "libssh2-sys 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
  "libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1383,7 +1383,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)",
  "rand 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)",
  "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
@@ -1844,7 +1844,7 @@ name = "rustc-ap-rustc_errors"
 version = "182.0.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-rustc_data_structures 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-serialize 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc-ap-syntax_pos 182.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2097,7 +2097,7 @@ dependencies = [
 name = "rustc_errors"
 version = "0.0.0"
 dependencies = [
- "atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
+ "atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
  "rustc_data_structures 0.0.0",
  "serialize 0.0.0",
  "syntax_pos 0.0.0",
@@ -2354,19 +2354,7 @@ dependencies = [
 
 [[package]]
 name = "rustfix"
-version = "0.3.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.70 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_json 1.0.24 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "rustfix"
-version = "0.4.0"
+version = "0.4.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 dependencies = [
  "failure 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2497,8 +2485,11 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 
 [[package]]
 name = "smallvec"
-version = "0.6.2"
+version = "0.6.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "unreachable 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
 
 [[package]]
 name = "socket2"
@@ -2785,6 +2776,14 @@ dependencies = [
 ]
 
 [[package]]
+name = "termcolor"
+version = "1.0.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "wincolor 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "termion"
 version = "1.5.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3026,6 +3025,14 @@ dependencies = [
 ]
 
 [[package]]
+name = "wincolor"
+version = "1.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+dependencies = [
+ "winapi 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)",
+]
+
+[[package]]
 name = "workspace_symbol"
 version = "0.1.0"
 
@@ -3056,7 +3063,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum ansi_term 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ee49baf6cb617b853aa8d93bf420db2383fab46d314482ca2803b40d5fde979b"
 "checksum arrayvec 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "a1e964f9e24d588183fcb43503abda40d288c8657dfc27311516ce2f05675aef"
 "checksum assert_cli 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "98589b0e465a6c510d95fceebd365bb79bedece7f6e18a480897f2015f85ec51"
-"checksum atty 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)" = "2fc4a1aa4c24c0718a250f0681885c1af91419d242f29eb8f2ab28502d80dbd1"
+"checksum atty 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
 "checksum backtrace 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
 "checksum backtrace-sys 0.1.23 (registry+https://github.com/rust-lang/crates.io-index)" = "bff67d0c06556c0b8e6b5f090f0eac52d950d9dfd1d35ba04e4ca3543eaf6a7e"
 "checksum bitflags 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "aad18937a628ec6abcd26d1489012cc0e18c21798210f491af69ded9b881106d"
@@ -3084,8 +3091,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum crossbeam-epoch 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "927121f5407de9956180ff5e936fe3cf4324279280001cd56b669d28ee7e9150"
 "checksum crossbeam-utils 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "2760899e32a1d58d5abb31129f8fae5de75220bc2176e77ff7c627ae45c918d9"
 "checksum crypto-hash 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "09de9ee0fc255ace04c7fa0763c9395a945c37c8292bb554f8d48361d1dcf1b4"
-"checksum curl 0.4.12 (registry+https://github.com/rust-lang/crates.io-index)" = "aaf20bbe084f285f215eef2165feed70d6b75ba29cad24469badb853a4a287d0"
-"checksum curl-sys 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "db735aaa19154d8d4ba28e4a3546e90f13a14016a7a8ac10c799bae6929c00a4"
+"checksum curl 0.4.13 (registry+https://github.com/rust-lang/crates.io-index)" = "893713db705eab9847e050268507b0e2a2aad64e90a831874bd4e8e0d67f9523"
+"checksum curl-sys 0.4.7 (registry+https://github.com/rust-lang/crates.io-index)" = "de9cf174efdf90b5887c4e2e900769373c89c5e18152e8f3ed75b501a6f1c0fb"
 "checksum datafrog 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "16d724bf4ffe77cdceeecd461009b5f8d9e23c5d645d68bedb4586bf43e7e142"
 "checksum derive-new 0.5.4 (registry+https://github.com/rust-lang/crates.io-index)" = "ceed73957c449214f8440eec8ad7fa282b67dc9eacbb24a3085b15d60397a17a"
 "checksum diff 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)" = "3c2b69f912779fbb121ceb775d74d51e915af17aaebc38d28a592843a2dd0a3a"
@@ -3113,7 +3120,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum futf 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "7c9c1ce3fa9336301af935ab852c437817d14cd33690446569392e65170aac3b"
 "checksum futures 0.1.21 (registry+https://github.com/rust-lang/crates.io-index)" = "1a70b146671de62ec8c8ed572219ca5d594d9b06c0b364d5e67b722fc559b48c"
 "checksum getopts 0.2.17 (registry+https://github.com/rust-lang/crates.io-index)" = "b900c08c1939860ce8b54dc6a89e26e00c04c380fd0e09796799bd7f12861e05"
-"checksum git2 0.7.2 (registry+https://github.com/rust-lang/crates.io-index)" = "910a2df52d2354e4eb27aa12f3803ea86bf461a93e17028908ec0e356572aa7b"
+"checksum git2 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "0b87cffac882c99f9654ca5eb4c6c61527b47bc1e113304f8c57333567cd31f2"
 "checksum git2-curl 0.8.1 (registry+https://github.com/rust-lang/crates.io-index)" = "b502f6b1b467957403d168f0039e0c46fa6a1220efa2adaef25d5b267b5fe024"
 "checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
 "checksum globset 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "142754da2c9b3722affd909f9e27f2a6700a7a303f362971e0a74c652005a43d"
@@ -3138,7 +3145,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum lazy_static 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "fb497c35d362b6a331cfd94956a07fc2c78a4604cdbee844a81170386b996dd3"
 "checksum lazycell 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d33a48d0365c96081958cc663eef834975cb1e8d8bea3378513fc72bdbf11e50"
 "checksum libc 0.2.42 (registry+https://github.com/rust-lang/crates.io-index)" = "b685088df2b950fccadf07a7187c8ef846a959c142338a48f9dc0b94517eb5f1"
-"checksum libgit2-sys 0.7.5 (registry+https://github.com/rust-lang/crates.io-index)" = "9dcce5a1ecca1891ab06c1545a422fd4b35f65c19acec51ea638c66d5be0810d"
+"checksum libgit2-sys 0.7.6 (registry+https://github.com/rust-lang/crates.io-index)" = "c9051a4b288ba6f8728e9e52bb2510816946b8bcb2e20259e4d4cdc93b9ecafd"
 "checksum libssh2-sys 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c628b499e8d1a4f4bd09a95d6cb1f8aeb231b46a9d40959bbd0408f14dd63adf"
 "checksum libz-sys 1.0.18 (registry+https://github.com/rust-lang/crates.io-index)" = "87f737ad6cc6fd6eefe3d9dc5412f1573865bded441300904d2f42269e140f16"
 "checksum log 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "e19e8d5c34a3e0e2223db8e060f9e8264aeeb5c5fc64a4ee9965c062211c024b"
@@ -3222,8 +3229,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "40f06724db71e18d68b3b946fdf890ca8c921d9edccc1404fdfdb537b0d12649"
 "checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
 "checksum rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "a54aa04a10c68c1c4eacb4337fd883b435997ede17a9385784b990777686b09a"
-"checksum rustfix 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9da3cf9b79dc889a2c9879643f26d7a53e37e9361c7566b7d2787d5ace0d8396"
-"checksum rustfix 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "6e2613df31a403754605dba168ded93d529a2b88c5a63b78cf2421bb5d62c936"
+"checksum rustfix 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "86f77b09d42bae4adfbcd105a8914e2d9fb46b63612c1a765b824a2b4a4bb814"
 "checksum same-file 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cfb6eded0b06a0b512c8ddbcf04089138c9b4362c2f696f3c3d76039d68f3637"
 "checksum schannel 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "dc1fabf2a7b6483a141426e1afd09ad543520a77ac49bd03c286e7696ccfd77f"
 "checksum scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "332ffa32bf586782a3efaeb58f127980944bbc8c4d6913a86107ac2a5ab24b28"
@@ -3237,7 +3243,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum shell-escape 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "170a13e64f2a51b77a45702ba77287f5c6829375b04a69cf2222acd17d0cfab9"
 "checksum shlex 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "7fdf1b9db47230893d76faad238fd6097fd6d6a9245cd7a4d90dbd639536bbd2"
 "checksum siphasher 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "0df90a788073e8d0235a67e50441d47db7c8ad9debd91cbf43736a2a92d36537"
-"checksum smallvec 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "312a7df010092e73d6bbaf141957e868d4f30efd2bfd9bb1028ad91abec58514"
+"checksum smallvec 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "26df3bb03ca5eac2e64192b723d51f56c1b1e0860e7c766281f4598f181acdc8"
 "checksum socket2 0.3.7 (registry+https://github.com/rust-lang/crates.io-index)" = "962a516af4d3a7c272cb3a1d50a8cc4e5b41802e4ad54cfb7bee8ba61d37d703"
 "checksum stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ffbc596e092fe5f598b12ef46cc03754085ac2f4d8c739ad61c4ae266cc3b3fa"
 "checksum string_cache 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "25d70109977172b127fe834e5449e5ab1740b9ba49fa18a2020f509174f25423"
@@ -3260,6 +3266,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum term 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "fa63644f74ce96fbeb9b794f66aff2a52d601cbd5e80f4b97123e3899f4570f1"
 "checksum term 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "5e6b677dd1e8214ea1ef4297f85dbcbed8e8cdddb561040cc998ca2551c37561"
 "checksum termcolor 0.3.6 (registry+https://github.com/rust-lang/crates.io-index)" = "adc4587ead41bf016f11af03e55a624c06568b5a19db4e90fde573d805074f83"
+"checksum termcolor 1.0.1 (registry+https://github.com/rust-lang/crates.io-index)" = "722426c4a0539da2c4ffd9b419d90ad540b4cff4a053be9069c908d4d07e2836"
 "checksum termion 1.5.1 (registry+https://github.com/rust-lang/crates.io-index)" = "689a3bdfaab439fd92bc87df5c4c78417d3cbe537487274e9b0b2dce76e92096"
 "checksum textwrap 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "307686869c93e71f94da64286f9a9524c0f308a9e1c87a583de8e9c9039ad3f6"
 "checksum thread_local 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "279ef31c19ededf577bfd12dfae728040a21f635b06a24cd670ff510edd38963"
@@ -3290,6 +3297,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum winapi-i686-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
 "checksum winapi-x86_64-pc-windows-gnu 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"
 "checksum wincolor 0.1.6 (registry+https://github.com/rust-lang/crates.io-index)" = "eeb06499a3a4d44302791052df005d5232b927ed1a9658146d842165c4de7767"
+"checksum wincolor 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b9dc3aa9dcda98b5a16150c54619c1ead22e3d3a5d458778ae914be760aa981a"
 "checksum xattr 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "244c3741f4240ef46274860397c7c74e50eb23624996930e484c16679633a54c"
 "checksum xz2 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "df8bf41d3030c3577c9458fd6640a05afbf43b150d0b531b16bd77d3f794f27a"
 "checksum yaml-rust 0.3.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e66366e18dc58b46801afbf2ca7661a9f59cc8c5962c29892b6039b4f86fa992"
diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs
index f2b2f6f1eeb..7192cae8956 100644
--- a/src/bootstrap/bin/rustc.rs
+++ b/src/bootstrap/bin/rustc.rs
@@ -296,8 +296,10 @@ fn main() {
         cmd.arg("--color=always");
     }
 
-    if env::var_os("RUSTC_DENY_WARNINGS").is_some() {
+    if env::var_os("RUSTC_DENY_WARNINGS").is_some() && env::var_os("RUSTC_EXTERNAL_TOOL").is_none()
+    {
         cmd.arg("-Dwarnings");
+        cmd.arg("-Dbare_trait_objects");
     }
 
     if verbose > 1 {
diff --git a/src/bootstrap/check.rs b/src/bootstrap/check.rs
index 39c5c832831..8838cdeed86 100644
--- a/src/bootstrap/check.rs
+++ b/src/bootstrap/check.rs
@@ -12,7 +12,7 @@
 
 use compile::{run_cargo, std_cargo, test_cargo, rustc_cargo, rustc_cargo_env, add_to_sysroot};
 use builder::{RunConfig, Builder, ShouldRun, Step};
-use tool::{self, prepare_tool_cargo};
+use tool::{self, prepare_tool_cargo, SourceType};
 use {Compiler, Mode};
 use cache::{INTERNER, Interned};
 use std::path::PathBuf;
@@ -222,7 +222,8 @@ impl Step for Rustdoc {
                                            Mode::ToolRustc,
                                            target,
                                            "check",
-                                           "src/tools/rustdoc");
+                                           "src/tools/rustdoc",
+                                           SourceType::InTree);
 
         let _folder = builder.fold_output(|| format!("stage{}-rustdoc", compiler.stage));
         println!("Checking rustdoc artifacts ({} -> {})", &compiler.host, target);
diff --git a/src/bootstrap/doc.rs b/src/bootstrap/doc.rs
index f71cb119b77..fd3730ffc78 100644
--- a/src/bootstrap/doc.rs
+++ b/src/bootstrap/doc.rs
@@ -28,7 +28,7 @@ use build_helper::up_to_date;
 
 use util::symlink_dir;
 use builder::{Builder, Compiler, RunConfig, ShouldRun, Step};
-use tool::{self, prepare_tool_cargo, Tool};
+use tool::{self, prepare_tool_cargo, Tool, SourceType};
 use compile;
 use cache::{INTERNER, Interned};
 use config::Config;
@@ -814,6 +814,7 @@ impl Step for Rustdoc {
             target,
             "doc",
             "src/tools/rustdoc",
+            SourceType::InTree,
         );
 
         cargo.env("RUSTDOCFLAGS", "--document-private-items");
diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs
index 639c96bc208..7c69197885c 100644
--- a/src/bootstrap/test.rs
+++ b/src/bootstrap/test.rs
@@ -30,7 +30,7 @@ use compile;
 use dist;
 use flags::Subcommand;
 use native;
-use tool::{self, Tool};
+use tool::{self, Tool, SourceType};
 use toolstate::ToolState;
 use util::{self, dylib_path, dylib_path_var};
 use Crate as CargoCrate;
@@ -222,17 +222,18 @@ impl Step for Cargo {
             compiler,
             target: self.host,
         });
-        let mut cargo = builder.cargo(compiler, Mode::ToolRustc, self.host, "test");
-        cargo
-            .arg("--manifest-path")
-            .arg(builder.src.join("src/tools/cargo/Cargo.toml"));
+        let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 self.host,
+                                                 "test",
+                                                 "src/tools/cargo",
+                                                 SourceType::Submodule);
+
         if !builder.fail_fast {
             cargo.arg("--no-fail-fast");
         }
 
-        // Don't build tests dynamically, just a pain to work with
-        cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
-
         // Don't run cross-compile tests, we may not have cross-compiled libstd libs
         // available.
         cargo.env("CFG_DISABLE_CROSS_TESTS", "1");
@@ -286,10 +287,8 @@ impl Step for Rls {
                                                  Mode::ToolRustc,
                                                  host,
                                                  "test",
-                                                 "src/tools/rls");
-
-        // Don't build tests dynamically, just a pain to work with
-        cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
+                                                 "src/tools/rls",
+                                                 SourceType::Submodule);
 
         builder.add_rustc_lib_path(compiler, &mut cargo);
 
@@ -341,10 +340,9 @@ impl Step for Rustfmt {
                                                  Mode::ToolRustc,
                                                  host,
                                                  "test",
-                                                 "src/tools/rustfmt");
+                                                 "src/tools/rustfmt",
+                                                 SourceType::Submodule);
 
-        // Don't build tests dynamically, just a pain to work with
-        cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
         let dir = testdir(builder, compiler.host);
         t!(fs::create_dir_all(&dir));
         cargo.env("RUSTFMT_TEST_DIR", dir);
@@ -392,13 +390,14 @@ impl Step for Miri {
             extra_features: Vec::new(),
         });
         if let Some(miri) = miri {
-            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
-            cargo
-                .arg("--manifest-path")
-                .arg(builder.src.join("src/tools/miri/Cargo.toml"));
+            let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/miri",
+                                                 SourceType::Submodule);
 
-            // Don't build tests dynamically, just a pain to work with
-            cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
             // miri tests need to know about the stage sysroot
             cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
             cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
@@ -450,13 +449,14 @@ impl Step for Clippy {
             extra_features: Vec::new(),
         });
         if let Some(clippy) = clippy {
-            let mut cargo = builder.cargo(compiler, Mode::ToolRustc, host, "test");
-            cargo
-                .arg("--manifest-path")
-                .arg(builder.src.join("src/tools/clippy/Cargo.toml"));
+            let mut cargo = tool::prepare_tool_cargo(builder,
+                                                 compiler,
+                                                 Mode::ToolRustc,
+                                                 host,
+                                                 "test",
+                                                 "src/tools/clippy",
+                                                 SourceType::Submodule);
 
-            // Don't build tests dynamically, just a pain to work with
-            cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
             // clippy tests need to know about the stage sysroot
             cargo.env("SYSROOT", builder.sysroot(compiler));
             cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
@@ -1739,7 +1739,8 @@ impl Step for CrateRustdoc {
                                                  Mode::ToolRustc,
                                                  target,
                                                  test_kind.subcommand(),
-                                                 "src/tools/rustdoc");
+                                                 "src/tools/rustdoc",
+                                                 SourceType::InTree);
         if test_kind.subcommand() == "test" && !builder.fail_fast {
             cargo.arg("--no-fail-fast");
         }
diff --git a/src/bootstrap/tool.rs b/src/bootstrap/tool.rs
index 0969e5abe07..5e68b797b3d 100644
--- a/src/bootstrap/tool.rs
+++ b/src/bootstrap/tool.rs
@@ -76,13 +76,20 @@ impl Step for CleanTools {
 }
 
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
+pub enum SourceType {
+    InTree,
+    Submodule,
+}
+
+#[derive(Debug, Clone, Hash, PartialEq, Eq)]
 struct ToolBuild {
     compiler: Compiler,
     target: Interned<String>,
     tool: &'static str,
     path: &'static str,
     mode: Mode,
-    is_ext_tool: bool,
+    is_optional_tool: bool,
+    source_type: SourceType,
     extra_features: Vec<String>,
 }
 
@@ -102,7 +109,7 @@ impl Step for ToolBuild {
         let target = self.target;
         let tool = self.tool;
         let path = self.path;
-        let is_ext_tool = self.is_ext_tool;
+        let is_optional_tool = self.is_optional_tool;
 
         match self.mode {
             Mode::ToolRustc => {
@@ -115,7 +122,15 @@ impl Step for ToolBuild {
             _ => panic!("unexpected Mode for tool build")
         }
 
-        let mut cargo = prepare_tool_cargo(builder, compiler, self.mode, target, "build", path);
+        let mut cargo = prepare_tool_cargo(
+            builder,
+            compiler,
+            self.mode,
+            target,
+            "build",
+            path,
+            self.source_type,
+        );
         cargo.arg("--features").arg(self.extra_features.join(" "));
 
         let _folder = builder.fold_output(|| format!("stage{}-{}", compiler.stage, tool));
@@ -216,7 +231,7 @@ impl Step for ToolBuild {
         });
 
         if !is_expected {
-            if !is_ext_tool {
+            if !is_optional_tool {
                 exit(1);
             } else {
                 return None;
@@ -238,6 +253,7 @@ pub fn prepare_tool_cargo(
     target: Interned<String>,
     command: &'static str,
     path: &'static str,
+    source_type: SourceType,
 ) -> Command {
     let mut cargo = builder.cargo(compiler, mode, target, command);
     let dir = builder.src.join(path);
@@ -247,6 +263,10 @@ pub fn prepare_tool_cargo(
     // stages and such and it's just easier if they're not dynamically linked.
     cargo.env("RUSTC_NO_PREFER_DYNAMIC", "1");
 
+    if source_type == SourceType::Submodule {
+        cargo.env("RUSTC_EXTERNAL_TOOL", "1");
+    }
+
     if let Some(dir) = builder.openssl_install_dir(target) {
         cargo.env("OPENSSL_STATIC", "1");
         cargo.env("OPENSSL_DIR", dir);
@@ -274,7 +294,8 @@ pub fn prepare_tool_cargo(
 }
 
 macro_rules! tool {
-    ($($name:ident, $path:expr, $tool_name:expr, $mode:expr $(,llvm_tools = $llvm:expr)*;)+) => {
+    ($($name:ident, $path:expr, $tool_name:expr, $mode:expr
+        $(,llvm_tools = $llvm:expr)* $(,is_external_tool = $external:expr)*;)+) => {
         #[derive(Copy, PartialEq, Eq, Clone)]
         pub enum Tool {
             $(
@@ -351,7 +372,12 @@ macro_rules! tool {
                     tool: $tool_name,
                     mode: $mode,
                     path: $path,
-                    is_ext_tool: false,
+                    is_optional_tool: false,
+                    source_type: if false $(|| $external)* {
+                        SourceType::Submodule
+                    } else {
+                        SourceType::InTree
+                    },
                     extra_features: Vec::new(),
                 }).expect("expected to build -- essential tool")
             }
@@ -370,7 +396,8 @@ tool!(
     Compiletest, "src/tools/compiletest", "compiletest", Mode::ToolBootstrap, llvm_tools = true;
     BuildManifest, "src/tools/build-manifest", "build-manifest", Mode::ToolBootstrap;
     RemoteTestClient, "src/tools/remote-test-client", "remote-test-client", Mode::ToolBootstrap;
-    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap;
+    RustInstaller, "src/tools/rust-installer", "fabricate", Mode::ToolBootstrap,
+        is_external_tool = true;
     RustdocTheme, "src/tools/rustdoc-themes", "rustdoc-themes", Mode::ToolBootstrap;
 );
 
@@ -401,7 +428,8 @@ impl Step for RemoteTestServer {
             tool: "remote-test-server",
             mode: Mode::ToolStd,
             path: "src/tools/remote-test-server",
-            is_ext_tool: false,
+            is_optional_tool: false,
+            source_type: SourceType::InTree,
             extra_features: Vec::new(),
         }).expect("expected to build -- essential tool")
     }
@@ -449,12 +477,15 @@ impl Step for Rustdoc {
             target: builder.config.build,
         });
 
-        let mut cargo = prepare_tool_cargo(builder,
-                                           build_compiler,
-                                           Mode::ToolRustc,
-                                           target,
-                                           "build",
-                                           "src/tools/rustdoc");
+        let mut cargo = prepare_tool_cargo(
+            builder,
+            build_compiler,
+            Mode::ToolRustc,
+            target,
+            "build",
+            "src/tools/rustdoc",
+            SourceType::InTree,
+        );
 
         // Most tools don't get debuginfo, but rustdoc should.
         cargo.env("RUSTC_DEBUGINFO", builder.config.rust_debuginfo.to_string())
@@ -525,7 +556,8 @@ impl Step for Cargo {
             tool: "cargo",
             mode: Mode::ToolRustc,
             path: "src/tools/cargo",
-            is_ext_tool: false,
+            is_optional_tool: false,
+            source_type: SourceType::Submodule,
             extra_features: Vec::new(),
         }).expect("expected to build -- essential tool")
     }
@@ -574,7 +606,8 @@ macro_rules! tool_extended {
                     mode: Mode::ToolRustc,
                     path: $path,
                     extra_features: $sel.extra_features,
-                    is_ext_tool: true,
+                    is_optional_tool: true,
+                    source_type: SourceType::Submodule,
                 })
             }
         }
diff --git a/src/build_helper/lib.rs b/src/build_helper/lib.rs
index 00e5dee256e..1cbb8e49bfa 100644
--- a/src/build_helper/lib.rs
+++ b/src/build_helper/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 use std::fs::File;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Stdio};
diff --git a/src/ci/docker/dist-various-2/Dockerfile b/src/ci/docker/dist-various-2/Dockerfile
index e8d6c12de44..7adb32efa1d 100644
--- a/src/ci/docker/dist-various-2/Dockerfile
+++ b/src/ci/docker/dist-various-2/Dockerfile
@@ -34,12 +34,12 @@ COPY scripts/sccache.sh /scripts/
 RUN sh /scripts/sccache.sh
 
 ENV \
-    AR_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-ar \
-    CC_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang \
-    CXX_x86_64_unknown_fuchsia=x86_64-unknown-fuchsia-clang++ \
-    AR_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-ar \
-    CC_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-clang \
-    CXX_aarch64_unknown_fuchsia=aarch64-unknown-fuchsia-clang++ \
+    AR_x86_64_fuchsia=x86_64-fuchsia-ar \
+    CC_x86_64_fuchsia=x86_64-fuchsia-clang \
+    CXX_x86_64_fuchsia=x86_64-fuchsia-clang++ \
+    AR_aarch64_fuchsia=aarch64-fuchsia-ar \
+    CC_aarch64_fuchsia=aarch64-fuchsia-clang \
+    CXX_aarch64_fuchsia=aarch64-fuchsia-clang++ \
     AR_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-ar \
     CC_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-gcc \
     CXX_sparcv9_sun_solaris=sparcv9-sun-solaris2.10-g++ \
@@ -47,8 +47,8 @@ ENV \
     CC_x86_64_sun_solaris=x86_64-sun-solaris2.10-gcc \
     CXX_x86_64_sun_solaris=x86_64-sun-solaris2.10-g++
 
-ENV TARGETS=x86_64-unknown-fuchsia
-ENV TARGETS=$TARGETS,aarch64-unknown-fuchsia
+ENV TARGETS=x86_64-fuchsia
+ENV TARGETS=$TARGETS,aarch64-fuchsia
 ENV TARGETS=$TARGETS,sparcv9-sun-solaris
 ENV TARGETS=$TARGETS,wasm32-unknown-unknown
 ENV TARGETS=$TARGETS,x86_64-sun-solaris
diff --git a/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh b/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh
index ef8f0c37f8c..ec19f7c4f45 100755
--- a/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh
+++ b/src/ci/docker/dist-various-2/build-fuchsia-toolchain.sh
@@ -39,7 +39,7 @@ build() {
   esac
 
   hide_output make -j$(getconf _NPROCESSORS_ONLN) $tgt
-  dst=/usr/local/${arch}-unknown-fuchsia
+  dst=/usr/local/${arch}-fuchsia
   mkdir -p $dst
   cp -a build-${tgt}/sysroot/include $dst/
   cp -a build-${tgt}/sysroot/lib $dst/
@@ -55,11 +55,11 @@ rm -rf zircon
 
 for arch in x86_64 aarch64; do
   for tool in clang clang++; do
-    cat >/usr/local/bin/${arch}-unknown-fuchsia-${tool} <<EOF
+    cat >/usr/local/bin/${arch}-fuchsia-${tool} <<EOF
 #!/bin/sh
-${tool} --target=${arch}-unknown-fuchsia --sysroot=/usr/local/${arch}-unknown-fuchsia "\$@"
+${tool} --target=${arch}-fuchsia --sysroot=/usr/local/${arch}-fuchsia "\$@"
 EOF
-    chmod +x /usr/local/bin/${arch}-unknown-fuchsia-${tool}
+    chmod +x /usr/local/bin/${arch}-fuchsia-${tool}
   done
-  ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-unknown-fuchsia-ar
+  ln -s /usr/local/bin/llvm-ar /usr/local/bin/${arch}-fuchsia-ar
 done
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 0f63519ea10c028f48b2dbf7d0a2454203b68b0
+Subproject 219e261ddb833a5683627b0a9be87a0f4486abb
diff --git a/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md
new file mode 100644
index 00000000000..f50472fb41e
--- /dev/null
+++ b/src/doc/unstable-book/src/language-features/infer-static-outlives-requirements.md
@@ -0,0 +1,45 @@
+# `infer_static_outlives_requirements`
+
+The tracking issue for this feature is: [#44493]
+
+[#44493]: https://github.com/rust-lang/rust/issues/44493
+
+------------------------
+The `infer_static_outlives_requirements` feature indicates that certain
+`'static` outlives requirements can be infered by the compiler rather than
+stating them explicitly.
+
+Note: It is an accompanying feature to `infer_outlives_requirements`,
+which must be enabled to infer outlives requirements.
+
+For example, currently generic struct definitions that contain
+references, require where-clauses of the form T: 'static. By using
+this feature the outlives predicates will be infered, although
+they may still be written explicitly.
+
+```rust,ignore (pseudo-Rust)
+struct Foo<U> where U: 'static { // <-- currently required
+    bar: Bar<U>
+}
+struct Bar<T: 'static> {
+    x: T,
+}
+```
+
+
+## Examples:
+
+```rust,ignore (pseudo-Rust)
+#![feature(infer_outlives_requirements)]
+#![feature(infer_static_outlives_requirements)]
+
+#[rustc_outlives]
+// Implicitly infer U: 'static
+struct Foo<U> {
+    bar: Bar<U>
+}
+struct Bar<T: 'static> {
+    x: T,
+}
+```
+
diff --git a/src/liballoc/lib.rs b/src/liballoc/lib.rs
index 63cf01a0fac..ef619527e06 100644
--- a/src/liballoc/lib.rs
+++ b/src/liballoc/lib.rs
@@ -72,7 +72,6 @@
        test(no_crate_inject, attr(allow(unused_variables), deny(warnings))))]
 #![no_std]
 #![needs_allocator]
-#![deny(bare_trait_objects)]
 #![deny(missing_debug_implementations)]
 
 #![cfg_attr(test, allow(deprecated))] // rand
diff --git a/src/liballoc/tests/arc.rs b/src/liballoc/tests/arc.rs
index 753873dd294..d90c22a3b18 100644
--- a/src/liballoc/tests/arc.rs
+++ b/src/liballoc/tests/arc.rs
@@ -18,7 +18,7 @@ fn uninhabited() {
     a = a.clone();
     assert!(a.upgrade().is_none());
 
-    let mut a: Weak<Any> = a;  // Unsizing
+    let mut a: Weak<dyn Any> = a;  // Unsizing
     a = a.clone();
     assert!(a.upgrade().is_none());
 }
@@ -39,7 +39,7 @@ fn slice() {
 #[test]
 fn trait_object() {
     let a: Arc<u32> = Arc::new(4);
-    let a: Arc<Any> = a;  // Unsizing
+    let a: Arc<dyn Any> = a;  // Unsizing
 
     // Exercise is_dangling() with a DST
     let mut a = Arc::downgrade(&a);
@@ -49,7 +49,7 @@ fn trait_object() {
     let mut b = Weak::<u32>::new();
     b = b.clone();
     assert!(b.upgrade().is_none());
-    let mut b: Weak<Any> = b;  // Unsizing
+    let mut b: Weak<dyn Any> = b;  // Unsizing
     b = b.clone();
     assert!(b.upgrade().is_none());
 }
diff --git a/src/liballoc/tests/btree/set.rs b/src/liballoc/tests/btree/set.rs
index 6171b8ba624..0330bda5e32 100644
--- a/src/liballoc/tests/btree/set.rs
+++ b/src/liballoc/tests/btree/set.rs
@@ -40,7 +40,7 @@ fn test_hash() {
 }
 
 fn check<F>(a: &[i32], b: &[i32], expected: &[i32], f: F)
-    where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut FnMut(&i32) -> bool) -> bool
+    where F: FnOnce(&BTreeSet<i32>, &BTreeSet<i32>, &mut dyn FnMut(&i32) -> bool) -> bool
 {
     let mut set_a = BTreeSet::new();
     let mut set_b = BTreeSet::new();
diff --git a/src/liballoc/tests/lib.rs b/src/liballoc/tests/lib.rs
index 2c361598e89..618aff963f2 100644
--- a/src/liballoc/tests/lib.rs
+++ b/src/liballoc/tests/lib.rs
@@ -24,6 +24,7 @@
 #![feature(try_reserve)]
 #![feature(unboxed_closures)]
 #![feature(exact_chunks)]
+#![feature(repeat_generic_slice)]
 
 extern crate alloc_system;
 extern crate core;
@@ -63,7 +64,7 @@ fn test_boxed_hasher() {
     5u32.hash(&mut hasher_1);
     assert_eq!(ordinary_hash, hasher_1.finish());
 
-    let mut hasher_2 = Box::new(DefaultHasher::new()) as Box<Hasher>;
+    let mut hasher_2 = Box::new(DefaultHasher::new()) as Box<dyn Hasher>;
     5u32.hash(&mut hasher_2);
     assert_eq!(ordinary_hash, hasher_2.finish());
 }
diff --git a/src/liballoc/tests/rc.rs b/src/liballoc/tests/rc.rs
index baa0406acfc..9ec7c831444 100644
--- a/src/liballoc/tests/rc.rs
+++ b/src/liballoc/tests/rc.rs
@@ -18,7 +18,7 @@ fn uninhabited() {
     a = a.clone();
     assert!(a.upgrade().is_none());
 
-    let mut a: Weak<Any> = a;  // Unsizing
+    let mut a: Weak<dyn Any> = a;  // Unsizing
     a = a.clone();
     assert!(a.upgrade().is_none());
 }
@@ -39,7 +39,7 @@ fn slice() {
 #[test]
 fn trait_object() {
     let a: Rc<u32> = Rc::new(4);
-    let a: Rc<Any> = a;  // Unsizing
+    let a: Rc<dyn Any> = a;  // Unsizing
 
     // Exercise is_dangling() with a DST
     let mut a = Rc::downgrade(&a);
@@ -49,7 +49,7 @@ fn trait_object() {
     let mut b = Weak::<u32>::new();
     b = b.clone();
     assert!(b.upgrade().is_none());
-    let mut b: Weak<Any> = b;  // Unsizing
+    let mut b: Weak<dyn Any> = b;  // Unsizing
     b = b.clone();
     assert!(b.upgrade().is_none());
 }
diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs
index 3b7eec38609..df5e18a9a18 100644
--- a/src/liballoc/tests/slice.rs
+++ b/src/liballoc/tests/slice.rs
@@ -1529,3 +1529,14 @@ fn panic_safe() {
         }
     }
 }
+
+#[test]
+fn repeat_generic_slice() {
+    assert_eq!([1, 2].repeat(2), vec![1, 2, 1, 2]);
+    assert_eq!([1, 2, 3, 4].repeat(0), vec![]);
+    assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]);
+    assert_eq!(
+        [1, 2, 3, 4].repeat(3),
+        vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]
+    );
+}
diff --git a/src/liballoc_jemalloc/lib.rs b/src/liballoc_jemalloc/lib.rs
index 413b212281b..b3b20715511 100644
--- a/src/liballoc_jemalloc/lib.rs
+++ b/src/liballoc_jemalloc/lib.rs
@@ -10,7 +10,6 @@
 
 #![no_std]
 #![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
 #![unstable(feature = "alloc_jemalloc",
             reason = "implementation detail of std, does not provide any public API",
             issue = "0")]
diff --git a/src/liballoc_system/lib.rs b/src/liballoc_system/lib.rs
index c6c0abefbab..64348e05de7 100644
--- a/src/liballoc_system/lib.rs
+++ b/src/liballoc_system/lib.rs
@@ -10,7 +10,6 @@
 
 #![no_std]
 #![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
 #![unstable(feature = "alloc_system",
             reason = "this library is unlikely to be stabilized in its current \
                       form or name",
diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs
index 6f692923c85..0f4a5d16e17 100644
--- a/src/libarena/lib.rs
+++ b/src/libarena/lib.rs
@@ -30,7 +30,6 @@
 #![cfg_attr(test, feature(test))]
 
 #![allow(deprecated)]
-#![deny(bare_trait_objects)]
 
 extern crate alloc;
 extern crate rustc_data_structures;
diff --git a/src/libcore/any.rs b/src/libcore/any.rs
index 94f23db1ccc..6b26093439e 100644
--- a/src/libcore/any.rs
+++ b/src/libcore/any.rs
@@ -120,7 +120,7 @@ impl<T: 'static + ?Sized > Any for T {
 ///////////////////////////////////////////////////////////////////////////////
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Any {
+impl fmt::Debug for dyn Any {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.pad("Any")
     }
@@ -130,20 +130,20 @@ impl fmt::Debug for Any {
 // hence used with `unwrap`. May eventually no longer be needed if
 // dispatch works with upcasting.
 #[stable(feature = "rust1", since = "1.0.0")]
-impl fmt::Debug for Any + Send {
+impl fmt::Debug for dyn Any + Send {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.pad("Any")
     }
 }
 
 #[stable(feature = "any_send_sync_methods", since = "1.28.0")]
-impl fmt::Debug for Any + Send + Sync {
+impl fmt::Debug for dyn Any + Send + Sync {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         f.pad("Any")
     }
 }
 
-impl Any {
+impl dyn Any {
     /// Returns `true` if the boxed type is the same as `T`.
     ///
     /// # Examples
@@ -203,7 +203,7 @@ impl Any {
     pub fn downcast_ref<T: Any>(&self) -> Option<&T> {
         if self.is::<T>() {
             unsafe {
-                Some(&*(self as *const Any as *const T))
+                Some(&*(self as *const dyn Any as *const T))
             }
         } else {
             None
@@ -240,7 +240,7 @@ impl Any {
     pub fn downcast_mut<T: Any>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
             unsafe {
-                Some(&mut *(self as *mut Any as *mut T))
+                Some(&mut *(self as *mut dyn Any as *mut T))
             }
         } else {
             None
@@ -248,7 +248,7 @@ impl Any {
     }
 }
 
-impl Any+Send {
+impl dyn Any+Send {
     /// Forwards to the method defined on the type `Any`.
     ///
     /// # Examples
@@ -332,7 +332,7 @@ impl Any+Send {
     }
 }
 
-impl Any+Send+Sync {
+impl dyn Any+Send+Sync {
     /// Forwards to the method defined on the type `Any`.
     ///
     /// # Examples
diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs
index b6087628ea6..137e9fe2c15 100644
--- a/src/libcore/cell.rs
+++ b/src/libcore/cell.rs
@@ -1532,7 +1532,7 @@ impl<T: CoerceUnsized<U>, U> CoerceUnsized<UnsafeCell<U>> for UnsafeCell<T> {}
 
 #[allow(unused)]
 fn assert_coerce_unsized(a: UnsafeCell<&i32>, b: Cell<&i32>, c: RefCell<&i32>) {
-    let _: UnsafeCell<&Send> = a;
-    let _: Cell<&Send> = b;
-    let _: RefCell<&Send> = c;
+    let _: UnsafeCell<&dyn Send> = a;
+    let _: Cell<&dyn Send> = b;
+    let _: RefCell<&dyn Send> = c;
 }
diff --git a/src/libcore/fmt/builders.rs b/src/libcore/fmt/builders.rs
index e8ea2e743da..3c5f934d4d8 100644
--- a/src/libcore/fmt/builders.rs
+++ b/src/libcore/fmt/builders.rs
@@ -11,7 +11,7 @@
 use fmt;
 
 struct PadAdapter<'a> {
-    buf: &'a mut (fmt::Write + 'a),
+    buf: &'a mut (dyn fmt::Write + 'a),
     on_newline: bool,
 }
 
@@ -107,7 +107,7 @@ pub fn debug_struct_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>,
 impl<'a, 'b: 'a> DebugStruct<'a, 'b> {
     /// Adds a new field to the generated struct output.
     #[stable(feature = "debug_builders", since = "1.2.0")]
-    pub fn field(&mut self, name: &str, value: &fmt::Debug) -> &mut DebugStruct<'a, 'b> {
+    pub fn field(&mut self, name: &str, value: &dyn fmt::Debug) -> &mut DebugStruct<'a, 'b> {
         self.result = self.result.and_then(|_| {
             let prefix = if self.has_fields {
                 ","
@@ -204,7 +204,7 @@ pub fn debug_tuple_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>, name: &str) -> D
 impl<'a, 'b: 'a> DebugTuple<'a, 'b> {
     /// Adds a new field to the generated tuple struct output.
     #[stable(feature = "debug_builders", since = "1.2.0")]
-    pub fn field(&mut self, value: &fmt::Debug) -> &mut DebugTuple<'a, 'b> {
+    pub fn field(&mut self, value: &dyn fmt::Debug) -> &mut DebugTuple<'a, 'b> {
         self.result = self.result.and_then(|_| {
             let (prefix, space) = if self.fields > 0 {
                 (",", " ")
@@ -258,7 +258,7 @@ struct DebugInner<'a, 'b: 'a> {
 }
 
 impl<'a, 'b: 'a> DebugInner<'a, 'b> {
-    fn entry(&mut self, entry: &fmt::Debug) {
+    fn entry(&mut self, entry: &dyn fmt::Debug) {
         self.result = self.result.and_then(|_| {
             if self.is_pretty() {
                 let mut slot = None;
@@ -340,7 +340,7 @@ pub fn debug_set_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugSet<'a, 'b
 impl<'a, 'b: 'a> DebugSet<'a, 'b> {
     /// Adds a new entry to the set output.
     #[stable(feature = "debug_builders", since = "1.2.0")]
-    pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugSet<'a, 'b> {
+    pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugSet<'a, 'b> {
         self.inner.entry(entry);
         self
     }
@@ -411,7 +411,7 @@ pub fn debug_list_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugList<'a,
 impl<'a, 'b: 'a> DebugList<'a, 'b> {
     /// Adds a new entry to the list output.
     #[stable(feature = "debug_builders", since = "1.2.0")]
-    pub fn entry(&mut self, entry: &fmt::Debug) -> &mut DebugList<'a, 'b> {
+    pub fn entry(&mut self, entry: &dyn fmt::Debug) -> &mut DebugList<'a, 'b> {
         self.inner.entry(entry);
         self
     }
@@ -482,7 +482,7 @@ pub fn debug_map_new<'a, 'b>(fmt: &'a mut fmt::Formatter<'b>) -> DebugMap<'a, 'b
 impl<'a, 'b: 'a> DebugMap<'a, 'b> {
     /// Adds a new entry to the map output.
     #[stable(feature = "debug_builders", since = "1.2.0")]
-    pub fn entry(&mut self, key: &fmt::Debug, value: &fmt::Debug) -> &mut DebugMap<'a, 'b> {
+    pub fn entry(&mut self, key: &dyn fmt::Debug, value: &dyn fmt::Debug) -> &mut DebugMap<'a, 'b> {
         self.result = self.result.and_then(|_| {
             if self.is_pretty() {
                 let mut slot = None;
diff --git a/src/libcore/fmt/mod.rs b/src/libcore/fmt/mod.rs
index d91bf463383..928f95e3ba2 100644
--- a/src/libcore/fmt/mod.rs
+++ b/src/libcore/fmt/mod.rs
@@ -255,7 +255,7 @@ pub struct Formatter<'a> {
     width: Option<usize>,
     precision: Option<usize>,
 
-    buf: &'a mut (Write+'a),
+    buf: &'a mut (dyn Write+'a),
     curarg: slice::Iter<'a, ArgumentV1<'a>>,
     args: &'a [ArgumentV1<'a>],
 }
@@ -272,7 +272,7 @@ struct Void {
     ///
     /// It was added after #45197 showed that one could share a `!Sync`
     /// object across threads by passing it into `format_args!`.
-    _oibit_remover: PhantomData<*mut Fn()>,
+    _oibit_remover: PhantomData<*mut dyn Fn()>,
 }
 
 /// This struct represents the generic "argument" which is taken by the Xprintf
@@ -1020,7 +1020,7 @@ pub trait UpperExp {
 ///
 /// [`write!`]: ../../std/macro.write.html
 #[stable(feature = "rust1", since = "1.0.0")]
-pub fn write(output: &mut Write, args: Arguments) -> Result {
+pub fn write(output: &mut dyn Write, args: Arguments) -> Result {
     let mut formatter = Formatter {
         flags: 0,
         width: None,
@@ -1062,7 +1062,7 @@ pub fn write(output: &mut Write, args: Arguments) -> Result {
 
 impl<'a> Formatter<'a> {
     fn wrap_buf<'b, 'c, F>(&'b mut self, wrap: F) -> Formatter<'c>
-        where 'b: 'c, F: FnOnce(&'b mut (Write+'b)) -> &'c mut (Write+'c)
+        where 'b: 'c, F: FnOnce(&'b mut (dyn Write+'b)) -> &'c mut (dyn Write+'c)
     {
         Formatter {
             // We want to change this
@@ -1342,7 +1342,7 @@ impl<'a> Formatter<'a> {
     }
 
     fn write_formatted_parts(&mut self, formatted: &flt2dec::Formatted) -> Result {
-        fn write_bytes(buf: &mut Write, s: &[u8]) -> Result {
+        fn write_bytes(buf: &mut dyn Write, s: &[u8]) -> Result {
             buf.write_str(unsafe { str::from_utf8_unchecked(s) })
         }
 
diff --git a/src/libcore/iter/iterator.rs b/src/libcore/iter/iterator.rs
index afc273d265b..48c6eb94144 100644
--- a/src/libcore/iter/iterator.rs
+++ b/src/libcore/iter/iterator.rs
@@ -18,7 +18,7 @@ use super::{Inspect, Map, Peekable, Scan, Skip, SkipWhile, StepBy, Take, TakeWhi
 use super::{Zip, Sum, Product};
 use super::{ChainState, FromIterator, ZipImpl};
 
-fn _assert_is_object_safe(_: &Iterator<Item=()>) {}
+fn _assert_is_object_safe(_: &dyn Iterator<Item=()>) {}
 
 /// An interface for dealing with iterators.
 ///
diff --git a/src/libcore/manually_drop_stage0.rs b/src/libcore/manually_drop_stage0.rs
new file mode 100644
index 00000000000..8643219cb61
--- /dev/null
+++ b/src/libcore/manually_drop_stage0.rs
@@ -0,0 +1,195 @@
+// 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.
+
+/// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
+///
+/// This wrapper is 0-cost.
+///
+/// # Examples
+///
+/// This wrapper helps with explicitly documenting the drop order dependencies between fields of
+/// the type:
+///
+/// ```rust
+/// use std::mem::ManuallyDrop;
+/// struct Peach;
+/// struct Banana;
+/// struct Melon;
+/// struct FruitBox {
+///     // Immediately clear there’s something non-trivial going on with these fields.
+///     peach: ManuallyDrop<Peach>,
+///     melon: Melon, // Field that’s independent of the other two.
+///     banana: ManuallyDrop<Banana>,
+/// }
+///
+/// impl Drop for FruitBox {
+///     fn drop(&mut self) {
+///         unsafe {
+///             // Explicit ordering in which field destructors are run specified in the intuitive
+///             // location – the destructor of the structure containing the fields.
+///             // Moreover, one can now reorder fields within the struct however much they want.
+///             ManuallyDrop::drop(&mut self.peach);
+///             ManuallyDrop::drop(&mut self.banana);
+///         }
+///         // After destructor for `FruitBox` runs (this function), the destructor for Melon gets
+///         // invoked in the usual manner, as it is not wrapped in `ManuallyDrop`.
+///     }
+/// }
+/// ```
+#[stable(feature = "manually_drop", since = "1.20.0")]
+#[allow(unions_with_drop_fields)]
+#[derive(Copy)]
+pub union ManuallyDrop<T>{ value: T }
+
+impl<T> ManuallyDrop<T> {
+    /// Wrap a value to be manually dropped.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::mem::ManuallyDrop;
+    /// ManuallyDrop::new(Box::new(()));
+    /// ```
+    #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[rustc_const_unstable(feature = "const_manually_drop_new")]
+    #[inline]
+    pub const fn new(value: T) -> ManuallyDrop<T> {
+        ManuallyDrop { value: value }
+    }
+
+    /// Extract the value from the ManuallyDrop container.
+    ///
+    /// # Examples
+    ///
+    /// ```rust
+    /// use std::mem::ManuallyDrop;
+    /// let x = ManuallyDrop::new(Box::new(()));
+    /// let _: Box<()> = ManuallyDrop::into_inner(x);
+    /// ```
+    #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[inline]
+    pub fn into_inner(slot: ManuallyDrop<T>) -> T {
+        unsafe {
+            slot.value
+        }
+    }
+
+    /// Manually drops the contained value.
+    ///
+    /// # Safety
+    ///
+    /// This function runs the destructor of the contained value and thus the wrapped value
+    /// now represents uninitialized data. It is up to the user of this method to ensure the
+    /// uninitialized data is not actually used.
+    #[stable(feature = "manually_drop", since = "1.20.0")]
+    #[inline]
+    pub unsafe fn drop(slot: &mut ManuallyDrop<T>) {
+        ptr::drop_in_place(&mut slot.value)
+    }
+}
+
+#[stable(feature = "manually_drop", since = "1.20.0")]
+impl<T> Deref for ManuallyDrop<T> {
+    type Target = T;
+    #[inline]
+    fn deref(&self) -> &Self::Target {
+        unsafe {
+            &self.value
+        }
+    }
+}
+
+#[stable(feature = "manually_drop", since = "1.20.0")]
+impl<T> DerefMut for ManuallyDrop<T> {
+    #[inline]
+    fn deref_mut(&mut self) -> &mut Self::Target {
+        unsafe {
+            &mut self.value
+        }
+    }
+}
+
+#[stable(feature = "manually_drop", since = "1.20.0")]
+impl<T: ::fmt::Debug> ::fmt::Debug for ManuallyDrop<T> {
+    fn fmt(&self, fmt: &mut ::fmt::Formatter) -> ::fmt::Result {
+        unsafe {
+            fmt.debug_tuple("ManuallyDrop").field(&self.value).finish()
+        }
+    }
+}
+
+#[stable(feature = "manually_drop_impls", since = "1.22.0")]
+impl<T: Clone> Clone for ManuallyDrop<T> {
+    fn clone(&self) -> Self {
+        ManuallyDrop::new(self.deref().clone())
+    }
+
+    fn clone_from(&mut self, source: &Self) {
+        self.deref_mut().clone_from(source);
+    }
+}
+
+#[stable(feature = "manually_drop_impls", since = "1.22.0")]
+impl<T: Default> Default for ManuallyDrop<T> {
+    fn default() -> Self {
+        ManuallyDrop::new(Default::default())
+    }
+}
+
+#[stable(feature = "manually_drop_impls", since = "1.22.0")]
+impl<T: PartialEq> PartialEq for ManuallyDrop<T> {
+    fn eq(&self, other: &Self) -> bool {
+        self.deref().eq(other)
+    }
+
+    fn ne(&self, other: &Self) -> bool {
+        self.deref().ne(other)
+    }
+}
+
+#[stable(feature = "manually_drop_impls", since = "1.22.0")]
+impl<T: Eq> Eq for ManuallyDrop<T> {}
+
+#[stable(feature = "manually_drop_impls", since = "1.22.0")]
+impl<T: PartialOrd> PartialOrd for ManuallyDrop<T> {
+    fn partial_cmp(&self, other: &Self) -> Option<::cmp::Ordering> {
+        self.deref().partial_cmp(other)
+    }
+
+    fn lt(&self, other: &Self) -> bool {
+        self.deref().lt(other)
+    }
+
+    fn le(&self, other: &Self) -> bool {
+        self.deref().le(other)
+    }
+
+    fn gt(&self, other: &Self) -> bool {
+        self.deref().gt(other)
+    }
+
+    fn ge(&self, other: &Self) -> bool {
+        self.deref().ge(other)
+    }
+}
+
+#[stable(feature = "manually_drop_impls", since = "1.22.0")]
+impl<T: Ord> Ord for ManuallyDrop<T> {
+    fn cmp(&self, other: &Self) -> ::cmp::Ordering {
+        self.deref().cmp(other)
+    }
+}
+
+#[stable(feature = "manually_drop_impls", since = "1.22.0")]
+impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> {
+    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
+        self.deref().hash(state);
+    }
+}
diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs
index a0fe6e98806..1a54f03bb00 100644
--- a/src/libcore/mem.rs
+++ b/src/libcore/mem.rs
@@ -918,7 +918,6 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
     }
 }
 
-
 /// A wrapper to inhibit compiler from automatically calling `T`’s destructor.
 ///
 /// This wrapper is 0-cost.
@@ -954,11 +953,18 @@ pub fn discriminant<T>(v: &T) -> Discriminant<T> {
 ///     }
 /// }
 /// ```
+#[cfg(not(stage0))]
 #[stable(feature = "manually_drop", since = "1.20.0")]
-#[allow(unions_with_drop_fields)]
-#[derive(Copy)]
-pub union ManuallyDrop<T>{ value: T }
+#[lang = "manually_drop"]
+#[derive(Copy, Clone, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct ManuallyDrop<T> {
+    value: T,
+}
+
+#[cfg(stage0)]
+include!("manually_drop_stage0.rs");
 
+#[cfg(not(stage0))]
 impl<T> ManuallyDrop<T> {
     /// Wrap a value to be manually dropped.
     ///
@@ -972,7 +978,7 @@ impl<T> ManuallyDrop<T> {
     #[rustc_const_unstable(feature = "const_manually_drop_new")]
     #[inline]
     pub const fn new(value: T) -> ManuallyDrop<T> {
-        ManuallyDrop { value: value }
+        ManuallyDrop { value }
     }
 
     /// Extract the value from the ManuallyDrop container.
@@ -987,9 +993,7 @@ impl<T> ManuallyDrop<T> {
     #[stable(feature = "manually_drop", since = "1.20.0")]
     #[inline]
     pub fn into_inner(slot: ManuallyDrop<T>) -> T {
-        unsafe {
-            slot.value
-        }
+        slot.value
     }
 
     /// Manually drops the contained value.
@@ -1006,102 +1010,22 @@ impl<T> ManuallyDrop<T> {
     }
 }
 
+#[cfg(not(stage0))]
 #[stable(feature = "manually_drop", since = "1.20.0")]
 impl<T> Deref for ManuallyDrop<T> {
     type Target = T;
     #[inline]
     fn deref(&self) -> &Self::Target {
-        unsafe {
-            &self.value
-        }
+        &self.value
     }
 }
 
+#[cfg(not(stage0))]
 #[stable(feature = "manually_drop", since = "1.20.0")]
 impl<T> DerefMut for ManuallyDrop<T> {
     #[inline]
     fn deref_mut(&mut self) -> &mut Self::Target {
-        unsafe {
-            &mut self.value
-        }
-    }
-}
-
-#[stable(feature = "manually_drop", since = "1.20.0")]
-impl<T: ::fmt::Debug> ::fmt::Debug for ManuallyDrop<T> {
-    fn fmt(&self, fmt: &mut ::fmt::Formatter) -> ::fmt::Result {
-        unsafe {
-            fmt.debug_tuple("ManuallyDrop").field(&self.value).finish()
-        }
-    }
-}
-
-#[stable(feature = "manually_drop_impls", since = "1.22.0")]
-impl<T: Clone> Clone for ManuallyDrop<T> {
-    fn clone(&self) -> Self {
-        ManuallyDrop::new(self.deref().clone())
-    }
-
-    fn clone_from(&mut self, source: &Self) {
-        self.deref_mut().clone_from(source);
-    }
-}
-
-#[stable(feature = "manually_drop_impls", since = "1.22.0")]
-impl<T: Default> Default for ManuallyDrop<T> {
-    fn default() -> Self {
-        ManuallyDrop::new(Default::default())
-    }
-}
-
-#[stable(feature = "manually_drop_impls", since = "1.22.0")]
-impl<T: PartialEq> PartialEq for ManuallyDrop<T> {
-    fn eq(&self, other: &Self) -> bool {
-        self.deref().eq(other)
-    }
-
-    fn ne(&self, other: &Self) -> bool {
-        self.deref().ne(other)
-    }
-}
-
-#[stable(feature = "manually_drop_impls", since = "1.22.0")]
-impl<T: Eq> Eq for ManuallyDrop<T> {}
-
-#[stable(feature = "manually_drop_impls", since = "1.22.0")]
-impl<T: PartialOrd> PartialOrd for ManuallyDrop<T> {
-    fn partial_cmp(&self, other: &Self) -> Option<::cmp::Ordering> {
-        self.deref().partial_cmp(other)
-    }
-
-    fn lt(&self, other: &Self) -> bool {
-        self.deref().lt(other)
-    }
-
-    fn le(&self, other: &Self) -> bool {
-        self.deref().le(other)
-    }
-
-    fn gt(&self, other: &Self) -> bool {
-        self.deref().gt(other)
-    }
-
-    fn ge(&self, other: &Self) -> bool {
-        self.deref().ge(other)
-    }
-}
-
-#[stable(feature = "manually_drop_impls", since = "1.22.0")]
-impl<T: Ord> Ord for ManuallyDrop<T> {
-    fn cmp(&self, other: &Self) -> ::cmp::Ordering {
-        self.deref().cmp(other)
-    }
-}
-
-#[stable(feature = "manually_drop_impls", since = "1.22.0")]
-impl<T: ::hash::Hash> ::hash::Hash for ManuallyDrop<T> {
-    fn hash<H: ::hash::Hasher>(&self, state: &mut H) {
-        self.deref().hash(state);
+        &mut self.value
     }
 }
 
diff --git a/src/libcore/panic.rs b/src/libcore/panic.rs
index 10f02ca2fdc..17cac5aa0a0 100644
--- a/src/libcore/panic.rs
+++ b/src/libcore/panic.rs
@@ -43,7 +43,7 @@ use fmt;
 #[stable(feature = "panic_hooks", since = "1.10.0")]
 #[derive(Debug)]
 pub struct PanicInfo<'a> {
-    payload: &'a (Any + Send),
+    payload: &'a (dyn Any + Send),
     message: Option<&'a fmt::Arguments<'a>>,
     location: Location<'a>,
 }
@@ -64,7 +64,7 @@ impl<'a> PanicInfo<'a> {
 
     #[doc(hidden)]
     #[inline]
-    pub fn set_payload(&mut self, info: &'a (Any + Send)) {
+    pub fn set_payload(&mut self, info: &'a (dyn Any + Send)) {
         self.payload = info;
     }
 
@@ -86,7 +86,7 @@ impl<'a> PanicInfo<'a> {
     /// panic!("Normal panic");
     /// ```
     #[stable(feature = "panic_hooks", since = "1.10.0")]
-    pub fn payload(&self) -> &(Any + Send) {
+    pub fn payload(&self) -> &(dyn Any + Send) {
         self.payload
     }
 
@@ -270,6 +270,6 @@ impl<'a> fmt::Display for Location<'a> {
 #[unstable(feature = "std_internals", issue = "0")]
 #[doc(hidden)]
 pub unsafe trait BoxMeUp {
-    fn box_me_up(&mut self) -> *mut (Any + Send);
-    fn get(&mut self) -> &(Any + Send);
+    fn box_me_up(&mut self) -> *mut (dyn Any + Send);
+    fn get(&mut self) -> &(dyn Any + Send);
 }
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index be82ab44cd1..fe5914c72e1 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -1162,8 +1162,8 @@ impl<T: ?Sized> *const T {
     ///
     /// Care must be taken with the ownership of `self` and `dest`.
     /// This method semantically moves the values of `self` into `dest`.
-    /// However it does not drop the contents of `self`, or prevent the contents
-    /// of `dest` from being dropped or used.
+    /// However it does not drop the contents of `dest`, or prevent the contents
+    /// of `self` from being dropped or used.
     ///
     /// # Examples
     ///
diff --git a/src/libcore/slice/memchr.rs b/src/libcore/slice/memchr.rs
index 7b62e7b0620..72e7b57a6cb 100644
--- a/src/libcore/slice/memchr.rs
+++ b/src/libcore/slice/memchr.rs
@@ -102,16 +102,13 @@ pub fn memrchr(x: u8, text: &[u8]) -> Option<usize> {
     let ptr = text.as_ptr();
     let usize_bytes = mem::size_of::<usize>();
 
-    // search to an aligned boundary
-    let end_align = (ptr as usize + len) & (usize_bytes - 1);
-    let mut offset;
-    if end_align > 0 {
-        offset = if end_align >= len { 0 } else { len - end_align };
-        if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
-            return Some(offset + index);
-        }
-    } else {
-        offset = len;
+    let mut offset = {
+        // We call this just to obtain the length of the suffix
+        let (_, _, suffix) = unsafe { text.align_to::<usize>() };
+        len - suffix.len()
+    };
+    if let Some(index) = text[offset..].iter().rposition(|elt| *elt == x) {
+        return Some(offset + index);
     }
 
     // search the body of the text
diff --git a/src/libcore/task/context.rs b/src/libcore/task/context.rs
index c69d45248a5..1fc975cb178 100644
--- a/src/libcore/task/context.rs
+++ b/src/libcore/task/context.rs
@@ -21,7 +21,7 @@ use super::{Executor, Waker, LocalWaker};
 /// when performing a single `poll` step on a task.
 pub struct Context<'a> {
     local_waker: &'a LocalWaker,
-    executor: &'a mut Executor,
+    executor: &'a mut dyn Executor,
 }
 
 impl<'a> fmt::Debug for Context<'a> {
@@ -34,7 +34,7 @@ impl<'a> fmt::Debug for Context<'a> {
 impl<'a> Context<'a> {
     /// Create a new task `Context` with the provided `local_waker`, `waker`, and `executor`.
     #[inline]
-    pub fn new(local_waker: &'a LocalWaker, executor: &'a mut Executor) -> Context<'a> {
+    pub fn new(local_waker: &'a LocalWaker, executor: &'a mut dyn Executor) -> Context<'a> {
         Context {
             local_waker,
             executor,
@@ -58,7 +58,7 @@ impl<'a> Context<'a> {
     /// This method is useful primarily if you want to explicitly handle
     /// spawn failures.
     #[inline]
-    pub fn executor(&mut self) -> &mut Executor {
+    pub fn executor(&mut self) -> &mut dyn Executor {
         self.executor
     }
 
diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs
index 3b901c9aef0..321b432d3f4 100644
--- a/src/libcore/task/wake.rs
+++ b/src/libcore/task/wake.rs
@@ -23,7 +23,7 @@ use ptr::NonNull;
 /// trait, allowing notifications to get routed through it.
 #[repr(transparent)]
 pub struct Waker {
-    inner: NonNull<UnsafeWake>,
+    inner: NonNull<dyn UnsafeWake>,
 }
 
 impl Unpin for Waker {}
@@ -41,7 +41,7 @@ impl Waker {
     /// use the `Waker::from` function instead which works with the safe
     /// `Arc` type and the safe `Wake` trait.
     #[inline]
-    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+    pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
         Waker { inner: inner }
     }
 
@@ -98,7 +98,7 @@ impl Drop for Waker {
 /// behavior.
 #[repr(transparent)]
 pub struct LocalWaker {
-    inner: NonNull<UnsafeWake>,
+    inner: NonNull<dyn UnsafeWake>,
 }
 
 impl Unpin for LocalWaker {}
@@ -119,7 +119,7 @@ impl LocalWaker {
     /// For this function to be used safely, it must be sound to call `inner.wake_local()`
     /// on the current thread.
     #[inline]
-    pub unsafe fn new(inner: NonNull<UnsafeWake>) -> Self {
+    pub unsafe fn new(inner: NonNull<dyn UnsafeWake>) -> Self {
         LocalWaker { inner: inner }
     }
 
diff --git a/src/libcore/tests/any.rs b/src/libcore/tests/any.rs
index 2d3e81aa131..a80bf939530 100644
--- a/src/libcore/tests/any.rs
+++ b/src/libcore/tests/any.rs
@@ -17,7 +17,7 @@ static TEST: &'static str = "Test";
 
 #[test]
 fn any_referenced() {
-    let (a, b, c) = (&5 as &Any, &TEST as &Any, &Test as &Any);
+    let (a, b, c) = (&5 as &dyn Any, &TEST as &dyn Any, &Test as &dyn Any);
 
     assert!(a.is::<i32>());
     assert!(!b.is::<i32>());
@@ -34,7 +34,11 @@ fn any_referenced() {
 
 #[test]
 fn any_owning() {
-    let (a, b, c) = (box 5_usize as Box<Any>, box TEST as Box<Any>, box Test as Box<Any>);
+    let (a, b, c) = (
+        box 5_usize as Box<dyn Any>,
+        box TEST as Box<dyn Any>,
+        box Test as Box<dyn Any>,
+    );
 
     assert!(a.is::<usize>());
     assert!(!b.is::<usize>());
@@ -51,7 +55,7 @@ fn any_owning() {
 
 #[test]
 fn any_downcast_ref() {
-    let a = &5_usize as &Any;
+    let a = &5_usize as &dyn Any;
 
     match a.downcast_ref::<usize>() {
         Some(&5) => {}
@@ -69,9 +73,9 @@ fn any_downcast_mut() {
     let mut a = 5_usize;
     let mut b: Box<_> = box 7_usize;
 
-    let a_r = &mut a as &mut Any;
+    let a_r = &mut a as &mut dyn Any;
     let tmp: &mut usize = &mut *b;
-    let b_r = tmp as &mut Any;
+    let b_r = tmp as &mut dyn Any;
 
     match a_r.downcast_mut::<usize>() {
         Some(x) => {
@@ -113,7 +117,7 @@ fn any_downcast_mut() {
 #[test]
 fn any_fixed_vec() {
     let test = [0_usize; 8];
-    let test = &test as &Any;
+    let test = &test as &dyn Any;
     assert!(test.is::<[usize; 8]>());
     assert!(!test.is::<[usize; 10]>());
 }
diff --git a/src/libcore/tests/hash/mod.rs b/src/libcore/tests/hash/mod.rs
index 8716421b424..85c9d41b65b 100644
--- a/src/libcore/tests/hash/mod.rs
+++ b/src/libcore/tests/hash/mod.rs
@@ -128,7 +128,7 @@ fn test_custom_state() {
 fn test_indirect_hasher() {
     let mut hasher = MyHasher { hash: 0 };
     {
-        let mut indirect_hasher: &mut Hasher = &mut hasher;
+        let mut indirect_hasher: &mut dyn Hasher = &mut hasher;
         5u32.hash(&mut indirect_hasher);
     }
     assert_eq!(hasher.hash, 5);
diff --git a/src/libcore/tests/intrinsics.rs b/src/libcore/tests/intrinsics.rs
index 2b380abf63c..9f3cba26a62 100644
--- a/src/libcore/tests/intrinsics.rs
+++ b/src/libcore/tests/intrinsics.rs
@@ -22,7 +22,7 @@ fn test_typeid_sized_types() {
 #[test]
 fn test_typeid_unsized_types() {
     trait Z {}
-    struct X(str); struct Y(Z + 'static);
+    struct X(str); struct Y(dyn Z + 'static);
 
     assert_eq!(TypeId::of::<X>(), TypeId::of::<X>());
     assert_eq!(TypeId::of::<Y>(), TypeId::of::<Y>());
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index ca7db6e4639..6fcfaae4535 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -62,6 +62,7 @@ mod fmt;
 mod hash;
 mod intrinsics;
 mod iter;
+mod manually_drop;
 mod mem;
 mod nonzero;
 mod num;
diff --git a/src/libcore/tests/manually_drop.rs b/src/libcore/tests/manually_drop.rs
new file mode 100644
index 00000000000..96bc9247da6
--- /dev/null
+++ b/src/libcore/tests/manually_drop.rs
@@ -0,0 +1,24 @@
+// 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 core::mem::ManuallyDrop;
+
+#[test]
+fn smoke() {
+    struct TypeWithDrop;
+    impl Drop for TypeWithDrop {
+        fn drop(&mut self) {
+            unreachable!("Should not get dropped");
+        }
+    }
+
+    let x = ManuallyDrop::new(TypeWithDrop);
+    drop(x);
+}
diff --git a/src/libcore/tests/mem.rs b/src/libcore/tests/mem.rs
index f55a1c81463..714f2babbdf 100644
--- a/src/libcore/tests/mem.rs
+++ b/src/libcore/tests/mem.rs
@@ -109,11 +109,11 @@ fn test_transmute() {
     trait Foo { fn dummy(&self) { } }
     impl Foo for isize {}
 
-    let a = box 100isize as Box<Foo>;
+    let a = box 100isize as Box<dyn Foo>;
     unsafe {
         let x: ::core::raw::TraitObject = transmute(a);
         assert!(*(x.data as *const isize) == 100);
-        let _x: Box<Foo> = transmute(x);
+        let _x: Box<dyn Foo> = transmute(x);
     }
 
     unsafe {
diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs
index bc3e61a4f54..324ebf43565 100644
--- a/src/libcore/tests/option.rs
+++ b/src/libcore/tests/option.rs
@@ -240,7 +240,7 @@ fn test_collect() {
     assert!(v == None);
 
     // test that it does not take more elements than it needs
-    let mut functions: [Box<Fn() -> Option<()>>; 3] =
+    let mut functions: [Box<dyn Fn() -> Option<()>>; 3] =
         [box || Some(()), box || None, box || panic!()];
 
     let v: Option<Vec<()>> = functions.iter_mut().map(|f| (*f)()).collect();
diff --git a/src/libcore/tests/ptr.rs b/src/libcore/tests/ptr.rs
index 31bc1d67768..92160910d8f 100644
--- a/src/libcore/tests/ptr.rs
+++ b/src/libcore/tests/ptr.rs
@@ -84,16 +84,16 @@ fn test_is_null() {
     assert!(nms.is_null());
 
     // Pointers to unsized types -- trait objects
-    let ci: *const ToString = &3;
+    let ci: *const dyn ToString = &3;
     assert!(!ci.is_null());
 
-    let mi: *mut ToString = &mut 3;
+    let mi: *mut dyn ToString = &mut 3;
     assert!(!mi.is_null());
 
-    let nci: *const ToString = null::<isize>();
+    let nci: *const dyn ToString = null::<isize>();
     assert!(nci.is_null());
 
-    let nmi: *mut ToString = null_mut::<isize>();
+    let nmi: *mut dyn ToString = null_mut::<isize>();
     assert!(nmi.is_null());
 }
 
@@ -140,16 +140,16 @@ fn test_as_ref() {
         assert_eq!(nms.as_ref(), None);
 
         // Pointers to unsized types -- trait objects
-        let ci: *const ToString = &3;
+        let ci: *const dyn ToString = &3;
         assert!(ci.as_ref().is_some());
 
-        let mi: *mut ToString = &mut 3;
+        let mi: *mut dyn ToString = &mut 3;
         assert!(mi.as_ref().is_some());
 
-        let nci: *const ToString = null::<isize>();
+        let nci: *const dyn ToString = null::<isize>();
         assert!(nci.as_ref().is_none());
 
-        let nmi: *mut ToString = null_mut::<isize>();
+        let nmi: *mut dyn ToString = null_mut::<isize>();
         assert!(nmi.as_ref().is_none());
     }
 }
@@ -182,10 +182,10 @@ fn test_as_mut() {
         assert_eq!(nms.as_mut(), None);
 
         // Pointers to unsized types -- trait objects
-        let mi: *mut ToString = &mut 3;
+        let mi: *mut dyn ToString = &mut 3;
         assert!(mi.as_mut().is_some());
 
-        let nmi: *mut ToString = null_mut::<isize>();
+        let nmi: *mut dyn ToString = null_mut::<isize>();
         assert!(nmi.as_mut().is_none());
     }
 }
diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs
index d9927ce4487..0616252c82c 100644
--- a/src/libcore/tests/result.rs
+++ b/src/libcore/tests/result.rs
@@ -81,7 +81,7 @@ fn test_collect() {
     assert!(v == Err(2));
 
     // test that it does not take more elements than it needs
-    let mut functions: [Box<Fn() -> Result<(), isize>>; 3] =
+    let mut functions: [Box<dyn Fn() -> Result<(), isize>>; 3] =
         [box || Ok(()), box || Err(1), box || panic!()];
 
     let v: Result<Vec<()>, isize> = functions.iter_mut().map(|f| (*f)()).collect();
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 30a3bbdc58e..3aa09a91e07 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -14,8 +14,6 @@
 //! Parsing does not happen at runtime: structures of `std::fmt::rt` are
 //! generated instead.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
diff --git a/src/libgraphviz/lib.rs b/src/libgraphviz/lib.rs
index 9e71ed4063e..158d0101515 100644
--- a/src/libgraphviz/lib.rs
+++ b/src/libgraphviz/lib.rs
@@ -283,8 +283,6 @@
 //!
 //! * [DOT language](http://www.graphviz.org/doc/info/lang.html)
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
diff --git a/src/libpanic_abort/lib.rs b/src/libpanic_abort/lib.rs
index 02ab28507d7..392bf17968f 100644
--- a/src/libpanic_abort/lib.rs
+++ b/src/libpanic_abort/lib.rs
@@ -21,7 +21,6 @@
        issue_tracker_base_url = "https://github.com/rust-lang/rust/issues/")]
 #![panic_runtime]
 #![allow(unused_features)]
-#![deny(bare_trait_objects)]
 
 #![feature(core_intrinsics)]
 #![feature(libc)]
diff --git a/src/libpanic_unwind/lib.rs b/src/libpanic_unwind/lib.rs
index f8cd29fc086..5c320bb369e 100644
--- a/src/libpanic_unwind/lib.rs
+++ b/src/libpanic_unwind/lib.rs
@@ -22,7 +22,6 @@
 //! More documentation about each implementation can be found in the respective
 //! module.
 
-#![deny(bare_trait_objects)]
 #![no_std]
 #![unstable(feature = "panic_unwind", issue = "32837")]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
diff --git a/src/libproc_macro/lib.rs b/src/libproc_macro/lib.rs
index 61da9db76f6..bf6e4a3aaa4 100644
--- a/src/libproc_macro/lib.rs
+++ b/src/libproc_macro/lib.rs
@@ -22,7 +22,6 @@
 //! See [the book](../book/first-edition/procedural-macros.html) for more.
 
 #![stable(feature = "proc_macro_lib", since = "1.15.0")]
-#![deny(bare_trait_objects)]
 #![deny(missing_docs)]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
diff --git a/src/libprofiler_builtins/lib.rs b/src/libprofiler_builtins/lib.rs
index 3d91505cd77..6d0d6d115b7 100644
--- a/src/libprofiler_builtins/lib.rs
+++ b/src/libprofiler_builtins/lib.rs
@@ -15,5 +15,4 @@
             reason = "internal implementation detail of rustc right now",
             issue = "0")]
 #![allow(unused_features)]
-#![deny(bare_trait_objects)]
 #![feature(staged_api)]
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 3b030fc098f..7e2c5d03d6b 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -746,7 +746,7 @@ impl<'a> LoweringContext<'a> {
     // This is used to track which lifetimes have already been defined, and
     // which are new in-band lifetimes that need to have a definition created
     // for them.
-    fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &Vec<GenericParam>, f: F) -> T
+    fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &[GenericParam], f: F) -> T
     where
         F: FnOnce(&mut LoweringContext) -> T,
     {
@@ -2237,7 +2237,7 @@ impl<'a> LoweringContext<'a> {
 
     fn lower_generic_params(
         &mut self,
-        params: &Vec<GenericParam>,
+        params: &[GenericParam],
         add_bounds: &NodeMap<Vec<GenericBound>>,
         mut itctx: ImplTraitContext,
     ) -> hir::HirVec<hir::GenericParam> {
diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs
index 656f325b4dd..a17c160c4d0 100644
--- a/src/librustc/hir/map/hir_id_validator.rs
+++ b/src/librustc/hir/map/hir_id_validator.rs
@@ -105,7 +105,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> {
               .collect();
 
             // Try to map those to something more useful
-            let mut missing_items = vec![];
+            let mut missing_items = Vec::with_capacity(missing.len());
 
             for local_id in missing {
                 let hir_id = HirId {
diff --git a/src/librustc/ich/hcx.rs b/src/librustc/ich/hcx.rs
index 04b725957b6..05361b65641 100644
--- a/src/librustc/ich/hcx.rs
+++ b/src/librustc/ich/hcx.rs
@@ -396,7 +396,7 @@ impl<'a> HashStable<StableHashingContext<'a>> for Span {
 pub fn hash_stable_trait_impls<'a, 'gcx, W, R>(
     hcx: &mut StableHashingContext<'a>,
     hasher: &mut StableHasher<W>,
-    blanket_impls: &Vec<DefId>,
+    blanket_impls: &[DefId],
     non_blanket_impls: &HashMap<fast_reject::SimplifiedType, Vec<DefId>, R>)
     where W: StableHasherResult,
           R: std_hash::BuildHasher,
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index c9ac6cdedbb..c106966fb70 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -423,6 +423,7 @@ impl_stable_hash_for!(enum ::syntax_pos::FileName {
     Anon,
     MacroExpansion,
     ProcMacroSourceCode,
+    CliCrateAttr,
     CfgSpec,
     Custom(s)
 });
diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs
index ae4d88704a0..205f8c5ad06 100644
--- a/src/librustc/infer/anon_types/mod.rs
+++ b/src/librustc/infer/anon_types/mod.rs
@@ -691,25 +691,41 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> {
                     // }
                     // ```
                     if let Some(anon_node_id) = tcx.hir.as_local_node_id(def_id) {
-                        let in_definition_scope = match tcx.hir.expect_item(anon_node_id).node {
-                            // impl trait
-                            hir::ItemKind::Existential(hir::ExistTy {
-                                impl_trait_fn: Some(parent),
-                                ..
-                            }) => parent == self.parent_def_id,
-                            // named existential types
-                            hir::ItemKind::Existential(hir::ExistTy {
-                                impl_trait_fn: None,
-                                ..
-                            }) => may_define_existential_type(
-                                tcx,
-                                self.parent_def_id,
-                                anon_node_id,
-                            ),
-                            _ => {
-                                let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
-                                self.parent_def_id == tcx.hir.local_def_id(anon_parent_node_id)
+                        let parent_def_id = self.parent_def_id;
+                        let def_scope_default = || {
+                            let anon_parent_node_id = tcx.hir.get_parent(anon_node_id);
+                            parent_def_id == tcx.hir.local_def_id(anon_parent_node_id)
+                        };
+                        let in_definition_scope = match tcx.hir.find(anon_node_id) {
+                            Some(hir::map::NodeItem(item)) => match item.node {
+                                // impl trait
+                                hir::ItemKind::Existential(hir::ExistTy {
+                                    impl_trait_fn: Some(parent),
+                                    ..
+                                }) => parent == self.parent_def_id,
+                                // named existential types
+                                hir::ItemKind::Existential(hir::ExistTy {
+                                    impl_trait_fn: None,
+                                    ..
+                                }) => may_define_existential_type(
+                                    tcx,
+                                    self.parent_def_id,
+                                    anon_node_id,
+                                ),
+                                _ => def_scope_default(),
                             },
+                            Some(hir::map::NodeImplItem(item)) => match item.node {
+                                hir::ImplItemKind::Existential(_) => may_define_existential_type(
+                                    tcx,
+                                    self.parent_def_id,
+                                    anon_node_id,
+                                ),
+                                _ => def_scope_default(),
+                            },
+                            _ => bug!(
+                                "expected (impl) item, found {}",
+                                tcx.hir.node_to_string(anon_node_id),
+                            ),
                         };
                         if in_definition_scope {
                             return self.fold_anon_ty(ty, def_id, substs);
diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs
index dbcb63addb8..693219ec4b0 100644
--- a/src/librustc/infer/error_reporting/need_type_info.rs
+++ b/src/librustc/infer/error_reporting/need_type_info.rs
@@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> Visitor<'gcx> for FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
 
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
-    fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
+    pub fn extract_type_name(&self, ty: &'a Ty<'tcx>) -> String {
         if let ty::TyInfer(ty::TyVar(ty_vid)) = (*ty).sty {
             let ty_vars = self.type_variables.borrow();
             if let TypeVariableOrigin::TypeParameterDefinition(_, name) =
diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs
index 07286f1250c..b8991a0366a 100644
--- a/src/librustc/infer/outlives/obligations.rs
+++ b/src/librustc/infer/outlives/obligations.rs
@@ -505,11 +505,7 @@ where
     }
 
     fn recursive_type_bound(&self, ty: Ty<'tcx>) -> VerifyBound<'tcx> {
-        let mut bounds = vec![];
-
-        for subty in ty.walk_shallow() {
-            bounds.push(self.type_bound(subty));
-        }
+        let mut bounds = ty.walk_shallow().map(|subty| self.type_bound(subty)).collect::<Vec<_>>();
 
         let mut regions = ty.regions();
         regions.retain(|r| !r.is_late_bound()); // ignore late-bound regions
diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs
index d709a4debd1..b6cb336648b 100644
--- a/src/librustc/lib.rs
+++ b/src/librustc/lib.rs
@@ -36,8 +36,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index 5c1009fb31f..14cfaa81533 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -219,7 +219,7 @@ impl LintStore {
             }
         }
 
-        let mut future_incompatible = vec![];
+        let mut future_incompatible = Vec::with_capacity(lints.len());
         for lint in lints {
             future_incompatible.push(lint.id);
             self.future_incompatible.insert(lint.id, lint);
diff --git a/src/librustc/middle/borrowck.rs b/src/librustc/middle/borrowck.rs
index 6f5791ed5d7..c8d513a59f0 100644
--- a/src/librustc/middle/borrowck.rs
+++ b/src/librustc/middle/borrowck.rs
@@ -15,9 +15,15 @@ use util::nodemap::FxHashSet;
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher,
                                            StableHasherResult};
 
+#[derive(Copy, Clone, Debug, RustcEncodable, RustcDecodable)]
+pub enum SignalledError { SawSomeError, NoErrorsSeen }
+
+impl_stable_hash_for!(enum self::SignalledError { SawSomeError, NoErrorsSeen });
+
 #[derive(Debug, RustcEncodable, RustcDecodable)]
 pub struct BorrowCheckResult {
     pub used_mut_nodes: FxHashSet<HirId>,
+    pub signalled_any_error: SignalledError,
 }
 
 impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult {
@@ -26,7 +32,9 @@ impl<'a> HashStable<StableHashingContext<'a>> for BorrowCheckResult {
                                           hasher: &mut StableHasher<W>) {
         let BorrowCheckResult {
             ref used_mut_nodes,
+            ref signalled_any_error,
         } = *self;
         used_mut_nodes.hash_stable(hcx, hasher);
+        signalled_any_error.hash_stable(hcx, hasher);
     }
 }
diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs
index 6c1ef851cbe..cf94a0fb4b4 100644
--- a/src/librustc/middle/lang_items.rs
+++ b/src/librustc/middle/lang_items.rs
@@ -324,6 +324,8 @@ language_item_table! {
 
     NonZeroItem,                     "non_zero",                non_zero;
 
+    ManuallyDropItem,                "manually_drop",           manually_drop;
+
     DebugTraitLangItem,              "debug_trait",             debug_trait;
 
     // A lang item for each of the 128-bit operators we can optionally lower.
diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs
index 54d9e24bbc0..8f3ed3106d5 100644
--- a/src/librustc/session/config.rs
+++ b/src/librustc/session/config.rs
@@ -455,15 +455,28 @@ pub enum BorrowckMode {
     Ast,
     Mir,
     Compare,
+    Migrate,
 }
 
 impl BorrowckMode {
+    /// Should we run the MIR-based borrow check, but also fall back
+    /// on the AST borrow check if the MIR-based one errors.
+    pub fn migrate(self) -> bool {
+        match self {
+            BorrowckMode::Ast => false,
+            BorrowckMode::Compare => false,
+            BorrowckMode::Mir => false,
+            BorrowckMode::Migrate => true,
+        }
+    }
+
     /// Should we emit the AST-based borrow checker errors?
     pub fn use_ast(self) -> bool {
         match self {
             BorrowckMode::Ast => true,
             BorrowckMode::Compare => true,
             BorrowckMode::Mir => false,
+            BorrowckMode::Migrate => false,
         }
     }
     /// Should we emit the MIR-based borrow checker errors?
@@ -472,6 +485,7 @@ impl BorrowckMode {
             BorrowckMode::Ast => false,
             BorrowckMode::Compare => true,
             BorrowckMode::Mir => true,
+            BorrowckMode::Migrate => true,
         }
     }
 }
@@ -1127,7 +1141,7 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
     emit_end_regions: bool = (false, parse_bool, [UNTRACKED],
         "emit EndRegion as part of MIR; enable transforms that solely process EndRegion"),
     borrowck: Option<String> = (None, parse_opt_string, [UNTRACKED],
-        "select which borrowck is used (`ast`, `mir`, or `compare`)"),
+        "select which borrowck is used (`ast`, `mir`, `migrate`, or `compare`)"),
     two_phase_borrows: bool = (false, parse_bool, [UNTRACKED],
         "use two-phase reserved/active distinction for `&mut` borrows in MIR borrowck"),
     two_phase_beyond_autoref: bool = (false, parse_bool, [UNTRACKED],
@@ -1233,8 +1247,6 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "for every macro invocation, print its name and arguments"),
     debug_macros: bool = (false, parse_bool, [TRACKED],
           "emit line numbers debug info inside macros"),
-    enable_nonzeroing_move_hints: bool = (false, parse_bool, [TRACKED],
-          "force nonzeroing move optimization on"),
     keep_hygiene_data: bool = (false, parse_bool, [UNTRACKED],
           "don't clear the hygiene data after analysis"),
     keep_ast: bool = (false, parse_bool, [UNTRACKED],
@@ -1355,6 +1367,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options,
           "don't run LLVM in parallel (while keeping codegen-units and ThinLTO)"),
     no_leak_check: bool = (false, parse_bool, [UNTRACKED],
         "disables the 'leak check' for subtyping; unsound, but useful for tests"),
+    crate_attr: Vec<String> = (Vec::new(), parse_string_push, [TRACKED],
+        "inject the given attribute in the crate"),
 }
 
 pub fn default_lib_output() -> CrateType {
@@ -2168,6 +2182,7 @@ pub fn build_session_options_and_crate_config(
         None | Some("ast") => BorrowckMode::Ast,
         Some("mir") => BorrowckMode::Mir,
         Some("compare") => BorrowckMode::Compare,
+        Some("migrate") => BorrowckMode::Migrate,
         Some(m) => early_error(error_format, &format!("unknown borrowck mode `{}`", m)),
     };
 
@@ -3154,10 +3169,6 @@ mod tests {
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
         opts = reference.clone();
-        opts.debugging_opts.enable_nonzeroing_move_hints = true;
-        assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
-
-        opts = reference.clone();
         opts.debugging_opts.show_span = Some(String::from("abc"));
         assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash());
 
diff --git a/src/librustc/session/mod.rs b/src/librustc/session/mod.rs
index 77a1129f66d..7b8bbbf4a10 100644
--- a/src/librustc/session/mod.rs
+++ b/src/librustc/session/mod.rs
@@ -624,9 +624,6 @@ impl Session {
     pub fn unstable_options(&self) -> bool {
         self.opts.debugging_opts.unstable_options
     }
-    pub fn nonzeroing_move_hints(&self) -> bool {
-        self.opts.debugging_opts.enable_nonzeroing_move_hints
-    }
     pub fn overflow_checks(&self) -> bool {
         self.opts
             .cg
diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs
index 6a6bebdbd86..02bfab033ef 100644
--- a/src/librustc/traits/coherence.rs
+++ b/src/librustc/traits/coherence.rs
@@ -59,7 +59,7 @@ where
     F1: FnOnce(OverlapResult<'_>) -> R,
     F2: FnOnce() -> R,
 {
-    debug!("impl_can_satisfy(\
+    debug!("overlapping_impls(\
            impl1_def_id={:?}, \
            impl2_def_id={:?},
            intercrate_mode={:?})",
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 8300f98fb1c..5f8a2208bb0 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -48,7 +48,7 @@ use syntax_pos::{DUMMY_SP, Span};
 
 impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     pub fn report_fulfillment_errors(&self,
-                                     errors: &Vec<FulfillmentError<'tcx>>,
+                                     errors: &[FulfillmentError<'tcx>],
                                      body_id: Option<hir::BodyId>,
                                      fallback_has_occurred: bool) {
         #[derive(Debug)]
@@ -1015,7 +1015,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
     ) -> DiagnosticBuilder<'tcx> {
         let kind = if is_closure { "closure" } else { "function" };
 
-        let args_str = |arguments: &Vec<ArgKind>, other: &Vec<ArgKind>| {
+        let args_str = |arguments: &[ArgKind], other: &[ArgKind]| {
             let arg_length = arguments.len();
             let distinct = match &other[..] {
                 &[ArgKind::Tuple(..)] => true,
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 83128ba75d5..aa4f63675d7 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -98,13 +98,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
                                             -> Vec<ObjectSafetyViolation>
     {
-        let mut violations = vec![];
-
-        for def_id in traits::supertrait_def_ids(self, trait_def_id) {
-            if self.predicates_reference_self(def_id, true) {
-                violations.push(ObjectSafetyViolation::SupertraitSelf);
-            }
-        }
+        let violations = traits::supertrait_def_ids(self, trait_def_id)
+            .filter(|&def_id| self.predicates_reference_self(def_id, true))
+            .map(|_| ObjectSafetyViolation::SupertraitSelf)
+            .collect();
 
         debug!("astconv_object_safety_violations(trait_def_id={:?}) = {:?}",
                trait_def_id,
diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs
index 1052d029e0d..1ce60d8f055 100644
--- a/src/librustc/traits/project.rs
+++ b/src/librustc/traits/project.rs
@@ -1502,7 +1502,7 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
     let param_env = obligation.param_env;
     let assoc_ty = assoc_ty_def(selcx, impl_def_id, obligation.predicate.item_def_id);
 
-    let ty = if !assoc_ty.item.defaultness.has_value() {
+    if !assoc_ty.item.defaultness.has_value() {
         // This means that the impl is missing a definition for the
         // associated type. This error will be reported by the type
         // checker method `check_impl_items_against_trait`, so here we
@@ -1510,11 +1510,18 @@ fn confirm_impl_candidate<'cx, 'gcx, 'tcx>(
         debug!("confirm_impl_candidate: no associated type {:?} for {:?}",
                assoc_ty.item.ident,
                obligation.predicate);
-        tcx.types.err
+        return Progress {
+            ty: tcx.types.err,
+            obligations: nested,
+        };
+    }
+    let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
+    let ty = if let ty::AssociatedKind::Existential = assoc_ty.item.kind {
+        let item_substs = Substs::identity_for_item(tcx, assoc_ty.item.def_id);
+        tcx.mk_anon(assoc_ty.item.def_id, item_substs)
     } else {
         tcx.type_of(assoc_ty.item.def_id)
     };
-    let substs = translate_substs(selcx.infcx(), param_env, impl_def_id, substs, assoc_ty.node);
     Progress {
         ty: ty.subst(tcx, substs),
         obligations: nested,
diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs
index 73a9ff4e483..a48d24bb97a 100644
--- a/src/librustc/traits/query/dropck_outlives.rs
+++ b/src/librustc/traits/query/dropck_outlives.rs
@@ -243,7 +243,10 @@ pub fn trivial_dropck_outlives<'tcx>(tcx: TyCtxt<'_, '_, 'tcx>, ty: Ty<'tcx>) ->
 
         ty::TyAdt(def, _) => {
             if def.is_union() {
-                // Unions never run have a dtor.
+                // Unions never have a dtor.
+                true
+            } else if Some(def.did) == tcx.lang_items().manually_drop() {
+                // `ManuallyDrop` never has a dtor.
                 true
             } else {
                 // Other types might. Moreover, PhantomData doesn't
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index b64e4228be9..f9c0581d3ca 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -73,8 +73,8 @@ enum Inserted {
     /// The impl was inserted as a new child in this group of children.
     BecameNewSibling(Option<OverlapError>),
 
-    /// The impl replaced an existing impl that specializes it.
-    Replaced(DefId),
+    /// The impl should replace an existing impl X, because the impl specializes X.
+    ReplaceChild(DefId),
 
     /// The impl is a specialization of an existing child.
     ShouldRecurseOn(DefId),
@@ -94,12 +94,34 @@ impl<'a, 'gcx, 'tcx> Children {
                       impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
         if let Some(sty) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
+            debug!("insert_blindly: impl_def_id={:?} sty={:?}", impl_def_id, sty);
             self.nonblanket_impls.entry(sty).or_insert(vec![]).push(impl_def_id)
         } else {
+            debug!("insert_blindly: impl_def_id={:?} sty=None", impl_def_id);
             self.blanket_impls.push(impl_def_id)
         }
     }
 
+    /// Remove an impl from this set of children. Used when replacing
+    /// an impl with a parent. The impl must be present in the list of
+    /// children already.
+    fn remove_existing(&mut self,
+                      tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                      impl_def_id: DefId) {
+        let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap();
+        let vec: &mut Vec<DefId>;
+        if let Some(sty) = fast_reject::simplify_type(tcx, trait_ref.self_ty(), false) {
+            debug!("remove_existing: impl_def_id={:?} sty={:?}", impl_def_id, sty);
+            vec = self.nonblanket_impls.get_mut(&sty).unwrap();
+        } else {
+            debug!("remove_existing: impl_def_id={:?} sty=None", impl_def_id);
+            vec = &mut self.blanket_impls;
+        }
+
+        let index = vec.iter().position(|d| *d == impl_def_id).unwrap();
+        vec.remove(index);
+    }
+
     /// Attempt to insert an impl into this set of children, while comparing for
     /// specialization relationships.
     fn insert(&mut self,
@@ -110,11 +132,22 @@ impl<'a, 'gcx, 'tcx> Children {
     {
         let mut last_lint = None;
 
-        for slot in match simplified_self {
-            Some(sty) => self.filtered_mut(sty),
-            None => self.iter_mut(),
+        debug!(
+            "insert(impl_def_id={:?}, simplified_self={:?})",
+            impl_def_id,
+            simplified_self,
+        );
+
+        for possible_sibling in match simplified_self {
+            Some(sty) => self.filtered(sty),
+            None => self.iter(),
         } {
-            let possible_sibling = *slot;
+            debug!(
+                "insert: impl_def_id={:?}, simplified_self={:?}, possible_sibling={:?}",
+                impl_def_id,
+                simplified_self,
+                possible_sibling,
+            );
 
             let overlap_error = |overlap: traits::coherence::OverlapResult| {
                 // overlap, but no specialization; error out
@@ -168,9 +201,7 @@ impl<'a, 'gcx, 'tcx> Children {
                 debug!("placing as parent of TraitRef {:?}",
                        tcx.impl_trait_ref(possible_sibling).unwrap());
 
-                    // possible_sibling specializes the impl
-                    *slot = impl_def_id;
-                return Ok(Inserted::Replaced(possible_sibling));
+                return Ok(Inserted::ReplaceChild(possible_sibling));
             } else {
                 if !tcx.impls_are_allowed_to_overlap(impl_def_id, possible_sibling) {
                     traits::overlapping_impls(
@@ -193,15 +224,14 @@ impl<'a, 'gcx, 'tcx> Children {
         Ok(Inserted::BecameNewSibling(last_lint))
     }
 
-    fn iter_mut(&'a mut self) -> Box<dyn Iterator<Item = &'a mut DefId> + 'a> {
-        let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter_mut());
-        Box::new(self.blanket_impls.iter_mut().chain(nonblanket))
+    fn iter(&mut self) -> Box<dyn Iterator<Item = DefId> + '_> {
+        let nonblanket = self.nonblanket_impls.iter_mut().flat_map(|(_, v)| v.iter());
+        Box::new(self.blanket_impls.iter().chain(nonblanket).cloned())
     }
 
-    fn filtered_mut(&'a mut self, sty: SimplifiedType)
-                    -> Box<dyn Iterator<Item = &'a mut DefId> + 'a> {
-        let nonblanket = self.nonblanket_impls.entry(sty).or_insert(vec![]).iter_mut();
-        Box::new(self.blanket_impls.iter_mut().chain(nonblanket))
+    fn filtered(&mut self, sty: SimplifiedType) -> Box<dyn Iterator<Item = DefId> + '_> {
+        let nonblanket = self.nonblanket_impls.entry(sty).or_insert(vec![]).iter();
+        Box::new(self.blanket_impls.iter().chain(nonblanket).cloned())
     }
 }
 
@@ -259,11 +289,38 @@ impl<'a, 'gcx, 'tcx> Graph {
                     last_lint = opt_lint;
                     break;
                 }
-                Replaced(new_child) => {
-                    self.parent.insert(new_child, impl_def_id);
-                    let mut new_children = Children::new();
-                    new_children.insert_blindly(tcx, new_child);
-                    self.children.insert(impl_def_id, new_children);
+                ReplaceChild(grand_child_to_be) => {
+                    // We currently have
+                    //
+                    //     P
+                    //     |
+                    //     G
+                    //
+                    // and we are inserting the impl N. We want to make it:
+                    //
+                    //     P
+                    //     |
+                    //     N
+                    //     |
+                    //     G
+
+                    // Adjust P's list of children: remove G and then add N.
+                    {
+                        let siblings = self.children
+                            .get_mut(&parent)
+                            .unwrap();
+                        siblings.remove_existing(tcx, grand_child_to_be);
+                        siblings.insert_blindly(tcx, impl_def_id);
+                    }
+
+                    // Set G's parent to N and N's parent to P
+                    self.parent.insert(grand_child_to_be, impl_def_id);
+                    self.parent.insert(impl_def_id, parent);
+
+                    // Add G as N's child.
+                    let mut grand_children = Children::new();
+                    grand_children.insert_blindly(tcx, grand_child_to_be);
+                    self.children.insert(impl_def_id, grand_children);
                     break;
                 }
                 ShouldRecurseOn(new_parent) => {
@@ -377,9 +434,19 @@ impl<'a, 'gcx, 'tcx> Ancestors {
         trait_def_id: DefId,
     ) -> impl Iterator<Item = NodeItem<ty::AssociatedItem>> + Captures<'gcx> + Captures<'tcx> + 'a {
         self.flat_map(move |node| {
-            node.items(tcx).filter(move |impl_item| {
-                impl_item.kind == trait_item_kind &&
-                tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id)
+            use ty::AssociatedKind::*;
+            node.items(tcx).filter(move |impl_item| match (trait_item_kind, impl_item.kind) {
+                | (Const, Const)
+                | (Method, Method)
+                | (Type, Type)
+                | (Type, Existential)
+                => tcx.hygienic_eq(impl_item.ident, trait_item_name, trait_def_id),
+
+                | (Const, _)
+                | (Method, _)
+                | (Type, _)
+                | (Existential, _)
+                => false,
             }).map(move |item| NodeItem { node: node, item: item })
         })
     }
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index 41007508c50..98568f860a4 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -74,6 +74,7 @@ use rustc_target::spec::abi;
 use syntax::ast::{self, NodeId};
 use syntax::attr;
 use syntax::codemap::MultiSpan;
+use syntax::edition::Edition;
 use syntax::feature_gate;
 use syntax::symbol::{Symbol, keywords, InternedString};
 use syntax_pos::Span;
@@ -1366,6 +1367,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.borrowck_mode().use_mir()
     }
 
+    /// If true, we should use the MIR-based borrow check, but also
+    /// fall back on the AST borrow check if the MIR-based one errors.
+    pub fn migrate_borrowck(self) -> bool {
+        self.borrowck_mode().migrate()
+    }
+
     /// If true, make MIR codegen for `match` emit a temp that holds a
     /// borrow of the input to the match expression.
     pub fn generate_borrow_of_any_match_input(&self) -> bool {
@@ -1397,18 +1404,51 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     /// What mode(s) of borrowck should we run? AST? MIR? both?
     /// (Also considers the `#![feature(nll)]` setting.)
     pub fn borrowck_mode(&self) -> BorrowckMode {
-        match self.sess.opts.borrowck_mode {
-            mode @ BorrowckMode::Mir |
-            mode @ BorrowckMode::Compare => mode,
+        // Here are the main constraints we need to deal with:
+        //
+        // 1. An opts.borrowck_mode of `BorrowckMode::Ast` is
+        //    synonymous with no `-Z borrowck=...` flag at all.
+        //    (This is arguably a historical accident.)
+        //
+        // 2. `BorrowckMode::Migrate` is the limited migration to
+        //    NLL that we are deploying with the 2018 edition.
+        //
+        // 3. We want to allow developers on the Nightly channel
+        //    to opt back into the "hard error" mode for NLL,
+        //    (which they can do via specifying `#![feature(nll)]`
+        //    explicitly in their crate).
+        //
+        // So, this precedence list is how pnkfelix chose to work with
+        // the above constraints:
+        //
+        // * `#![feature(nll)]` *always* means use NLL with hard
+        //   errors. (To simplify the code here, it now even overrides
+        //   a user's attempt to specify `-Z borrowck=compare`, which
+        //   we arguably do not need anymore and should remove.)
+        //
+        // * Otherwise, if no `-Z borrowck=...` flag was given (or
+        //   if `borrowck=ast` was specified), then use the default
+        //   as required by the edition.
+        //
+        // * Otherwise, use the behavior requested via `-Z borrowck=...`
 
-            mode @ BorrowckMode::Ast => {
-                if self.features().nll {
-                    BorrowckMode::Mir
-                } else {
-                    mode
-                }
-            }
+        if self.features().nll { return BorrowckMode::Mir; }
 
+        match self.sess.opts.borrowck_mode {
+            mode @ BorrowckMode::Mir |
+            mode @ BorrowckMode::Compare |
+            mode @ BorrowckMode::Migrate => mode,
+
+            BorrowckMode::Ast => match self.sess.edition() {
+                Edition::Edition2015 => BorrowckMode::Ast,
+                Edition::Edition2018 => BorrowckMode::Migrate,
+
+                // For now, future editions mean Migrate. (But it
+                // would make a lot of sense for it to be changed to
+                // `BorrowckMode::Mir`, depending on how we plan to
+                // time the forcing of full migration to NLL.)
+                _ => BorrowckMode::Migrate,
+            },
         }
     }
 
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index d5425aff6ba..95caa0c185b 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -932,6 +932,9 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         // Foreign types can never have destructors
         ty::TyForeign(..) => false,
 
+        // `ManuallyDrop` doesn't have a destructor regardless of field types.
+        ty::TyAdt(def, _) if Some(def.did) == tcx.lang_items().manually_drop() => false,
+
         // Issue #22536: We first query type_moves_by_default.  It sees a
         // normalized version of the type, and therefore will definitely
         // know whether the type implements Copy (and thus needs no
@@ -967,7 +970,8 @@ fn needs_drop_raw<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
         ty::TyTuple(ref tys) => tys.iter().cloned().any(needs_drop),
 
-        // unions don't have destructors regardless of the child types
+        // unions don't have destructors because of the child types,
+        // only if they manually implement `Drop` (handled above).
         ty::TyAdt(def, _) if def.is_union() => false,
 
         ty::TyAdt(def, substs) =>
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index c67453d2b20..15b5edaa3d5 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -19,7 +19,7 @@ use ty::{TyError, TyStr, TyArray, TySlice, TyFloat, TyFnDef, TyFnPtr};
 use ty::{TyParam, TyRawPtr, TyRef, TyNever, TyTuple};
 use ty::{TyClosure, TyGenerator, TyGeneratorWitness, TyForeign, TyProjection, TyAnon};
 use ty::{TyDynamic, TyInt, TyUint, TyInfer};
-use ty::{self, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind};
+use ty::{self, RegionVid, Ty, TyCtxt, TypeFoldable, GenericParamCount, GenericParamDefKind};
 use util::nodemap::FxHashSet;
 
 use std::cell::Cell;
@@ -32,6 +32,12 @@ use syntax::ast::CRATE_NODE_ID;
 use syntax::symbol::{Symbol, InternedString};
 use hir;
 
+thread_local! {
+    /// Mechanism for highlighting of specific regions for display in NLL region inference errors.
+    /// Contains region to highlight and counter for number to use when highlighting.
+    static HIGHLIGHT_REGION: Cell<Option<(RegionVid, usize)>> = Cell::new(None)
+}
+
 macro_rules! gen_display_debug_body {
     ( $with:path ) => {
         fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -562,6 +568,19 @@ pub fn parameterized<F: fmt::Write>(f: &mut F,
     PrintContext::new().parameterized(f, substs, did, projections)
 }
 
+fn get_highlight_region() -> Option<(RegionVid, usize)> {
+    HIGHLIGHT_REGION.with(|hr| hr.get())
+}
+
+pub fn with_highlight_region<R>(r: RegionVid, counter: usize, op: impl FnOnce() -> R) -> R {
+    HIGHLIGHT_REGION.with(|hr| {
+        assert_eq!(hr.get(), None);
+        hr.set(Some((r, counter)));
+        let r = op();
+        hr.set(None);
+        r
+    })
+}
 
 impl<'a, T: Print> Print for &'a T {
     fn print<F: fmt::Write>(&self, f: &mut F, cx: &mut PrintContext) -> fmt::Result {
@@ -733,7 +752,7 @@ define_print! {
 define_print! {
     () ty::RegionKind, (self, f, cx) {
         display {
-            if cx.is_verbose {
+            if cx.is_verbose || get_highlight_region().is_some() {
                 return self.print_debug(f, cx);
             }
 
@@ -905,6 +924,15 @@ impl fmt::Debug for ty::FloatVid {
 
 impl fmt::Debug for ty::RegionVid {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        if let Some((region, counter)) = get_highlight_region() {
+            debug!("RegionVid.fmt: region={:?} self={:?} counter={:?}", region, self, counter);
+            return if *self == region {
+                write!(f, "'{:?}", counter)
+            } else {
+                write!(f, "'_")
+            }
+        }
+
         write!(f, "'_#{}r", self.index())
     }
 }
@@ -1022,9 +1050,11 @@ define_print! {
                 TyRef(r, ty, mutbl) => {
                     write!(f, "&")?;
                     let s = r.print_to_string(cx);
-                    write!(f, "{}", s)?;
-                    if !s.is_empty() {
-                        write!(f, " ")?;
+                    if s != "'_" {
+                        write!(f, "{}", s)?;
+                        if !s.is_empty() {
+                            write!(f, " ")?;
+                        }
                     }
                     ty::TypeAndMut { ty, mutbl }.print(f, cx)
                 }
diff --git a/src/librustc_allocator/lib.rs b/src/librustc_allocator/lib.rs
index 1227936ce96..b217d3665a2 100644
--- a/src/librustc_allocator/lib.rs
+++ b/src/librustc_allocator/lib.rs
@@ -8,7 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
 #![feature(rustc_private)]
 
 #[macro_use] extern crate log;
diff --git a/src/librustc_apfloat/lib.rs b/src/librustc_apfloat/lib.rs
index c7cd958016d..08438805a70 100644
--- a/src/librustc_apfloat/lib.rs
+++ b/src/librustc_apfloat/lib.rs
@@ -40,8 +40,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_asan/lib.rs b/src/librustc_asan/lib.rs
index 7bd1e98f85d..0c78fd74a23 100644
--- a/src/librustc_asan/lib.rs
+++ b/src/librustc_asan/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![sanitizer_runtime]
 #![feature(alloc_system)]
 #![feature(sanitizer_runtime)]
diff --git a/src/librustc_borrowck/borrowck/check_loans.rs b/src/librustc_borrowck/borrowck/check_loans.rs
index 002e8697588..49bd69f8262 100644
--- a/src/librustc_borrowck/borrowck/check_loans.rs
+++ b/src/librustc_borrowck/borrowck/check_loans.rs
@@ -447,10 +447,12 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                                       .region_scope_tree
                                       .yield_in_scope_for_expr(scope,
                                                                cmt.hir_id,
-                                                               self.bccx.body) {
+                                                               self.bccx.body)
+        {
             self.bccx.cannot_borrow_across_generator_yield(borrow_span,
                                                            yield_span,
                                                            Origin::Ast).emit();
+            self.bccx.signal_error();
         }
     }
 
@@ -507,9 +509,13 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
             new_loan, old_loan, old_loan, new_loan).err();
 
         match (err_old_new, err_new_old) {
-            (Some(mut err), None) | (None, Some(mut err)) => err.emit(),
+            (Some(mut err), None) | (None, Some(mut err)) => {
+                err.emit();
+                self.bccx.signal_error();
+            }
             (Some(mut err_old), Some(mut err_new)) => {
                 err_old.emit();
+                self.bccx.signal_error();
                 err_new.cancel();
             }
             (None, None) => return true,
@@ -695,6 +701,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                         loan_span, &self.bccx.loan_path_to_string(&loan_path),
                         Origin::Ast)
                     .emit();
+                self.bccx.signal_error();
             }
         }
     }
@@ -745,6 +752,7 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
                 };
 
                 err.emit();
+                self.bccx.signal_error();
             }
         }
     }
@@ -914,5 +922,6 @@ impl<'a, 'tcx> CheckLoanCtxt<'a, 'tcx> {
         self.bccx.cannot_assign_to_borrowed(
             span, loan.span, &self.bccx.loan_path_to_string(loan_path), Origin::Ast)
             .emit();
+        self.bccx.signal_error();
     }
 }
diff --git a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
index f221565c7f3..b217e6a8564 100644
--- a/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
+++ b/src/librustc_borrowck/borrowck/gather_loans/move_error.rs
@@ -68,7 +68,7 @@ pub struct GroupedMoveErrors<'tcx> {
     move_to_places: Vec<MovePlace<'tcx>>
 }
 
-fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<MoveError<'tcx>>) {
+fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &[MoveError<'tcx>]) {
     let grouped_errors = group_errors_with_same_origin(errors);
     for error in &grouped_errors {
         let mut err = report_cannot_move_out_of(bccx, error.move_from.clone());
@@ -99,10 +99,11 @@ fn report_move_errors<'a, 'tcx>(bccx: &BorrowckCtxt<'a, 'tcx>, errors: &Vec<Move
                            "captured outer variable");
         }
         err.emit();
+        bccx.signal_error();
     }
 }
 
-fn group_errors_with_same_origin<'tcx>(errors: &Vec<MoveError<'tcx>>)
+fn group_errors_with_same_origin<'tcx>(errors: &[MoveError<'tcx>])
                                        -> Vec<GroupedMoveErrors<'tcx>> {
     let mut grouped_errors = Vec::new();
     for error in errors {
diff --git a/src/librustc_borrowck/borrowck/mod.rs b/src/librustc_borrowck/borrowck/mod.rs
index 3ae1e5aac50..0cb4a766e80 100644
--- a/src/librustc_borrowck/borrowck/mod.rs
+++ b/src/librustc_borrowck/borrowck/mod.rs
@@ -28,7 +28,7 @@ use rustc::middle::dataflow::DataFlowContext;
 use rustc::middle::dataflow::BitwiseOperator;
 use rustc::middle::dataflow::DataFlowOperator;
 use rustc::middle::dataflow::KillFrom;
-use rustc::middle::borrowck::BorrowCheckResult;
+use rustc::middle::borrowck::{BorrowCheckResult, SignalledError};
 use rustc::hir::def_id::{DefId, LocalDefId};
 use rustc::middle::expr_use_visitor as euv;
 use rustc::middle::mem_categorization as mc;
@@ -42,7 +42,7 @@ use rustc_mir::util::borrowck_errors::{BorrowckErrors, Origin};
 use rustc_mir::util::suggest_ref_mut;
 use rustc::util::nodemap::FxHashSet;
 
-use std::cell::RefCell;
+use std::cell::{Cell, RefCell};
 use std::fmt;
 use std::rc::Rc;
 use rustc_data_structures::sync::Lrc;
@@ -90,7 +90,7 @@ pub struct AnalysisData<'a, 'tcx: 'a> {
 fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
     -> Lrc<BorrowCheckResult>
 {
-    assert!(tcx.use_ast_borrowck());
+    assert!(tcx.use_ast_borrowck() || tcx.migrate_borrowck());
 
     debug!("borrowck(body_owner_def_id={:?})", owner_def_id);
 
@@ -105,6 +105,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
             // and do not need borrowchecking.
             return Lrc::new(BorrowCheckResult {
                 used_mut_nodes: FxHashSet(),
+                signalled_any_error: SignalledError::NoErrorsSeen,
             })
         }
         _ => { }
@@ -121,6 +122,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
         owner_def_id,
         body,
         used_mut_nodes: RefCell::new(FxHashSet()),
+        signalled_any_error: Cell::new(SignalledError::NoErrorsSeen),
     };
 
     // Eventually, borrowck will always read the MIR, but at the
@@ -154,6 +156,7 @@ fn borrowck<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, owner_def_id: DefId)
 
     Lrc::new(BorrowCheckResult {
         used_mut_nodes: bccx.used_mut_nodes.into_inner(),
+        signalled_any_error: bccx.signalled_any_error.into_inner(),
     })
 }
 
@@ -234,6 +237,7 @@ pub fn build_borrowck_dataflow_data_for_fn<'a, 'tcx>(
         owner_def_id,
         body,
         used_mut_nodes: RefCell::new(FxHashSet()),
+        signalled_any_error: Cell::new(SignalledError::NoErrorsSeen),
     };
 
     let dataflow_data = build_borrowck_dataflow_data(&mut bccx, true, body_id, |_| cfg);
@@ -257,6 +261,15 @@ pub struct BorrowckCtxt<'a, 'tcx: 'a> {
     body: &'tcx hir::Body,
 
     used_mut_nodes: RefCell<FxHashSet<HirId>>,
+
+    signalled_any_error: Cell<SignalledError>,
+}
+
+
+impl<'a, 'tcx: 'a> BorrowckCtxt<'a, 'tcx> {
+    fn signal_error(&self) {
+        self.signalled_any_error.set(SignalledError::SawSomeError);
+    }
 }
 
 impl<'a, 'b, 'tcx: 'b> BorrowckErrors<'a> for &'a BorrowckCtxt<'b, 'tcx> {
@@ -645,6 +658,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     .span_label(use_span, format!("use of possibly uninitialized `{}`",
                                                   self.loan_path_to_string(lp)))
                     .emit();
+                self.signal_error();
                 return;
             }
             _ => {
@@ -760,6 +774,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
         // not considered particularly helpful.
 
         err.emit();
+        self.signal_error();
     }
 
     pub fn report_partial_reinitialization_of_uninitialized_structure(
@@ -770,6 +785,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                                       &self.loan_path_to_string(lp),
                                                       Origin::Ast)
             .emit();
+        self.signal_error();
     }
 
     pub fn report_reassigned_immutable_variable(&self,
@@ -787,6 +803,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                                 self.loan_path_to_string(lp)));
         }
         err.emit();
+        self.signal_error();
     }
 
     pub fn struct_span_err_with_code<S: Into<MultiSpan>>(&self,
@@ -908,6 +925,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     self.tcx.hir.hir_to_node_id(err.cmt.hir_id)
                 );
                 db.emit();
+                self.signal_error();
             }
             err_out_of_scope(super_scope, sub_scope, cause) => {
                 let msg = match opt_loan_path(&err.cmt) {
@@ -1022,6 +1040,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                 }
 
                 db.emit();
+                self.signal_error();
             }
             err_borrowed_pointer_too_short(loan_scope, ptr_scope) => {
                 let descr = self.cmt_to_path_or_string(err.cmt);
@@ -1047,6 +1066,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                     "");
 
                 db.emit();
+                self.signal_error();
             }
         }
     }
@@ -1125,6 +1145,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
             err.help("closures behind references must be called via `&mut`");
         }
         err.emit();
+        self.signal_error();
     }
 
     /// Given a type, if it is an immutable reference, return a suggestion to make it mutable
@@ -1307,6 +1328,7 @@ impl<'a, 'tcx> BorrowckCtxt<'a, 'tcx> {
                                        cmt_path_or_string),
                              suggestion)
             .emit();
+        self.signal_error();
     }
 
     fn region_end_span(&self, region: ty::Region<'tcx>) -> Option<Span> {
diff --git a/src/librustc_borrowck/lib.rs b/src/librustc_borrowck/lib.rs
index d583a32c431..a5a20af0e4e 100644
--- a/src/librustc_borrowck/lib.rs
+++ b/src/librustc_borrowck/lib.rs
@@ -13,7 +13,6 @@
       html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![allow(non_camel_case_types)]
-#![deny(bare_trait_objects)]
 
 #![feature(from_ref)]
 #![feature(quote)]
diff --git a/src/librustc_codegen_llvm/back/link.rs b/src/librustc_codegen_llvm/back/link.rs
index f2b17584adc..13f0c90e885 100644
--- a/src/librustc_codegen_llvm/back/link.rs
+++ b/src/librustc_codegen_llvm/back/link.rs
@@ -40,6 +40,7 @@ use std::env;
 use std::fmt;
 use std::fs;
 use std::io;
+use std::iter;
 use std::path::{Path, PathBuf};
 use std::process::{Output, Stdio};
 use std::str;
@@ -885,9 +886,9 @@ fn exec_linker(sess: &Session, cmd: &mut Command, out_filename: &Path, tmpdir: &
     }
     let file = tmpdir.join("linker-arguments");
     let bytes = if sess.target.target.options.is_like_msvc {
-        let mut out = vec![];
+        let mut out = Vec::with_capacity((1 + args.len()) * 2);
         // start the stream with a UTF-16 BOM
-        for c in vec![0xFEFF].into_iter().chain(args.encode_utf16()) {
+        for c in iter::once(0xFEFF).chain(args.encode_utf16()) {
             // encode in little endian
             out.push(c as u8);
             out.push((c >> 8) as u8);
diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs
index 8aa7902021f..90f96c9687b 100644
--- a/src/librustc_codegen_llvm/lib.rs
+++ b/src/librustc_codegen_llvm/lib.rs
@@ -23,7 +23,6 @@
 #![feature(custom_attribute)]
 #![feature(fs_read_write)]
 #![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
 #![feature(libc)]
 #![feature(quote)]
 #![feature(range_contains)]
diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs
index e9031007a4e..f59cf5832fc 100644
--- a/src/librustc_codegen_utils/lib.rs
+++ b/src/librustc_codegen_utils/lib.rs
@@ -20,7 +20,6 @@
 #![feature(box_syntax)]
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
 #![feature(quote)]
 #![feature(rustc_diagnostic_macros)]
 
diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs
index ef0d57c7b7c..a9e582e510e 100644
--- a/src/librustc_data_structures/lib.rs
+++ b/src/librustc_data_structures/lib.rs
@@ -16,8 +16,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://www.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 91392ab013d..24a2354775c 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -798,7 +798,7 @@ where
 pub fn phase_2_configure_and_expand_inner<'a, F>(
     sess: &'a Session,
     cstore: &'a CStore,
-    krate: ast::Crate,
+    mut krate: ast::Crate,
     registry: Option<Registry>,
     crate_name: &str,
     addl_plugins: Option<Vec<String>>,
@@ -810,6 +810,10 @@ pub fn phase_2_configure_and_expand_inner<'a, F>(
 where
     F: FnOnce(&ast::Crate) -> CompileResult,
 {
+    krate = time(sess, "attributes injection", || {
+        syntax::attr::inject(krate, &sess.parse_sess, &sess.opts.debugging_opts.crate_attr)
+    });
+
     let (mut krate, features) = syntax::config::features(
         krate,
         &sess.parse_sess,
@@ -1395,7 +1399,7 @@ fn generated_output_paths(
 
 // Runs `f` on every output file path and returns the first non-None result, or None if `f`
 // returns None for every file path.
-fn check_output<F, T>(output_paths: &Vec<PathBuf>, f: F) -> Option<T>
+fn check_output<F, T>(output_paths: &[PathBuf], f: F) -> Option<T>
 where
     F: Fn(&PathBuf) -> Option<T>,
 {
@@ -1407,7 +1411,7 @@ where
     None
 }
 
-pub fn output_contains_path(output_paths: &Vec<PathBuf>, input_path: &PathBuf) -> bool {
+pub fn output_contains_path(output_paths: &[PathBuf], input_path: &PathBuf) -> bool {
     let input_path = input_path.canonicalize().ok();
     if input_path.is_none() {
         return false;
@@ -1422,7 +1426,7 @@ pub fn output_contains_path(output_paths: &Vec<PathBuf>, input_path: &PathBuf) -
     check_output(output_paths, check).is_some()
 }
 
-pub fn output_conflicts_with_dir(output_paths: &Vec<PathBuf>) -> Option<PathBuf> {
+pub fn output_conflicts_with_dir(output_paths: &[PathBuf]) -> Option<PathBuf> {
     let check = |output_path: &PathBuf| {
         if output_path.is_dir() {
             Some(output_path.clone())
@@ -1433,7 +1437,7 @@ pub fn output_conflicts_with_dir(output_paths: &Vec<PathBuf>) -> Option<PathBuf>
     check_output(output_paths, check)
 }
 
-fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &Vec<PathBuf>) {
+fn write_out_deps(sess: &Session, outputs: &OutputFilenames, out_filenames: &[PathBuf]) {
     // Write out dependency rules to the dep-info file if requested
     if !sess.opts.output_types.contains_key(&OutputType::DepInfo) {
         return;
diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs
index 3ec73059721..29b9990de34 100644
--- a/src/librustc_driver/lib.rs
+++ b/src/librustc_driver/lib.rs
@@ -14,8 +14,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_driver/profile/mod.rs b/src/librustc_driver/profile/mod.rs
index a362556717b..2ec85e1c27f 100644
--- a/src/librustc_driver/profile/mod.rs
+++ b/src/librustc_driver/profile/mod.rs
@@ -62,7 +62,7 @@ struct StackFrame {
     pub traces:   Vec<trace::Rec>,
 }
 
-fn total_duration(traces: &Vec<trace::Rec>) -> Duration {
+fn total_duration(traces: &[trace::Rec]) -> Duration {
     let mut sum : Duration = Duration::new(0,0);
     for t in traces.iter() { sum += t.dur_total; }
     return sum
diff --git a/src/librustc_driver/profile/trace.rs b/src/librustc_driver/profile/trace.rs
index 970a860fdff..797ed4505b4 100644
--- a/src/librustc_driver/profile/trace.rs
+++ b/src/librustc_driver/profile/trace.rs
@@ -107,7 +107,7 @@ fn html_of_fraction(frac: f64) -> (String, String) {
     else { (format!("< 0.1%", ), css) }
 }
 
-fn total_duration(traces: &Vec<Rec>) -> Duration {
+fn total_duration(traces: &[Rec]) -> Duration {
     let mut sum : Duration = Duration::new(0,0);
     for t in traces.iter() {
         sum += t.dur_total;
@@ -123,7 +123,7 @@ fn duration_div(nom: Duration, den: Duration) -> f64 {
     to_nanos(nom) as f64 / to_nanos(den) as f64
 }
 
-fn write_traces_rec(file: &mut File, traces: &Vec<Rec>, total: Duration, depth: usize) {
+fn write_traces_rec(file: &mut File, traces: &[Rec], total: Duration, depth: usize) {
     for t in traces {
         let (eff_text, eff_css_classes) = html_of_effect(&t.effect);
         let (dur_text, dur_css_classes) = html_of_duration(&t.start, &t.dur_total);
@@ -149,7 +149,7 @@ fn write_traces_rec(file: &mut File, traces: &Vec<Rec>, total: Duration, depth:
     }
 }
 
-fn compute_counts_rec(counts: &mut HashMap<String,QueryMetric>, traces: &Vec<Rec>) {
+fn compute_counts_rec(counts: &mut HashMap<String,QueryMetric>, traces: &[Rec]) {
     for t in traces.iter() {
         match t.effect {
             Effect::TimeBegin(ref msg) => {
@@ -218,7 +218,7 @@ pub fn write_counts(count_file: &mut File, counts: &mut HashMap<String,QueryMetr
     }
 }
 
-pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &Vec<Rec>) {
+pub fn write_traces(html_file: &mut File, counts_file: &mut File, traces: &[Rec]) {
     let capacity = traces.iter().fold(0, |acc, t| acc + 1 + t.extent.len());
     let mut counts : HashMap<String, QueryMetric> = HashMap::with_capacity(capacity);
     compute_counts_rec(&mut counts, traces);
diff --git a/src/librustc_errors/diagnostic.rs b/src/librustc_errors/diagnostic.rs
index b1578b697bb..825e31539c8 100644
--- a/src/librustc_errors/diagnostic.rs
+++ b/src/librustc_errors/diagnostic.rs
@@ -99,6 +99,25 @@ impl Diagnostic {
         }
     }
 
+    pub fn is_error(&self) -> bool {
+        match self.level {
+            Level::Bug |
+            Level::Fatal |
+            Level::PhaseFatal |
+            Level::Error |
+            Level::FailureNote => {
+                true
+            }
+
+            Level::Warning |
+            Level::Note |
+            Level::Help |
+            Level::Cancelled => {
+                false
+            }
+        }
+    }
+
     /// Cancel the diagnostic (a structured diagnostic must either be emitted or
     /// canceled or it will panic when dropped).
     pub fn cancel(&mut self) {
diff --git a/src/librustc_errors/diagnostic_builder.rs b/src/librustc_errors/diagnostic_builder.rs
index 8f99ad87cb8..a0f3abda077 100644
--- a/src/librustc_errors/diagnostic_builder.rs
+++ b/src/librustc_errors/diagnostic_builder.rs
@@ -100,25 +100,6 @@ impl<'a> DiagnosticBuilder<'a> {
         buffered_diagnostics.push(diagnostic);
     }
 
-    pub fn is_error(&self) -> bool {
-        match self.level {
-            Level::Bug |
-            Level::Fatal |
-            Level::PhaseFatal |
-            Level::Error |
-            Level::FailureNote => {
-                true
-            }
-
-            Level::Warning |
-            Level::Note |
-            Level::Help |
-            Level::Cancelled => {
-                false
-            }
-        }
-    }
-
     /// Convenience function for internal use, clients should use one of the
     /// span_* methods instead.
     pub fn sub<S: Into<MultiSpan>>(
diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs
index e0ed89a6416..09295e2c7ff 100644
--- a/src/librustc_errors/emitter.rs
+++ b/src/librustc_errors/emitter.rs
@@ -747,7 +747,7 @@ impl EmitterWriter {
         max
     }
 
-    fn get_max_line_num(&mut self, span: &MultiSpan, children: &Vec<SubDiagnostic>) -> usize {
+    fn get_max_line_num(&mut self, span: &MultiSpan, children: &[SubDiagnostic]) -> usize {
         let mut max = 0;
 
         let primary = self.get_multispan_max_line_num(span);
@@ -950,7 +950,7 @@ impl EmitterWriter {
 
     fn emit_message_default(&mut self,
                             msp: &MultiSpan,
-                            msg: &Vec<(String, Style)>,
+                            msg: &[(String, Style)],
                             code: &Option<DiagnosticId>,
                             level: &Level,
                             max_line_num_len: usize,
@@ -1313,10 +1313,10 @@ impl EmitterWriter {
 
     fn emit_messages_default(&mut self,
                              level: &Level,
-                             message: &Vec<(String, Style)>,
+                             message: &[(String, Style)],
                              code: &Option<DiagnosticId>,
                              span: &MultiSpan,
-                             children: &Vec<SubDiagnostic>,
+                             children: &[SubDiagnostic],
                              suggestions: &[CodeSuggestion]) {
         let max_line_num_len = if self.ui_testing {
             ANONYMIZED_LINE_NUM.len()
@@ -1429,7 +1429,7 @@ fn overlaps(a1: &Annotation, a2: &Annotation, padding: usize) -> bool {
     num_overlap(a1.start_col, a1.end_col + padding, a2.start_col, a2.end_col, false)
 }
 
-fn emit_to_destination(rendered_buffer: &Vec<Vec<StyledString>>,
+fn emit_to_destination(rendered_buffer: &[Vec<StyledString>],
                        lvl: &Level,
                        dst: &mut Destination,
                        short_message: bool)
diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs
index 400e5829d33..82546747755 100644
--- a/src/librustc_errors/lib.rs
+++ b/src/librustc_errors/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_incremental/lib.rs b/src/librustc_incremental/lib.rs
index 2ef88041d33..3839c133a6e 100644
--- a/src/librustc_incremental/lib.rs
+++ b/src/librustc_incremental/lib.rs
@@ -10,8 +10,6 @@
 
 //! Support for serializing the dep-graph and reloading it.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_lint/lib.rs b/src/librustc_lint/lib.rs
index 798c289ac2f..78a8c494f48 100644
--- a/src/librustc_lint/lib.rs
+++ b/src/librustc_lint/lib.rs
@@ -19,8 +19,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_llvm/lib.rs b/src/librustc_llvm/lib.rs
index c60016cde0d..741758cb954 100644
--- a/src/librustc_llvm/lib.rs
+++ b/src/librustc_llvm/lib.rs
@@ -12,7 +12,6 @@
 #![allow(non_camel_case_types)]
 #![allow(non_snake_case)]
 #![allow(dead_code)]
-#![deny(bare_trait_objects)]
 
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
diff --git a/src/librustc_lsan/lib.rs b/src/librustc_lsan/lib.rs
index 7bd1e98f85d..0c78fd74a23 100644
--- a/src/librustc_lsan/lib.rs
+++ b/src/librustc_lsan/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![sanitizer_runtime]
 #![feature(alloc_system)]
 #![feature(sanitizer_runtime)]
diff --git a/src/librustc_metadata/dynamic_lib.rs b/src/librustc_metadata/dynamic_lib.rs
index d7da0d00012..182a071277e 100644
--- a/src/librustc_metadata/dynamic_lib.rs
+++ b/src/librustc_metadata/dynamic_lib.rs
@@ -90,30 +90,29 @@ mod tests {
     use std::mem;
 
     #[test]
-    fn test_loading_cosine() {
+    fn test_loading_atoi() {
         if cfg!(windows) {
             return
         }
 
-        // The math library does not need to be loaded since it is already
-        // statically linked in
-        let libm = match DynamicLibrary::open(None) {
+        // The C library does not need to be loaded since it is already linked in
+        let lib = match DynamicLibrary::open(None) {
             Err(error) => panic!("Could not load self as module: {}", error),
-            Ok(libm) => libm
+            Ok(lib) => lib
         };
 
-        let cosine: extern fn(libc::c_double) -> libc::c_double = unsafe {
-            match libm.symbol("cos") {
-                Err(error) => panic!("Could not load function cos: {}", error),
-                Ok(cosine) => mem::transmute::<*mut u8, _>(cosine)
+        let atoi: extern fn(*const libc::c_char) -> libc::c_int = unsafe {
+            match lib.symbol("atoi") {
+                Err(error) => panic!("Could not load function atoi: {}", error),
+                Ok(atoi) => mem::transmute::<*mut u8, _>(atoi)
             }
         };
 
-        let argument = 0.0;
-        let expected_result = 1.0;
-        let result = cosine(argument);
+        let argument = CString::new("1383428980").unwrap();
+        let expected_result = 0x52757374;
+        let result = atoi(argument.as_ptr());
         if result != expected_result {
-            panic!("cos({}) != {} but equaled {} instead", argument,
+            panic!("atoi({:?}) != {} but equaled {} instead", argument,
                    expected_result, result)
         }
     }
diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs
index d535c1ef903..5cba0387d17 100644
--- a/src/librustc_metadata/lib.rs
+++ b/src/librustc_metadata/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_mir/borrow_check/borrow_set.rs b/src/librustc_mir/borrow_check/borrow_set.rs
index e9e0c5c3613..347bf61480e 100644
--- a/src/librustc_mir/borrow_check/borrow_set.rs
+++ b/src/librustc_mir/borrow_check/borrow_set.rs
@@ -333,14 +333,21 @@ impl<'a, 'gcx, 'tcx> GatherBorrows<'a, 'gcx, 'tcx> {
 
         // Consider the borrow not activated to start. When we find an activation, we'll update
         // this field.
-        let borrow_data = &mut self.idx_vec[borrow_index];
-        borrow_data.activation_location = TwoPhaseActivation::NotActivated;
+        {
+            let borrow_data = &mut self.idx_vec[borrow_index];
+            borrow_data.activation_location = TwoPhaseActivation::NotActivated;
+        }
 
         // Insert `temp` into the list of pending activations. From
         // now on, we'll be on the lookout for a use of it. Note that
         // we are guaranteed that this use will come after the
         // assignment.
         let old_value = self.pending_activations.insert(temp, borrow_index);
-        assert!(old_value.is_none());
+        if let Some(old_index) = old_value {
+            span_bug!(self.mir.source_info(start_location).span,
+                      "found already pending activation for temp: {:?} \
+                       at borrow_index: {:?} with associated data {:?}",
+                      temp, old_index, self.idx_vec[old_index]);
+        }
     }
 }
diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs
index 84e3ecd5096..4ba96f643b0 100644
--- a/src/librustc_mir/borrow_check/mod.rs
+++ b/src/librustc_mir/borrow_check/mod.rs
@@ -16,6 +16,7 @@ use rustc::hir::def_id::DefId;
 use rustc::hir::map::definitions::DefPathData;
 use rustc::infer::InferCtxt;
 use rustc::lint::builtin::UNUSED_MUT;
+use rustc::middle::borrowck::SignalledError;
 use rustc::mir::{AggregateKind, BasicBlock, BorrowCheckResult, BorrowKind};
 use rustc::mir::{ClearCrossCrate, Local, Location, Mir, Mutability, Operand, Place};
 use rustc::mir::{Field, Projection, ProjectionElem, Rvalue, Statement, StatementKind};
@@ -23,7 +24,7 @@ use rustc::mir::{Terminator, TerminatorKind};
 use rustc::ty::query::Providers;
 use rustc::ty::{self, ParamEnv, TyCtxt};
 
-use rustc_errors::{Diagnostic, DiagnosticBuilder};
+use rustc_errors::{Diagnostic, DiagnosticBuilder, Level};
 use rustc_data_structures::graph::dominators::Dominators;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::indexed_set::IdxSetBuf;
@@ -329,8 +330,34 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
         }
     }
 
-    for diag in mbcx.errors_buffer.drain(..) {
-        DiagnosticBuilder::new_diagnostic(mbcx.tcx.sess.diagnostic(), diag).emit();
+    if mbcx.errors_buffer.len() > 0 {
+        if tcx.migrate_borrowck() {
+            match tcx.borrowck(def_id).signalled_any_error {
+                SignalledError::NoErrorsSeen => {
+                    // if AST-borrowck signalled no errors, then
+                    // downgrade all the buffered MIR-borrowck errors
+                    // to warnings.
+                    for err in &mut mbcx.errors_buffer {
+                        if err.is_error() {
+                            err.level = Level::Warning;
+                            err.warn("This error has been downgraded to a warning \
+                                      for backwards compatibility with previous releases.\n\
+                                      It represents potential unsoundness in your code.\n\
+                                      This warning will become a hard error in the future.");
+                        }
+                    }
+                }
+                SignalledError::SawSomeError => {
+                    // if AST-borrowck signalled a (cancelled) error,
+                    // then we will just emit the buffered
+                    // MIR-borrowck errors as normal.
+                }
+            }
+        }
+
+        for diag in mbcx.errors_buffer.drain(..) {
+            DiagnosticBuilder::new_diagnostic(mbcx.tcx.sess.diagnostic(), diag).emit();
+        }
     }
 
     let result = BorrowCheckResult {
@@ -1747,20 +1774,44 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
                 }
             }
 
-            Reservation(WriteKind::Move)
-            | Write(WriteKind::Move)
-            | Reservation(WriteKind::StorageDeadOrDrop)
-            | Reservation(WriteKind::MutableBorrow(BorrowKind::Shared))
-            | Write(WriteKind::StorageDeadOrDrop)
-            | Write(WriteKind::MutableBorrow(BorrowKind::Shared)) => {
+            Reservation(wk @ WriteKind::Move)
+            | Write(wk @ WriteKind::Move)
+            | Reservation(wk @ WriteKind::StorageDeadOrDrop)
+            | Reservation(wk @ WriteKind::MutableBorrow(BorrowKind::Shared))
+            | Write(wk @ WriteKind::StorageDeadOrDrop)
+            | Write(wk @ WriteKind::MutableBorrow(BorrowKind::Shared)) => {
                 if let Err(_place_err) = self.is_mutable(place, is_local_mutation_allowed) {
-                    self.tcx.sess.delay_span_bug(
-                        span,
-                        &format!(
-                            "Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
-                            place, kind
-                        ),
-                    );
+                    if self.tcx.migrate_borrowck() {
+                        // rust-lang/rust#46908: In pure NLL mode this
+                        // code path should be unreachable (and thus
+                        // we signal an ICE in the else branch
+                        // here). But we can legitimately get here
+                        // under borrowck=migrate mode, so instead of
+                        // ICE'ing we instead report a legitimate
+                        // error (which will then be downgraded to a
+                        // warning by the migrate machinery).
+                        error_access = match wk {
+                            WriteKind::MutableBorrow(_) => AccessKind::MutableBorrow,
+                            WriteKind::Move => AccessKind::Move,
+                            WriteKind::StorageDeadOrDrop |
+                            WriteKind::Mutate => AccessKind::Mutate,
+                        };
+                        self.report_mutability_error(
+                            place,
+                            span,
+                            _place_err,
+                            error_access,
+                            location,
+                        );
+                    } else {
+                        self.tcx.sess.delay_span_bug(
+                            span,
+                            &format!(
+                                "Accessing `{:?}` with the kind `{:?}` shouldn't be possible",
+                                place, kind
+                            ),
+                        );
+                    }
                 }
                 return false;
             }
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index 4aa38fb5f37..215ade5bd4d 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -87,6 +87,10 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 cannot_move_out_of: IllegalMoveOrigin { location, kind },
             } => {
                 let stmt_source_info = self.mir.source_info(location);
+                // Note: that the only time we assign a place isn't a temporary
+                // to a user variable is when initializing it.
+                // If that ever stops being the case, then the ever initialized
+                // flow could be used.
                 if let Some(StatementKind::Assign(
                     Place::Local(local),
                     Rvalue::Use(Operand::Move(move_from)),
@@ -109,26 +113,16 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                         opt_ty_info: _,
                     }))) = local_decl.is_user_variable
                     {
-                        // HACK use scopes to determine if this assignment is
-                        // the initialization of a variable.
-                        // FIXME(matthewjasper) This would probably be more
-                        // reliable if it used the ever initialized dataflow
-                        // but move errors are currently reported before the
-                        // rest of borrowck has run.
-                        if self
-                            .mir
-                            .is_sub_scope(local_decl.source_info.scope, stmt_source_info.scope)
-                        {
-                            self.append_binding_error(
-                                grouped_errors,
-                                kind,
-                                move_from,
-                                *local,
-                                opt_match_place,
-                                match_span,
-                            );
-                            return;
-                        }
+                        self.append_binding_error(
+                            grouped_errors,
+                            kind,
+                            move_from,
+                            *local,
+                            opt_match_place,
+                            match_span,
+                            stmt_source_info.span,
+                        );
+                        return;
                     }
                 }
                 grouped_errors.push(GroupedMoveError::OtherIllegalMove {
@@ -147,6 +141,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
         bind_to: Local,
         match_place: &Option<Place<'tcx>>,
         match_span: Span,
+        statement_span: Span,
     ) {
         debug!(
             "append_to_grouped_errors(match_place={:?}, match_span={:?})",
@@ -173,13 +168,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                 debug!("found a new move error location");
 
                 // Don't need to point to x in let x = ... .
-                let binds_to = if from_simple_let {
-                    vec![]
+                let (binds_to, span) = if from_simple_let {
+                    (vec![], statement_span)
                 } else {
-                    vec![bind_to]
+                    (vec![bind_to], match_span)
                 };
                 grouped_errors.push(GroupedMoveError::MovesFromMatchPlace {
-                    span: match_span,
+                    span,
                     move_from: match_place.clone(),
                     kind,
                     binds_to,
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index ab1ff1fa347..571a1188d49 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -24,6 +24,7 @@ use util::suggest_ref_mut;
 pub(super) enum AccessKind {
     MutableBorrow,
     Mutate,
+    Move,
 }
 
 impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
@@ -110,6 +111,7 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
                     if let Some(desc) = access_place_desc {
                         item_msg = format!("`{}`", desc);
                         reason = match error_access {
+                            AccessKind::Move |
                             AccessKind::Mutate => format!(" which is behind a {}", pointer_type),
                             AccessKind::MutableBorrow => {
                                 format!(", as it is behind a {}", pointer_type)
@@ -160,6 +162,13 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> {
 
 
         let span = match error_access {
+            AccessKind::Move => {
+                err = self.tcx
+                    .cannot_move_out_of(span, &(item_msg + &reason), Origin::Mir);
+                act = "move";
+                acted_on = "moved";
+                span
+            }
             AccessKind::Mutate => {
                 err = self.tcx
                     .cannot_assign(span, &(item_msg + &reason), Origin::Mir);
diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index 2523711f936..8eb052f88e1 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -120,7 +120,7 @@ struct FactWriter<'w> {
 impl<'w> FactWriter<'w> {
     fn write_facts_to_path<T>(
         &self,
-        rows: &Vec<T>,
+        rows: &[T],
         file_name: &str,
     ) -> Result<(), Box<dyn Error>>
     where
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
index 1b540ef74be..c2c5c6771b0 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs
@@ -31,9 +31,7 @@ mod var_name;
 enum ConstraintCategory {
     Cast,
     Assignment,
-    AssignmentToUpvar,
     Return,
-    CallArgumentToUpvar,
     CallArgument,
     Other,
     Boring,
@@ -41,16 +39,13 @@ enum ConstraintCategory {
 
 impl fmt::Display for ConstraintCategory {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        // Must end with a space. Allows for empty names to be provided.
         match self {
-            ConstraintCategory::Assignment | ConstraintCategory::AssignmentToUpvar => {
-                write!(f, "assignment")
-            }
-            ConstraintCategory::Return => write!(f, "return"),
-            ConstraintCategory::Cast => write!(f, "cast"),
-            ConstraintCategory::CallArgument | ConstraintCategory::CallArgumentToUpvar => {
-                write!(f, "argument")
-            }
-            _ => write!(f, "free region"),
+            ConstraintCategory::Assignment => write!(f, "assignment "),
+            ConstraintCategory::Return => write!(f, "return "),
+            ConstraintCategory::Cast => write!(f, "cast "),
+            ConstraintCategory::CallArgument => write!(f, "argument "),
+            _ => write!(f, ""),
         }
     }
 }
@@ -224,10 +219,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             "constraint_is_interesting: locations={:?} constraint={:?}",
             constraint.locations, constraint
         );
-        if let Locations::Interesting(_) = constraint.locations {
-            true
-        } else {
-            false
+
+        match constraint.locations {
+            Locations::Interesting(_) | Locations::All => true,
+            _ => false,
         }
     }
 
@@ -320,45 +315,26 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             }
         }
 
-        let category = match (
-            category,
+        let (fr_is_local, outlived_fr_is_local): (bool, bool) = (
             self.universal_regions.is_local_free_region(fr),
             self.universal_regions.is_local_free_region(outlived_fr),
-        ) {
-            (ConstraintCategory::Assignment, true, false) => ConstraintCategory::AssignmentToUpvar,
-            (ConstraintCategory::CallArgument, true, false) => {
-                ConstraintCategory::CallArgumentToUpvar
-            }
-            (category, _, _) => category,
+        );
+        debug!("report_error: fr_is_local={:?} outlived_fr_is_local={:?} category={:?}",
+               fr_is_local, outlived_fr_is_local, category);
+
+        match (category, fr_is_local, outlived_fr_is_local) {
+            (ConstraintCategory::Assignment, true, false) |
+            (ConstraintCategory::CallArgument, true, false) =>
+                self.report_escaping_data_error(mir, infcx, mir_def_id, fr, outlived_fr,
+                                                category, span, errors_buffer),
+            _ =>
+                self.report_general_error(mir, infcx, mir_def_id, fr, fr_is_local,
+                                          outlived_fr, outlived_fr_is_local,
+                                          category, span, errors_buffer),
         };
-
-        debug!("report_error: category={:?}", category);
-        match category {
-            ConstraintCategory::AssignmentToUpvar | ConstraintCategory::CallArgumentToUpvar => self
-                .report_closure_error(
-                    mir,
-                    infcx,
-                    mir_def_id,
-                    fr,
-                    outlived_fr,
-                    category,
-                    span,
-                    errors_buffer,
-                ),
-            _ => self.report_general_error(
-                mir,
-                infcx,
-                mir_def_id,
-                fr,
-                outlived_fr,
-                category,
-                span,
-                errors_buffer,
-            ),
-        }
     }
 
-    fn report_closure_error(
+    fn report_escaping_data_error(
         &self,
         mir: &Mir<'tcx>,
         infcx: &InferCtxt<'_, '_, 'tcx>,
@@ -373,29 +349,23 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         let outlived_fr_name_and_span =
             self.get_var_name_and_span_for_region(infcx.tcx, mir, outlived_fr);
 
+        let escapes_from = if infcx.tcx.is_closure(mir_def_id) { "closure" } else { "function" };
+
         if fr_name_and_span.is_none() && outlived_fr_name_and_span.is_none() {
-            return self.report_general_error(
-                mir,
-                infcx,
-                mir_def_id,
-                fr,
-                outlived_fr,
-                category,
-                span,
-                errors_buffer,
-            );
+            return self.report_general_error(mir, infcx, mir_def_id,
+                                             fr, true, outlived_fr, false,
+                                             category, span, errors_buffer);
         }
 
-        let mut diag = infcx
-            .tcx
-            .sess
-            .struct_span_err(span, &format!("borrowed data escapes outside of closure"));
+        let mut diag = infcx.tcx.sess.struct_span_err(
+            span, &format!("borrowed data escapes outside of {}", escapes_from),
+        );
 
         if let Some((outlived_fr_name, outlived_fr_span)) = outlived_fr_name_and_span {
             if let Some(name) = outlived_fr_name {
                 diag.span_label(
                     outlived_fr_span,
-                    format!("`{}` is declared here, outside of the closure body", name),
+                    format!("`{}` is declared here, outside of the {} body", name, escapes_from),
                 );
             }
         }
@@ -404,13 +374,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
             if let Some(name) = fr_name {
                 diag.span_label(
                     fr_span,
-                    format!(
-                        "`{}` is a reference that is only valid in the closure body",
-                        name
-                    ),
+                    format!("`{}` is a reference that is only valid in the {} body",
+                            name, escapes_from),
                 );
 
-                diag.span_label(span, format!("`{}` escapes the closure body here", name));
+                diag.span_label(span, format!("`{}` escapes the {} body here",
+                                               name, escapes_from));
             }
         }
 
@@ -423,7 +392,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         infcx: &InferCtxt<'_, '_, 'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
+        fr_is_local: bool,
         outlived_fr: RegionVid,
+        outlived_fr_is_local: bool,
         category: ConstraintCategory,
         span: Span,
         errors_buffer: &mut Vec<Diagnostic>,
@@ -434,17 +405,28 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         );
 
         let counter = &mut 1;
-        let fr_name = self.give_region_a_name(infcx.tcx, mir, mir_def_id, fr, counter, &mut diag);
-        let outlived_fr_name =
-            self.give_region_a_name(infcx.tcx, mir, mir_def_id, outlived_fr, counter, &mut diag);
-
-        diag.span_label(
-            span,
-            format!(
-                "{} requires that `{}` must outlive `{}`",
-                category, fr_name, outlived_fr_name,
-            ),
-        );
+        let fr_name = self.give_region_a_name(
+            infcx, mir, mir_def_id, fr, counter, &mut diag);
+        let outlived_fr_name = self.give_region_a_name(
+            infcx, mir, mir_def_id, outlived_fr, counter, &mut diag);
+
+        let mir_def_name = if infcx.tcx.is_closure(mir_def_id) { "closure" } else { "function" };
+
+        match (category, outlived_fr_is_local, fr_is_local) {
+            (ConstraintCategory::Return, true, _) => {
+                diag.span_label(span, format!(
+                    "{} was supposed to return data with lifetime `{}` but it is returning \
+                    data with lifetime `{}`",
+                    mir_def_name, fr_name, outlived_fr_name,
+                ));
+            },
+            _ => {
+                diag.span_label(span, format!(
+                    "{}requires that `{}` must outlive `{}`",
+                    category, fr_name, outlived_fr_name,
+                ));
+            },
+        }
 
         diag.buffer(errors_buffer);
     }
diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
index c0eca026331..8505d8e1ef3 100644
--- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
+++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/region_name.rs
@@ -12,9 +12,11 @@ use borrow_check::nll::region_infer::RegionInferenceContext;
 use borrow_check::nll::ToRegionVid;
 use rustc::hir;
 use rustc::hir::def_id::DefId;
+use rustc::infer::InferCtxt;
 use rustc::mir::Mir;
 use rustc::ty::subst::{Substs, UnpackedKind};
 use rustc::ty::{self, RegionVid, Ty, TyCtxt};
+use rustc::util::ppaux::with_highlight_region;
 use rustc_errors::DiagnosticBuilder;
 use syntax::ast::Name;
 use syntax::symbol::keywords;
@@ -48,7 +50,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// and then return the name `'1` for us to use.
     crate fn give_region_a_name(
         &self,
-        tcx: TyCtxt<'_, '_, 'tcx>,
+        infcx: &InferCtxt<'_, '_, 'tcx>,
         mir: &Mir<'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
@@ -59,17 +61,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
         assert!(self.universal_regions.is_universal_region(fr));
 
-        self.give_name_from_error_region(tcx, mir_def_id, fr, counter, diag)
+        self.give_name_from_error_region(infcx.tcx, mir_def_id, fr, counter, diag)
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_arguments(
-                    tcx, mir, mir_def_id, fr, counter, diag)
+                    infcx, mir, mir_def_id, fr, counter, diag)
             })
             .or_else(|| {
                 self.give_name_if_anonymous_region_appears_in_upvars(
-                    tcx, mir, fr, counter, diag)
+                    infcx.tcx, mir, fr, counter, diag)
             })
             .or_else(|| {
-                self.give_name_if_anonymous_region_appears_in_output(tcx, mir, fr, counter, diag)
+                self.give_name_if_anonymous_region_appears_in_output(
+                    infcx.tcx, mir, fr, counter, diag)
             })
             .unwrap_or_else(|| span_bug!(mir.span, "can't make a name for free region {:?}", fr))
     }
@@ -130,7 +133,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
     /// ```
     fn give_name_if_anonymous_region_appears_in_arguments(
         &self,
-        tcx: TyCtxt<'_, '_, 'tcx>,
+        infcx: &InferCtxt<'_, '_, 'tcx>,
         mir: &Mir<'tcx>,
         mir_def_id: DefId,
         fr: RegionVid,
@@ -138,12 +141,13 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         diag: &mut DiagnosticBuilder<'_>,
     ) -> Option<InternedString> {
         let implicit_inputs = self.universal_regions.defining_ty.implicit_inputs();
-        let argument_index = self.get_argument_index_for_region(tcx, fr)?;
+        let argument_index = self.get_argument_index_for_region(infcx.tcx, fr)?;
 
         let arg_ty =
             self.universal_regions.unnormalized_input_tys[implicit_inputs + argument_index];
         if let Some(region_name) = self.give_name_if_we_can_match_hir_ty_from_argument(
-            tcx,
+            infcx,
+            mir,
             mir_def_id,
             fr,
             arg_ty,
@@ -169,7 +173,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
 
     fn give_name_if_we_can_match_hir_ty_from_argument(
         &self,
-        tcx: TyCtxt<'_, '_, 'tcx>,
+        infcx: &InferCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
         mir_def_id: DefId,
         needle_fr: RegionVid,
         argument_ty: Ty<'tcx>,
@@ -177,17 +182,24 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         counter: &mut usize,
         diag: &mut DiagnosticBuilder<'_>,
     ) -> Option<InternedString> {
-        let mir_node_id = tcx.hir.as_local_node_id(mir_def_id)?;
-        let fn_decl = tcx.hir.fn_decl(mir_node_id)?;
+        let mir_node_id = infcx.tcx.hir.as_local_node_id(mir_def_id)?;
+        let fn_decl = infcx.tcx.hir.fn_decl(mir_node_id)?;
         let argument_hir_ty: &hir::Ty = &fn_decl.inputs[argument_index];
         match argument_hir_ty.node {
             // This indicates a variable with no type annotation, like
             // `|x|`... in that case, we can't highlight the type but
             // must highlight the variable.
-            hir::TyKind::Infer => None,
+            hir::TyKind::Infer => self.give_name_if_we_cannot_match_hir_ty(
+                infcx,
+                mir,
+                needle_fr,
+                argument_ty,
+                counter,
+                diag,
+            ),
 
             _ => self.give_name_if_we_can_match_hir_ty(
-                tcx,
+                infcx.tcx,
                 needle_fr,
                 argument_ty,
                 argument_hir_ty,
@@ -197,6 +209,49 @@ impl<'tcx> RegionInferenceContext<'tcx> {
         }
     }
 
+    /// Attempts to highlight the specific part of a type in an argument
+    /// that has no type annotation.
+    /// For example, we might produce an annotation like this:
+    ///
+    /// ```
+    ///  |     foo(|a, b| b)
+    ///  |          -  -
+    ///  |          |  |
+    ///  |          |  has type `&'1 u32`
+    ///  |          has type `&'2 u32`
+    /// ```
+    fn give_name_if_we_cannot_match_hir_ty(
+        &self,
+        infcx: &InferCtxt<'_, '_, 'tcx>,
+        mir: &Mir<'tcx>,
+        needle_fr: RegionVid,
+        argument_ty: Ty<'tcx>,
+        counter: &mut usize,
+        diag: &mut DiagnosticBuilder<'_>,
+    ) -> Option<InternedString> {
+        let type_name = with_highlight_region(needle_fr, *counter, || {
+            infcx.extract_type_name(&argument_ty)
+        });
+
+        debug!("give_name_if_we_cannot_match_hir_ty: type_name={:?} needle_fr={:?}",
+               type_name, needle_fr);
+        let assigned_region_name = if type_name.find(&format!("'{}", counter)).is_some() {
+            // Only add a label if we can confirm that a region was labelled.
+            let argument_index = self.get_argument_index_for_region(infcx.tcx, needle_fr)?;
+            let (_, span) = self.get_argument_name_and_span_for_region(mir, argument_index);
+            diag.span_label(span, format!("has type `{}`", type_name));
+
+            // This counter value will already have been used, so this function will increment it
+            // so the next value will be used next and return the region name that would have been
+            // used.
+            Some(self.synthesize_region_name(counter))
+        } else {
+            None
+        };
+
+        assigned_region_name
+    }
+
     /// Attempts to highlight the specific part of a type annotation
     /// that contains the anonymous reference we want to give a name
     /// to. For example, we might produce an annotation like this:
diff --git a/src/librustc_mir/build/block.rs b/src/librustc_mir/build/block.rs
index bbbe757e96e..c3637a5abeb 100644
--- a/src/librustc_mir/build/block.rs
+++ b/src/librustc_mir/build/block.rs
@@ -16,6 +16,8 @@ use rustc::mir::*;
 use rustc::hir;
 use syntax_pos::Span;
 
+use std::slice;
+
 impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     pub fn ast_block(&mut self,
                      destination: &Place<'tcx>,
@@ -126,7 +128,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                             None,
                             remainder_span,
                             lint_level,
-                            &pattern,
+                            slice::from_ref(&pattern),
                             ArmHasGuard(false),
                             Some((None, initializer_span)),
                         );
@@ -138,8 +140,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                                 })
                             }));
                     } else {
-                        scope = this.declare_bindings(None, remainder_span, lint_level, &pattern,
-                                                        ArmHasGuard(false), None);
+                        scope = this.declare_bindings(
+                            None, remainder_span, lint_level, slice::from_ref(&pattern),
+                            ArmHasGuard(false), None);
 
                         // FIXME(#47184): We currently only insert `UserAssertTy` statements for
                         // patterns that are bindings, this is as we do not want to deconstruct
diff --git a/src/librustc_mir/build/expr/as_place.rs b/src/librustc_mir/build/expr/as_place.rs
index 964841e7a9e..a38ca7ae5bf 100644
--- a/src/librustc_mir/build/expr/as_place.rs
+++ b/src/librustc_mir/build/expr/as_place.rs
@@ -11,7 +11,7 @@
 //! See docs in build/expr/mod.rs
 
 use build::{BlockAnd, BlockAndExtension, Builder};
-use build::ForGuard::{OutsideGuard, RefWithinGuard, ValWithinGuard};
+use build::ForGuard::{OutsideGuard, RefWithinGuard};
 use build::expr::category::Category;
 use hair::*;
 use rustc::mir::*;
@@ -87,14 +87,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 block.and(Place::Local(Local::new(1)))
             }
             ExprKind::VarRef { id } => {
-                let place = if this.is_bound_var_in_guard(id) {
-                    if this.hir.tcx().all_pat_vars_are_implicit_refs_within_guards() {
-                        let index = this.var_local_id(id, RefWithinGuard);
-                        Place::Local(index).deref()
-                    } else {
-                        let index = this.var_local_id(id, ValWithinGuard);
-                        Place::Local(index)
-                    }
+                let place = if this.is_bound_var_in_guard(id) &&
+                    this.hir.tcx().all_pat_vars_are_implicit_refs_within_guards()
+                {
+                    let index = this.var_local_id(id, RefWithinGuard);
+                    Place::Local(index).deref()
                 } else {
                     let index = this.var_local_id(id, OutsideGuard);
                     Place::Local(index)
diff --git a/src/librustc_mir/build/matches/mod.rs b/src/librustc_mir/build/matches/mod.rs
index 5de316a6640..a509ec08a14 100644
--- a/src/librustc_mir/build/matches/mod.rs
+++ b/src/librustc_mir/build/matches/mod.rs
@@ -63,13 +63,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         // injects a borrow of the matched input, which should have the same effect
         // as eddyb's hack. Once NLL is the default, we can remove the hack.
 
-        let dummy_source_info = self.source_info(span);
+        let dummy_source_info = self.source_info(discriminant_span);
         let dummy_access = Rvalue::Discriminant(discriminant_place.clone());
         let dummy_ty = dummy_access.ty(&self.local_decls, tcx);
         let dummy_temp = self.temp(dummy_ty, dummy_source_info.span);
         self.cfg.push_assign(block, dummy_source_info, &dummy_temp, dummy_access);
 
-        let source_info = self.source_info(span);
+        let source_info = self.source_info(discriminant_span);
         let borrowed_input_temp = if tcx.generate_borrow_of_any_match_input() {
             // The region is unknown at this point; we rely on NLL
             // inference to find an appropriate one. Therefore you can
@@ -97,7 +97,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             let body = self.hir.mirror(arm.body.clone());
             let scope = self.declare_bindings(None, body.span,
                                               LintLevel::Inherited,
-                                              &arm.patterns[0],
+                                              &arm.patterns[..],
                                               ArmHasGuard(arm.guard.is_some()),
                                               Some((Some(&discriminant_place), discriminant_span)));
             (body, scope.unwrap_or(self.source_scope))
@@ -118,11 +118,13 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             arms.iter()
                 .enumerate()
                 .flat_map(|(arm_index, arm)| {
-                    arm.patterns.iter()
-                                .map(move |pat| (arm_index, pat, arm.guard.clone()))
+                    arm.patterns.iter().enumerate()
+                        .map(move |(pat_index, pat)| {
+                            (arm_index, pat_index, pat, arm.guard.clone())
+                        })
                 })
                 .zip(pre_binding_blocks.iter().zip(pre_binding_blocks.iter().skip(1)))
-                .map(|((arm_index, pattern, guard),
+                .map(|((arm_index, pat_index, pattern, guard),
                        (pre_binding_block, next_candidate_pre_binding_block))| {
 
                     if let (true, Some(borrow_temp)) = (tcx.emit_read_for_match(),
@@ -134,9 +136,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                         // This should ensure that you cannot change
                         // the variant for an enum while you are in
                         // the midst of matching on it.
-
+                        let pattern_source_info = self.source_info(pattern.span);
                         self.cfg.push(*pre_binding_block, Statement {
-                            source_info,
+                            source_info: pattern_source_info,
                             kind: StatementKind::ReadForMatch(borrow_temp.clone()),
                         });
                     }
@@ -168,6 +170,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                         bindings: vec![],
                         guard,
                         arm_index,
+                        pat_index,
                         pre_binding_block: *pre_binding_block,
                         next_candidate_pre_binding_block: *next_candidate_pre_binding_block,
                     }
@@ -277,6 +280,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
             // since we don't call `match_candidates`, next fields is unused
             arm_index: 0,
+            pat_index: 0,
             pre_binding_block: block,
             next_candidate_pre_binding_block: block
         };
@@ -324,14 +328,15 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                             mut visibility_scope: Option<SourceScope>,
                             scope_span: Span,
                             lint_level: LintLevel,
-                            pattern: &Pattern<'tcx>,
+                            patterns: &[Pattern<'tcx>],
                             has_guard: ArmHasGuard,
                             opt_match_place: Option<(Option<&Place<'tcx>>, Span)>)
                             -> Option<SourceScope> {
         assert!(!(visibility_scope.is_some() && lint_level.is_explicit()),
                 "can't have both a visibility and a lint scope at the same time");
         let mut scope = self.source_scope;
-        self.visit_bindings(pattern, &mut |this, mutability, name, mode, var, span, ty| {
+        let num_patterns = patterns.len();
+        self.visit_bindings(&patterns[0], &mut |this, mutability, name, mode, var, span, ty| {
             if visibility_scope.is_none() {
                 visibility_scope = Some(this.new_source_scope(scope_span,
                                                            LintLevel::Inherited,
@@ -349,8 +354,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 scope,
             };
             let visibility_scope = visibility_scope.unwrap();
-            this.declare_binding(source_info, visibility_scope, mutability, name, mode, var,
-                                 ty, has_guard, opt_match_place.map(|(x, y)| (x.cloned(), y)));
+            this.declare_binding(source_info, visibility_scope, mutability, name, mode,
+                                 num_patterns, var, ty, has_guard,
+                                 opt_match_place.map(|(x, y)| (x.cloned(), y)));
         });
         visibility_scope
     }
@@ -453,6 +459,9 @@ pub struct Candidate<'pat, 'tcx:'pat> {
     // ...and the blocks for add false edges between candidates
     pre_binding_block: BasicBlock,
     next_candidate_pre_binding_block: BasicBlock,
+
+    // This uniquely identifies this candidate *within* the arm.
+    pat_index: usize,
 }
 
 #[derive(Clone, Debug)]
@@ -972,7 +981,8 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         let autoref = self.hir.tcx().all_pat_vars_are_implicit_refs_within_guards();
         if let Some(guard) = candidate.guard {
             if autoref {
-                self.bind_matched_candidate_for_guard(block, &candidate.bindings);
+                self.bind_matched_candidate_for_guard(
+                    block, candidate.pat_index, &candidate.bindings);
                 let guard_frame = GuardFrame {
                     locals: candidate.bindings.iter()
                         .map(|b| GuardFrameLocal::new(b.var_id, b.binding_mode))
@@ -1058,9 +1068,10 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
     // and thus all code/comments assume we are in that context.
     fn bind_matched_candidate_for_guard(&mut self,
                                         block: BasicBlock,
+                                        pat_index: usize,
                                         bindings: &[Binding<'tcx>]) {
-        debug!("bind_matched_candidate_for_guard(block={:?}, bindings={:?})",
-               block, bindings);
+        debug!("bind_matched_candidate_for_guard(block={:?}, pat_index={:?}, bindings={:?})",
+               block, pat_index, bindings);
 
         // Assign each of the bindings. Since we are binding for a
         // guard expression, this will never trigger moves out of the
@@ -1099,8 +1110,9 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     // used by the arm body itself. This eases
                     // observing two-phase borrow restrictions.
                     let val_for_guard = self.storage_live_binding(
-                        block, binding.var_id, binding.span, ValWithinGuard);
-                    self.schedule_drop_for_binding(binding.var_id, binding.span, ValWithinGuard);
+                        block, binding.var_id, binding.span, ValWithinGuard(pat_index));
+                    self.schedule_drop_for_binding(
+                        binding.var_id, binding.span, ValWithinGuard(pat_index));
 
                     // rust-lang/rust#27282: We reuse the two-phase
                     // borrow infrastructure so that the mutable
@@ -1146,16 +1158,26 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
     /// Each binding (`ref mut var`/`ref var`/`mut var`/`var`, where
     /// the bound `var` has type `T` in the arm body) in a pattern
-    /// maps to *two* locals. The first local is a binding for
+    /// maps to `2+N` locals. The first local is a binding for
     /// occurrences of `var` in the guard, which will all have type
-    /// `&T`. The second local is a binding for occurrences of `var`
-    /// in the arm body, which will have type `T`.
+    /// `&T`. The N locals are bindings for the `T` that is referenced
+    /// by the first local; they are not used outside of the
+    /// guard. The last local is a binding for occurrences of `var` in
+    /// the arm body, which will have type `T`.
+    ///
+    /// The reason we have N locals rather than just 1 is to
+    /// accommodate rust-lang/rust#51348: If the arm has N candidate
+    /// patterns, then in general they can correspond to distinct
+    /// parts of the matched data, and we want them to be distinct
+    /// temps in order to simplify checks performed by our internal
+    /// leveraging of two-phase borrows).
     fn declare_binding(&mut self,
                        source_info: SourceInfo,
                        visibility_scope: SourceScope,
                        mutability: Mutability,
                        name: Name,
                        mode: BindingMode,
+                       num_patterns: usize,
                        var_id: NodeId,
                        var_ty: Ty<'tcx>,
                        has_guard: ArmHasGuard,
@@ -1189,7 +1211,11 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
         };
         let for_arm_body = self.local_decls.push(local.clone());
         let locals = if has_guard.0 && tcx.all_pat_vars_are_implicit_refs_within_guards() {
-            let val_for_guard =  self.local_decls.push(local);
+            let mut vals_for_guard = Vec::with_capacity(num_patterns);
+            for _ in 0..num_patterns {
+                let val_for_guard_idx =  self.local_decls.push(local.clone());
+                vals_for_guard.push(val_for_guard_idx);
+            }
             let ref_for_guard = self.local_decls.push(LocalDecl::<'tcx> {
                 mutability,
                 ty: tcx.mk_imm_ref(tcx.types.re_empty, var_ty),
@@ -1200,7 +1226,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                 internal: false,
                 is_user_variable: Some(ClearCrossCrate::Set(BindingForm::RefForGuard)),
             });
-            LocalsForNode::Three { val_for_guard, ref_for_guard, for_arm_body }
+            LocalsForNode::ForGuard { vals_for_guard, ref_for_guard, for_arm_body }
         } else {
             LocalsForNode::One(for_arm_body)
         };
diff --git a/src/librustc_mir/build/matches/test.rs b/src/librustc_mir/build/matches/test.rs
index 3ff209c872f..afa0d28dd77 100644
--- a/src/librustc_mir/build/matches/test.rs
+++ b/src/librustc_mir/build/matches/test.rs
@@ -631,6 +631,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             bindings: candidate.bindings.clone(),
             guard: candidate.guard.clone(),
             arm_index: candidate.arm_index,
+            pat_index: candidate.pat_index,
             pre_binding_block: candidate.pre_binding_block,
             next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
         }
@@ -694,6 +695,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
             bindings: candidate.bindings.clone(),
             guard: candidate.guard.clone(),
             arm_index: candidate.arm_index,
+            pat_index: candidate.pat_index,
             pre_binding_block: candidate.pre_binding_block,
             next_candidate_pre_binding_block: candidate.next_candidate_pre_binding_block,
         }
diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs
index 24228389fbf..054bd69c361 100644
--- a/src/librustc_mir/build/mod.rs
+++ b/src/librustc_mir/build/mod.rs
@@ -310,8 +310,31 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
 
 #[derive(Debug)]
 enum LocalsForNode {
+    /// In the usual case, a node-id for an identifier maps to at most
+    /// one Local declaration.
     One(Local),
-    Three { val_for_guard: Local, ref_for_guard: Local, for_arm_body: Local },
+
+    /// The exceptional case is identifiers in a match arm's pattern
+    /// that are referenced in a guard of that match arm. For these,
+    /// we can have `2+k` Locals, where `k` is the number of candidate
+    /// patterns (separated by `|`) in the arm.
+    ///
+    /// * `for_arm_body` is the Local used in the arm body (which is
+    ///   just like the `One` case above),
+    ///
+    /// * `ref_for_guard` is the Local used in the arm's guard (which
+    ///   is a reference to a temp that is an alias of
+    ///   `for_arm_body`).
+    ///
+    /// * `vals_for_guard` is the `k` Locals; at most one of them will
+    ///   get initialized by the arm's execution, and after it is
+    ///   initialized, `ref_for_guard` will be assigned a reference to
+    ///   it.
+    ///
+    /// There reason we have `k` Locals rather than just 1 is to
+    /// accommodate some restrictions imposed by two-phase borrows,
+    /// which apply when we have a `ref mut` pattern.
+    ForGuard { vals_for_guard: Vec<Local>, ref_for_guard: Local, for_arm_body: Local },
 }
 
 #[derive(Debug)]
@@ -350,7 +373,10 @@ struct GuardFrame {
 ///   3. the temp for use outside of guard expressions.
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum ForGuard {
-    ValWithinGuard,
+    /// The `usize` identifies for which candidate pattern we want the
+    /// local binding. We keep a temp per-candidate to accommodate
+    /// two-phase borrows (see `LocalsForNode` documentation).
+    ValWithinGuard(usize),
     RefWithinGuard,
     OutsideGuard,
 }
@@ -359,12 +385,15 @@ impl LocalsForNode {
     fn local_id(&self, for_guard: ForGuard) -> Local {
         match (self, for_guard) {
             (&LocalsForNode::One(local_id), ForGuard::OutsideGuard) |
-            (&LocalsForNode::Three { val_for_guard: local_id, .. }, ForGuard::ValWithinGuard) |
-            (&LocalsForNode::Three { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) |
-            (&LocalsForNode::Three { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) =>
+            (&LocalsForNode::ForGuard { ref_for_guard: local_id, .. }, ForGuard::RefWithinGuard) |
+            (&LocalsForNode::ForGuard { for_arm_body: local_id, .. }, ForGuard::OutsideGuard) =>
                 local_id,
 
-            (&LocalsForNode::One(_), ForGuard::ValWithinGuard) |
+            (&LocalsForNode::ForGuard { ref vals_for_guard, .. },
+             ForGuard::ValWithinGuard(pat_idx)) =>
+                vals_for_guard[pat_idx],
+
+            (&LocalsForNode::One(_), ForGuard::ValWithinGuard(_)) |
             (&LocalsForNode::One(_), ForGuard::RefWithinGuard) =>
                 bug!("anything with one local should never be within a guard."),
         }
@@ -740,7 +769,7 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> {
                     }
                     _ => {
                         scope = self.declare_bindings(scope, ast_body.span,
-                                                      LintLevel::Inherited, &pattern,
+                                                      LintLevel::Inherited, &[pattern.clone()],
                                                       matches::ArmHasGuard(false),
                                                       Some((Some(&place), span)));
                         unpack!(block = self.place_into_pattern(block, pattern, &place, false));
diff --git a/src/librustc_mir/interpret/terminator/drop.rs b/src/librustc_mir/interpret/terminator/drop.rs
index c0fafa7f83e..d750c1f47a6 100644
--- a/src/librustc_mir/interpret/terminator/drop.rs
+++ b/src/librustc_mir/interpret/terminator/drop.rs
@@ -78,7 +78,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
         self.eval_fn_call(
             instance,
             Some((Place::undef(), target)),
-            &vec![valty],
+            &[valty],
             span,
             fn_sig,
         )
diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs
index 382248c2d15..54730ecd75f 100644
--- a/src/librustc_mir/lib.rs
+++ b/src/librustc_mir/lib.rs
@@ -14,8 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment!
 
 */
 
-#![deny(bare_trait_objects)]
-
 #![feature(slice_patterns)]
 #![feature(slice_sort_by_cached_key)]
 #![feature(from_ref)]
diff --git a/src/librustc_mir/transform/elaborate_drops.rs b/src/librustc_mir/transform/elaborate_drops.rs
index d35608068a6..937d01a0c5e 100644
--- a/src/librustc_mir/transform/elaborate_drops.rs
+++ b/src/librustc_mir/transform/elaborate_drops.rs
@@ -41,7 +41,20 @@ impl MirPass for ElaborateDrops {
 
         let id = tcx.hir.as_local_node_id(src.def_id).unwrap();
         let param_env = tcx.param_env(src.def_id).with_reveal_all();
-        let move_data = MoveData::gather_moves(mir, tcx).unwrap();
+        let move_data = match MoveData::gather_moves(mir, tcx) {
+            Ok(move_data) => move_data,
+            Err((move_data, _move_errors)) => {
+                // The only way we should be allowing any move_errors
+                // in here is if we are in the migration path for the
+                // NLL-based MIR-borrowck.
+                //
+                // If we are in the migration path, we have already
+                // reported these errors as warnings to the user. So
+                // we will just ignore them here.
+                assert!(tcx.migrate_borrowck());
+                move_data
+            }
+        };
         let elaborate_patch = {
             let mir = &*mir;
             let env = MoveDataParamEnv {
diff --git a/src/librustc_mir/transform/uniform_array_move_out.rs b/src/librustc_mir/transform/uniform_array_move_out.rs
index 5019c74742a..7a8c35e7b96 100644
--- a/src/librustc_mir/transform/uniform_array_move_out.rs
+++ b/src/librustc_mir/transform/uniform_array_move_out.rs
@@ -222,7 +222,7 @@ impl RestoreSubsliceArrayMoveOut {
     // indices is an integer interval. If all checks pass do the replacent.
     // items are Vec<Option<LocalUse, index in source array, source place for init local>>
     fn check_and_patch<'tcx>(candidate: Location,
-                             items: &Vec<Option<(&LocalUse, u32, &Place<'tcx>)>>,
+                             items: &[Option<(&LocalUse, u32, &Place<'tcx>)>],
                              opt_size: Option<u64>,
                              patch: &mut MirPatch<'tcx>,
                              dst_place: &Place<'tcx>) {
diff --git a/src/librustc_mir/util/elaborate_drops.rs b/src/librustc_mir/util/elaborate_drops.rs
index 689eb62042b..bbffeec631a 100644
--- a/src/librustc_mir/util/elaborate_drops.rs
+++ b/src/librustc_mir/util/elaborate_drops.rs
@@ -369,7 +369,9 @@ impl<'l, 'b, 'tcx, D> DropCtxt<'l, 'b, 'tcx, D>
             });
         }
 
-        let contents_drop = if adt.is_union() {
+        let skip_contents =
+            adt.is_union() || Some(adt.did) == self.tcx().lang_items().manually_drop();
+        let contents_drop = if skip_contents {
             (self.succ, self.unwind)
         } else {
             self.open_drop_for_adt_contents(adt, substs)
diff --git a/src/librustc_msan/lib.rs b/src/librustc_msan/lib.rs
index 7bd1e98f85d..0c78fd74a23 100644
--- a/src/librustc_msan/lib.rs
+++ b/src/librustc_msan/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![sanitizer_runtime]
 #![feature(alloc_system)]
 #![feature(sanitizer_runtime)]
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index f27ca444672..c6bad9e1980 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -147,7 +147,7 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn check_late_bound_lifetime_defs(&self, params: &Vec<GenericParam>) {
+    fn check_late_bound_lifetime_defs(&self, params: &[GenericParam]) {
         // Check only lifetime parameters are present and that the lifetime
         // parameters that are present have no bounds.
         let non_lt_param_spans: Vec<_> = params.iter().filter_map(|param| match param.kind {
diff --git a/src/librustc_passes/lib.rs b/src/librustc_passes/lib.rs
index 15d7c0fdaa3..41f1e782965 100644
--- a/src/librustc_passes/lib.rs
+++ b/src/librustc_passes/lib.rs
@@ -14,8 +14,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_platform_intrinsics/lib.rs b/src/librustc_platform_intrinsics/lib.rs
index 92e83fd70fa..b57debdd994 100644
--- a/src/librustc_platform_intrinsics/lib.rs
+++ b/src/librustc_platform_intrinsics/lib.rs
@@ -9,7 +9,6 @@
 // except according to those terms.
 
 #![allow(bad_style)]
-#![deny(bare_trait_objects)]
 
 pub struct Intrinsic {
     pub inputs: &'static [&'static Type],
diff --git a/src/librustc_plugin/lib.rs b/src/librustc_plugin/lib.rs
index b2c492f204f..348aa6a7cef 100644
--- a/src/librustc_plugin/lib.rs
+++ b/src/librustc_plugin/lib.rs
@@ -60,8 +60,6 @@
 //! See the [`plugin` feature](../unstable-book/language-features/plugin.html) of
 //! the Unstable Book for more examples.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 7b13c98b31d..405952065da 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index d8b9c58950f..725b3b4f150 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs
index 0ad652b4710..29b6f958cc1 100644
--- a/src/librustc_resolve/macros.rs
+++ b/src/librustc_resolve/macros.rs
@@ -783,7 +783,7 @@ impl<'a> Resolver<'a> {
                 }
             };
             let ident = Ident::new(Symbol::intern(name), span);
-            self.lookup_typo_candidate(&vec![ident], MacroNS, is_macro, span)
+            self.lookup_typo_candidate(&[ident], MacroNS, is_macro, span)
         });
 
         if let Some(suggestion) = suggestion {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index c84f194f023..a250d4a3598 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -13,7 +13,6 @@
        html_root_url = "https://doc.rust-lang.org/nightly/")]
 #![feature(custom_attribute)]
 #![allow(unused_attributes)]
-#![deny(bare_trait_objects)]
 
 #![recursion_limit="256"]
 
diff --git a/src/librustc_target/lib.rs b/src/librustc_target/lib.rs
index e611d26da56..8f491157439 100644
--- a/src/librustc_target/lib.rs
+++ b/src/librustc_target/lib.rs
@@ -21,8 +21,6 @@
 //! one that doesn't; the one that doesn't might get decent parallel
 //! build speedups.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/librustc_target/spec/aarch64_unknown_fuchsia.rs b/src/librustc_target/spec/aarch64_fuchsia.rs
index 4da6724ef62..28baf6f66e7 100644
--- a/src/librustc_target/spec/aarch64_unknown_fuchsia.rs
+++ b/src/librustc_target/spec/aarch64_fuchsia.rs
@@ -15,7 +15,7 @@ pub fn target() -> TargetResult {
     base.max_atomic_width = Some(128);
 
     Ok(Target {
-        llvm_target: "aarch64-unknown-fuchsia".to_string(),
+        llvm_target: "aarch64-fuchsia".to_string(),
         target_endian: "little".to_string(),
         target_pointer_width: "64".to_string(),
         target_c_int_width: "32".to_string(),
@@ -23,7 +23,7 @@ pub fn target() -> TargetResult {
         arch: "aarch64".to_string(),
         target_os: "fuchsia".to_string(),
         target_env: "".to_string(),
-        target_vendor: "unknown".to_string(),
+        target_vendor: "".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: TargetOptions {
             abi_blacklist: super::arm_base::abi_blacklist(),
diff --git a/src/librustc_target/spec/fuchsia_base.rs b/src/librustc_target/spec/fuchsia_base.rs
index 19a66b693f2..b593b835326 100644
--- a/src/librustc_target/spec/fuchsia_base.rs
+++ b/src/librustc_target/spec/fuchsia_base.rs
@@ -33,7 +33,7 @@ pub fn opts() -> TargetOptions {
         executables: true,
         target_family: Some("unix".to_string()),
         linker_is_gnu: true,
-        has_rpath: true,
+        has_rpath: false,
         pre_link_args: args,
         position_independent_executables: true,
         has_elf_tls: true,
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 9ac6e9835f0..c5d21cdc46a 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -332,8 +332,8 @@ supported_targets! {
     ("x86_64-apple-darwin", x86_64_apple_darwin),
     ("i686-apple-darwin", i686_apple_darwin),
 
-    ("aarch64-unknown-fuchsia", aarch64_unknown_fuchsia),
-    ("x86_64-unknown-fuchsia", x86_64_unknown_fuchsia),
+    ("aarch64-fuchsia", aarch64_fuchsia),
+    ("x86_64-fuchsia", x86_64_fuchsia),
 
     ("x86_64-unknown-l4re-uclibc", x86_64_unknown_l4re_uclibc),
 
diff --git a/src/librustc_target/spec/x86_64_unknown_fuchsia.rs b/src/librustc_target/spec/x86_64_fuchsia.rs
index a510ec8eb34..e8fa179887c 100644
--- a/src/librustc_target/spec/x86_64_unknown_fuchsia.rs
+++ b/src/librustc_target/spec/x86_64_fuchsia.rs
@@ -18,7 +18,7 @@ pub fn target() -> TargetResult {
     base.stack_probes = true;
 
     Ok(Target {
-        llvm_target: "x86_64-unknown-fuchsia".to_string(),
+        llvm_target: "x86_64-fuchsia".to_string(),
         target_endian: "little".to_string(),
         target_pointer_width: "64".to_string(),
         target_c_int_width: "32".to_string(),
@@ -26,7 +26,7 @@ pub fn target() -> TargetResult {
         arch: "x86_64".to_string(),
         target_os: "fuchsia".to_string(),
         target_env: "".to_string(),
-        target_vendor: "unknown".to_string(),
+        target_vendor: "".to_string(),
         linker_flavor: LinkerFlavor::Gcc,
         options: base,
     })
diff --git a/src/librustc_traits/lib.rs b/src/librustc_traits/lib.rs
index 2a4cacb5623..d17cf35f181 100644
--- a/src/librustc_traits/lib.rs
+++ b/src/librustc_traits/lib.rs
@@ -11,8 +11,6 @@
 //! New recursive solver modeled on Chalk's recursive solver. Most of
 //! the guts are broken up into modules; see the comments in those modules.
 
-#![deny(bare_trait_objects)]
-
 #![feature(crate_in_paths)]
 #![feature(crate_visibility_modifier)]
 #![feature(extern_prelude)]
diff --git a/src/librustc_tsan/lib.rs b/src/librustc_tsan/lib.rs
index 7bd1e98f85d..0c78fd74a23 100644
--- a/src/librustc_tsan/lib.rs
+++ b/src/librustc_tsan/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![sanitizer_runtime]
 #![feature(alloc_system)]
 #![feature(sanitizer_runtime)]
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 220dd122b26..55aa38d942e 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -319,6 +319,17 @@ fn compare_predicate_entailment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                             E0053,
                                             "method `{}` has an incompatible type for trait",
                                             trait_m.ident);
+            if let TypeError::Mutability = terr {
+                if let Some(trait_err_span) = trait_err_span {
+                    if let Ok(trait_err_str) = tcx.sess.codemap().span_to_snippet(trait_err_span) {
+                        diag.span_suggestion(
+                            impl_err_span,
+                            "consider change the type to match the mutability in trait",
+                            format!("{}", trait_err_str),
+                        );
+                    }
+                }
+            }
 
             infcx.note_type_err(&mut diag,
                                 &cause,
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index 03ecb945cbd..38743cc9cf6 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -211,8 +211,7 @@ fn check_associated_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                 }
             }
             ty::AssociatedKind::Existential => {
-                // FIXME(oli-obk) implement existential types in trait impls
-                unimplemented!()
+                // do nothing, existential types check themselves
             }
         }
 
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 60f89282551..cd84a61bb2c 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -1046,12 +1046,12 @@ fn type_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     tcx.mk_fn_def(def_id, substs)
                 }
                 ImplItemKind::Const(ref ty, _) => icx.to_ty(ty),
-                ImplItemKind::Existential(ref _bounds) => {
+                ImplItemKind::Existential(_) => {
                     if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
                         report_assoc_ty_on_inherent_impl(tcx, item.span);
                     }
-                    // FIXME(oli-obk) implement existential types in trait impls
-                    unimplemented!()
+
+                    find_existential_constraints(tcx, def_id)
                 }
                 ImplItemKind::Type(ref ty) => {
                     if tcx.impl_trait_ref(tcx.hir.get_parent_did(node_id)).is_none() {
@@ -1186,8 +1186,10 @@ fn find_existential_constraints<'a, 'tcx>(
     }
     impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> {
         fn check(&mut self, def_id: DefId) {
+            trace!("checking {:?}", def_id);
             // don't try to check items that cannot possibly constrain the type
             if !self.tcx.has_typeck_tables(def_id) {
+                trace!("no typeck tables for {:?}", def_id);
                 return;
             }
             let ty = self
@@ -1244,9 +1246,11 @@ fn find_existential_constraints<'a, 'tcx>(
     let mut locator = ConstraintLocator { def_id, tcx, found: None };
     let node_id = tcx.hir.as_local_node_id(def_id).unwrap();
     let parent = tcx.hir.get_parent(node_id);
+    trace!("parent_id: {:?}", parent);
     if parent == ast::CRATE_NODE_ID {
         intravisit::walk_crate(&mut locator, tcx.hir.krate());
     } else {
+        trace!("parent: {:?}", tcx.hir.get(parent));
         match tcx.hir.get(parent) {
             NodeItem(ref it) => intravisit::walk_item(&mut locator, it),
             NodeImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it),
@@ -1485,7 +1489,23 @@ fn explicit_predicates_of<'a, 'tcx>(
             &item.generics
         }
 
-        NodeImplItem(item) => &item.generics,
+        NodeImplItem(item) => match item.node {
+            ImplItemKind::Existential(ref bounds) => {
+                let substs = Substs::identity_for_item(tcx, def_id);
+                let anon_ty = tcx.mk_anon(def_id, substs);
+
+                // Collect the bounds, i.e. the `A+B+'c` in `impl A+B+'c`.
+                let bounds = compute_bounds(&icx,
+                                            anon_ty,
+                                            bounds,
+                                            SizedByDefault::Yes,
+                                            tcx.def_span(def_id));
+
+                predicates.extend(bounds.predicates(tcx, anon_ty));
+                &item.generics
+            },
+            _ => &item.generics,
+        }
 
         NodeItem(item) => {
             match item.node {
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index e343fb1a57b..6bf1ec8f697 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -70,7 +70,6 @@ This API is completely unstable and subject to change.
       html_root_url = "https://doc.rust-lang.org/nightly/")]
 
 #![allow(non_camel_case_types)]
-#![deny(bare_trait_objects)]
 
 #![feature(box_patterns)]
 #![feature(box_syntax)]
diff --git a/src/librustc_typeck/outlives/utils.rs b/src/librustc_typeck/outlives/utils.rs
index 5cb1822b04e..0d833c50d7e 100644
--- a/src/librustc_typeck/outlives/utils.rs
+++ b/src/librustc_typeck/outlives/utils.rs
@@ -27,7 +27,7 @@ pub fn insert_outlives_predicate<'tcx>(
 ) {
     // If the `'a` region is bound within the field type itself, we
     // don't want to propagate this constraint to the header.
-    if !is_free_region(outlived_region) {
+    if !is_free_region(tcx, outlived_region) {
         return;
     }
 
@@ -120,7 +120,7 @@ pub fn insert_outlives_predicate<'tcx>(
         }
 
         UnpackedKind::Lifetime(r) => {
-            if !is_free_region(r) {
+            if !is_free_region(tcx, r) {
                 return;
             }
             required_predicates.insert(ty::OutlivesPredicate(kind, outlived_region));
@@ -128,19 +128,36 @@ pub fn insert_outlives_predicate<'tcx>(
     }
 }
 
-fn is_free_region(region: Region<'_>) -> bool {
+fn is_free_region<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>, region: Region<'_>) -> bool {
     // First, screen for regions that might appear in a type header.
     match region {
-        // *These* correspond to `T: 'a` relationships where `'a` is
-        // either declared on the type or `'static`:
+        // These correspond to `T: 'a` relationships:
         //
         //     struct Foo<'a, T> {
         //         field: &'a T, // this would generate a ReEarlyBound referencing `'a`
-        //         field2: &'static T, // this would generate a ReStatic
         //     }
         //
         // We care about these, so fall through.
-        RegionKind::ReStatic | RegionKind::ReEarlyBound(_) => true,
+        RegionKind::ReEarlyBound(_) => true,
+
+        // These correspond to `T: 'static` relationships which can be
+        // rather surprising. We are therefore putting this behind a
+        // feature flag:
+        //
+        //     struct Foo<'a, T> {
+        //         field: &'static T, // this would generate a ReStatic
+        //     }
+        RegionKind::ReStatic => {
+            if tcx
+                .sess
+                .features_untracked()
+                .infer_static_outlives_requirements
+            {
+                true
+            } else {
+                false
+            }
+        }
 
         // Late-bound regions can appear in `fn` types:
         //
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 0cdab134815..c30d6817b46 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -8,10 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-use rustc::traits::auto_trait as auto;
-use rustc::ty::TypeFoldable;
 use rustc::hir;
+use rustc::traits::{self, auto_trait as auto};
+use rustc::ty::{self, ToPredicate, TypeFoldable};
+use rustc::ty::subst::Subst;
+use rustc::infer::InferOk;
 use std::fmt::Debug;
+use syntax_pos::DUMMY_SP;
+
+use core::DocAccessLevels;
 
 use super::*;
 
@@ -75,6 +80,141 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
         self.get_auto_trait_impls(did, &def_ctor, Some(name))
     }
 
+    fn get_real_ty<F>(&self,
+                      def_id: DefId,
+                      def_ctor: &F,
+                      real_name: &Option<Ident>,
+                      generics: &ty::Generics,
+    ) -> hir::Ty
+    where F: Fn(DefId) -> Def {
+        let path = get_path_for_type(self.cx.tcx, def_id, def_ctor);
+        let mut segments = path.segments.into_vec();
+        let last = segments.pop().unwrap();
+
+        segments.push(hir::PathSegment::new(
+            real_name.unwrap_or(last.ident),
+            self.generics_to_path_params(generics.clone()),
+            false,
+        ));
+
+        let new_path = hir::Path {
+            span: path.span,
+            def: path.def,
+            segments: HirVec::from_vec(segments),
+        };
+
+        hir::Ty {
+            id: ast::DUMMY_NODE_ID,
+            node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))),
+            span: DUMMY_SP,
+            hir_id: hir::DUMMY_HIR_ID,
+        }
+    }
+
+    pub fn get_blanket_impls<F>(
+        &self,
+        def_id: DefId,
+        def_ctor: &F,
+        name: Option<String>,
+        generics: &ty::Generics,
+    ) -> Vec<Item>
+    where F: Fn(DefId) -> Def {
+        let ty = self.cx.tcx.type_of(def_id);
+        let mut traits = Vec::new();
+        if self.cx.access_levels.borrow().is_doc_reachable(def_id) {
+            let real_name = name.clone().map(|name| Ident::from_str(&name));
+            let param_env = self.cx.tcx.param_env(def_id);
+            for &trait_def_id in self.cx.all_traits.iter() {
+                if !self.cx.access_levels.borrow().is_doc_reachable(trait_def_id) ||
+                   self.cx.generated_synthetics
+                          .borrow_mut()
+                          .get(&(def_id, trait_def_id))
+                          .is_some() {
+                    continue
+                }
+                self.cx.tcx.for_each_relevant_impl(trait_def_id, ty, |impl_def_id| {
+                    self.cx.tcx.infer_ctxt().enter(|infcx| {
+                        let t_generics = infcx.tcx.generics_of(impl_def_id);
+                        let trait_ref = infcx.tcx.impl_trait_ref(impl_def_id).unwrap();
+
+                        match infcx.tcx.type_of(impl_def_id).sty {
+                            ::rustc::ty::TypeVariants::TyParam(_) => {},
+                            _ => return,
+                        }
+
+                        let substs = infcx.fresh_substs_for_item(DUMMY_SP, def_id);
+                        let ty = ty.subst(infcx.tcx, substs);
+                        let param_env = param_env.subst(infcx.tcx, substs);
+
+                        let impl_substs = infcx.fresh_substs_for_item(DUMMY_SP, impl_def_id);
+                        let trait_ref = trait_ref.subst(infcx.tcx, impl_substs);
+
+                        // Require the type the impl is implemented on to match
+                        // our type, and ignore the impl if there was a mismatch.
+                        let cause = traits::ObligationCause::dummy();
+                        let eq_result = infcx.at(&cause, param_env)
+                                             .eq(trait_ref.self_ty(), ty);
+                        if let Ok(InferOk { value: (), obligations }) = eq_result {
+                            // FIXME(eddyb) ignoring `obligations` might cause false positives.
+                            drop(obligations);
+
+                            let may_apply = infcx.predicate_may_hold(&traits::Obligation::new(
+                                cause.clone(),
+                                param_env,
+                                trait_ref.to_predicate(),
+                            ));
+                            if !may_apply {
+                                return
+                            }
+                            self.cx.generated_synthetics.borrow_mut()
+                                                        .insert((def_id, trait_def_id));
+                            let trait_ = hir::TraitRef {
+                                path: get_path_for_type(infcx.tcx,
+                                                        trait_def_id,
+                                                        hir::def::Def::Trait),
+                                ref_id: ast::DUMMY_NODE_ID,
+                            };
+                            let provided_trait_methods =
+                                infcx.tcx.provided_trait_methods(trait_def_id)
+                                         .into_iter()
+                                         .map(|meth| meth.ident.to_string())
+                                         .collect();
+
+                            let ty = self.get_real_ty(def_id, def_ctor, &real_name, generics);
+                            let predicates = infcx.tcx.predicates_of(impl_def_id);
+
+                            traits.push(Item {
+                                source: infcx.tcx.def_span(impl_def_id).clean(self.cx),
+                                name: None,
+                                attrs: Default::default(),
+                                visibility: None,
+                                def_id: self.next_def_id(impl_def_id.krate),
+                                stability: None,
+                                deprecation: None,
+                                inner: ImplItem(Impl {
+                                    unsafety: hir::Unsafety::Normal,
+                                    generics: (t_generics, &predicates).clean(self.cx),
+                                    provided_trait_methods,
+                                    trait_: Some(trait_.clean(self.cx)),
+                                    for_: ty.clean(self.cx),
+                                    items: infcx.tcx.associated_items(impl_def_id)
+                                                    .collect::<Vec<_>>()
+                                                    .clean(self.cx),
+                                    polarity: None,
+                                    synthetic: false,
+                                    blanket_impl: Some(infcx.tcx.type_of(impl_def_id)
+                                                                .clean(self.cx)),
+                                }),
+                            });
+                            debug!("{:?} => {}", trait_ref, may_apply);
+                        }
+                    });
+                });
+            }
+        }
+        traits
+    }
+
     pub fn get_auto_trait_impls<F>(
         &self,
         def_id: DefId,
@@ -122,6 +262,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                 def_ctor,
                 tcx.require_lang_item(lang_items::SyncTraitLangItem),
             ).into_iter())
+            .chain(self.get_blanket_impls(def_id, def_ctor, name, &generics).into_iter())
             .collect();
 
         debug!(
@@ -196,31 +337,8 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                 }
                 _ => unreachable!(),
             };
-
-            let path = get_path_for_type(self.cx.tcx, def_id, def_ctor);
-            let mut segments = path.segments.into_vec();
-            let last = segments.pop().unwrap();
-
             let real_name = name.map(|name| Ident::from_str(&name));
-
-            segments.push(hir::PathSegment::new(
-                real_name.unwrap_or(last.ident),
-                self.generics_to_path_params(generics.clone()),
-                false,
-            ));
-
-            let new_path = hir::Path {
-                span: path.span,
-                def: path.def,
-                segments: HirVec::from_vec(segments),
-            };
-
-            let ty = hir::Ty {
-                id: ast::DUMMY_NODE_ID,
-                node: hir::TyKind::Path(hir::QPath::Resolved(None, P(new_path))),
-                span: DUMMY_SP,
-                hir_id: hir::DUMMY_HIR_ID,
-            };
+            let ty = self.get_real_ty(def_id, def_ctor, &real_name, &generics);
 
             return Some(Item {
                 source: Span::empty(),
@@ -239,6 +357,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                     items: Vec::new(),
                     polarity,
                     synthetic: true,
+                    blanket_impl: None,
                 }),
             });
         }
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 0117e4fde84..9245ef3cf50 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -275,7 +275,6 @@ pub fn build_impls(cx: &DocContext, did: DefId, auto_traits: bool) -> Vec<clean:
     if auto_traits {
         let auto_impls = get_auto_traits_with_def_id(cx, did);
         let mut renderinfo = cx.renderinfo.borrow_mut();
-
         let new_impls: Vec<clean::Item> = auto_impls.into_iter()
             .filter(|i| renderinfo.inlined.insert(i.def_id)).collect();
 
@@ -415,6 +414,7 @@ pub fn build_impl(cx: &DocContext, did: DefId, ret: &mut Vec<clean::Item>) {
             items: trait_items,
             polarity: Some(polarity.clean(cx)),
             synthetic: false,
+            blanket_impl: None,
         }),
         source: tcx.def_span(did).clean(cx),
         name: None,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 98684b27973..c050e30fea0 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -375,7 +375,7 @@ impl fmt::Debug for Item {
 
         let fake = MAX_DEF_ID.with(|m| m.borrow().get(&self.def_id.krate)
                                    .map(|id| self.def_id >= *id).unwrap_or(false));
-        let def_id: &fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
+        let def_id: &dyn fmt::Debug = if fake { &"**FAKE**" } else { &self.def_id };
 
         fmt.debug_struct("Item")
             .field("source", &self.source)
@@ -1549,7 +1549,6 @@ impl GenericBound {
     }
 
     fn get_trait_type(&self) -> Option<Type> {
-
         if let GenericBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
             return Some(trait_.clone());
         }
@@ -3880,6 +3879,7 @@ pub struct Impl {
     pub items: Vec<Item>,
     pub polarity: Option<ImplPolarity>,
     pub synthetic: bool,
+    pub blanket_impl: Option<Type>,
 }
 
 pub fn get_auto_traits_with_node_id(cx: &DocContext, id: ast::NodeId, name: String) -> Vec<Item> {
@@ -3947,6 +3947,7 @@ impl Clean<Vec<Item>> for doctree::Impl {
                 items,
                 polarity: Some(self.polarity.clean(cx)),
                 synthetic: false,
+                blanket_impl: None,
             })
         });
         ret
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 6e1b4589547..77375442d4c 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -11,7 +11,7 @@
 use rustc_lint;
 use rustc_driver::{self, driver, target_features, abort_on_err};
 use rustc::session::{self, config};
-use rustc::hir::def_id::{DefId, CrateNum};
+use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE};
 use rustc::hir::def::Def;
 use rustc::middle::cstore::CrateStore;
 use rustc::middle::privacy::AccessLevels;
@@ -55,7 +55,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
     /// The stack of module NodeIds up till this point
     pub mod_ids: RefCell<Vec<NodeId>>,
     pub crate_name: Option<String>,
-    pub cstore: Rc<CrateStore>,
+    pub cstore: Rc<dyn CrateStore>,
     pub populated_all_crate_impls: Cell<bool>,
     // Note that external items for which `doc(hidden)` applies to are shown as
     // non-reachable while local items aren't. This is because we're reusing
@@ -84,6 +84,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
     /// Maps (type_id, trait_id) -> auto trait impl
     pub generated_synthetics: RefCell<FxHashSet<(DefId, DefId)>>,
     pub current_item_name: RefCell<Option<Name>>,
+    pub all_traits: Vec<DefId>,
 }
 
 impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> {
@@ -386,6 +387,7 @@ pub fn run_core(search_paths: SearchPaths,
                 all_fake_def_ids: RefCell::new(FxHashSet()),
                 generated_synthetics: RefCell::new(FxHashSet()),
                 current_item_name: RefCell::new(None),
+                all_traits: tcx.all_traits(LOCAL_CRATE).to_vec(),
             };
             debug!("crate: {:?}", tcx.hir.krate());
 
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 0a25e9091de..feec513b975 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -767,7 +767,11 @@ fn fmt_impl(i: &clean::Impl,
         write!(f, " for ")?;
     }
 
-    fmt_type(&i.for_, f, use_absolute)?;
+    if let Some(ref ty) = i.blanket_impl {
+        fmt_type(ty, f, use_absolute)?;
+    } else {
+        fmt_type(&i.for_, f, use_absolute)?;
+    }
 
     fmt::Display::fmt(&WhereClause { gens: &i.generics, indent: 0, end_newline: true }, f)?;
     Ok(())
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 5939d5341e3..6cf9b143373 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -395,7 +395,7 @@ impl Class {
 
 fn write_header(class: Option<&str>,
                 id: Option<&str>,
-                out: &mut Write)
+                out: &mut dyn Write)
                 -> io::Result<()> {
     write!(out, "<pre ")?;
     if let Some(id) = id {
@@ -404,6 +404,6 @@ fn write_header(class: Option<&str>,
     write!(out, "class=\"rust {}\">\n", class.unwrap_or(""))
 }
 
-fn write_footer(out: &mut Write) -> io::Result<()> {
+fn write_footer(out: &mut dyn Write) -> io::Result<()> {
     write!(out, "</pre>\n")
 }
diff --git a/src/librustdoc/html/layout.rs b/src/librustdoc/html/layout.rs
index 5e93b20ea17..af7c0a04215 100644
--- a/src/librustdoc/html/layout.rs
+++ b/src/librustdoc/html/layout.rs
@@ -32,7 +32,7 @@ pub struct Page<'a> {
 }
 
 pub fn render<T: fmt::Display, S: fmt::Display>(
-    dst: &mut io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
+    dst: &mut dyn io::Write, layout: &Layout, page: &Page, sidebar: &S, t: &T,
     css_file_extension: bool, themes: &[PathBuf])
     -> io::Result<()>
 {
@@ -194,7 +194,7 @@ pub fn render<T: fmt::Display, S: fmt::Display>(
     )
 }
 
-pub fn redirect(dst: &mut io::Write, url: &str) -> io::Result<()> {
+pub fn redirect(dst: &mut dyn io::Write, url: &str) -> io::Result<()> {
     // <script> triggers a redirect before refresh, so this is fine.
     write!(dst,
 r##"<!DOCTYPE html>
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c06323b22dc..9f4f20e3539 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -176,7 +176,7 @@ pub enum ExternalLocation {
 }
 
 /// Metadata about implementations for a type or trait.
-#[derive(Clone)]
+#[derive(Clone, Debug)]
 pub struct Impl {
     pub impl_item: clean::Item,
 }
@@ -1821,7 +1821,7 @@ impl Context {
     }
 
     fn render_item(&self,
-                   writer: &mut io::Write,
+                   writer: &mut dyn io::Write,
                    it: &clean::Item,
                    pushname: bool)
                    -> io::Result<()> {
@@ -2688,7 +2688,7 @@ fn render_implementor(cx: &Context, implementor: &Impl, w: &mut fmt::Formatter,
     for it in &implementor.inner_impl().items {
         if let clean::TypedefItem(ref tydef, _) = it.inner {
             write!(w, "<span class=\"where fmt-newline\">  ")?;
-            assoc_type(w, it, &vec![], Some(&tydef.type_), AssocItemLink::Anchor(None))?;
+            assoc_type(w, it, &[], Some(&tydef.type_), AssocItemLink::Anchor(None))?;
             write!(w, ";</span>")?;
         }
     }
@@ -2898,18 +2898,18 @@ fn item_trait(
     render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All)?;
 
     let cache = cache();
-    let impl_header = "
-        <h2 id='implementors' class='small-section-header'>
-          Implementors<a href='#implementors' class='anchor'></a>
-        </h2>
-        <ul class='item-list' id='implementors-list'>
+    let impl_header = "\
+        <h2 id='implementors' class='small-section-header'>\
+          Implementors<a href='#implementors' class='anchor'></a>\
+        </h2>\
+        <ul class='item-list' id='implementors-list'>\
     ";
 
-    let synthetic_impl_header = "
-        <h2 id='synthetic-implementors' class='small-section-header'>
-          Auto implementors<a href='#synthetic-implementors' class='anchor'></a>
-        </h2>
-        <ul class='item-list' id='synthetic-implementors-list'>
+    let synthetic_impl_header = "\
+        <h2 id='synthetic-implementors' class='small-section-header'>\
+          Auto implementors<a href='#synthetic-implementors' class='anchor'></a>\
+        </h2>\
+        <ul class='item-list' id='synthetic-implementors-list'>\
     ";
 
     let mut synthetic_types = Vec::new();
@@ -2940,9 +2940,9 @@ fn item_trait(
                                          .map_or(true, |d| cache.paths.contains_key(&d)));
 
 
-        let (synthetic, concrete) = local.iter()
-            .partition::<Vec<_>, _>(|i| i.inner_impl().synthetic);
-
+        let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = local.iter()
+            .filter(|i| i.inner_impl().blanket_impl.is_none())
+            .partition(|i| i.inner_impl().synthetic);
 
         if !foreign.is_empty() {
             write!(w, "
@@ -3038,7 +3038,7 @@ fn assoc_const(w: &mut fmt::Formatter,
 }
 
 fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item,
-                             bounds: &Vec<clean::GenericBound>,
+                             bounds: &[clean::GenericBound],
                              default: Option<&clean::Type>,
                              link: AssocItemLink) -> fmt::Result {
     write!(w, "type <a href='{}' class=\"type\">{}</a>",
@@ -3588,18 +3588,19 @@ fn render_assoc_items(w: &mut fmt::Formatter,
     if !non_trait.is_empty() {
         let render_mode = match what {
             AssocItemRender::All => {
-                write!(w, "
-                    <h2 id='methods' class='small-section-header'>
-                      Methods<a href='#methods' class='anchor'></a>
-                    </h2>
+                write!(w, "\
+                    <h2 id='methods' class='small-section-header'>\
+                      Methods<a href='#methods' class='anchor'></a>\
+                    </h2>\
                 ")?;
                 RenderMode::Normal
             }
             AssocItemRender::DerefFor { trait_, type_, deref_mut_ } => {
-                write!(w, "
-                    <h2 id='deref-methods' class='small-section-header'>
-                      Methods from {}&lt;Target = {}&gt;<a href='#deref-methods' class='anchor'></a>
-                    </h2>
+                write!(w, "\
+                    <h2 id='deref-methods' class='small-section-header'>\
+                      Methods from {}&lt;Target = {}&gt;\
+                      <a href='#deref-methods' class='anchor'></a>\
+                    </h2>\
                 ", trait_, type_)?;
                 RenderMode::ForDeref { mut_: deref_mut_ }
             }
@@ -3623,9 +3624,12 @@ fn render_assoc_items(w: &mut fmt::Formatter,
             render_deref_methods(w, cx, impl_, containing_item, has_deref_mut)?;
         }
 
-        let (synthetic, concrete) = traits
+        let (synthetic, concrete): (Vec<&&Impl>, Vec<&&Impl>) = traits
             .iter()
-            .partition::<Vec<_>, _>(|t| t.inner_impl().synthetic);
+            .partition(|t| t.inner_impl().synthetic);
+        let (blanket_impl, concrete) = concrete
+            .into_iter()
+            .partition(|t| t.inner_impl().blanket_impl.is_some());
 
         struct RendererStruct<'a, 'b, 'c>(&'a Context, Vec<&'b &'b Impl>, &'c clean::Item);
 
@@ -3637,23 +3641,36 @@ fn render_assoc_items(w: &mut fmt::Formatter,
 
         let impls = format!("{}", RendererStruct(cx, concrete, containing_item));
         if !impls.is_empty() {
-            write!(w, "
-                <h2 id='implementations' class='small-section-header'>
-                  Trait Implementations<a href='#implementations' class='anchor'></a>
-                </h2>
+            write!(w, "\
+                <h2 id='implementations' class='small-section-header'>\
+                  Trait Implementations<a href='#implementations' class='anchor'></a>\
+                </h2>\
                 <div id='implementations-list'>{}</div>", impls)?;
         }
 
         if !synthetic.is_empty() {
-            write!(w, "
-                <h2 id='synthetic-implementations' class='small-section-header'>
-                  Auto Trait Implementations<a href='#synthetic-implementations' class='anchor'></a>
-                </h2>
-                <div id='synthetic-implementations-list'>
+            write!(w, "\
+                <h2 id='synthetic-implementations' class='small-section-header'>\
+                  Auto Trait Implementations\
+                  <a href='#synthetic-implementations' class='anchor'></a>\
+                </h2>\
+                <div id='synthetic-implementations-list'>\
             ")?;
             render_impls(cx, w, &synthetic, containing_item)?;
             write!(w, "</div>")?;
         }
+
+        if !blanket_impl.is_empty() {
+            write!(w, "\
+                <h2 id='blanket-implementations' class='small-section-header'>\
+                  Blanket Implementations\
+                  <a href='#blanket-implementations' class='anchor'></a>\
+                </h2>\
+                <div id='blanket-implementations-list'>\
+            ")?;
+            render_impls(cx, w, &blanket_impl, containing_item)?;
+            write!(w, "</div>")?;
+        }
     }
     Ok(())
 }
@@ -3747,7 +3764,7 @@ fn spotlight_decl(decl: &clean::FnDecl) -> Result<String, fmt::Error> {
                     for it in &impl_.items {
                         if let clean::TypedefItem(ref tydef, _) = it.inner {
                             out.push_str("<span class=\"where fmt-newline\">    ");
-                            assoc_type(&mut out, it, &vec![],
+                            assoc_type(&mut out, it, &[],
                                        Some(&tydef.type_),
                                        AssocItemLink::GotoSource(t_did, &FxHashSet()))?;
                             out.push_str(";</span>");
@@ -4199,12 +4216,16 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                            .collect::<String>()
             };
 
-            let (synthetic, concrete) = v
+            let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) = v
                 .iter()
                 .partition::<Vec<_>, _>(|i| i.inner_impl().synthetic);
+            let (blanket_impl, concrete): (Vec<&Impl>, Vec<&Impl>) = concrete
+                .into_iter()
+                .partition::<Vec<_>, _>(|i| i.inner_impl().blanket_impl.is_some());
 
             let concrete_format = format_impls(concrete);
             let synthetic_format = format_impls(synthetic);
+            let blanket_format = format_impls(blanket_impl);
 
             if !concrete_format.is_empty() {
                 out.push_str("<a class=\"sidebar-title\" href=\"#implementations\">\
@@ -4217,6 +4238,12 @@ fn sidebar_assoc_items(it: &clean::Item) -> String {
                               Auto Trait Implementations</a>");
                 out.push_str(&format!("<div class=\"sidebar-links\">{}</div>", synthetic_format));
             }
+
+            if !blanket_format.is_empty() {
+                out.push_str("<a class=\"sidebar-title\" href=\"#blanket-implementations\">\
+                              Blanket Implementations</a>");
+                out.push_str(&format!("<div class=\"sidebar-links\">{}</div>", blanket_format));
+            }
         }
     }
 
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 9ebefdabbb4..00cad5e376a 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -373,6 +373,10 @@ pub fn main_args(args: &[String]) -> isize {
         for &name in passes::DEFAULT_PASSES {
             println!("{:>20}", name);
         }
+        println!("\nPasses run with `--document-private-items`:");
+        for &name in passes::DEFAULT_PRIVATE_PASSES {
+            println!("{:>20}", name);
+        }
         return 0;
     }
 
@@ -623,20 +627,16 @@ fn rust_input<R, F>(cratefile: PathBuf,
 where R: 'static + Send,
       F: 'static + Send + FnOnce(Output) -> R
 {
-    let mut default_passes = !matches.opt_present("no-defaults");
-    let mut passes = matches.opt_strs("passes");
-    let mut plugins = matches.opt_strs("plugins");
-
-    // We hardcode in the passes here, as this is a new flag and we
-    // are generally deprecating passes.
-    if matches.opt_present("document-private-items") {
-        default_passes = false;
+    let mut default_passes = if matches.opt_present("no-defaults") {
+        passes::DefaultPassOption::None
+    } else if matches.opt_present("document-private-items") {
+        passes::DefaultPassOption::Private
+    } else {
+        passes::DefaultPassOption::Default
+    };
 
-        passes = vec![
-            String::from("collapse-docs"),
-            String::from("unindent-comments"),
-        ];
-    }
+    let mut manual_passes = matches.opt_strs("passes");
+    let mut plugins = matches.opt_strs("plugins");
 
     // First, parse the crate and extract all relevant information.
     let mut paths = SearchPaths::new();
@@ -706,13 +706,15 @@ where R: 'static + Send,
             if attr.is_word() {
                 if name == Some("no_default_passes") {
                     report_deprecated_attr("no_default_passes", &diag);
-                    default_passes = false;
+                    if default_passes == passes::DefaultPassOption::Default {
+                        default_passes = passes::DefaultPassOption::None;
+                    }
                 }
             } else if let Some(value) = attr.value_str() {
                 let sink = match name {
                     Some("passes") => {
                         report_deprecated_attr("passes = \"...\"", &diag);
-                        &mut passes
+                        &mut manual_passes
                     },
                     Some("plugins") => {
                         report_deprecated_attr("plugins = \"...\"", &diag);
@@ -726,20 +728,15 @@ where R: 'static + Send,
             }
 
             if attr.is_word() && name == Some("document_private_items") {
-                default_passes = false;
-
-                passes = vec![
-                    String::from("collapse-docs"),
-                    String::from("unindent-comments"),
-                ];
+                if default_passes == passes::DefaultPassOption::Default {
+                    default_passes = passes::DefaultPassOption::Private;
+                }
             }
         }
 
-        if default_passes {
-            for name in passes::DEFAULT_PASSES.iter().rev() {
-                passes.insert(0, name.to_string());
-            }
-        }
+        let mut passes: Vec<String> =
+            passes::defaults(default_passes).iter().map(|p| p.to_string()).collect();
+        passes.extend(manual_passes);
 
         if !plugins.is_empty() {
             eprintln!("WARNING: --plugins no longer functions; see CVE-2018-1000622");
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 63b74ceafac..8de4fed5bf0 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -63,6 +63,33 @@ pub const DEFAULT_PASSES: &'static [&'static str] = &[
     "propagate-doc-cfg",
 ];
 
+pub const DEFAULT_PRIVATE_PASSES: &'static [&'static str] = &[
+    "strip-priv-imports",
+    "collapse-docs",
+    "unindent-comments",
+    "propagate-doc-cfg",
+];
+
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+pub enum DefaultPassOption {
+    Default,
+    Private,
+    None,
+}
+
+pub fn defaults(default_set: DefaultPassOption) -> &'static [&'static str] {
+    match default_set {
+        DefaultPassOption::Default => {
+            DEFAULT_PASSES
+        },
+        DefaultPassOption::Private => {
+            DEFAULT_PRIVATE_PASSES
+        },
+        DefaultPassOption::None => {
+            &[]
+        },
+    }
+}
 
 struct Stripper<'a> {
     retained: &'a mut DefIdSet,
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index eb980a7369b..2966b9e9819 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -249,7 +249,7 @@ fn run_test(test: &str, cratename: &str, filename: &FileName, line: usize,
         }
         fn flush(&mut self) -> io::Result<()> { Ok(()) }
     }
-    struct Bomb(Arc<Mutex<Vec<u8>>>, Box<Write+Send>);
+    struct Bomb(Arc<Mutex<Vec<u8>>>, Box<dyn Write+Send>);
     impl Drop for Bomb {
         fn drop(&mut self) {
             let _ = self.1.write_all(&self.0.lock().unwrap());
diff --git a/src/libserialize/lib.rs b/src/libserialize/lib.rs
index 7c1bb69434d..a5f4b32b329 100644
--- a/src/libserialize/lib.rs
+++ b/src/libserialize/lib.rs
@@ -14,8 +14,6 @@
 Core encoding and decoding interfaces.
 */
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
diff --git a/src/libstd/error.rs b/src/libstd/error.rs
index 1958915602f..29534696abc 100644
--- a/src/libstd/error.rs
+++ b/src/libstd/error.rs
@@ -138,7 +138,7 @@ pub trait Error: Debug + Display {
     /// }
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
-    fn cause(&self) -> Option<&Error> { None }
+    fn cause(&self) -> Option<&dyn Error> { None }
 
     /// Get the `TypeId` of `self`
     #[doc(hidden)]
@@ -151,22 +151,22 @@ pub trait Error: Debug + Display {
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + 'a> From<E> for Box<Error + 'a> {
-    fn from(err: E) -> Box<Error + 'a> {
+impl<'a, E: Error + 'a> From<E> for Box<dyn Error + 'a> {
+    fn from(err: E) -> Box<dyn Error + 'a> {
         Box::new(err)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<Error + Send + Sync + 'a> {
-    fn from(err: E) -> Box<Error + Send + Sync + 'a> {
+impl<'a, E: Error + Send + Sync + 'a> From<E> for Box<dyn Error + Send + Sync + 'a> {
+    fn from(err: E) -> Box<dyn Error + Send + Sync + 'a> {
         Box::new(err)
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl From<String> for Box<Error + Send + Sync> {
-    fn from(err: String) -> Box<Error + Send + Sync> {
+impl From<String> for Box<dyn Error + Send + Sync> {
+    fn from(err: String) -> Box<dyn Error + Send + Sync> {
         #[derive(Debug)]
         struct StringError(String);
 
@@ -185,38 +185,38 @@ impl From<String> for Box<Error + Send + Sync> {
 }
 
 #[stable(feature = "string_box_error", since = "1.6.0")]
-impl From<String> for Box<Error> {
-    fn from(str_err: String) -> Box<Error> {
-        let err1: Box<Error + Send + Sync> = From::from(str_err);
-        let err2: Box<Error> = err1;
+impl From<String> for Box<dyn Error> {
+    fn from(str_err: String) -> Box<dyn Error> {
+        let err1: Box<dyn Error + Send + Sync> = From::from(str_err);
+        let err2: Box<dyn Error> = err1;
         err2
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-impl<'a, 'b> From<&'b str> for Box<Error + Send + Sync + 'a> {
-    fn from(err: &'b str) -> Box<Error + Send + Sync + 'a> {
+impl<'a, 'b> From<&'b str> for Box<dyn Error + Send + Sync + 'a> {
+    fn from(err: &'b str) -> Box<dyn Error + Send + Sync + 'a> {
         From::from(String::from(err))
     }
 }
 
 #[stable(feature = "string_box_error", since = "1.6.0")]
-impl<'a> From<&'a str> for Box<Error> {
-    fn from(err: &'a str) -> Box<Error> {
+impl<'a> From<&'a str> for Box<dyn Error> {
+    fn from(err: &'a str) -> Box<dyn Error> {
         From::from(String::from(err))
     }
 }
 
 #[stable(feature = "cow_box_error", since = "1.22.0")]
-impl<'a, 'b> From<Cow<'b, str>> for Box<Error + Send + Sync + 'a> {
-    fn from(err: Cow<'b, str>) -> Box<Error + Send + Sync + 'a> {
+impl<'a, 'b> From<Cow<'b, str>> for Box<dyn Error + Send + Sync + 'a> {
+    fn from(err: Cow<'b, str>) -> Box<dyn Error + Send + Sync + 'a> {
         From::from(String::from(err))
     }
 }
 
 #[stable(feature = "cow_box_error", since = "1.22.0")]
-impl<'a> From<Cow<'a, str>> for Box<Error> {
-    fn from(err: Cow<'a, str>) -> Box<Error> {
+impl<'a> From<Cow<'a, str>> for Box<dyn Error> {
+    fn from(err: Cow<'a, str>) -> Box<dyn Error> {
         From::from(String::from(err))
     }
 }
@@ -327,7 +327,7 @@ impl<T: Error> Error for Box<T> {
         Error::description(&**self)
     }
 
-    fn cause(&self) -> Option<&Error> {
+    fn cause(&self) -> Option<&dyn Error> {
         Error::cause(&**self)
     }
 }
@@ -368,7 +368,7 @@ impl Error for char::ParseCharError {
 }
 
 // copied from any.rs
-impl Error + 'static {
+impl dyn Error + 'static {
     /// Returns true if the boxed type is the same as `T`
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
@@ -390,7 +390,7 @@ impl Error + 'static {
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
         if self.is::<T>() {
             unsafe {
-                Some(&*(self as *const Error as *const T))
+                Some(&*(self as *const dyn Error as *const T))
             }
         } else {
             None
@@ -404,7 +404,7 @@ impl Error + 'static {
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
         if self.is::<T>() {
             unsafe {
-                Some(&mut *(self as *mut Error as *mut T))
+                Some(&mut *(self as *mut dyn Error as *mut T))
             }
         } else {
             None
@@ -412,60 +412,60 @@ impl Error + 'static {
     }
 }
 
-impl Error + 'static + Send {
+impl dyn Error + 'static + Send {
     /// Forwards to the method defined on the type `Any`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn is<T: Error + 'static>(&self) -> bool {
-        <Error + 'static>::is::<T>(self)
+        <dyn Error + 'static>::is::<T>(self)
     }
 
     /// Forwards to the method defined on the type `Any`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
-        <Error + 'static>::downcast_ref::<T>(self)
+        <dyn Error + 'static>::downcast_ref::<T>(self)
     }
 
     /// Forwards to the method defined on the type `Any`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
-        <Error + 'static>::downcast_mut::<T>(self)
+        <dyn Error + 'static>::downcast_mut::<T>(self)
     }
 }
 
-impl Error + 'static + Send + Sync {
+impl dyn Error + 'static + Send + Sync {
     /// Forwards to the method defined on the type `Any`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn is<T: Error + 'static>(&self) -> bool {
-        <Error + 'static>::is::<T>(self)
+        <dyn Error + 'static>::is::<T>(self)
     }
 
     /// Forwards to the method defined on the type `Any`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_ref<T: Error + 'static>(&self) -> Option<&T> {
-        <Error + 'static>::downcast_ref::<T>(self)
+        <dyn Error + 'static>::downcast_ref::<T>(self)
     }
 
     /// Forwards to the method defined on the type `Any`.
     #[stable(feature = "error_downcast", since = "1.3.0")]
     #[inline]
     pub fn downcast_mut<T: Error + 'static>(&mut self) -> Option<&mut T> {
-        <Error + 'static>::downcast_mut::<T>(self)
+        <dyn Error + 'static>::downcast_mut::<T>(self)
     }
 }
 
-impl Error {
+impl dyn Error {
     #[inline]
     #[stable(feature = "error_downcast", since = "1.3.0")]
     /// Attempt to downcast the box to a concrete type.
-    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<Error>> {
+    pub fn downcast<T: Error + 'static>(self: Box<Self>) -> Result<Box<T>, Box<dyn Error>> {
         if self.is::<T>() {
             unsafe {
-                let raw: *mut Error = Box::into_raw(self);
+                let raw: *mut dyn Error = Box::into_raw(self);
                 Ok(Box::from_raw(raw as *mut T))
             }
         } else {
@@ -474,30 +474,30 @@ impl Error {
     }
 }
 
-impl Error + Send {
+impl dyn Error + Send {
     #[inline]
     #[stable(feature = "error_downcast", since = "1.3.0")]
     /// Attempt to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>)
-                                        -> Result<Box<T>, Box<Error + Send>> {
-        let err: Box<Error> = self;
-        <Error>::downcast(err).map_err(|s| unsafe {
+                                        -> Result<Box<T>, Box<dyn Error + Send>> {
+        let err: Box<dyn Error> = self;
+        <dyn Error>::downcast(err).map_err(|s| unsafe {
             // reapply the Send marker
-            transmute::<Box<Error>, Box<Error + Send>>(s)
+            transmute::<Box<dyn Error>, Box<dyn Error + Send>>(s)
         })
     }
 }
 
-impl Error + Send + Sync {
+impl dyn Error + Send + Sync {
     #[inline]
     #[stable(feature = "error_downcast", since = "1.3.0")]
     /// Attempt to downcast the box to a concrete type.
     pub fn downcast<T: Error + 'static>(self: Box<Self>)
                                         -> Result<Box<T>, Box<Self>> {
-        let err: Box<Error> = self;
-        <Error>::downcast(err).map_err(|s| unsafe {
+        let err: Box<dyn Error> = self;
+        <dyn Error>::downcast(err).map_err(|s| unsafe {
             // reapply the Send+Sync marker
-            transmute::<Box<Error>, Box<Error + Send + Sync>>(s)
+            transmute::<Box<dyn Error>, Box<dyn Error + Send + Sync>>(s)
         })
     }
 }
@@ -533,13 +533,13 @@ mod tests {
     #[test]
     fn downcasting() {
         let mut a = A;
-        let a = &mut a as &mut (Error + 'static);
+        let a = &mut a as &mut (dyn Error + 'static);
         assert_eq!(a.downcast_ref::<A>(), Some(&A));
         assert_eq!(a.downcast_ref::<B>(), None);
         assert_eq!(a.downcast_mut::<A>(), Some(&mut A));
         assert_eq!(a.downcast_mut::<B>(), None);
 
-        let a: Box<Error> = Box::new(A);
+        let a: Box<dyn Error> = Box::new(A);
         match a.downcast::<B>() {
             Ok(..) => panic!("expected error"),
             Err(e) => assert_eq!(*e.downcast::<A>().unwrap(), A),
diff --git a/src/libstd/ffi/c_str.rs b/src/libstd/ffi/c_str.rs
index b816f4b7850..754e2bbc412 100644
--- a/src/libstd/ffi/c_str.rs
+++ b/src/libstd/ffi/c_str.rs
@@ -891,7 +891,7 @@ impl Error for IntoStringError {
         "C string contained non-utf8 bytes"
     }
 
-    fn cause(&self) -> Option<&Error> {
+    fn cause(&self) -> Option<&dyn Error> {
         Some(&self.error)
     }
 }
diff --git a/src/libstd/io/error.rs b/src/libstd/io/error.rs
index bdd675e6e2b..02a3ce8b9c4 100644
--- a/src/libstd/io/error.rs
+++ b/src/libstd/io/error.rs
@@ -83,7 +83,7 @@ enum Repr {
 #[derive(Debug)]
 struct Custom {
     kind: ErrorKind,
-    error: Box<error::Error+Send+Sync>,
+    error: Box<dyn error::Error+Send+Sync>,
 }
 
 /// A list specifying general categories of I/O error.
@@ -250,12 +250,12 @@ impl Error {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     pub fn new<E>(kind: ErrorKind, error: E) -> Error
-        where E: Into<Box<error::Error+Send+Sync>>
+        where E: Into<Box<dyn error::Error+Send+Sync>>
     {
         Self::_new(kind, error.into())
     }
 
-    fn _new(kind: ErrorKind, error: Box<error::Error+Send+Sync>) -> Error {
+    fn _new(kind: ErrorKind, error: Box<dyn error::Error+Send+Sync>) -> Error {
         Error {
             repr: Repr::Custom(Box::new(Custom {
                 kind,
@@ -373,7 +373,7 @@ impl Error {
     /// }
     /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
-    pub fn get_ref(&self) -> Option<&(error::Error+Send+Sync+'static)> {
+    pub fn get_ref(&self) -> Option<&(dyn error::Error+Send+Sync+'static)> {
         match self.repr {
             Repr::Os(..) => None,
             Repr::Simple(..) => None,
@@ -444,7 +444,7 @@ impl Error {
     /// }
     /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
-    pub fn get_mut(&mut self) -> Option<&mut (error::Error+Send+Sync+'static)> {
+    pub fn get_mut(&mut self) -> Option<&mut (dyn error::Error+Send+Sync+'static)> {
         match self.repr {
             Repr::Os(..) => None,
             Repr::Simple(..) => None,
@@ -478,7 +478,7 @@ impl Error {
     /// }
     /// ```
     #[stable(feature = "io_error_inner", since = "1.3.0")]
-    pub fn into_inner(self) -> Option<Box<error::Error+Send+Sync>> {
+    pub fn into_inner(self) -> Option<Box<dyn error::Error+Send+Sync>> {
         match self.repr {
             Repr::Os(..) => None,
             Repr::Simple(..) => None,
@@ -551,7 +551,7 @@ impl error::Error for Error {
         }
     }
 
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         match self.repr {
             Repr::Os(..) => None,
             Repr::Simple(..) => None,
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 2b4644bd013..85304874848 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -1972,7 +1972,7 @@ impl<T: BufRead> BufRead for Take<T> {
     }
 }
 
-fn read_one_byte(reader: &mut Read) -> Option<Result<u8>> {
+fn read_one_byte(reader: &mut dyn Read) -> Option<Result<u8>> {
     let mut buf = [0];
     loop {
         return match reader.read(&mut buf) {
@@ -2081,7 +2081,7 @@ impl std_error::Error for CharsError {
             CharsError::Other(ref e) => std_error::Error::description(e),
         }
     }
-    fn cause(&self) -> Option<&std_error::Error> {
+    fn cause(&self) -> Option<&dyn std_error::Error> {
         match *self {
             CharsError::NotUtf8 => None,
             CharsError::Other(ref e) => e.cause(),
diff --git a/src/libstd/io/stdio.rs b/src/libstd/io/stdio.rs
index fce85a200ba..fffe8fc559b 100644
--- a/src/libstd/io/stdio.rs
+++ b/src/libstd/io/stdio.rs
@@ -21,7 +21,7 @@ use thread::LocalKey;
 
 /// Stdout used by print! and println! macros
 thread_local! {
-    static LOCAL_STDOUT: RefCell<Option<Box<Write + Send>>> = {
+    static LOCAL_STDOUT: RefCell<Option<Box<dyn Write + Send>>> = {
         RefCell::new(None)
     }
 }
@@ -624,7 +624,7 @@ impl<'a> fmt::Debug for StderrLock<'a> {
                      with a more general mechanism",
            issue = "0")]
 #[doc(hidden)]
-pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
+pub fn set_panic(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
     use panicking::LOCAL_STDERR;
     use mem;
     LOCAL_STDERR.with(move |slot| {
@@ -648,7 +648,7 @@ pub fn set_panic(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
                      with a more general mechanism",
            issue = "0")]
 #[doc(hidden)]
-pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
+pub fn set_print(sink: Option<Box<dyn Write + Send>>) -> Option<Box<dyn Write + Send>> {
     use mem;
     LOCAL_STDOUT.with(move |slot| {
         mem::replace(&mut *slot.borrow_mut(), sink)
@@ -670,7 +670,7 @@ pub fn set_print(sink: Option<Box<Write + Send>>) -> Option<Box<Write + Send>> {
 /// However, if the actual I/O causes an error, this function does panic.
 fn print_to<T>(
     args: fmt::Arguments,
-    local_s: &'static LocalKey<RefCell<Option<Box<Write+Send>>>>,
+    local_s: &'static LocalKey<RefCell<Option<Box<dyn Write+Send>>>>,
     global_s: fn() -> T,
     label: &str,
 )
diff --git a/src/libstd/io/util.rs b/src/libstd/io/util.rs
index 195310a26fe..33f741dbc38 100644
--- a/src/libstd/io/util.rs
+++ b/src/libstd/io/util.rs
@@ -223,7 +223,7 @@ mod tests {
         assert_eq!(copy(&mut r, &mut w).unwrap(), 4);
 
         let mut r = repeat(0).take(1 << 17);
-        assert_eq!(copy(&mut r as &mut Read, &mut w as &mut Write).unwrap(), 1 << 17);
+        assert_eq!(copy(&mut r as &mut dyn Read, &mut w as &mut dyn Write).unwrap(), 1 << 17);
     }
 
     #[test]
diff --git a/src/libstd/net/parser.rs b/src/libstd/net/parser.rs
index 008c5da171f..cf3e5354a31 100644
--- a/src/libstd/net/parser.rs
+++ b/src/libstd/net/parser.rs
@@ -58,7 +58,7 @@ impl<'a> Parser<'a> {
     }
 
     // Return result of first successful parser
-    fn read_or<T>(&mut self, parsers: &mut [Box<FnMut(&mut Parser) -> Option<T> + 'static>])
+    fn read_or<T>(&mut self, parsers: &mut [Box<dyn FnMut(&mut Parser) -> Option<T> + 'static>])
                -> Option<T> {
         for pf in parsers {
             if let Some(r) = self.read_atomically(|p: &mut Parser| pf(p)) {
diff --git a/src/libstd/net/tcp.rs b/src/libstd/net/tcp.rs
index 6b4bbdddf32..75c7a3d9280 100644
--- a/src/libstd/net/tcp.rs
+++ b/src/libstd/net/tcp.rs
@@ -927,7 +927,7 @@ mod tests {
     use time::{Instant, Duration};
     use thread;
 
-    fn each_ip(f: &mut FnMut(SocketAddr)) {
+    fn each_ip(f: &mut dyn FnMut(SocketAddr)) {
         f(next_test_ip4());
         f(next_test_ip6());
     }
diff --git a/src/libstd/net/udp.rs b/src/libstd/net/udp.rs
index d25e29999cb..0ebe3284b4f 100644
--- a/src/libstd/net/udp.rs
+++ b/src/libstd/net/udp.rs
@@ -826,7 +826,7 @@ mod tests {
     use time::{Instant, Duration};
     use thread;
 
-    fn each_ip(f: &mut FnMut(SocketAddr, SocketAddr)) {
+    fn each_ip(f: &mut dyn FnMut(SocketAddr, SocketAddr)) {
         f(next_test_ip4(), next_test_ip4());
         f(next_test_ip6(), next_test_ip6());
     }
diff --git a/src/libstd/panic.rs b/src/libstd/panic.rs
index 451420ae88a..b8c1c4f9e68 100644
--- a/src/libstd/panic.rs
+++ b/src/libstd/panic.rs
@@ -421,6 +421,6 @@ pub fn catch_unwind<F: FnOnce() -> R + UnwindSafe, R>(f: F) -> Result<R> {
 /// }
 /// ```
 #[stable(feature = "resume_unwind", since = "1.9.0")]
-pub fn resume_unwind(payload: Box<Any + Send>) -> ! {
+pub fn resume_unwind(payload: Box<dyn Any + Send>) -> ! {
     panicking::update_count_then_panic(payload)
 }
diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs
index 46b6cf60705..283fd36af41 100644
--- a/src/libstd/panicking.rs
+++ b/src/libstd/panicking.rs
@@ -36,7 +36,7 @@ use sys_common::util;
 use thread;
 
 thread_local! {
-    pub static LOCAL_STDERR: RefCell<Option<Box<Write + Send>>> = {
+    pub static LOCAL_STDERR: RefCell<Option<Box<dyn Write + Send>>> = {
         RefCell::new(None)
     }
 }
@@ -64,7 +64,7 @@ extern {
 #[derive(Copy, Clone)]
 enum Hook {
     Default,
-    Custom(*mut (Fn(&PanicInfo) + 'static + Sync + Send)),
+    Custom(*mut (dyn Fn(&PanicInfo) + 'static + Sync + Send)),
 }
 
 static HOOK_LOCK: RWLock = RWLock::new();
@@ -104,7 +104,7 @@ static mut HOOK: Hook = Hook::Default;
 /// panic!("Normal panic");
 /// ```
 #[stable(feature = "panic_hooks", since = "1.10.0")]
-pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
+pub fn set_hook(hook: Box<dyn Fn(&PanicInfo) + 'static + Sync + Send>) {
     if thread::panicking() {
         panic!("cannot modify the panic hook from a panicking thread");
     }
@@ -149,7 +149,7 @@ pub fn set_hook(hook: Box<Fn(&PanicInfo) + 'static + Sync + Send>) {
 /// panic!("Normal panic");
 /// ```
 #[stable(feature = "panic_hooks", since = "1.10.0")]
-pub fn take_hook() -> Box<Fn(&PanicInfo) + 'static + Sync + Send> {
+pub fn take_hook() -> Box<dyn Fn(&PanicInfo) + 'static + Sync + Send> {
     if thread::panicking() {
         panic!("cannot modify the panic hook from a panicking thread");
     }
@@ -197,7 +197,7 @@ fn default_hook(info: &PanicInfo) {
     let thread = thread_info::current_thread();
     let name = thread.as_ref().and_then(|t| t.name()).unwrap_or("<unnamed>");
 
-    let write = |err: &mut ::io::Write| {
+    let write = |err: &mut dyn (::io::Write)| {
         let _ = writeln!(err, "thread '{}' panicked at '{}', {}",
                          name, msg, location);
 
@@ -248,7 +248,7 @@ pub fn update_panic_count(amt: isize) -> usize {
 pub use realstd::rt::update_panic_count;
 
 /// Invoke a closure, capturing the cause of an unwinding panic if one occurs.
-pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<Any + Send>> {
+pub unsafe fn try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>> {
     #[allow(unions_with_drop_fields)]
     union Data<F, R> {
         f: F,
@@ -369,12 +369,12 @@ fn continue_panic_fmt(info: &PanicInfo) -> ! {
     }
 
     unsafe impl<'a> BoxMeUp for PanicPayload<'a> {
-        fn box_me_up(&mut self) -> *mut (Any + Send) {
+        fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
             let contents = mem::replace(self.fill(), String::new());
             Box::into_raw(Box::new(contents))
         }
 
-        fn get(&mut self) -> &(Any + Send) {
+        fn get(&mut self) -> &(dyn Any + Send) {
             self.fill()
         }
     }
@@ -419,15 +419,15 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3
     }
 
     unsafe impl<A: Send + 'static> BoxMeUp for PanicPayload<A> {
-        fn box_me_up(&mut self) -> *mut (Any + Send) {
+        fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
             let data = match self.inner.take() {
-                Some(a) => Box::new(a) as Box<Any + Send>,
+                Some(a) => Box::new(a) as Box<dyn Any + Send>,
                 None => Box::new(()),
             };
             Box::into_raw(data)
         }
 
-        fn get(&mut self) -> &(Any + Send) {
+        fn get(&mut self) -> &(dyn Any + Send) {
             match self.inner {
                 Some(ref a) => a,
                 None => &(),
@@ -441,7 +441,7 @@ pub fn begin_panic<M: Any + Send>(msg: M, file_line_col: &(&'static str, u32, u3
 /// Executes the primary logic for a panic, including checking for recursive
 /// panics, panic hooks, and finally dispatching to the panic runtime to either
 /// abort or unwind.
-fn rust_panic_with_hook(payload: &mut BoxMeUp,
+fn rust_panic_with_hook(payload: &mut dyn BoxMeUp,
                         message: Option<&fmt::Arguments>,
                         file_line_col: &(&str, u32, u32)) -> ! {
     let (file, line, col) = *file_line_col;
@@ -496,17 +496,17 @@ fn rust_panic_with_hook(payload: &mut BoxMeUp,
 }
 
 /// Shim around rust_panic. Called by resume_unwind.
-pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! {
+pub fn update_count_then_panic(msg: Box<dyn Any + Send>) -> ! {
     update_panic_count(1);
 
-    struct RewrapBox(Box<Any + Send>);
+    struct RewrapBox(Box<dyn Any + Send>);
 
     unsafe impl BoxMeUp for RewrapBox {
-        fn box_me_up(&mut self) -> *mut (Any + Send) {
+        fn box_me_up(&mut self) -> *mut (dyn Any + Send) {
             Box::into_raw(mem::replace(&mut self.0, Box::new(())))
         }
 
-        fn get(&mut self) -> &(Any + Send) {
+        fn get(&mut self) -> &(dyn Any + Send) {
             &*self.0
         }
     }
@@ -517,9 +517,9 @@ pub fn update_count_then_panic(msg: Box<Any + Send>) -> ! {
 /// A private no-mangle function on which to slap yer breakpoints.
 #[no_mangle]
 #[allow(private_no_mangle_fns)] // yes we get it, but we like breakpoints
-pub fn rust_panic(mut msg: &mut BoxMeUp) -> ! {
+pub fn rust_panic(mut msg: &mut dyn BoxMeUp) -> ! {
     let code = unsafe {
-        let obj = &mut msg as *mut &mut BoxMeUp;
+        let obj = &mut msg as *mut &mut dyn BoxMeUp;
         __rust_start_panic(obj as usize)
     };
     rtabort!("failed to initiate panic, error {}", code)
diff --git a/src/libstd/process.rs b/src/libstd/process.rs
index 00051d4487a..39692836866 100644
--- a/src/libstd/process.rs
+++ b/src/libstd/process.rs
@@ -813,13 +813,13 @@ impl fmt::Debug for Output {
     fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
 
         let stdout_utf8 = str::from_utf8(&self.stdout);
-        let stdout_debug: &fmt::Debug = match stdout_utf8 {
+        let stdout_debug: &dyn fmt::Debug = match stdout_utf8 {
             Ok(ref str) => str,
             Err(_) => &self.stdout
         };
 
         let stderr_utf8 = str::from_utf8(&self.stderr);
-        let stderr_debug: &fmt::Debug = match stderr_utf8 {
+        let stderr_debug: &dyn fmt::Debug = match stderr_utf8 {
             Ok(ref str) => str,
             Err(_) => &self.stderr
         };
diff --git a/src/libstd/rt.rs b/src/libstd/rt.rs
index 8f945470b7e..9e957bd87d7 100644
--- a/src/libstd/rt.rs
+++ b/src/libstd/rt.rs
@@ -29,7 +29,7 @@ pub use panicking::{begin_panic, begin_panic_fmt, update_panic_count};
 // To reduce the generated code of the new `lang_start`, this function is doing
 // the real work.
 #[cfg(not(test))]
-fn lang_start_internal(main: &(Fn() -> i32 + Sync + ::panic::RefUnwindSafe),
+fn lang_start_internal(main: &(dyn Fn() -> i32 + Sync + ::panic::RefUnwindSafe),
                        argc: isize, argv: *const *const u8) -> isize {
     use panic;
     use sys;
diff --git a/src/libstd/sync/mpsc/mod.rs b/src/libstd/sync/mpsc/mod.rs
index cbda5afadcd..02a96b01cca 100644
--- a/src/libstd/sync/mpsc/mod.rs
+++ b/src/libstd/sync/mpsc/mod.rs
@@ -1638,7 +1638,7 @@ impl<T: Send> error::Error for SendError<T> {
         "sending on a closed channel"
     }
 
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         None
     }
 }
@@ -1681,7 +1681,7 @@ impl<T: Send> error::Error for TrySendError<T> {
         }
     }
 
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         None
     }
 }
@@ -1709,7 +1709,7 @@ impl error::Error for RecvError {
         "receiving on a closed channel"
     }
 
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         None
     }
 }
@@ -1742,7 +1742,7 @@ impl error::Error for TryRecvError {
         }
     }
 
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         None
     }
 }
@@ -1783,7 +1783,7 @@ impl error::Error for RecvTimeoutError {
         }
     }
 
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         None
     }
 }
diff --git a/src/libstd/sync/mpsc/select.rs b/src/libstd/sync/mpsc/select.rs
index 9310dad9172..a7a284cfb79 100644
--- a/src/libstd/sync/mpsc/select.rs
+++ b/src/libstd/sync/mpsc/select.rs
@@ -93,7 +93,7 @@ pub struct Handle<'rx, T:Send+'rx> {
     next: *mut Handle<'static, ()>,
     prev: *mut Handle<'static, ()>,
     added: bool,
-    packet: &'rx (Packet+'rx),
+    packet: &'rx (dyn Packet+'rx),
 
     // due to our fun transmutes, we be sure to place this at the end. (nothing
     // previous relies on T)
diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs
index 443e2a6980d..10282ecb658 100644
--- a/src/libstd/sync/once.rs
+++ b/src/libstd/sync/once.rs
@@ -309,7 +309,7 @@ impl Once {
     #[cold]
     fn call_inner(&self,
                   ignore_poisoning: bool,
-                  init: &mut FnMut(bool)) {
+                  init: &mut dyn FnMut(bool)) {
         let mut state = self.state.load(Ordering::SeqCst);
 
         'outer: loop {
diff --git a/src/libstd/sys/cloudabi/thread.rs b/src/libstd/sys/cloudabi/thread.rs
index 5d66936b2a4..8cca47efd22 100644
--- a/src/libstd/sys/cloudabi/thread.rs
+++ b/src/libstd/sys/cloudabi/thread.rs
@@ -32,7 +32,7 @@ unsafe impl Send for Thread {}
 unsafe impl Sync for Thread {}
 
 impl Thread {
-    pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread> {
+    pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
         let p = box p;
         let mut native: libc::pthread_t = mem::zeroed();
         let mut attr: libc::pthread_attr_t = mem::zeroed();
diff --git a/src/libstd/sys/redox/process.rs b/src/libstd/sys/redox/process.rs
index d0b94e14f54..02bc467541e 100644
--- a/src/libstd/sys/redox/process.rs
+++ b/src/libstd/sys/redox/process.rs
@@ -51,7 +51,7 @@ pub struct Command {
     uid: Option<u32>,
     gid: Option<u32>,
     saw_nul: bool,
-    closures: Vec<Box<FnMut() -> io::Result<()> + Send + Sync>>,
+    closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,
     stdin: Option<Stdio>,
     stdout: Option<Stdio>,
     stderr: Option<Stdio>,
@@ -122,7 +122,7 @@ impl Command {
     }
 
     pub fn before_exec(&mut self,
-                       f: Box<FnMut() -> io::Result<()> + Send + Sync>) {
+                       f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
         self.closures.push(f);
     }
 
diff --git a/src/libstd/sys/redox/thread.rs b/src/libstd/sys/redox/thread.rs
index 110d46ca3ab..f4177087d77 100644
--- a/src/libstd/sys/redox/thread.rs
+++ b/src/libstd/sys/redox/thread.rs
@@ -28,7 +28,7 @@ unsafe impl Send for Thread {}
 unsafe impl Sync for Thread {}
 
 impl Thread {
-    pub unsafe fn new<'a>(_stack: usize, p: Box<FnBox() + 'a>) -> io::Result<Thread> {
+    pub unsafe fn new<'a>(_stack: usize, p: Box<dyn FnBox() + 'a>) -> io::Result<Thread> {
         let p = box p;
 
         let id = cvt(syscall::clone(syscall::CLONE_VM | syscall::CLONE_FS | syscall::CLONE_FILES))?;
diff --git a/src/libstd/sys/unix/process/process_common.rs b/src/libstd/sys/unix/process/process_common.rs
index 6396bb3a49e..77f125f3c5b 100644
--- a/src/libstd/sys/unix/process/process_common.rs
+++ b/src/libstd/sys/unix/process/process_common.rs
@@ -52,7 +52,7 @@ pub struct Command {
     uid: Option<uid_t>,
     gid: Option<gid_t>,
     saw_nul: bool,
-    closures: Vec<Box<FnMut() -> io::Result<()> + Send + Sync>>,
+    closures: Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>>,
     stdin: Option<Stdio>,
     stdout: Option<Stdio>,
     stderr: Option<Stdio>,
@@ -155,12 +155,12 @@ impl Command {
         self.gid
     }
 
-    pub fn get_closures(&mut self) -> &mut Vec<Box<FnMut() -> io::Result<()> + Send + Sync>> {
+    pub fn get_closures(&mut self) -> &mut Vec<Box<dyn FnMut() -> io::Result<()> + Send + Sync>> {
         &mut self.closures
     }
 
     pub fn before_exec(&mut self,
-                       f: Box<FnMut() -> io::Result<()> + Send + Sync>) {
+                       f: Box<dyn FnMut() -> io::Result<()> + Send + Sync>) {
         self.closures.push(f);
     }
 
diff --git a/src/libstd/sys/unix/thread.rs b/src/libstd/sys/unix/thread.rs
index 7fdecc9c0c0..e26306c045d 100644
--- a/src/libstd/sys/unix/thread.rs
+++ b/src/libstd/sys/unix/thread.rs
@@ -49,7 +49,7 @@ unsafe fn pthread_attr_setstacksize(_attr: *mut libc::pthread_attr_t,
 }
 
 impl Thread {
-    pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
+    pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
                           -> io::Result<Thread> {
         let p = box p;
         let mut native: libc::pthread_t = mem::zeroed();
diff --git a/src/libstd/sys/wasm/thread.rs b/src/libstd/sys/wasm/thread.rs
index 728e678a2e8..8173a624211 100644
--- a/src/libstd/sys/wasm/thread.rs
+++ b/src/libstd/sys/wasm/thread.rs
@@ -19,7 +19,7 @@ pub struct Thread(Void);
 pub const DEFAULT_MIN_STACK_SIZE: usize = 4096;
 
 impl Thread {
-    pub unsafe fn new<'a>(_stack: usize, _p: Box<FnBox() + 'a>)
+    pub unsafe fn new<'a>(_stack: usize, _p: Box<dyn FnBox() + 'a>)
         -> io::Result<Thread>
     {
         unsupported()
diff --git a/src/libstd/sys/windows/thread.rs b/src/libstd/sys/windows/thread.rs
index b6f63303dc2..44ec872b244 100644
--- a/src/libstd/sys/windows/thread.rs
+++ b/src/libstd/sys/windows/thread.rs
@@ -28,7 +28,7 @@ pub struct Thread {
 }
 
 impl Thread {
-    pub unsafe fn new<'a>(stack: usize, p: Box<FnBox() + 'a>)
+    pub unsafe fn new<'a>(stack: usize, p: Box<dyn FnBox() + 'a>)
                           -> io::Result<Thread> {
         let p = box p;
 
diff --git a/src/libstd/sys_common/at_exit_imp.rs b/src/libstd/sys_common/at_exit_imp.rs
index d268d9ad6f9..b28a4d2f8be 100644
--- a/src/libstd/sys_common/at_exit_imp.rs
+++ b/src/libstd/sys_common/at_exit_imp.rs
@@ -17,7 +17,7 @@ use ptr;
 use mem;
 use sys_common::mutex::Mutex;
 
-type Queue = Vec<Box<FnBox()>>;
+type Queue = Vec<Box<dyn FnBox()>>;
 
 // NB these are specifically not types from `std::sync` as they currently rely
 // on poisoning and this module needs to operate at a lower level than requiring
@@ -68,7 +68,7 @@ pub fn cleanup() {
     }
 }
 
-pub fn push(f: Box<FnBox()>) -> bool {
+pub fn push(f: Box<dyn FnBox()>) -> bool {
     unsafe {
         let _guard = LOCK.lock();
         if init() {
diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs
index 2db47bd5947..77371782977 100644
--- a/src/libstd/sys_common/backtrace.rs
+++ b/src/libstd/sys_common/backtrace.rs
@@ -49,7 +49,7 @@ pub struct Frame {
 const MAX_NB_FRAMES: usize = 100;
 
 /// Prints the current backtrace.
-pub fn print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
+pub fn print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
     static LOCK: Mutex = Mutex::new();
 
     // Use a lock to prevent mixed output in multithreading context.
@@ -62,7 +62,7 @@ pub fn print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
     }
 }
 
-fn _print(w: &mut Write, format: PrintFormat) -> io::Result<()> {
+fn _print(w: &mut dyn Write, format: PrintFormat) -> io::Result<()> {
     let mut frames = [Frame {
         exact_position: ptr::null(),
         symbol_addr: ptr::null(),
@@ -176,7 +176,7 @@ pub fn log_enabled() -> Option<PrintFormat> {
 ///
 /// These output functions should now be used everywhere to ensure consistency.
 /// You may want to also use `output_fileline`.
-fn output(w: &mut Write, idx: usize, frame: Frame,
+fn output(w: &mut dyn Write, idx: usize, frame: Frame,
               s: Option<&str>, format: PrintFormat) -> io::Result<()> {
     // Remove the `17: 0x0 - <unknown>` line.
     if format == PrintFormat::Short && frame.exact_position == ptr::null() {
@@ -201,7 +201,7 @@ fn output(w: &mut Write, idx: usize, frame: Frame,
 ///
 /// See also `output`.
 #[allow(dead_code)]
-fn output_fileline(w: &mut Write,
+fn output_fileline(w: &mut dyn Write,
                    file: &[u8],
                    line: u32,
                    format: PrintFormat) -> io::Result<()> {
@@ -253,7 +253,7 @@ fn output_fileline(w: &mut Write,
 // Note that this demangler isn't quite as fancy as it could be. We have lots
 // of other information in our symbols like hashes, version, type information,
 // etc. Additionally, this doesn't handle glue symbols at all.
-pub fn demangle(writer: &mut Write, mut s: &str, format: PrintFormat) -> io::Result<()> {
+pub fn demangle(writer: &mut dyn Write, mut s: &str, format: PrintFormat) -> io::Result<()> {
     // During ThinLTO LLVM may import and rename internal symbols, so strip out
     // those endings first as they're one of the last manglings applied to
     // symbol names.
diff --git a/src/libstd/sys_common/poison.rs b/src/libstd/sys_common/poison.rs
index e74c40ae04b..1625efe4a2a 100644
--- a/src/libstd/sys_common/poison.rs
+++ b/src/libstd/sys_common/poison.rs
@@ -251,7 +251,7 @@ impl<T> Error for TryLockError<T> {
         }
     }
 
-    fn cause(&self) -> Option<&Error> {
+    fn cause(&self) -> Option<&dyn Error> {
         match *self {
             TryLockError::Poisoned(ref p) => Some(p),
             _ => None
diff --git a/src/libstd/sys_common/thread.rs b/src/libstd/sys_common/thread.rs
index da6f58ef6bb..86a5e2b8694 100644
--- a/src/libstd/sys_common/thread.rs
+++ b/src/libstd/sys_common/thread.rs
@@ -21,7 +21,7 @@ pub unsafe fn start_thread(main: *mut u8) {
     let _handler = stack_overflow::Handler::new();
 
     // Finally, let's run some code.
-    Box::from_raw(main as *mut Box<FnBox()>)()
+    Box::from_raw(main as *mut Box<dyn FnBox()>)()
 }
 
 pub fn min_stack() -> usize {
diff --git a/src/libstd/thread/mod.rs b/src/libstd/thread/mod.rs
index 90f054186d1..ae804ad409e 100644
--- a/src/libstd/thread/mod.rs
+++ b/src/libstd/thread/mod.rs
@@ -1175,7 +1175,7 @@ impl fmt::Debug for Thread {
 ///
 /// [`Result`]: ../../std/result/enum.Result.html
 #[stable(feature = "rust1", since = "1.0.0")]
-pub type Result<T> = ::result::Result<T, Box<Any + Send + 'static>>;
+pub type Result<T> = ::result::Result<T, Box<dyn Any + Send + 'static>>;
 
 // This packet is used to communicate the return value between the child thread
 // and the parent thread. Memory is shared through the `Arc` within and there's
@@ -1276,6 +1276,11 @@ impl<T> JoinInner<T> {
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct JoinHandle<T>(JoinInner<T>);
 
+#[stable(feature = "joinhandle_impl_send_sync", since = "1.29.0")]
+unsafe impl<T> Send for JoinHandle<T> {}
+#[stable(feature = "joinhandle_impl_send_sync", since = "1.29.0")]
+unsafe impl<T> Sync for JoinHandle<T> {}
+
 impl<T> JoinHandle<T> {
     /// Extracts a handle to the underlying thread.
     ///
@@ -1438,7 +1443,7 @@ mod tests {
         rx.recv().unwrap();
     }
 
-    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<Fn() + Send>) {
+    fn avoid_copying_the_body<F>(spawnfn: F) where F: FnOnce(Box<dyn Fn() + Send>) {
         let (tx, rx) = channel();
 
         let x: Box<_> = box 1;
@@ -1485,7 +1490,7 @@ mod tests {
         // (well, it would if the constant were 8000+ - I lowered it to be more
         // valgrind-friendly. try this at home, instead..!)
         const GENERATIONS: u32 = 16;
-        fn child_no(x: u32) -> Box<Fn() + Send> {
+        fn child_no(x: u32) -> Box<dyn Fn() + Send> {
             return Box::new(move|| {
                 if x < GENERATIONS {
                     thread::spawn(move|| child_no(x+1)());
@@ -1531,10 +1536,10 @@ mod tests {
     #[test]
     fn test_try_panic_message_any() {
         match thread::spawn(move|| {
-            panic!(box 413u16 as Box<Any + Send>);
+            panic!(box 413u16 as Box<dyn Any + Send>);
         }).join() {
             Err(e) => {
-                type T = Box<Any + Send>;
+                type T = Box<dyn Any + Send>;
                 assert!(e.is::<T>());
                 let any = e.downcast::<T>().unwrap();
                 assert!(any.is::<u16>());
diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs
index d746ac3c577..137b94230a3 100644
--- a/src/libsyntax/attr/mod.rs
+++ b/src/libsyntax/attr/mod.rs
@@ -22,11 +22,11 @@ pub use self::ReprAttr::*;
 pub use self::StabilityLevel::*;
 
 use ast;
-use ast::{AttrId, Attribute, Name, Ident, Path, PathSegment};
+use ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment};
 use ast::{MetaItem, MetaItemKind, NestedMetaItem, NestedMetaItemKind};
 use ast::{Lit, LitKind, Expr, ExprKind, Item, Local, Stmt, StmtKind, GenericParam};
 use codemap::{BytePos, Spanned, respan, dummy_spanned};
-use syntax_pos::Span;
+use syntax_pos::{FileName, Span};
 use parse::lexer::comments::{doc_comment_style, strip_doc_comment_decoration};
 use parse::parser::Parser;
 use parse::{self, ParseSess, PResult};
@@ -821,3 +821,33 @@ derive_has_attrs! {
     Item, Expr, Local, ast::ForeignItem, ast::StructField, ast::ImplItem, ast::TraitItem, ast::Arm,
     ast::Field, ast::FieldPat, ast::Variant_
 }
+
+pub fn inject(mut krate: ast::Crate, parse_sess: &ParseSess, attrs: &[String]) -> ast::Crate {
+    for raw_attr in attrs {
+        let mut parser = parse::new_parser_from_source_str(
+            parse_sess,
+            FileName::CliCrateAttr,
+            raw_attr.clone(),
+        );
+
+        let start_span = parser.span;
+        let (path, tokens) = panictry!(parser.parse_path_and_tokens());
+        let end_span = parser.span;
+        if parser.token != token::Eof {
+            parse_sess.span_diagnostic
+                .span_err(start_span.to(end_span), "invalid crate attribute");
+            continue;
+        }
+
+        krate.attrs.push(Attribute {
+            id: mk_attr_id(),
+            style: AttrStyle::Inner,
+            path,
+            tokens,
+            is_sugared_doc: false,
+            span: start_span.to(end_span),
+        });
+    }
+
+    krate
+}
diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs
index 30137439e77..087fec09719 100644
--- a/src/libsyntax/feature_gate.rs
+++ b/src/libsyntax/feature_gate.rs
@@ -396,6 +396,9 @@ declare_features! (
     // Infer outlives requirements; RFC 2093
     (active, infer_outlives_requirements, "1.26.0", Some(44493), None),
 
+    // Infer outlives requirements; RFC 2093
+    (active, infer_static_outlives_requirements, "1.26.0", Some(44493), None),
+
     // Multiple patterns with `|` in `if let` and `while let`
     (active, if_while_or_patterns, "1.26.0", Some(48215), None),
 
@@ -1057,6 +1060,12 @@ pub const BUILTIN_ATTRIBUTES: &'static [(&'static str, AttributeType, AttributeG
                                    "infer outlives requirements is an experimental feature",
                                    cfg_fn!(infer_outlives_requirements))),
 
+    // RFC #2093
+    ("infer_static_outlives_requirements", Normal, Gated(Stability::Unstable,
+                                   "infer_static_outlives_requirements",
+                                   "infer 'static lifetime requirements",
+                                   cfg_fn!(infer_static_outlives_requirements))),
+
     // RFC 2070
     ("panic_implementation", Normal, Gated(Stability::Unstable,
                            "panic_implementation",
diff --git a/src/libsyntax/lib.rs b/src/libsyntax/lib.rs
index d241ae1d442..60de94821bb 100644
--- a/src/libsyntax/lib.rs
+++ b/src/libsyntax/lib.rs
@@ -14,8 +14,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/",
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 64309dd9b8b..56760546c50 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -6514,6 +6514,39 @@ impl<'a> Parser<'a> {
         })
     }
 
+    fn parse_crate_name_with_dashes(&mut self) -> PResult<'a, ast::Ident> {
+        let error_msg = "crate name using dashes are not valid in `extern crate` statements";
+        let suggestion_msg = "if the original crate name uses dashes you need to use underscores \
+                              in the code";
+        let mut ident = self.parse_ident()?;
+        let mut idents = vec![];
+        let mut replacement = vec![];
+        let mut fixed_crate_name = false;
+        // Accept `extern crate name-like-this` for better diagnostics
+        let dash = token::Token::BinOp(token::BinOpToken::Minus);
+        if self.token == dash {  // Do not include `-` as part of the expected tokens list
+            while self.eat(&dash) {
+                fixed_crate_name = true;
+                replacement.push((self.prev_span, "_".to_string()));
+                idents.push(self.parse_ident()?);
+            }
+        }
+        if fixed_crate_name {
+            let fixed_name_sp = ident.span.to(idents.last().unwrap().span);
+            let mut fixed_name = format!("{}", ident.name);
+            for part in idents {
+                fixed_name.push_str(&format!("_{}", part.name));
+            }
+            ident = Ident::from_str(&fixed_name).with_span_pos(fixed_name_sp);
+
+            let mut err = self.struct_span_err(fixed_name_sp, error_msg);
+            err.span_label(fixed_name_sp, "dash-separated idents are not valid");
+            err.multipart_suggestion(suggestion_msg, replacement);
+            err.emit();
+        }
+        Ok(ident)
+    }
+
     /// Parse extern crate links
     ///
     /// # Examples
@@ -6525,7 +6558,8 @@ impl<'a> Parser<'a> {
                                visibility: Visibility,
                                attrs: Vec<Attribute>)
                                -> PResult<'a, P<Item>> {
-        let orig_name = self.parse_ident()?;
+        // Accept `extern crate name-like-this` for better diagnostics
+        let orig_name = self.parse_crate_name_with_dashes()?;
         let (item_name, orig_name) = if let Some(rename) = self.parse_rename()? {
             (rename, Some(orig_name.name))
         } else {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 0ef390beac9..08c9ec4c989 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -3065,7 +3065,7 @@ impl<'a> State<'a> {
                        unsafety: ast::Unsafety,
                        decl: &ast::FnDecl,
                        name: Option<ast::Ident>,
-                       generic_params: &Vec<ast::GenericParam>)
+                       generic_params: &[ast::GenericParam])
                        -> io::Result<()> {
         self.ibox(INDENT_UNIT)?;
         if !generic_params.is_empty() {
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index ff76e788b3c..f0d33835cd0 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -10,8 +10,6 @@
 
 //! Syntax extensions in the Rust compiler.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
        html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
        html_root_url = "https://doc.rust-lang.org/nightly/")]
diff --git a/src/libsyntax_pos/lib.rs b/src/libsyntax_pos/lib.rs
index cc09a944e4c..44cd53282ec 100644
--- a/src/libsyntax_pos/lib.rs
+++ b/src/libsyntax_pos/lib.rs
@@ -14,8 +14,6 @@
 //!
 //! This API is completely unstable and subject to change.
 
-#![deny(bare_trait_objects)]
-
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
       html_favicon_url = "https://doc.rust-lang.org/favicon.ico",
       html_root_url = "https://doc.rust-lang.org/nightly/")]
@@ -100,6 +98,8 @@ pub enum FileName {
     ProcMacroSourceCode,
     /// Strings provided as --cfg [cfgspec] stored in a crate_cfg
     CfgSpec,
+    /// Strings provided as crate attributes in the CLI
+    CliCrateAttr,
     /// Custom sources for explicit parser calls from plugins and drivers
     Custom(String),
 }
@@ -115,6 +115,7 @@ impl std::fmt::Display for FileName {
             Anon => write!(fmt, "<anon>"),
             ProcMacroSourceCode => write!(fmt, "<proc-macro source code>"),
             CfgSpec => write!(fmt, "cfgspec"),
+            CliCrateAttr => write!(fmt, "<crate attribute>"),
             Custom(ref s) => write!(fmt, "<{}>", s),
         }
     }
@@ -137,6 +138,7 @@ impl FileName {
             MacroExpansion |
             ProcMacroSourceCode |
             CfgSpec |
+            CliCrateAttr |
             Custom(_) |
             QuoteExpansion => false,
         }
@@ -150,6 +152,7 @@ impl FileName {
             MacroExpansion |
             ProcMacroSourceCode |
             CfgSpec |
+            CliCrateAttr |
             Custom(_) |
             QuoteExpansion => false,
             Macros(_) => true,
@@ -634,15 +637,14 @@ impl MultiSpan {
     /// `SpanLabel` instances with empty labels.
     pub fn span_labels(&self) -> Vec<SpanLabel> {
         let is_primary = |span| self.primary_spans.contains(&span);
-        let mut span_labels = vec![];
 
-        for &(span, ref label) in &self.span_labels {
-            span_labels.push(SpanLabel {
+        let mut span_labels = self.span_labels.iter().map(|&(span, ref label)|
+            SpanLabel {
                 span,
                 is_primary: is_primary(span),
                 label: Some(label.clone())
-            });
-        }
+            }
+        ).collect::<Vec<_>>();
 
         for &span in &self.primary_spans {
             if !span_labels.iter().any(|sl| sl.span == span) {
diff --git a/src/libterm/lib.rs b/src/libterm/lib.rs
index a012f4e776f..cf92ce27ee5 100644
--- a/src/libterm/lib.rs
+++ b/src/libterm/lib.rs
@@ -66,9 +66,9 @@ pub mod terminfo;
 mod win;
 
 /// Alias for stdout terminals.
-pub type StdoutTerminal = Terminal<Output = Stdout> + Send;
+pub type StdoutTerminal = dyn Terminal<Output = Stdout> + Send;
 /// Alias for stderr terminals.
-pub type StderrTerminal = Terminal<Output = Stderr> + Send;
+pub type StderrTerminal = dyn Terminal<Output = Stderr> + Send;
 
 #[cfg(not(windows))]
 /// Return a Terminal wrapping stdout, or None if a terminal couldn't be
diff --git a/src/libterm/terminfo/mod.rs b/src/libterm/terminfo/mod.rs
index c5e68eed407..51e0fa315f4 100644
--- a/src/libterm/terminfo/mod.rs
+++ b/src/libterm/terminfo/mod.rs
@@ -58,7 +58,7 @@ impl error::Error for Error {
         "failed to create TermInfo"
     }
 
-    fn cause(&self) -> Option<&error::Error> {
+    fn cause(&self) -> Option<&dyn error::Error> {
         use self::Error::*;
         match self {
             &IoError(ref e) => Some(e),
diff --git a/src/libterm/terminfo/parser/compiled.rs b/src/libterm/terminfo/parser/compiled.rs
index 0cdea64db8b..d5e5df54733 100644
--- a/src/libterm/terminfo/parser/compiled.rs
+++ b/src/libterm/terminfo/parser/compiled.rs
@@ -164,7 +164,7 @@ pub static stringnames: &'static[&'static str] = &[ "cbt", "_", "cr", "csr", "tb
     "OTG3", "OTG1", "OTG4", "OTGR", "OTGL", "OTGU", "OTGD", "OTGH", "OTGV", "OTGC", "meml", "memu",
     "box1"];
 
-fn read_le_u16(r: &mut io::Read) -> io::Result<u16> {
+fn read_le_u16(r: &mut dyn io::Read) -> io::Result<u16> {
     let mut b = [0; 2];
     let mut amt = 0;
     while amt < b.len() {
@@ -176,7 +176,7 @@ fn read_le_u16(r: &mut io::Read) -> io::Result<u16> {
     Ok((b[0] as u16) | ((b[1] as u16) << 8))
 }
 
-fn read_byte(r: &mut io::Read) -> io::Result<u8> {
+fn read_byte(r: &mut dyn io::Read) -> io::Result<u8> {
     match r.bytes().next() {
         Some(s) => s,
         None => Err(io::Error::new(io::ErrorKind::Other, "end of file")),
@@ -185,7 +185,7 @@ fn read_byte(r: &mut io::Read) -> io::Result<u8> {
 
 /// Parse a compiled terminfo entry, using long capability names if `longnames`
 /// is true
-pub fn parse(file: &mut io::Read, longnames: bool) -> Result<TermInfo, String> {
+pub fn parse(file: &mut dyn io::Read, longnames: bool) -> Result<TermInfo, String> {
     macro_rules! t( ($e:expr) => (
         match $e {
             Ok(e) => e,
diff --git a/src/libtest/lib.rs b/src/libtest/lib.rs
index 9f670de4f5b..ed5b5565d89 100644
--- a/src/libtest/lib.rs
+++ b/src/libtest/lib.rs
@@ -27,8 +27,6 @@
 // this crate, which relies on this attribute (rather than the value of `--crate-name` passed by
 // cargo) to detect this crate.
 
-#![deny(bare_trait_objects)]
-
 #![crate_name = "test"]
 #![unstable(feature = "test", issue = "27812")]
 #![doc(html_logo_url = "https://www.rust-lang.org/logos/rust-logo-128x128-blk-v2.png",
diff --git a/src/libunwind/lib.rs b/src/libunwind/lib.rs
index ea5eee3cc7d..2b3c19c067e 100644
--- a/src/libunwind/lib.rs
+++ b/src/libunwind/lib.rs
@@ -8,8 +8,6 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![deny(bare_trait_objects)]
-
 #![no_std]
 #![unstable(feature = "panic_unwind", issue = "32837")]
 
diff --git a/src/stage0.txt b/src/stage0.txt
index f2c0e9e3b2a..aa6339c8522 100644
--- a/src/stage0.txt
+++ b/src/stage0.txt
@@ -12,7 +12,7 @@
 # source tarball for a stable release you'll likely see `1.x.0` for rustc and
 # `0.x.0` for Cargo where they were released on `date`.
 
-date: 2018-07-13
+date: 2018-07-27
 rustc: beta
 cargo: beta
 
diff --git a/src/test/compile-fail/specialization/issue-52050.rs b/src/test/compile-fail/specialization/issue-52050.rs
new file mode 100644
index 00000000000..70cdb4899c4
--- /dev/null
+++ b/src/test/compile-fail/specialization/issue-52050.rs
@@ -0,0 +1,42 @@
+// Copyright 2015 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(specialization)]
+
+// Regression test for #52050: when inserting the blanket impl `I`
+// into the tree, we had to replace the child node for `Foo`, which
+// led to the struture of the tree being messed up.
+
+use std::iter::Iterator;
+
+trait IntoPyDictPointer { }
+
+struct Foo { }
+
+impl Iterator for Foo {
+    type Item = ();
+    fn next(&mut self) -> Option<()> {
+        None
+    }
+}
+
+impl IntoPyDictPointer for Foo { }
+
+impl<I> IntoPyDictPointer for I
+where
+    I: Iterator,
+{
+}
+
+impl IntoPyDictPointer for () //~ ERROR conflicting implementations
+{
+}
+
+fn main() { }
diff --git a/src/test/run-pass/z-crate-attr.rs b/src/test/run-pass/z-crate-attr.rs
new file mode 100644
index 00000000000..3df0985a2a3
--- /dev/null
+++ b/src/test/run-pass/z-crate-attr.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.
+
+// This test checks if an unstable feature is enabled with the -Zcrate-attr=feature(foo) flag. If
+// the exact feature used here is causing problems feel free to replace it with another
+// perma-unstable feature.
+
+// compile-flags: -Zcrate-attr=feature(abi_unadjusted)
+
+#![allow(dead_code)]
+
+extern "unadjusted" fn foo() {}
+
+fn main() {}
diff --git a/src/test/rustdoc/generic-impl.rs b/src/test/rustdoc/generic-impl.rs
new file mode 100644
index 00000000000..e2665fd8f37
--- /dev/null
+++ b/src/test/rustdoc/generic-impl.rs
@@ -0,0 +1,25 @@
+// 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.
+
+#![crate_name = "foo"]
+
+use std::fmt;
+
+// @!has foo/struct.Bar.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for T'
+pub struct Bar;
+
+// @has foo/struct.Foo.html '//h3[@id="impl-ToString"]//code' 'impl<T> ToString for T'
+pub struct Foo;
+
+impl fmt::Display for Foo {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        write!(f, "Foo")
+    }
+}
diff --git a/src/test/rustdoc/manual_impl.rs b/src/test/rustdoc/manual_impl.rs
index befd3161ac4..54a8a764833 100644
--- a/src/test/rustdoc/manual_impl.rs
+++ b/src/test/rustdoc/manual_impl.rs
@@ -56,7 +56,6 @@ impl T for S1 {
 // @!has - '//*[@class="docblock"]' 'Docs associated with the trait a_method definition.'
 // @!has - '//*[@class="docblock"]' 'Docs associated with the trait c_method definition.'
 // @has - '//*[@class="docblock"]' 'Docs associated with the trait b_method definition.'
-// @!has - '//*[@class="docblock"]' 'Read more'
 pub struct S2(usize);
 
 /// Docs associated with the S2 trait implementation.
diff --git a/src/test/rustdoc/sidebar-items.rs b/src/test/rustdoc/sidebar-items.rs
index 9be40441e9d..3ecd6b63510 100644
--- a/src/test/rustdoc/sidebar-items.rs
+++ b/src/test/rustdoc/sidebar-items.rs
@@ -31,11 +31,11 @@ pub trait Foo {
 // @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields'
 // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f"]' 'f'
 // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.u"]' 'u'
-// @!has - '//*[@class="sidebar-links"]/a' 'w'
+// @!has - '//*[@class="sidebar-links"]/a' 'waza'
 pub struct Bar {
     pub f: u32,
     pub u: u32,
-    w: u32,
+    waza: u32,
 }
 
 // @has foo/enum.En.html
@@ -51,9 +51,9 @@ pub enum En {
 // @has - '//*[@class="sidebar-title"][@href="#fields"]' 'Fields'
 // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f1"]' 'f1'
 // @has - '//*[@class="sidebar-links"]/a[@href="#structfield.f2"]' 'f2'
-// @!has - '//*[@class="sidebar-links"]/a' 'w'
+// @!has - '//*[@class="sidebar-links"]/a' 'waza'
 pub union MyUnion {
     pub f1: u32,
     pub f2: f32,
-    w: u32,
+    waza: u32,
 }
diff --git a/src/test/ui/bad-crate-name.rs b/src/test/ui/bad-crate-name.rs
new file mode 100644
index 00000000000..70e1806a20b
--- /dev/null
+++ b/src/test/ui/bad-crate-name.rs
@@ -0,0 +1,15 @@
+// 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.
+
+extern crate krate-name-here;
+//~^ ERROR crate name using dashes are not valid in `extern crate` statements
+//~| ERROR can't find crate for `krate_name_here`
+
+fn main() {}
diff --git a/src/test/ui/bad-crate-name.stderr b/src/test/ui/bad-crate-name.stderr
new file mode 100644
index 00000000000..8348badeeeb
--- /dev/null
+++ b/src/test/ui/bad-crate-name.stderr
@@ -0,0 +1,19 @@
+error: crate name using dashes are not valid in `extern crate` statements
+  --> $DIR/bad-crate-name.rs:11:14
+   |
+LL | extern crate krate-name-here;
+   |              ^^^^^^^^^^^^^^^ dash-separated idents are not valid
+help: if the original crate name uses dashes you need to use underscores in the code
+   |
+LL | extern crate krate_name_here;
+   |                   ^    ^
+
+error[E0463]: can't find crate for `krate_name_here`
+  --> $DIR/bad-crate-name.rs:11:1
+   |
+LL | extern crate krate-name-here;
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ can't find crate
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0463`.
diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr
new file mode 100644
index 00000000000..fa82efa3533
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.edition.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17
+   |
+LL |                 (|| { let bar = foo; bar.take() })();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs
new file mode 100644
index 00000000000..72043938f53
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.rs
@@ -0,0 +1,40 @@
+// 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.
+
+// This is a test that the `#![feature(nll)]` opt-in overrides the
+// migration mode. The intention here is to emulate the goal behavior
+// that `--edition 2018` effects on borrowck (modeled here by `-Z
+// borrowck=migrate`) are themselves overridden by the
+// `#![feature(nll)]` opt-in.
+//
+// Therefore, for developer convenience, under `#[feature(nll)]` the
+// NLL checks will be emitted as errors *even* in the presence of `-Z
+// borrowck=migrate`.
+
+// revisions: zflag edition
+// [zflag]compile-flags: -Z borrowck=migrate
+// [edition]compile-flags: --edition 2018
+
+#![feature(nll)]
+
+fn main() {
+    match Some(&4) {
+        None => {},
+        ref mut foo
+            if {
+                (|| { let bar = foo; bar.take() })();
+                //[zflag]~^ ERROR cannot move out of borrowed content [E0507]
+                //[edition]~^^ ERROR cannot move out of borrowed content [E0507]
+                false
+            } => {},
+        Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
+        _ => println!("Here is some supposedly unreachable code."),
+    }
+}
diff --git a/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr
new file mode 100644
index 00000000000..fa82efa3533
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-feature-nll-overrides-migrate.zflag.stderr
@@ -0,0 +1,9 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/borrowck-feature-nll-overrides-migrate.rs:32:17
+   |
+LL |                 (|| { let bar = foo; bar.take() })();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0507`.
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
new file mode 100644
index 00000000000..f5a9db36406
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.edition.stderr
@@ -0,0 +1,24 @@
+warning[E0507]: cannot move out of borrowed content
+  --> $DIR/borrowck-migrate-to-nll.rs:35:17
+   |
+LL |                 (|| { let bar = foo; bar.take() })();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |
+   = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+           It represents potential unsoundness in your code.
+           This warning will become a hard error in the future.
+
+warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard
+  --> $DIR/borrowck-migrate-to-nll.rs:35:17
+   |
+LL |                 (|| { let bar = foo; bar.take() })();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 cannot move out of `foo`, as it is immutable for the pattern guard
+   |                 cannot move
+   |
+   = note: variables bound in patterns are immutable until the end of the pattern guard
+   = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+           It represents potential unsoundness in your code.
+           This warning will become a hard error in the future.
+
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.rs b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
new file mode 100644
index 00000000000..e7f2bfbfedb
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.rs
@@ -0,0 +1,41 @@
+// 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.
+
+// This is a test of the borrowck migrate mode. It leverages #27282, a
+// bug that is fixed by NLL: this code is (unsoundly) accepted by
+// AST-borrowck, but is correctly rejected by the NLL borrowck.
+//
+// Therefore, for backwards-compatiblity, under borrowck=migrate the
+// NLL checks will be emitted as *warnings*.
+
+// NLL mode makes this compile-fail; we cannot currently encode a
+// test that is run-pass or compile-fail based on compare-mode. So
+// just ignore it instead:
+
+// ignore-compare-mode-nll
+
+// revisions: zflag edition
+//[zflag]compile-flags: -Z borrowck=migrate
+//[edition]compile-flags: --edition 2018
+//[zflag] run-pass
+//[edition] run-pass
+
+fn main() {
+    match Some(&4) {
+        None => {},
+        ref mut foo
+            if {
+                (|| { let bar = foo; bar.take() })();
+                false
+            } => {},
+        Some(ref _s) => println!("Note this arm is bogus; the `Some` became `None` in the guard."),
+        _ => println!("Here is some supposedly unreachable code."),
+    }
+}
diff --git a/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
new file mode 100644
index 00000000000..f5a9db36406
--- /dev/null
+++ b/src/test/ui/borrowck/borrowck-migrate-to-nll.zflag.stderr
@@ -0,0 +1,24 @@
+warning[E0507]: cannot move out of borrowed content
+  --> $DIR/borrowck-migrate-to-nll.rs:35:17
+   |
+LL |                 (|| { let bar = foo; bar.take() })();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of borrowed content
+   |
+   = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+           It represents potential unsoundness in your code.
+           This warning will become a hard error in the future.
+
+warning[E0507]: cannot move out of `foo`, as it is immutable for the pattern guard
+  --> $DIR/borrowck-migrate-to-nll.rs:35:17
+   |
+LL |                 (|| { let bar = foo; bar.take() })();
+   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                 |
+   |                 cannot move out of `foo`, as it is immutable for the pattern guard
+   |                 cannot move
+   |
+   = note: variables bound in patterns are immutable until the end of the pattern guard
+   = warning: This error has been downgraded to a warning for backwards compatibility with previous releases.
+           It represents potential unsoundness in your code.
+           This warning will become a hard error in the future.
+
diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr
index bd5d2a46fd8..4048243acfa 100644
--- a/src/test/ui/borrowck/issue-41962.stderr
+++ b/src/test/ui/borrowck/issue-41962.stderr
@@ -17,26 +17,22 @@ LL |         if let Some(thing) = maybe {
    = note: move occurs because the value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `maybe` (Mir)
-  --> $DIR/issue-41962.rs:17:9
+  --> $DIR/issue-41962.rs:17:30
    |
-LL |           if let Some(thing) = maybe {
-   |           ^           ----- value moved here
-   |  _________|
-   | |
-LL | |         }
-   | |_________^ value used here after move
+LL |         if let Some(thing) = maybe {
+   |                     -----    ^^^^^ value used here after move
+   |                     |
+   |                     value moved here
    |
    = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
 error[E0382]: borrow of moved value: `maybe` (Mir)
-  --> $DIR/issue-41962.rs:17:9
+  --> $DIR/issue-41962.rs:17:30
    |
-LL |           if let Some(thing) = maybe {
-   |           ^           ----- value moved here
-   |  _________|
-   | |
-LL | |         }
-   | |_________^ value borrowed here after move
+LL |         if let Some(thing) = maybe {
+   |                     -----    ^^^^^ value borrowed here after move
+   |                     |
+   |                     value moved here
    |
    = note: move occurs because value has type `std::vec::Vec<bool>`, which does not implement the `Copy` trait
 
diff --git a/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs b/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs
new file mode 100644
index 00000000000..c9d39fa360e
--- /dev/null
+++ b/src/test/ui/borrowck/issue-51348-multi-ref-mut-in-guard.rs
@@ -0,0 +1,33 @@
+// 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.
+
+// We used to ICE if you had a single match arm with multiple
+// candidate patterns with `ref mut` identifiers used in the arm's
+// guard.
+//
+// Also, this test expands on the original bug's example by actually
+// trying to double check that we are matching against the right part
+// of the input data based on which candidate pattern actually fired.
+
+// run-pass
+
+#![feature(nll)]
+
+fn foo(x: &mut Result<(u32, u32), (u32, u32)>) -> u32 {
+    match *x {
+        Ok((ref mut v, _)) | Err((_, ref mut v)) if *v > 0 => { *v }
+        _ => { 0 }
+    }
+}
+
+fn main() {
+    assert_eq!(foo(&mut Ok((3, 4))), 3);
+    assert_eq!(foo(&mut Err((3, 4))), 4);
+}
diff --git a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
index 9c7e3db67a6..0ac295c54bc 100644
--- a/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
+++ b/src/test/ui/error-codes/E0621-does-not-trigger-for-closures.nll.stderr
@@ -10,8 +10,8 @@ error: unsatisfied lifetime constraints
 LL |     invoke(&x, |a, b| if a > b { a } else { b }); //~ ERROR E0495
    |                ----------^^^^^-----------------
    |                |   |     |
-   |                |   |     free region requires that `'1` must outlive `'2`
-   |                |   lifetime `'1` appears in this argument
+   |                |   |     requires that `'1` must outlive `'2`
+   |                |   has type `&'1 i32`
    |                lifetime `'2` appears in return type
 
 error: aborting due to previous error
diff --git a/src/test/ui/feature-gate-infer_static_outlives_requirements.rs b/src/test/ui/feature-gate-infer_static_outlives_requirements.rs
new file mode 100644
index 00000000000..7b68449859e
--- /dev/null
+++ b/src/test/ui/feature-gate-infer_static_outlives_requirements.rs
@@ -0,0 +1,22 @@
+// Copyright 2015 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.
+
+// Needs an explicit where clause stating outlives condition. (RFC 2093)
+
+// Type T needs to outlive lifetime 'static.
+struct Foo<U> {
+    bar: Bar<U> //~ ERROR 15:5: 15:16: the parameter type `U` may not live long enough [E0310]
+}
+struct Bar<T: 'static> {
+    x: T,
+}
+
+
+fn main() { }
diff --git a/src/test/ui/feature-gate-infer_static_outlives_requirements.stderr b/src/test/ui/feature-gate-infer_static_outlives_requirements.stderr
new file mode 100644
index 00000000000..13022b901a7
--- /dev/null
+++ b/src/test/ui/feature-gate-infer_static_outlives_requirements.stderr
@@ -0,0 +1,17 @@
+error[E0310]: the parameter type `U` may not live long enough
+  --> $DIR/feature-gate-infer_static_outlives_requirements.rs:15:5
+   |
+LL | struct Foo<U> {
+   |            - help: consider adding an explicit lifetime bound `U: 'static`...
+LL |     bar: Bar<U> //~ ERROR 15:5: 15:16: the parameter type `U` may not live long enough [E0310]
+   |     ^^^^^^^^^^^
+   |
+note: ...so that the type `U` will meet its required lifetime bounds
+  --> $DIR/feature-gate-infer_static_outlives_requirements.rs:15:5
+   |
+LL |     bar: Bar<U> //~ ERROR 15:5: 15:16: the parameter type `U` may not live long enough [E0310]
+   |     ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/generator/generator-with-nll.rs b/src/test/ui/generator/generator-with-nll.rs
index 3223ff4dc8b..fdfe9e2c562 100644
--- a/src/test/ui/generator/generator-with-nll.rs
+++ b/src/test/ui/generator/generator-with-nll.rs
@@ -8,17 +8,15 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-// compile-flags: -Z borrowck=compare
-
 #![feature(generators)]
 #![feature(nll)]
 
 fn main() {
     || {
         // The reference in `_a` is a Legal with NLL since it ends before the yield
-        let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
-        let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
-        //~^ borrow may still be in use when generator yields (Mir)
+        let _a = &mut true;
+        let b = &mut true;
+        //~^ borrow may still be in use when generator yields
         yield ();
         println!("{}", b);
     };
diff --git a/src/test/ui/generator/generator-with-nll.stderr b/src/test/ui/generator/generator-with-nll.stderr
index 7e39d3c5459..1dc663d8bcb 100644
--- a/src/test/ui/generator/generator-with-nll.stderr
+++ b/src/test/ui/generator/generator-with-nll.stderr
@@ -1,30 +1,12 @@
-error[E0626]: borrow may still be in use when generator yields (Ast)
-  --> $DIR/generator-with-nll.rs:19:23
+error[E0626]: borrow may still be in use when generator yields
+  --> $DIR/generator-with-nll.rs:18:17
    |
-LL |         let _a = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
-   |                       ^^^^
-...
-LL |         yield ();
-   |         -------- possible yield occurs here
-
-error[E0626]: borrow may still be in use when generator yields (Ast)
-  --> $DIR/generator-with-nll.rs:20:22
-   |
-LL |         let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
-   |                      ^^^^
-LL |         //~^ borrow may still be in use when generator yields (Mir)
-LL |         yield ();
-   |         -------- possible yield occurs here
-
-error[E0626]: borrow may still be in use when generator yields (Mir)
-  --> $DIR/generator-with-nll.rs:20:17
-   |
-LL |         let b = &mut true; //~ ERROR borrow may still be in use when generator yields (Ast)
+LL |         let b = &mut true;
    |                 ^^^^^^^^^
-LL |         //~^ borrow may still be in use when generator yields (Mir)
+LL |         //~^ borrow may still be in use when generator yields
 LL |         yield ();
    |         -------- possible yield occurs here
 
-error: aborting due to 3 previous errors
+error: aborting due to previous error
 
 For more information about this error, try `rustc --explain E0626`.
diff --git a/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs b/src/test/ui/impl-trait/associated-existential-type-generic-trait.rs
new file mode 100644
index 00000000000..c9bf7b87ef4
--- /dev/null
+++ b/src/test/ui/impl-trait/associated-existential-type-generic-trait.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.
+
+#![feature(existential_type)]
+// compile-pass
+
+trait Bar {}
+struct Dummy<U>(U);
+impl<V> Bar for Dummy<V> {}
+
+trait Foo<T> {
+    type Assoc: Bar;
+    fn foo(t: T) -> Self::Assoc;
+}
+
+impl<W> Foo<W> for i32 {
+    existential type Assoc: Bar;
+    fn foo(w: W) -> Self::Assoc {
+        Dummy(w)
+    }
+}
+
+struct NonGeneric;
+impl Bar for NonGeneric {}
+
+impl<W> Foo<W> for u32 {
+    existential type Assoc: Bar;
+    fn foo(_: W) -> Self::Assoc {
+        NonGeneric
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/associated-existential-type-trivial.rs b/src/test/ui/impl-trait/associated-existential-type-trivial.rs
new file mode 100644
index 00000000000..78593fe319c
--- /dev/null
+++ b/src/test/ui/impl-trait/associated-existential-type-trivial.rs
@@ -0,0 +1,30 @@
+// 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(existential_type)]
+// compile-pass
+
+trait Bar {}
+struct Dummy;
+impl Bar for Dummy {}
+
+trait Foo {
+    type Assoc: Bar;
+    fn foo() -> Self::Assoc;
+}
+
+impl Foo for i32 {
+    existential type Assoc: Bar;
+    fn foo() -> Self::Assoc {
+        Dummy
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/associated-existential-type.rs b/src/test/ui/impl-trait/associated-existential-type.rs
new file mode 100644
index 00000000000..d880428411f
--- /dev/null
+++ b/src/test/ui/impl-trait/associated-existential-type.rs
@@ -0,0 +1,34 @@
+// 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(existential_type)]
+// compile-pass
+
+trait Bar {}
+struct Dummy;
+impl Bar for Dummy {}
+
+trait Foo {
+    type Assoc: Bar;
+    fn foo() -> Self::Assoc;
+    fn bar() -> Self::Assoc;
+}
+
+impl Foo for i32 {
+    existential type Assoc: Bar;
+    fn foo() -> Self::Assoc {
+        Dummy
+    }
+    fn bar() -> Self::Assoc {
+        Dummy
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
index c6f8d2e519c..bbc63e6feca 100644
--- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
+++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr
@@ -10,21 +10,19 @@ warning: not reporting region error due to nll
 LL |         self.x.iter().map(|a| a.0)
    |                ^^^^
 
-error: borrowed data escapes outside of closure
+error: unsatisfied lifetime constraints
   --> $DIR/static-return-lifetime-infered.rs:17:9
    |
 LL |     fn iter_values_anon(&self) -> impl Iterator<Item=u32> {
-   |                         ----- `self` is a reference that is only valid in the closure body
+   |                         - let's call the lifetime of this reference `'1`
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
+   |         ^^^^^^^^^^^^^ requires that `'1` must outlive `'static`
 
-error: borrowed data escapes outside of closure
+error: unsatisfied lifetime constraints
   --> $DIR/static-return-lifetime-infered.rs:21:9
    |
-LL |     fn iter_values<'a>(&'a self) -> impl Iterator<Item=u32> {
-   |                        -------- `self` is a reference that is only valid in the closure body
 LL |         self.x.iter().map(|a| a.0)
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^ `self` escapes the closure body here
+   |         ^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr
index e26b1956d5e..f5d98e04ad8 100644
--- a/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr
+++ b/src/test/ui/in-band-lifetimes/impl/dyn-trait.nll.stderr
@@ -4,13 +4,13 @@ warning: not reporting region error due to nll
 LL |     static_val(x); //~ ERROR cannot infer
    |                ^
 
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/dyn-trait.rs:32:5
    |
 LL | fn with_dyn_debug_static<'a>(x: Box<dyn Debug + 'a>) {
-   |                              - `x` is a reference that is only valid in the closure body
+   |                              - `x` is a reference that is only valid in the function body
 LL |     static_val(x); //~ ERROR cannot infer
-   |     ^^^^^^^^^^^^^ `x` escapes the closure body here
+   |     ^^^^^^^^^^^^^ `x` escapes the function body here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-10291.nll.stderr b/src/test/ui/issue-10291.nll.stderr
index 1358fe010b4..6de00ffd48c 100644
--- a/src/test/ui/issue-10291.nll.stderr
+++ b/src/test/ui/issue-10291.nll.stderr
@@ -8,7 +8,7 @@ error: unsatisfied lifetime constraints
   --> $DIR/issue-10291.rs:12:5
    |
 LL |     drop::<Box<for<'z> FnMut(&'z isize) -> &'z isize>>(Box::new(|z| {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ free region requires that `'x` must outlive `'static`
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-13033.stderr b/src/test/ui/issue-13033.stderr
index 2db3cb80a81..f06d7360d85 100644
--- a/src/test/ui/issue-13033.stderr
+++ b/src/test/ui/issue-13033.stderr
@@ -9,6 +9,10 @@ LL |     fn bar(&mut self, other: &Foo) {}
    |
    = note: expected type `fn(&mut Baz, &mut dyn Foo)`
               found type `fn(&mut Baz, &dyn Foo)`
+help: consider change the type to match the mutability in trait
+   |
+LL |     fn bar(&mut self, other: &mut Foo) {}
+   |                              ^^^^^^^^
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-16683.nll.stderr b/src/test/ui/issue-16683.nll.stderr
index f9dda27da09..890bb426441 100644
--- a/src/test/ui/issue-16683.nll.stderr
+++ b/src/test/ui/issue-16683.nll.stderr
@@ -10,13 +10,13 @@ warning: not reporting region error due to nll
 LL |         self.a(); //~ ERROR cannot infer
    |              ^
 
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/issue-16683.rs:14:9
    |
 LL |     fn b(&self) {
-   |          ----- `self` is a reference that is only valid in the closure body
+   |          ----- `self` is a reference that is only valid in the function body
 LL |         self.a(); //~ ERROR cannot infer
-   |         ^^^^^^^^ `self` escapes the closure body here
+   |         ^^^^^^^^ `self` escapes the function body here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-17385.nll.stderr b/src/test/ui/issue-17385.nll.stderr
index c3387e58fcf..85924a75261 100644
--- a/src/test/ui/issue-17385.nll.stderr
+++ b/src/test/ui/issue-17385.nll.stderr
@@ -1,26 +1,20 @@
 error[E0382]: use of moved value: `foo`
-  --> $DIR/issue-17385.rs:28:5
+  --> $DIR/issue-17385.rs:28:11
    |
-LL |       drop(foo);
-   |            --- value moved here
-LL | /     match foo { //~ ERROR use of moved value
-LL | |         X(1) => (),
-LL | |         _ => unreachable!()
-LL | |     }
-   | |_____^ value used here after move
+LL |     drop(foo);
+   |          --- value moved here
+LL |     match foo { //~ ERROR use of moved value
+   |           ^^^ value used here after move
    |
    = note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait
 
 error[E0382]: borrow of moved value: `foo`
-  --> $DIR/issue-17385.rs:28:5
+  --> $DIR/issue-17385.rs:28:11
    |
-LL |       drop(foo);
-   |            --- value moved here
-LL | /     match foo { //~ ERROR use of moved value
-LL | |         X(1) => (),
-LL | |         _ => unreachable!()
-LL | |     }
-   | |_____^ value borrowed here after move
+LL |     drop(foo);
+   |          --- value moved here
+LL |     match foo { //~ ERROR use of moved value
+   |           ^^^ value borrowed here after move
    |
    = note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait
 
@@ -36,28 +30,22 @@ LL |         X(1) => (),
    = note: move occurs because `foo` has type `X`, which does not implement the `Copy` trait
 
 error[E0382]: use of moved value: `e`
-  --> $DIR/issue-17385.rs:35:5
+  --> $DIR/issue-17385.rs:35:11
    |
-LL |       drop(e);
-   |            - value moved here
-LL | /     match e { //~ ERROR use of moved value
-LL | |         Enum::Variant1 => unreachable!(),
-LL | |         Enum::Variant2 => ()
-LL | |     }
-   | |_____^ value used here after move
+LL |     drop(e);
+   |          - value moved here
+LL |     match e { //~ ERROR use of moved value
+   |           ^ value used here after move
    |
    = note: move occurs because `e` has type `Enum`, which does not implement the `Copy` trait
 
 error[E0382]: borrow of moved value: `e`
-  --> $DIR/issue-17385.rs:35:5
+  --> $DIR/issue-17385.rs:35:11
    |
-LL |       drop(e);
-   |            - value moved here
-LL | /     match e { //~ ERROR use of moved value
-LL | |         Enum::Variant1 => unreachable!(),
-LL | |         Enum::Variant2 => ()
-LL | |     }
-   | |_____^ value borrowed here after move
+LL |     drop(e);
+   |          - value moved here
+LL |     match e { //~ ERROR use of moved value
+   |           ^ value borrowed here after move
    |
    = note: move occurs because `e` has type `Enum`, which does not implement the `Copy` trait
 
diff --git a/src/test/ui/issue-17758.nll.stderr b/src/test/ui/issue-17758.nll.stderr
index 5775135aefc..c51a72f885d 100644
--- a/src/test/ui/issue-17758.nll.stderr
+++ b/src/test/ui/issue-17758.nll.stderr
@@ -10,13 +10,13 @@ warning: not reporting region error due to nll
 LL |         self.foo();
    |              ^^^
 
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/issue-17758.rs:17:9
    |
 LL |     fn bar(&self) {
-   |            ----- `self` is a reference that is only valid in the closure body
+   |            ----- `self` is a reference that is only valid in the function body
 LL |         self.foo();
-   |         ^^^^^^^^^^ `self` escapes the closure body here
+   |         ^^^^^^^^^^ `self` escapes the function body here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-20801.nll.stderr b/src/test/ui/issue-20801.nll.stderr
index 0394309a6e2..fc94cc423c5 100644
--- a/src/test/ui/issue-20801.nll.stderr
+++ b/src/test/ui/issue-20801.nll.stderr
@@ -2,25 +2,37 @@ error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:36:22
    |
 LL |     let a = unsafe { *mut_ref() };
-   |                      ^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*mut_ref()`
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:39:22
    |
 LL |     let b = unsafe { *imm_ref() };
-   |                      ^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*imm_ref()`
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:42:22
    |
 LL |     let c = unsafe { *mut_ptr() };
-   |                      ^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*mut_ptr()`
 
 error[E0507]: cannot move out of borrowed content
   --> $DIR/issue-20801.rs:45:22
    |
 LL |     let d = unsafe { *const_ptr() };
-   |                      ^^^^^^^^^^^^ cannot move out of borrowed content
+   |                      ^^^^^^^^^^^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider using a reference instead: `&*const_ptr()`
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/issue-27282-move-match-input-into-guard.stderr
index f89388f1738..d264bf8d273 100644
--- a/src/test/ui/issue-27282-move-match-input-into-guard.stderr
+++ b/src/test/ui/issue-27282-move-match-input-into-guard.stderr
@@ -1,21 +1,14 @@
 error[E0505]: cannot move out of `b` because it is borrowed
   --> $DIR/issue-27282-move-match-input-into-guard.rs:26:16
    |
-LL |        match b {
-   |   _____-
-   |  |_____|
-   | ||
-LL | ||         &mut false => {},
-LL | ||         _ if { (|| { let bar = b; *bar = false; })();
-   | ||                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here
-LL | ||                      //~^ ERROR cannot move out of `b` because it is borrowed [E0505]
-...  ||
-LL | ||         _ => panic!("surely we could never get here, since rustc warns it is unreachable."),
-LL | ||     }
-   | ||     -
-   | ||_____|
-   | |______borrow of `b` occurs here
-   |        borrow later used here
+LL |     match b {
+   |           - borrow of `b` occurs here
+LL |         &mut false => {},
+LL |         _ if { (|| { let bar = b; *bar = false; })();
+   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here
+...
+LL |         &mut true => { println!("You might think we should get here"); },
+   |         --------- borrow later used here
 
 error[E0382]: use of moved value: `*b`
   --> $DIR/issue-27282-move-match-input-into-guard.rs:29:14
diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr
index 8f7fe9d33fe..fb11090c222 100644
--- a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr
+++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr
@@ -1,24 +1,16 @@
 error[E0500]: closure requires unique access to `x` but it is already borrowed
   --> $DIR/issue-27282-mutate-before-diverging-arm-1.rs:33:14
    |
-LL |        match x {
-   |   _____-
-   |  |_____|
-   | ||
-LL | ||         &mut None => panic!("unreachable"),
-LL | ||         &mut Some(&_) if {
-LL | ||             // ForceFnOnce needed to exploit #27282
-LL | ||             (|| { *x = None; drop(force_fn_once); })();
-   | ||              ^^    - borrow occurs due to use of `x` in closure
-   | ||              |
-   | ||              closure construction occurs here
-...  ||
-LL | ||         _ => panic!("unreachable"),
-LL | ||     }
-   | ||     -
-   | ||_____|
-   | |______borrow occurs here
-   |        borrow later used here
+LL |     match x {
+   |           - borrow occurs here
+...
+LL |             (|| { *x = None; drop(force_fn_once); })();
+   |              ^^    - borrow occurs due to use of `x` in closure
+   |              |
+   |              closure construction occurs here
+...
+LL |         &mut Some(&a) if { // this binds to garbage if we've corrupted discriminant
+   |         ------------- borrow later used here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr
index df5e4300cec..6e643d30185 100644
--- a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr
+++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr
@@ -1,25 +1,16 @@
 error[E0500]: closure requires unique access to `x` but it is already borrowed
   --> $DIR/issue-27282-mutate-before-diverging-arm-2.rs:38:18
    |
-LL |        match x {
-   |   _____-
-   |  |_____|
-   | ||
-LL | ||         &mut None => panic!("unreachable"),
-LL | ||         &mut Some(&_)
-LL | ||             if {
-LL | ||                 // ForceFnOnce needed to exploit #27282
-LL | ||                 (|| { *x = None; drop(force_fn_once); })();
-   | ||                  ^^    - borrow occurs due to use of `x` in closure
-   | ||                  |
-   | ||                  closure construction occurs here
-...  ||
-LL | ||         _ => panic!("unreachable"),
-LL | ||     }
-   | ||     -
-   | ||_____|
-   | |______borrow occurs here
-   |        borrow later used here
+LL |     match x {
+   |           - borrow occurs here
+...
+LL |                 (|| { *x = None; drop(force_fn_once); })();
+   |                  ^^    - borrow occurs due to use of `x` in closure
+   |                  |
+   |                  closure construction occurs here
+...
+LL |         &mut Some(&2)
+   |         ------------- borrow later used here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-40510-1.nll.stderr b/src/test/ui/issue-40510-1.nll.stderr
index 73a8d58290d..312ec6e742e 100644
--- a/src/test/ui/issue-40510-1.nll.stderr
+++ b/src/test/ui/issue-40510-1.nll.stderr
@@ -6,7 +6,7 @@ LL |        || {
    |  |_____|
    | ||
 LL | ||         &mut x
-   | ||         ^^^^^^ free region requires that `'1` must outlive `'2`
+   | ||         ^^^^^^ return requires that `'1` must outlive `'2`
 LL | ||     };
    | ||     -
    | ||_____|
diff --git a/src/test/ui/issue-40510-3.nll.stderr b/src/test/ui/issue-40510-3.nll.stderr
index 4133c69f031..eb44850e639 100644
--- a/src/test/ui/issue-40510-3.nll.stderr
+++ b/src/test/ui/issue-40510-3.nll.stderr
@@ -9,7 +9,7 @@ LL |  ||         || {
    |  ||_________^
 LL | |||             x.push(())
 LL | |||         }
-   | |||_________^ free region requires that `'1` must outlive `'2`
+   | |||_________^ requires that `'1` must outlive `'2`
 LL |  ||     };
    |  ||     -
    |  ||_____|
diff --git a/src/test/ui/issue-47412.stderr b/src/test/ui/issue-47412.stderr
index 6ca404003a5..d8a47efc0aa 100644
--- a/src/test/ui/issue-47412.stderr
+++ b/src/test/ui/issue-47412.stderr
@@ -1,16 +1,16 @@
 error[E0133]: access to union field is unsafe and requires unsafe function or block
-  --> $DIR/issue-47412.rs:21:5
+  --> $DIR/issue-47412.rs:21:11
    |
 LL |     match u.void {}
-   |     ^^^^^^^^^^^^^^^ access to union field
+   |           ^^^^^^ access to union field
    |
    = note: the field may not be properly initialized: using uninitialized data will cause undefined behavior
 
 error[E0133]: dereference of raw pointer is unsafe and requires unsafe function or block
-  --> $DIR/issue-47412.rs:27:5
+  --> $DIR/issue-47412.rs:27:11
    |
 LL |     match *ptr {}
-   |     ^^^^^^^^^^^^^ dereference of raw pointer
+   |           ^^^^ dereference of raw pointer
    |
    = note: raw pointers may be NULL, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
 
diff --git a/src/test/ui/issue-52213.nll.stderr b/src/test/ui/issue-52213.nll.stderr
index c288cf9ed82..7dd513d1b71 100644
--- a/src/test/ui/issue-52213.nll.stderr
+++ b/src/test/ui/issue-52213.nll.stderr
@@ -8,7 +8,7 @@ error: unsatisfied lifetime constraints
   --> $DIR/issue-52213.rs:13:11
    |
 LL |         ((u,),) => u,
-   |           ^ free region requires that `'a` must outlive `'b`
+   |           ^ requires that `'a` must outlive `'b`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issue-52533-1.nll.stderr b/src/test/ui/issue-52533-1.nll.stderr
new file mode 100644
index 00000000000..87fda1dd99c
--- /dev/null
+++ b/src/test/ui/issue-52533-1.nll.stderr
@@ -0,0 +1,17 @@
+warning: not reporting region error due to nll
+  --> $DIR/issue-52533-1.rs:19:18
+   |
+LL |     gimme(|x, y| y)
+   |                  ^
+
+error: unsatisfied lifetime constraints
+  --> $DIR/issue-52533-1.rs:19:18
+   |
+LL |     gimme(|x, y| y)
+   |            -  -  ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
+   |            |  |
+   |            |  has type `&Foo<'_, '1, u32>`
+   |            has type `&Foo<'_, '2, u32>`
+
+error: aborting due to previous error
+
diff --git a/src/liballoc/repeat-generic-slice.rs b/src/test/ui/issue-52533-1.rs
index 5c14ee4fd83..22af5a86702 100644
--- a/src/liballoc/repeat-generic-slice.rs
+++ b/src/test/ui/issue-52533-1.rs
@@ -8,12 +8,14 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(repeat_generic_slice)]
+#![allow(warnings)]
+
+struct Foo<'a, 'b, T: 'a + 'b> { x: &'a T, y: &'b T }
+
+fn gimme(_: impl for<'a, 'b, 'c> FnOnce(&'a Foo<'a, 'b, u32>,
+                                        &'a Foo<'a, 'c, u32>) -> &'a Foo<'a, 'b, u32>) { }
 
 fn main() {
-    assert_eq!([1, 2].repeat(2), vec![1, 2, 1, 2]);
-    assert_eq!([1, 2, 3, 4].repeat(0), vec![]);
-    assert_eq!([1, 2, 3, 4].repeat(1), vec![1, 2, 3, 4]);
-    assert_eq!([1, 2, 3, 4].repeat(3),
-               vec![1, 2, 3, 4, 1, 2, 3, 4, 1, 2, 3, 4]);
+    gimme(|x, y| y)
+    //~^ ERROR mismatched types [E0308]
 }
diff --git a/src/test/ui/issue-52533-1.stderr b/src/test/ui/issue-52533-1.stderr
new file mode 100644
index 00000000000..38deb7d66de
--- /dev/null
+++ b/src/test/ui/issue-52533-1.stderr
@@ -0,0 +1,22 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-52533-1.rs:19:18
+   |
+LL |     gimme(|x, y| y)
+   |                  ^ lifetime mismatch
+   |
+   = note: expected type `&Foo<'_, '_, u32>`
+              found type `&Foo<'_, '_, u32>`
+note: the anonymous lifetime #4 defined on the body at 19:11...
+  --> $DIR/issue-52533-1.rs:19:11
+   |
+LL |     gimme(|x, y| y)
+   |           ^^^^^^^^
+note: ...does not necessarily outlive the anonymous lifetime #3 defined on the body at 19:11
+  --> $DIR/issue-52533-1.rs:19:11
+   |
+LL |     gimme(|x, y| y)
+   |           ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/issue-52533.nll.stderr b/src/test/ui/issue-52533.nll.stderr
new file mode 100644
index 00000000000..a13b06e3204
--- /dev/null
+++ b/src/test/ui/issue-52533.nll.stderr
@@ -0,0 +1,17 @@
+warning: not reporting region error due to nll
+  --> $DIR/issue-52533.rs:15:16
+   |
+LL |     foo(|a, b| b)
+   |                ^
+
+error: unsatisfied lifetime constraints
+  --> $DIR/issue-52533.rs:15:16
+   |
+LL |     foo(|a, b| b)
+   |          -  -  ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
+   |          |  |
+   |          |  has type `&'1 u32`
+   |          has type `&'2 u32`
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/issue-52533.rs b/src/test/ui/issue-52533.rs
new file mode 100644
index 00000000000..08f2805cefd
--- /dev/null
+++ b/src/test/ui/issue-52533.rs
@@ -0,0 +1,17 @@
+// 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 foo(_: impl for<'a> FnOnce(&'a u32, &u32) -> &'a u32) {
+}
+
+fn main() {
+    foo(|a, b| b)
+    //~^ ERROR lifetime of reference outlives lifetime of borrowed content...
+}
diff --git a/src/test/ui/issue-52533.stderr b/src/test/ui/issue-52533.stderr
new file mode 100644
index 00000000000..76a2470a2e0
--- /dev/null
+++ b/src/test/ui/issue-52533.stderr
@@ -0,0 +1,20 @@
+error[E0312]: lifetime of reference outlives lifetime of borrowed content...
+  --> $DIR/issue-52533.rs:15:16
+   |
+LL |     foo(|a, b| b)
+   |                ^
+   |
+note: ...the reference is valid for the anonymous lifetime #2 defined on the body at 15:9...
+  --> $DIR/issue-52533.rs:15:9
+   |
+LL |     foo(|a, b| b)
+   |         ^^^^^^^^
+note: ...but the borrowed content is only valid for the anonymous lifetime #3 defined on the body at 15:9
+  --> $DIR/issue-52533.rs:15:9
+   |
+LL |     foo(|a, b| b)
+   |         ^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0312`.
diff --git a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr
index 5451562cdfb..e5b001def56 100644
--- a/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr
+++ b/src/test/ui/lifetime-errors/ex1-return-one-existing-name-early-bound-in-struct.nll.stderr
@@ -5,18 +5,12 @@ LL |                     other //~ ERROR explicit lifetime
    |                     ^^^^^
 
 error[E0621]: explicit lifetime required in the type of `other`
-  --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:18:9
+  --> $DIR/ex1-return-one-existing-name-early-bound-in-struct.rs:18:15
    |
-LL |       fn bar(&self, other: Foo) -> Foo<'a> {
-   |                     ----- consider changing the type of `other` to `Foo<'a>`
-LL | /         match *self {
-LL | |             Foo::Bar(s) => {
-LL | |                 if s == "test" {
-LL | |                     other //~ ERROR explicit lifetime
-...  |
-LL | |             }
-LL | |         }
-   | |_________^ lifetime `'a` required
+LL |     fn bar(&self, other: Foo) -> Foo<'a> {
+   |                   ----- consider changing the type of `other` to `Foo<'a>`
+LL |         match *self {
+   |               ^^^^^ lifetime `'a` required
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/mismatched_types/E0053.stderr b/src/test/ui/mismatched_types/E0053.stderr
index 1b16694bf2c..f707a600f29 100644
--- a/src/test/ui/mismatched_types/E0053.stderr
+++ b/src/test/ui/mismatched_types/E0053.stderr
@@ -21,6 +21,10 @@ LL |     fn bar(&mut self) { }
    |
    = note: expected type `fn(&Bar)`
               found type `fn(&mut Bar)`
+help: consider change the type to match the mutability in trait
+   |
+LL |     fn bar(&self) { }
+   |            ^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
index 28b16641e4d..631af21cac5 100644
--- a/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
+++ b/src/test/ui/mismatched_types/trait-impl-fn-incompatibility.stderr
@@ -21,6 +21,10 @@ LL |     fn bar(&mut self, bar: &Bar) { } //~ ERROR incompatible type
    |
    = note: expected type `fn(&mut Bar, &mut Bar)`
               found type `fn(&mut Bar, &Bar)`
+help: consider change the type to match the mutability in trait
+   |
+LL |     fn bar(&mut self, bar: &mut Bar) { } //~ ERROR incompatible type
+   |                            ^^^^^^^^
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/nll/borrowed-match-issue-45045.stderr b/src/test/ui/nll/borrowed-match-issue-45045.stderr
index 7904e601579..acbba9ee187 100644
--- a/src/test/ui/nll/borrowed-match-issue-45045.stderr
+++ b/src/test/ui/nll/borrowed-match-issue-45045.stderr
@@ -1,17 +1,14 @@
 error[E0503]: cannot use `e` because it was mutably borrowed
-  --> $DIR/borrowed-match-issue-45045.rs:24:5
+  --> $DIR/borrowed-match-issue-45045.rs:24:11
    |
-LL |       let f = &mut e;
-   |               ------ borrow of `e` occurs here
-LL |       let g = f;
-LL | /     match e { //~ cannot use `e` because it was mutably borrowed [E0503]
-LL | |         Xyz::A => println!("a"),
-LL | |         //~^ cannot use `e` because it was mutably borrowed [E0503]
-LL | |         Xyz::B => println!("b"),
-LL | |     };
-   | |_____^ use of borrowed `e`
-LL |       *g = Xyz::B;
-   |       ----------- borrow later used here
+LL |     let f = &mut e;
+   |             ------ borrow of `e` occurs here
+LL |     let g = f;
+LL |     match e { //~ cannot use `e` because it was mutably borrowed [E0503]
+   |           ^ use of borrowed `e`
+...
+LL |     *g = Xyz::B;
+   |     ----------- borrow later used here
 
 error[E0503]: cannot use `e` because it was mutably borrowed
   --> $DIR/borrowed-match-issue-45045.rs:25:9
diff --git a/src/test/ui/nll/cannot-move-block-spans.nll.stderr b/src/test/ui/nll/cannot-move-block-spans.nll.stderr
new file mode 100644
index 00000000000..814e11b6f06
--- /dev/null
+++ b/src/test/ui/nll/cannot-move-block-spans.nll.stderr
@@ -0,0 +1,85 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:15:15
+   |
+LL |     let x = { *r }; //~ ERROR
+   |               ^^
+   |               |
+   |               cannot move out of borrowed content
+   |               help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:16:22
+   |
+LL |     let y = unsafe { *r }; //~ ERROR
+   |                      ^^
+   |                      |
+   |                      cannot move out of borrowed content
+   |                      help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:17:26
+   |
+LL |     let z = loop { break *r; }; //~ ERROR
+   |                          ^^
+   |                          |
+   |                          cannot move out of borrowed content
+   |                          help: consider removing this dereference operator: `r`
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:21:15
+   |
+LL |     let x = { arr[0] }; //~ ERROR
+   |               ^^^^^^
+   |               |
+   |               cannot move out of here
+   |               help: consider using a reference instead: `&arr[0]`
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:22:22
+   |
+LL |     let y = unsafe { arr[0] }; //~ ERROR
+   |                      ^^^^^^
+   |                      |
+   |                      cannot move out of here
+   |                      help: consider using a reference instead: `&arr[0]`
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:23:26
+   |
+LL |     let z = loop { break arr[0]; }; //~ ERROR
+   |                          ^^^^^^
+   |                          |
+   |                          cannot move out of here
+   |                          help: consider using a reference instead: `&arr[0]`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:27:38
+   |
+LL |     let x = { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                      ^^
+   |                                      |
+   |                                      cannot move out of borrowed content
+   |                                      help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:28:45
+   |
+LL |     let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                             ^^
+   |                                             |
+   |                                             cannot move out of borrowed content
+   |                                             help: consider removing this dereference operator: `r`
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:29:49
+   |
+LL |     let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR
+   |                                                 ^^
+   |                                                 |
+   |                                                 cannot move out of borrowed content
+   |                                                 help: consider removing this dereference operator: `r`
+
+error: aborting due to 9 previous errors
+
+Some errors occurred: E0507, E0508.
+For more information about an error, try `rustc --explain E0507`.
diff --git a/src/test/ui/nll/cannot-move-block-spans.rs b/src/test/ui/nll/cannot-move-block-spans.rs
new file mode 100644
index 00000000000..5a84a4ca48e
--- /dev/null
+++ b/src/test/ui/nll/cannot-move-block-spans.rs
@@ -0,0 +1,32 @@
+// 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.
+
+// Test that the we point to the inner expression when moving out to initialize
+// a variable, and that we don't give a useless suggestion such as &{ *r }.
+
+pub fn deref(r: &String) {
+    let x = { *r }; //~ ERROR
+    let y = unsafe { *r }; //~ ERROR
+    let z = loop { break *r; }; //~ ERROR
+}
+
+pub fn index(arr: [String; 2]) {
+    let x = { arr[0] }; //~ ERROR
+    let y = unsafe { arr[0] }; //~ ERROR
+    let z = loop { break arr[0]; }; //~ ERROR
+}
+
+pub fn additional_statement_cases(r: &String) {
+    let x = { let mut u = 0; u += 1; *r }; //~ ERROR
+    let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR
+    let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR
+}
+
+fn main() {}
diff --git a/src/test/ui/nll/cannot-move-block-spans.stderr b/src/test/ui/nll/cannot-move-block-spans.stderr
new file mode 100644
index 00000000000..d4956900239
--- /dev/null
+++ b/src/test/ui/nll/cannot-move-block-spans.stderr
@@ -0,0 +1,58 @@
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:15:15
+   |
+LL |     let x = { *r }; //~ ERROR
+   |               ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:16:22
+   |
+LL |     let y = unsafe { *r }; //~ ERROR
+   |                      ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:17:26
+   |
+LL |     let z = loop { break *r; }; //~ ERROR
+   |                          ^^ cannot move out of borrowed content
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:21:15
+   |
+LL |     let x = { arr[0] }; //~ ERROR
+   |               ^^^^^^ cannot move out of here
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:22:22
+   |
+LL |     let y = unsafe { arr[0] }; //~ ERROR
+   |                      ^^^^^^ cannot move out of here
+
+error[E0508]: cannot move out of type `[std::string::String; 2]`, a non-copy array
+  --> $DIR/cannot-move-block-spans.rs:23:26
+   |
+LL |     let z = loop { break arr[0]; }; //~ ERROR
+   |                          ^^^^^^ cannot move out of here
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:27:38
+   |
+LL |     let x = { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                      ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:28:45
+   |
+LL |     let y = unsafe { let mut u = 0; u += 1; *r }; //~ ERROR
+   |                                             ^^ cannot move out of borrowed content
+
+error[E0507]: cannot move out of borrowed content
+  --> $DIR/cannot-move-block-spans.rs:29:49
+   |
+LL |     let z = loop { let mut u = 0; u += 1; break *r; u += 2; }; //~ ERROR
+   |                                                 ^^ cannot move out of borrowed content
+
+error: aborting due to 9 previous errors
+
+Some errors occurred: E0507, E0508.
+For more information about an error, try `rustc --explain E0507`.
diff --git a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
index d6f54218360..ccf116e640d 100644
--- a/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
+++ b/src/test/ui/nll/closure-requirements/escape-argument-callee.stderr
@@ -8,10 +8,10 @@ error: unsatisfied lifetime constraints
   --> $DIR/escape-argument-callee.rs:36:45
    |
 LL |         let mut closure = expect_sig(|p, y| *p = y);
-   |                                       -  -  ^^^^^^ free region requires that `'1` must outlive `'2`
+   |                                       -  -  ^^^^^^ requires that `'1` must outlive `'2`
    |                                       |  |
-   |                                       |  lifetime `'1` appears in this argument
-   |                                       lifetime `'2` appears in this argument
+   |                                       |  has type `&'1 i32`
+   |                                       has type `&mut &'2 i32`
 
 note: No external requirements
   --> $DIR/escape-argument-callee.rs:36:38
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
index a7a50a3a029..b4508824901 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-fail-no-postdom.stderr
@@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
   --> $DIR/propagate-approximated-fail-no-postdom.rs:57:13
    |
 LL |         |_outlives1, _outlives2, _outlives3, x, y| {
-   |          ----------              ---------- lifetime `'2` appears in this argument
+   |          ----------              ---------- has type `std::cell::Cell<&'2 &u32>`
    |          |
-   |          lifetime `'1` appears in this argument
+   |          has type `std::cell::Cell<&&'1 u32>`
 ...
 LL |             demand_y(x, y, p) //~ ERROR
    |             ^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
index 3177cd7c28f..33e4240736f 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-no-bound.stderr
@@ -23,18 +23,18 @@ LL | |     });
    = note: number of external vids: 2
    = note: where '_#1r: '_#0r
 
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:45:5
    |
 LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-   |                     ------ `cell_a` is a reference that is only valid in the closure body
+   |                     ------ `cell_a` is a reference that is only valid in the function body
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
 LL | |         //~^ ERROR
 LL | |
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get()) //~ WARNING not reporting region error due to nll
 LL | |     });
-   | |______^ `cell_a` escapes the closure body here
+   | |______^ `cell_a` escapes the function body here
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-no-bound.rs:44:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
index 089c88abcdd..5f98a0fd36d 100644
--- a/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-approximated-shorter-to-static-wrong-bound.stderr
@@ -23,18 +23,18 @@ LL | |     });
    = note: number of external vids: 3
    = note: where '_#1r: '_#0r
 
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:48:5
    |
 LL |   fn supply<'a, 'b>(cell_a: Cell<&'a u32>, cell_b: Cell<&'b u32>) {
-   |                     ------ `cell_a` is a reference that is only valid in the closure body
+   |                     ------ `cell_a` is a reference that is only valid in the function body
 LL | /     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
 LL | |         //~^ ERROR
 LL | |         // Only works if 'x: 'y:
 LL | |         demand_y(x, y, x.get())
 LL | |         //~^ WARNING not reporting region error due to nll
 LL | |     });
-   | |______^ `cell_a` escapes the closure body here
+   | |______^ `cell_a` escapes the function body here
 
 note: No external requirements
   --> $DIR/propagate-approximated-shorter-to-static-wrong-bound.rs:47:1
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
index fb98c506c7d..40ebda4419b 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-no-bounds.stderr
@@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-no-bounds.rs:47:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives, x, y| {
-   |                                                ---------  - lifetime `'1` appears in this argument
+   |                                                ---------  - has type `&std::cell::Cell<&'1 u32>`
    |                                                |
-   |                                                lifetime `'2` appears in this argument
+   |                                                has type `&std::cell::Cell<&'2 &u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
index 73d39a8502b..37ea6103976 100644
--- a/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
+++ b/src/test/ui/nll/closure-requirements/propagate-fail-to-approximate-longer-wrong-bounds.stderr
@@ -8,9 +8,9 @@ error: unsatisfied lifetime constraints
   --> $DIR/propagate-fail-to-approximate-longer-wrong-bounds.rs:51:9
    |
 LL |     establish_relationships(&cell_a, &cell_b, |_outlives1, _outlives2, x, y| {
-   |                                                ----------  ---------- lifetime `'2` appears in this argument
+   |                                                ----------  ---------- has type `&std::cell::Cell<&'2 &u32>`
    |                                                |
-   |                                                lifetime `'1` appears in this argument
+   |                                                has type `&std::cell::Cell<&'1 &u32>`
 LL |         // Only works if 'x: 'y:
 LL |         demand_y(x, y, x.get())
    |         ^^^^^^^^^^^^^^^^^^^^^^^ argument requires that `'1` must outlive `'2`
diff --git a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
index d012dca2527..b0562711627 100644
--- a/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
+++ b/src/test/ui/nll/closure-requirements/region-lbr-named-does-not-outlive-static.stderr
@@ -8,7 +8,7 @@ error: unsatisfied lifetime constraints
   --> $DIR/region-lbr-named-does-not-outlive-static.rs:19:5
    |
 LL |     &*x
-   |     ^^^ free region requires that `'a` must outlive `'static`
+   |     ^^^ requires that `'a` must outlive `'static`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
index 5724cdbd8c9..d6d1645ceea 100644
--- a/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
+++ b/src/test/ui/nll/closure-requirements/return-wrong-bound-region.stderr
@@ -8,10 +8,10 @@ error: unsatisfied lifetime constraints
   --> $DIR/return-wrong-bound-region.rs:21:23
    |
 LL |     expect_sig(|a, b| b); // ought to return `a`
-   |                 -  -  ^ free region requires that `'1` must outlive `'2`
+   |                 -  -  ^ closure was supposed to return data with lifetime `'1` but it is returning data with lifetime `'2`
    |                 |  |
-   |                 |  lifetime `'1` appears in this argument
-   |                 lifetime `'2` appears in this argument
+   |                 |  has type `&'1 i32`
+   |                 has type `&'2 i32`
 
 note: No external requirements
   --> $DIR/return-wrong-bound-region.rs:21:16
diff --git a/src/test/ui/nll/issue-50716.stderr b/src/test/ui/nll/issue-50716.stderr
index 8acf2ef51ec..f12ab9b4f96 100644
--- a/src/test/ui/nll/issue-50716.stderr
+++ b/src/test/ui/nll/issue-50716.stderr
@@ -1,11 +1,11 @@
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/issue-50716.rs:25:14
    |
 LL | fn foo<'a, T: 'static>(s: Box<<&'a T as A>::X>)
-   |                        - `s` is a reference that is only valid in the closure body
+   |                        - `s` is a reference that is only valid in the function body
 ...
 LL |     let _x = *s; //~ ERROR
-   |              ^^ `s` escapes the closure body here
+   |              ^^ `s` escapes the function body here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/mir_check_cast_reify.stderr b/src/test/ui/nll/mir_check_cast_reify.stderr
index 13f90e1f159..d8f186a2232 100644
--- a/src/test/ui/nll/mir_check_cast_reify.stderr
+++ b/src/test/ui/nll/mir_check_cast_reify.stderr
@@ -4,14 +4,14 @@ warning: not reporting region error due to nll
 LL |     let f: fn(_) -> _ = foo;
    |                         ^^^
 
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/mir_check_cast_reify.rs:48:5
    |
 LL | fn bar<'a>(x: &'a u32) -> &'static u32 {
-   |            - `x` is a reference that is only valid in the closure body
+   |            - `x` is a reference that is only valid in the function body
 ...
 LL |     f(x)
-   |     ^^^^ `x` escapes the closure body here
+   |     ^^^^ `x` escapes the function body here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
index b08c6f32e6b..98c03e37814 100644
--- a/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
+++ b/src/test/ui/nll/mir_check_cast_unsafe_fn.stderr
@@ -4,14 +4,14 @@ warning: not reporting region error due to nll
 LL |     let g: unsafe fn(_) -> _ = f;
    |                                ^
 
-error: borrowed data escapes outside of closure
+error: borrowed data escapes outside of function
   --> $DIR/mir_check_cast_unsafe_fn.rs:20:14
    |
 LL | fn bar<'a>(input: &'a u32, f: fn(&'a u32) -> &'a u32) -> &'static u32 {
-   |            ----- `input` is a reference that is only valid in the closure body
+   |            ----- `input` is a reference that is only valid in the function body
 ...
 LL |     unsafe { g(input) }
-   |              ^^^^^^^^ `input` escapes the closure body here
+   |              ^^^^^^^^ `input` escapes the function body here
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs
new file mode 100644
index 00000000000..72d5127c294
--- /dev/null
+++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.rs
@@ -0,0 +1,29 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+// ignore-tidy-linelength
+
+#![feature(infer_outlives_requirements)]
+
+/*
+ * We don't infer `T: 'static` outlives relationships by default.
+ * Instead an additional feature gate `infer_static_outlives_requirements`
+ * is required.
+ */
+
+struct Foo<U> {
+    bar: Bar<U> //~ ERROR 22:5: 22:16: the parameter type `U` may not live long enough [E0310]
+}
+struct Bar<T: 'static> {
+    x: T,
+}
+
+fn main() {}
+
diff --git a/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
new file mode 100644
index 00000000000..775ac215e19
--- /dev/null
+++ b/src/test/ui/rfc-2093-infer-outlives/dont-infer-static.stderr
@@ -0,0 +1,17 @@
+error[E0310]: the parameter type `U` may not live long enough
+  --> $DIR/dont-infer-static.rs:22:5
+   |
+LL | struct Foo<U> {
+   |            - help: consider adding an explicit lifetime bound `U: 'static`...
+LL |     bar: Bar<U> //~ ERROR 22:5: 22:16: the parameter type `U` may not live long enough [E0310]
+   |     ^^^^^^^^^^^
+   |
+note: ...so that the type `U` will meet its required lifetime bounds
+  --> $DIR/dont-infer-static.rs:22:5
+   |
+LL |     bar: Bar<U> //~ ERROR 22:5: 22:16: the parameter type `U` may not live long enough [E0310]
+   |     ^^^^^^^^^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.rs b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs
new file mode 100644
index 00000000000..aeca18c24b3
--- /dev/null
+++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.rs
@@ -0,0 +1,24 @@
+// Copyright 2015 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(rustc_attrs)]
+#![feature(infer_outlives_requirements)]
+#![feature(infer_static_outlives_requirements)]
+
+#[rustc_outlives]
+struct Foo<U> { //~ ERROR 16:1: 18:2: rustc_outlives
+    bar: Bar<U>
+}
+struct Bar<T: 'static> {
+    x: T,
+}
+
+fn main() {}
+
diff --git a/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr
new file mode 100644
index 00000000000..f167e522df6
--- /dev/null
+++ b/src/test/ui/rfc-2093-infer-outlives/infer-static.stderr
@@ -0,0 +1,12 @@
+error: rustc_outlives
+  --> $DIR/infer-static.rs:16:1
+   |
+LL | / struct Foo<U> { //~ ERROR 16:1: 18:2: rustc_outlives
+LL | |     bar: Bar<U>
+LL | | }
+   | |_^
+   |
+   = note: U : 'static
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/span/issue-40157.nll.stderr b/src/test/ui/span/issue-40157.nll.stderr
index def4a308bc7..09e634ba725 100644
--- a/src/test/ui/span/issue-40157.nll.stderr
+++ b/src/test/ui/span/issue-40157.nll.stderr
@@ -2,11 +2,11 @@ error[E0597]: `foo` does not live long enough
   --> $DIR/issue-40157.rs:12:53
    |
 LL |     {println!("{:?}", match { let foo = vec![1, 2]; foo.get(1) } { x => x });}
-   |                       ------------------------------^^^--------------------
-   |                       |                             |          |
-   |                       |                             |          `foo` dropped here while still borrowed
-   |                       |                             borrowed value does not live long enough
-   |                       borrow later used here
+   |                             ------------------------^^^---------
+   |                             |                       |          |
+   |                             |                       |          `foo` dropped here while still borrowed
+   |                             |                       borrowed value does not live long enough
+   |                             borrow later used here
 
 error: aborting due to previous error
 
diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index bb20678d4a1..83b2895e1d6 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -46,9 +46,9 @@ static HOSTS: &'static [&'static str] = &[
 
 static TARGETS: &'static [&'static str] = &[
     "aarch64-apple-ios",
+    "aarch64-fuchsia",
     "aarch64-linux-android",
     "aarch64-unknown-cloudabi",
-    "aarch64-unknown-fuchsia",
     "aarch64-unknown-linux-gnu",
     "aarch64-unknown-linux-musl",
     "arm-linux-androideabi",
@@ -101,6 +101,7 @@ static TARGETS: &'static [&'static str] = &[
     "wasm32-unknown-unknown",
     "x86_64-apple-darwin",
     "x86_64-apple-ios",
+    "x86_64-fuchsia",
     "x86_64-linux-android",
     "x86_64-pc-windows-gnu",
     "x86_64-pc-windows-msvc",
@@ -108,7 +109,6 @@ static TARGETS: &'static [&'static str] = &[
     "x86_64-sun-solaris",
     "x86_64-unknown-cloudabi",
     "x86_64-unknown-freebsd",
-    "x86_64-unknown-fuchsia",
     "x86_64-unknown-linux-gnu",
     "x86_64-unknown-linux-gnux32",
     "x86_64-unknown-linux-musl",
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 506eea76edbf7198258265ddabcf320365bc4c5
+Subproject 2cd36b4ed1aef1ae39a30783e006411d1a4218a
diff --git a/src/tools/compiletest/Cargo.toml b/src/tools/compiletest/Cargo.toml
index 582ba5adfe5..6639ba51b12 100644
--- a/src/tools/compiletest/Cargo.toml
+++ b/src/tools/compiletest/Cargo.toml
@@ -13,7 +13,7 @@ regex = "0.2"
 serde = "1.0"
 serde_json = "1.0"
 serde_derive = "1.0"
-rustfix = "0.3.1"
+rustfix = "0.4.1"
 
 [target.'cfg(unix)'.dependencies]
 libc = "0.2"
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index eeb280e1de3..d77261f4959 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -14,7 +14,7 @@ use std::io::prelude::*;
 use std::io::BufReader;
 use std::path::{Path, PathBuf};
 
-use common::{self, Config, Mode};
+use common::{self, CompareMode, Config, Mode};
 use util;
 
 use extract_gdb_version;
@@ -416,7 +416,7 @@ impl TestProps {
     }
 }
 
-fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut FnMut(&str)) {
+fn iter_header(testfile: &Path, cfg: Option<&str>, it: &mut dyn FnMut(&str)) {
     if testfile.is_dir() {
         return;
     }
@@ -608,7 +608,12 @@ impl Config {
                     common::DebugInfoLldb => name == "lldb",
                     common::Pretty => name == "pretty",
                     _ => false,
-                } || (self.target != self.host && name == "cross-compile")
+                } || (self.target != self.host && name == "cross-compile") ||
+                match self.compare_mode {
+                    Some(CompareMode::Nll) => name == "compare-mode-nll",
+                    Some(CompareMode::Polonius) => name == "compare-mode-polonius",
+                    None => false,
+                }
         } else {
             false
         }
diff --git a/src/tools/compiletest/src/read2.rs b/src/tools/compiletest/src/read2.rs
index 5bf898f5f1b..f056a041c13 100644
--- a/src/tools/compiletest/src/read2.rs
+++ b/src/tools/compiletest/src/read2.rs
@@ -21,7 +21,7 @@ mod imp {
     pub fn read2(
         out_pipe: ChildStdout,
         err_pipe: ChildStderr,
-        data: &mut FnMut(bool, &mut Vec<u8>, bool),
+        data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
     ) -> io::Result<()> {
         let mut buffer = Vec::new();
         out_pipe.read_to_end(&mut buffer)?;
@@ -45,7 +45,7 @@ mod imp {
     pub fn read2(
         mut out_pipe: ChildStdout,
         mut err_pipe: ChildStderr,
-        data: &mut FnMut(bool, &mut Vec<u8>, bool),
+        data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
     ) -> io::Result<()> {
         unsafe {
             libc::fcntl(out_pipe.as_raw_fd(), libc::F_SETFL, libc::O_NONBLOCK);
@@ -133,7 +133,7 @@ mod imp {
     pub fn read2(
         out_pipe: ChildStdout,
         err_pipe: ChildStderr,
-        data: &mut FnMut(bool, &mut Vec<u8>, bool),
+        data: &mut dyn FnMut(bool, &mut Vec<u8>, bool),
     ) -> io::Result<()> {
         let mut out = Vec::new();
         let mut err = Vec::new();
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index ad86844cec3..ce7828144cd 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -21,7 +21,7 @@ use filetime::FileTime;
 use header::TestProps;
 use json;
 use regex::Regex;
-use rustfix::{apply_suggestions, get_suggestions_from_json};
+use rustfix::{apply_suggestions, get_suggestions_from_json, Filter};
 use util::{logv, PathBufExt};
 
 use std::collections::hash_map::DefaultHasher;
@@ -2621,7 +2621,11 @@ impl<'test> TestCx<'test> {
             let unfixed_code = self
                 .load_expected_output_from_path(&self.testpaths.file)
                 .unwrap();
-            let suggestions = get_suggestions_from_json(&proc_res.stderr, &HashSet::new()).unwrap();
+            let suggestions = get_suggestions_from_json(
+                &proc_res.stderr,
+                &HashSet::new(),
+                Filter::Everything,
+            ).unwrap();
             let fixed_code = apply_suggestions(&unfixed_code, &suggestions).expect(&format!(
                 "failed to apply suggestions for {:?} with rustfix",
                 self.testpaths.file
diff --git a/src/tools/error_index_generator/main.rs b/src/tools/error_index_generator/main.rs
index ade7ae0a4ae..e72f90554d3 100644
--- a/src/tools/error_index_generator/main.rs
+++ b/src/tools/error_index_generator/main.rs
@@ -44,18 +44,18 @@ impl OutputFormat {
 }
 
 trait Formatter {
-    fn header(&self, output: &mut Write) -> Result<(), Box<Error>>;
-    fn title(&self, output: &mut Write) -> Result<(), Box<Error>>;
-    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
-                        err_code: &str) -> Result<(), Box<Error>>;
-    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>>;
+    fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
+    fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
+    fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata,
+                        err_code: &str) -> Result<(), Box<dyn Error>>;
+    fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>>;
 }
 
 struct HTMLFormatter;
 struct MarkdownFormatter;
 
 impl Formatter for HTMLFormatter {
-    fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
+    fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
         write!(output, r##"<!DOCTYPE html>
 <html>
 <head>
@@ -75,13 +75,13 @@ impl Formatter for HTMLFormatter {
         Ok(())
     }
 
-    fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
+    fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
         write!(output, "<h1>Rust Compiler Error Index</h1>\n")?;
         Ok(())
     }
 
-    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
-                        err_code: &str) -> Result<(), Box<Error>> {
+    fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata,
+                        err_code: &str) -> Result<(), Box<dyn Error>> {
         // Enclose each error in a div so they can be shown/hidden en masse.
         let desc_desc = match info.description {
             Some(_) => "error-described",
@@ -108,7 +108,7 @@ impl Formatter for HTMLFormatter {
         Ok(())
     }
 
-    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
+    fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
         write!(output, r##"<script>
 function onEach(arr, func) {{
     if (arr && arr.length > 0 && func) {{
@@ -174,17 +174,17 @@ onEach(document.getElementsByClassName('rust-example-rendered'), function(e) {{
 
 impl Formatter for MarkdownFormatter {
     #[allow(unused_variables)]
-    fn header(&self, output: &mut Write) -> Result<(), Box<Error>> {
+    fn header(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
         Ok(())
     }
 
-    fn title(&self, output: &mut Write) -> Result<(), Box<Error>> {
+    fn title(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
         write!(output, "# Rust Compiler Error Index\n")?;
         Ok(())
     }
 
-    fn error_code_block(&self, output: &mut Write, info: &ErrorMetadata,
-                        err_code: &str) -> Result<(), Box<Error>> {
+    fn error_code_block(&self, output: &mut dyn Write, info: &ErrorMetadata,
+                        err_code: &str) -> Result<(), Box<dyn Error>> {
         Ok(match info.description {
             Some(ref desc) => write!(output, "## {}\n{}\n", err_code, desc)?,
             None => (),
@@ -192,13 +192,13 @@ impl Formatter for MarkdownFormatter {
     }
 
     #[allow(unused_variables)]
-    fn footer(&self, output: &mut Write) -> Result<(), Box<Error>> {
+    fn footer(&self, output: &mut dyn Write) -> Result<(), Box<dyn Error>> {
         Ok(())
     }
 }
 
 /// Load all the metadata files from `metadata_dir` into an in-memory map.
-fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>> {
+fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<dyn Error>> {
     let mut all_errors = BTreeMap::new();
 
     for entry in read_dir(metadata_dir)? {
@@ -219,7 +219,7 @@ fn load_all_errors(metadata_dir: &Path) -> Result<ErrorMetadataMap, Box<Error>>
 
 /// Output an HTML page for the errors in `err_map` to `output_path`.
 fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Path,
-                                   formatter: T) -> Result<(), Box<Error>> {
+                                   formatter: T) -> Result<(), Box<dyn Error>> {
     let mut output_file = File::create(output_path)?;
 
     formatter.header(&mut output_file)?;
@@ -232,7 +232,7 @@ fn render_error_page<T: Formatter>(err_map: &ErrorMetadataMap, output_path: &Pat
     formatter.footer(&mut output_file)
 }
 
-fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<Error>> {
+fn main_with_result(format: OutputFormat, dst: &Path) -> Result<(), Box<dyn Error>> {
     let build_arch = env::var("CFG_BUILD")?;
     let metadata_dir = get_metadata_dir(&build_arch);
     let err_map = load_all_errors(&metadata_dir)?;
diff --git a/src/tools/remote-test-client/src/main.rs b/src/tools/remote-test-client/src/main.rs
index 2f5275bb5be..011bf551140 100644
--- a/src/tools/remote-test-client/src/main.rs
+++ b/src/tools/remote-test-client/src/main.rs
@@ -177,7 +177,7 @@ fn start_qemu_emulator(target: &str,
         _ => panic!("cannot start emulator for: {}"< target),
     }
 
-    fn add_files(w: &mut Write, root: &Path, cur: &Path) {
+    fn add_files(w: &mut dyn Write, root: &Path, cur: &Path) {
         for entry in t!(cur.read_dir()) {
             let entry = t!(entry);
             let path = entry.path();
@@ -297,7 +297,7 @@ fn run(files: String, args: Vec<String>) {
     }
 }
 
-fn send(path: &Path, dst: &mut Write) {
+fn send(path: &Path, dst: &mut dyn Write) {
     t!(dst.write_all(path.file_name().unwrap().to_str().unwrap().as_bytes()));
     t!(dst.write_all(&[0]));
     let mut file = t!(File::open(&path));
diff --git a/src/tools/remote-test-server/src/main.rs b/src/tools/remote-test-server/src/main.rs
index ae13acd58bb..5116f6662ff 100644
--- a/src/tools/remote-test-server/src/main.rs
+++ b/src/tools/remote-test-server/src/main.rs
@@ -270,7 +270,7 @@ fn recv<B: BufRead>(dir: &Path, io: &mut B) -> PathBuf {
     return dst
 }
 
-fn my_copy(src: &mut Read, which: u8, dst: &Mutex<Write>) {
+fn my_copy(src: &mut dyn Read, which: u8, dst: &Mutex<dyn Write>) {
     let mut b = [0; 1024];
     loop {
         let n = t!(src.read(&mut b));
@@ -290,7 +290,7 @@ fn my_copy(src: &mut Read, which: u8, dst: &Mutex<Write>) {
     }
 }
 
-fn read_u32(r: &mut Read) -> u32 {
+fn read_u32(r: &mut dyn Read) -> u32 {
     let mut len = [0; 4];
     t!(r.read_exact(&mut len));
     ((len[0] as u32) << 24) |
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 5105fc4ca4c..1a2e0f7fb24 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -26,6 +26,7 @@ static LICENSES: &'static [&'static str] = &[
     "MIT OR Apache-2.0",
     "MIT",
     "Unlicense/MIT",
+    "Unlicense OR MIT",
 ];
 
 /// These are exceptions to Rust's permissive licensing policy, and
diff --git a/src/tools/tidy/src/features.rs b/src/tools/tidy/src/features.rs
index c9bc1b9d849..f68ba0b095b 100644
--- a/src/tools/tidy/src/features.rs
+++ b/src/tools/tidy/src/features.rs
@@ -334,7 +334,7 @@ fn get_and_check_lib_features(base_src_path: &Path,
 }
 
 fn map_lib_features(base_src_path: &Path,
-                    mf: &mut FnMut(Result<(&str, Feature), &str>, &Path, usize)) {
+                    mf: &mut dyn FnMut(Result<(&str, Feature), &str>, &Path, usize)) {
     let mut contents = String::new();
     super::walk(base_src_path,
                 &mut |path| super::filter_dirs(path) || path.ends_with("src/test"),
diff --git a/src/tools/tidy/src/lib.rs b/src/tools/tidy/src/lib.rs
index 46217a42009..bb041b39785 100644
--- a/src/tools/tidy/src/lib.rs
+++ b/src/tools/tidy/src/lib.rs
@@ -82,13 +82,13 @@ fn filter_dirs(path: &Path) -> bool {
     skip.iter().any(|p| path.ends_with(p))
 }
 
-fn walk_many(paths: &[&Path], skip: &mut FnMut(&Path) -> bool, f: &mut FnMut(&Path)) {
+fn walk_many(paths: &[&Path], skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
     for path in paths {
         walk(path, skip, f);
     }
 }
 
-fn walk(path: &Path, skip: &mut FnMut(&Path) -> bool, f: &mut FnMut(&Path)) {
+fn walk(path: &Path, skip: &mut dyn FnMut(&Path) -> bool, f: &mut dyn FnMut(&Path)) {
     for entry in t!(fs::read_dir(path), path) {
         let entry = t!(entry);
         let kind = t!(entry.file_type());