about summary refs log tree commit diff
diff options
context:
space:
mode:
authorBaoshan <pangbw@gmail.com>2019-09-05 22:42:04 -0700
committerGitHub <noreply@github.com>2019-09-05 22:42:04 -0700
commit414d1047291348b5b8bf49e1d76fec978238d89f (patch)
tree7894264d7d7758bbfe15952b598cabd05da75911
parent109e16e8574a4fc47bf7c1d26b6000731002bc34 (diff)
parent618768492f0c731fcb770dc2d178abe840846419 (diff)
downloadrust-414d1047291348b5b8bf49e1d76fec978238d89f.tar.gz
rust-414d1047291348b5b8bf49e1d76fec978238d89f.zip
Merge pull request #17 from rust-lang/master
sync with rust-lang/rust master branch
-rw-r--r--Cargo.lock21
m---------src/doc/embedded-book0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
-rw-r--r--src/doc/rustc/src/linker-plugin-lto.md1
-rw-r--r--src/doc/unstable-book/src/language-features/plugin.md6
-rw-r--r--src/libcore/char/methods.rs23
-rw-r--r--src/libcore/cmp.rs20
-rw-r--r--src/libcore/iter/adapters/mod.rs7
-rw-r--r--src/libcore/pin.rs4
-rw-r--r--src/libcore/result.rs81
-rw-r--r--src/libcore/tests/iter.rs6
-rw-r--r--src/libcore/unicode/mod.rs5
-rw-r--r--src/libcore/unicode/tables.rs375
-rwxr-xr-xsrc/libcore/unicode/unicode.py9
-rw-r--r--src/libfmt_macros/Cargo.toml2
-rw-r--r--src/libfmt_macros/lib.rs9
-rw-r--r--src/librustc/Cargo.toml2
-rw-r--r--src/librustc/error_codes.rs2
-rw-r--r--src/librustc/hir/map/collector.rs2
-rw-r--r--src/librustc/ich/impls_syntax.rs23
-rw-r--r--src/librustc/infer/error_reporting/mod.rs13
-rw-r--r--src/librustc/lint/context.rs4
-rw-r--r--src/librustc/lint/levels.rs2
-rw-r--r--src/librustc/mir/mod.rs25
-rw-r--r--src/librustc/traits/error_reporting.rs5
-rw-r--r--src/librustc/traits/object_safety.rs72
-rw-r--r--src/librustc/traits/on_unimplemented.rs19
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc/ty/util.rs6
-rw-r--r--src/librustc_codegen_llvm/builder.rs8
-rw-r--r--src/librustc_codegen_llvm/callee.rs2
-rw-r--r--src/librustc_codegen_llvm/common.rs15
-rw-r--r--src/librustc_codegen_llvm/consts.rs15
-rw-r--r--src/librustc_codegen_llvm/context.rs4
-rw-r--r--src/librustc_codegen_llvm/debuginfo/metadata.rs2
-rw-r--r--src/librustc_codegen_llvm/debuginfo/mod.rs2
-rw-r--r--src/librustc_codegen_llvm/intrinsic.rs2
-rw-r--r--src/librustc_codegen_ssa/back/symbol_export.rs2
-rw-r--r--src/librustc_codegen_ssa/mir/block.rs15
-rw-r--r--src/librustc_codegen_ssa/mir/mod.rs4
-rw-r--r--src/librustc_codegen_ssa/mir/operand.rs1
-rw-r--r--src/librustc_codegen_ssa/mir/place.rs22
-rw-r--r--src/librustc_codegen_ssa/mir/rvalue.rs2
-rw-r--r--src/librustc_codegen_ssa/mono_item.rs2
-rw-r--r--src/librustc_codegen_ssa/traits/statics.rs6
-rw-r--r--src/librustc_codegen_utils/symbol_names_test.rs2
-rw-r--r--src/librustc_lexer/Cargo.toml8
-rw-r--r--src/librustc_lexer/src/lib.rs142
-rw-r--r--src/librustc_lint/unused.rs81
-rw-r--r--src/librustc_llvm/build.rs6
-rw-r--r--src/librustc_metadata/encoder.rs2
-rw-r--r--src/librustc_mir/Cargo.toml3
-rw-r--r--src/librustc_mir/borrow_check/error_reporting.rs2
-rw-r--r--src/librustc_mir/borrow_check/flows.rs4
-rw-r--r--src/librustc_mir/borrow_check/move_errors.rs4
-rw-r--r--src/librustc_mir/borrow_check/mutability_errors.rs3
-rw-r--r--src/librustc_mir/borrow_check/nll/facts.rs17
-rw-r--r--src/librustc_mir/borrow_check/nll/mod.rs87
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs22
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs4
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs67
-rw-r--r--src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs100
-rw-r--r--src/librustc_mir/borrow_check/path_utils.rs23
-rw-r--r--src/librustc_mir/dataflow/impls/borrowed_locals.rs17
-rw-r--r--src/librustc_mir/dataflow/move_paths/abs_domain.rs40
-rw-r--r--src/librustc_mir/dataflow/move_paths/builder.rs200
-rw-r--r--src/librustc_mir/dataflow/move_paths/mod.rs47
-rw-r--r--src/librustc_mir/interpret/place.rs5
-rw-r--r--src/librustc_mir/monomorphize/partitioning.rs2
-rw-r--r--src/librustc_mir/transform/const_prop.rs13
-rw-r--r--src/librustc_target/spec/linux_kernel_base.rs26
-rw-r--r--src/librustc_target/spec/mod.rs3
-rw-r--r--src/librustc_target/spec/x86_64_linux_kernel.rs31
-rw-r--r--src/librustc_typeck/check/expr.rs8
-rw-r--r--src/librustc_typeck/check/mod.rs47
-rw-r--r--src/librustc_typeck/check/wfcheck.rs36
-rw-r--r--src/librustc_typeck/error_codes.rs84
-rw-r--r--src/librustdoc/html/static/main.js2
-rw-r--r--src/librustdoc/lib.rs1
-rw-r--r--src/librustdoc/passes/check_code_block_syntax.rs2
-rw-r--r--src/librustdoc/passes/collect_intra_doc_links.rs4
-rw-r--r--src/librustdoc/passes/mod.rs21
-rw-r--r--src/librustdoc/test.rs4
-rw-r--r--src/libstd/io/mod.rs8
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/sys/sgx/condvar.rs3
-rw-r--r--src/libstd/sys/sgx/mutex.rs4
-rw-r--r--src/libstd/sys/sgx/rwlock.rs34
-rw-r--r--src/libstd/sys/sgx/waitqueue.rs11
-rw-r--r--src/libstd/time.rs6
-rw-r--r--src/libsyntax/diagnostics/plugin.rs46
-rw-r--r--src/libsyntax/ext/base.rs27
-rw-r--r--src/libsyntax/ext/expand.rs2
-rw-r--r--src/libsyntax/ext/proc_macro_server.rs3
-rw-r--r--src/libsyntax/parse/parser/expr.rs56
-rw-r--r--src/libsyntax/print/pprust.rs6
-rw-r--r--src/libsyntax/tests.rs14
-rw-r--r--src/libsyntax/tokenstream.rs2
-rw-r--r--src/libsyntax_ext/Cargo.toml1
-rw-r--r--src/libsyntax_ext/asm.rs24
-rw-r--r--src/libsyntax_ext/assert.rs6
-rw-r--r--src/libsyntax_ext/cfg.rs6
-rw-r--r--src/libsyntax_ext/compile_error.rs4
-rw-r--r--src/libsyntax_ext/concat.rs6
-rw-r--r--src/libsyntax_ext/concat_idents.rs16
-rw-r--r--src/libsyntax_ext/env.rs6
-rw-r--r--src/libsyntax_ext/format.rs10
-rw-r--r--src/libsyntax_ext/global_asm.rs6
-rw-r--r--src/libsyntax_ext/lib.rs6
-rw-r--r--src/libsyntax_ext/log_syntax.rs6
-rw-r--r--src/libsyntax_ext/source_util.rs18
-rw-r--r--src/libsyntax_ext/trace_macros.rs27
-rw-r--r--src/libsyntax_pos/symbol.rs84
-rw-r--r--src/test/rustdoc/auxiliary/through-proc-macro-aux.rs20
-rw-r--r--src/test/rustdoc/through-proc-macro.rs12
-rw-r--r--src/test/ui-fulldeps/auxiliary/roman-numerals.rs6
-rw-r--r--src/test/ui/associated-const/associated-const-in-trait.stderr5
-rw-r--r--src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs13
-rw-r--r--src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr19
-rw-r--r--src/test/ui/async-await/recursive-async-impl-trait-type.stderr4
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr4
-rw-r--r--src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr4
-rw-r--r--src/test/ui/consts/const-err2.rs3
-rw-r--r--src/test/ui/consts/const-err2.stderr12
-rw-r--r--src/test/ui/consts/const-err3.rs30
-rw-r--r--src/test/ui/consts/const-err3.stderr38
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors.rs2
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors2.rs22
-rw-r--r--src/test/ui/consts/const-eval/promoted_errors2.stderr68
-rw-r--r--src/test/ui/consts/issue-64059-2.rs6
-rw-r--r--src/test/ui/consts/issue-64059.rs5
-rw-r--r--src/test/ui/did_you_mean/issue-40006.stderr5
-rw-r--r--src/test/ui/error-codes/E0033-teach.rs3
-rw-r--r--src/test/ui/error-codes/E0033-teach.stderr7
-rw-r--r--src/test/ui/error-codes/E0033.rs3
-rw-r--r--src/test/ui/error-codes/E0033.stderr7
-rw-r--r--src/test/ui/error-codes/E0038.stderr5
-rw-r--r--src/test/ui/explicit/explicit-self-lifetime-mismatch.rs4
-rw-r--r--src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr4
-rw-r--r--src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs25
-rw-r--r--src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr35
-rw-r--r--src/test/ui/issues/issue-17740.rs4
-rw-r--r--src/test/ui/issues/issue-17740.stderr4
-rw-r--r--src/test/ui/issues/issue-17905-2.rs4
-rw-r--r--src/test/ui/issues/issue-17905-2.stderr4
-rw-r--r--src/test/ui/issues/issue-18959.stderr5
-rw-r--r--src/test/ui/issues/issue-19380.stderr5
-rw-r--r--src/test/ui/issues/issue-19538.stderr9
-rw-r--r--src/test/ui/issues/issue-50781.stderr4
-rw-r--r--src/test/ui/issues/issue-56806.rs5
-rw-r--r--src/test/ui/issues/issue-56806.stderr5
-rw-r--r--src/test/ui/issues/issue-8460-const.rs2
-rw-r--r--src/test/ui/issues/issue-8460-const.stderr82
-rw-r--r--src/test/ui/issues/issue-8460-const2.rs59
-rw-r--r--src/test/ui/issues/issue-8460-const2.stderr188
-rw-r--r--src/test/ui/lint/issue-54538-unused-parens-lint.rs90
-rw-r--r--src/test/ui/lint/issue-54538-unused-parens-lint.stderr149
-rw-r--r--src/test/ui/object-safety/object-safety-associated-consts.stderr5
-rw-r--r--src/test/ui/object-safety/object-safety-generics.stderr10
-rw-r--r--src/test/ui/object-safety/object-safety-mentions-Self.stderr10
-rw-r--r--src/test/ui/object-safety/object-safety-no-static.stderr5
-rw-r--r--src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs31
-rw-r--r--src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr68
-rw-r--r--src/test/ui/resolve/issue-3907-2.stderr2
-rw-r--r--src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs84
-rw-r--r--src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr28
-rw-r--r--src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs11
-rw-r--r--src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs60
-rw-r--r--src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr228
-rw-r--r--src/test/ui/self/arbitrary-self-types-not-object-safe.stderr9
-rw-r--r--src/test/ui/span/issue-27522.rs2
-rw-r--r--src/test/ui/span/issue-27522.stderr5
-rw-r--r--src/test/ui/suggestions/opaque-type-error.stderr4
-rw-r--r--src/test/ui/traits/trait-item-privacy.stderr13
-rw-r--r--src/test/ui/traits/trait-object-safety.stderr9
-rw-r--r--src/test/ui/traits/trait-test-2.stderr15
-rw-r--r--src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr5
-rw-r--r--src/test/ui/ufcs/ufcs-explicit-self-bad.rs14
-rw-r--r--src/test/ui/ufcs/ufcs-explicit-self-bad.stderr23
-rw-r--r--src/test/ui/underscore-imports/auxiliary/duplicate.rs (renamed from src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs)0
-rw-r--r--src/test/ui/underscore-imports/auxiliary/underscore-imports.rs (renamed from src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs)0
-rw-r--r--src/test/ui/underscore-imports/basic.rs (renamed from src/test/ui/rfc-2166-underscore-imports/basic.rs)0
-rw-r--r--src/test/ui/underscore-imports/basic.stderr (renamed from src/test/ui/rfc-2166-underscore-imports/basic.stderr)0
-rw-r--r--src/test/ui/underscore-imports/cycle.rs18
-rw-r--r--src/test/ui/underscore-imports/duplicate.rs (renamed from src/test/ui/rfc-2166-underscore-imports/duplicate.rs)0
-rw-r--r--src/test/ui/underscore-imports/intercrate.rs (renamed from src/test/ui/rfc-2166-underscore-imports/intercrate.rs)0
-rw-r--r--src/test/ui/underscore-imports/shadow.rs23
-rw-r--r--src/test/ui/underscore-imports/shadow.stderr13
-rw-r--r--src/test/ui/underscore-imports/unused-2018.rs (renamed from src/test/ui/rfc-2166-underscore-imports/unused-2018.rs)0
-rw-r--r--src/test/ui/underscore-imports/unused-2018.stderr (renamed from src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr)0
-rw-r--r--src/test/ui/wf/wf-object-safe.stderr5
m---------src/tools/cargo0
m---------src/tools/clippy16
-rw-r--r--src/tools/compiletest/src/common.rs4
-rw-r--r--src/tools/compiletest/src/header.rs16
-rw-r--r--src/tools/compiletest/src/runtest.rs96
-rw-r--r--src/tools/tidy/src/features/tests.rs4
198 files changed, 2724 insertions, 1575 deletions
diff --git a/Cargo.lock b/Cargo.lock
index e0d30647809..243a326646c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -1011,6 +1011,7 @@ dependencies = [
 name = "fmt_macros"
 version = "0.0.0"
 dependencies = [
+ "rustc_lexer",
  "syntax_pos",
 ]
 
@@ -2324,9 +2325,9 @@ checksum = "676e8eb2b1b4c9043511a9b7bea0915320d7e502b0a079fb03f9635a5252b18c"
 
 [[package]]
 name = "polonius-engine"
-version = "0.9.0"
+version = "0.10.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "f6b8a5defa2aef9ba4999aaa745fbc01c622ecea35964a306adc3e44be4f3b5b"
+checksum = "50fa9dbfd0d3d60594da338cfe6f94028433eecae4b11b7e83fd99759227bbfe"
 dependencies = [
  "datafrog",
  "log",
@@ -2372,7 +2373,7 @@ version = "0.4.30"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "cf3d2011ab5c909338f7887f4fc896d35932e29146c12c8d01da6b22a80ba759"
 dependencies = [
- "unicode-xid",
+ "unicode-xid 0.1.0",
 ]
 
 [[package]]
@@ -3290,7 +3291,7 @@ dependencies = [
 name = "rustc_lexer"
 version = "0.1.0"
 dependencies = [
- "unicode-xid",
+ "unicode-xid 0.2.0",
 ]
 
 [[package]]
@@ -3368,6 +3369,7 @@ dependencies = [
  "rustc_apfloat",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_lexer",
  "rustc_target",
  "serialize",
  "smallvec",
@@ -3976,7 +3978,7 @@ checksum = "641e117d55514d6d918490e47102f7e08d096fdde360247e4a10f7a91a8478d3"
 dependencies = [
  "proc-macro2",
  "quote",
- "unicode-xid",
+ "unicode-xid 0.1.0",
 ]
 
 [[package]]
@@ -3988,7 +3990,7 @@ dependencies = [
  "proc-macro2",
  "quote",
  "syn",
- "unicode-xid",
+ "unicode-xid 0.1.0",
 ]
 
 [[package]]
@@ -4017,6 +4019,7 @@ dependencies = [
  "log",
  "rustc_data_structures",
  "rustc_errors",
+ "rustc_lexer",
  "rustc_target",
  "smallvec",
  "syntax",
@@ -4533,6 +4536,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "fc72304796d0818e357ead4e000d19c9c174ab23dc11093ac919054d20a6a7fc"
 
 [[package]]
+name = "unicode-xid"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c"
+
+[[package]]
 name = "unicode_categories"
 version = "0.1.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/src/doc/embedded-book b/src/doc/embedded-book
-Subproject 432ca26686c11d396eed6a59499f93ce1bf2433
+Subproject 5ca585c4a7552efb546e7681c3de0712f4ae4fd
diff --git a/src/doc/reference b/src/doc/reference
-Subproject d191a0cdd3b92648e0f1e53b13140a14677cc65
+Subproject 090c015f7939665866432c334957bd536c81187
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject 580839d90aacd537f0293697096fa8355bc4e67
+Subproject e76be6b2dc84c6a992e186157efe29d625e29b9
diff --git a/src/doc/rustc/src/linker-plugin-lto.md b/src/doc/rustc/src/linker-plugin-lto.md
index 2ae726c4ba6..6f1bbe60569 100644
--- a/src/doc/rustc/src/linker-plugin-lto.md
+++ b/src/doc/rustc/src/linker-plugin-lto.md
@@ -105,5 +105,6 @@ The following table shows known good combinations of toolchain versions.
 | Rust 1.34 |     ✗     |     ✓     |
 | Rust 1.35 |     ✗     |     ✓     |
 | Rust 1.36 |     ✗     |     ✓     |
+| Rust 1.37 |     ✗     |     ✓     |
 
 Note that the compatibility policy for this feature might change in the future.
diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md
index 53e8393ec52..68877b48433 100644
--- a/src/doc/unstable-book/src/language-features/plugin.md
+++ b/src/doc/unstable-book/src/language-features/plugin.md
@@ -57,12 +57,12 @@ extern crate rustc;
 extern crate rustc_driver;
 
 use syntax::parse::token::{self, Token};
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax_pos::Span;
 use rustc_driver::plugin::Registry;
 
-fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: TokenStream)
         -> Box<dyn MacResult + 'static> {
 
     static NUMERALS: &'static [(&'static str, usize)] = &[
@@ -78,7 +78,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         return DummyResult::any(sp);
     }
 
-    let text = match args[0] {
+    let text = match args.into_trees().next().unwrap() {
         TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
diff --git a/src/libcore/char/methods.rs b/src/libcore/char/methods.rs
index e91bf53c5b4..a69eb0f6d4b 100644
--- a/src/libcore/char/methods.rs
+++ b/src/libcore/char/methods.rs
@@ -547,29 +547,6 @@ impl char {
         }
     }
 
-    /// Returns `true` if this `char` satisfies the `XID_Start` Unicode property, and false
-    /// otherwise.
-    ///
-    /// `XID_Start` is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to `ID_Start` but modified for closure under `NFKx`.
-    #[unstable(feature = "unicode_internals", issue = "0")]
-    pub fn is_xid_start(self) -> bool {
-        derived_property::XID_Start(self)
-    }
-
-    /// Returns `true` if this `char` satisfies the `XID_Continue` Unicode property, and false
-    /// otherwise.
-    ///
-    /// `XID_Continue` is a Unicode Derived Property specified in
-    /// [UAX #31](http://unicode.org/reports/tr31/#NFKC_Modifications),
-    /// mostly similar to `ID_Continue` but modified for closure under NFKx.
-    #[unstable(feature = "unicode_internals", issue = "0")]
-    #[inline]
-    pub fn is_xid_continue(self) -> bool {
-        derived_property::XID_Continue(self)
-    }
-
     /// Returns `true` if this `char` is lowercase.
     ///
     /// 'Lowercase' is defined according to the terms of the Unicode Derived Core
diff --git a/src/libcore/cmp.rs b/src/libcore/cmp.rs
index 607427a85d6..7ec2295f97e 100644
--- a/src/libcore/cmp.rs
+++ b/src/libcore/cmp.rs
@@ -9,14 +9,22 @@
 //! * [`Ord`] and [`PartialOrd`] are traits that allow you to define total and
 //!   partial orderings between values, respectively. Implementing them overloads
 //!   the `<`, `<=`, `>`, and `>=` operators.
-//! * [`Ordering`][cmp::Ordering] is an enum returned by the
-//!   main functions of [`Ord`] and [`PartialOrd`], and describes an ordering.
-//! * [`Reverse`][cmp::Reverse] is a struct that allows you to easily reverse
-//!   an ordering.
-//! * [`max`][cmp::max] and [`min`][cmp::min] are functions that build off of
-//!   [`Ord`] and allow you to find the maximum or minimum of two values.
+//! * [`Ordering`] is an enum returned by the main functions of [`Ord`] and
+//!   [`PartialOrd`], and describes an ordering.
+//! * [`Reverse`] is a struct that allows you to easily reverse an ordering.
+//! * [`max`] and [`min`] are functions that build off of [`Ord`] and allow you
+//!   to find the maximum or minimum of two values.
 //!
 //! For more details, see the respective documentation of each item in the list.
+//!
+//! [`Eq`]: trait.Eq.html
+//! [`PartialEq`]: trait.PartialEq.html
+//! [`Ord`]: trait.Ord.html
+//! [`PartialOrd`]: trait.PartialOrd.html
+//! [`Ordering`]: enum.Ordering.html
+//! [`Reverse`]: struct.Reverse.html
+//! [`max`]: fn.max.html
+//! [`min`]: fn.min.html
 
 #![stable(feature = "rust1", since = "1.0.0")]
 
diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs
index f50781890ab..8e1ac6082c8 100644
--- a/src/libcore/iter/adapters/mod.rs
+++ b/src/libcore/iter/adapters/mod.rs
@@ -66,13 +66,6 @@ impl<I> Iterator for Rev<I> where I: DoubleEndedIterator {
     {
         self.iter.rfind(predicate)
     }
-
-    #[inline]
-    fn rposition<P>(&mut self, predicate: P) -> Option<usize> where
-        P: FnMut(Self::Item) -> bool
-    {
-        self.iter.position(predicate)
-    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs
index 6efeaf9ee7d..1080fd32a88 100644
--- a/src/libcore/pin.rs
+++ b/src/libcore/pin.rs
@@ -462,7 +462,7 @@ impl<P: Deref<Target: Unpin>> Pin<P> {
     /// can ignore the pinning invariants when unwrapping it.
     ///
     /// [`Unpin`]: ../../std/marker/trait.Unpin.html
-    #[unstable(feature = "pin_into_inner", issue = "60245")]
+    #[stable(feature = "pin_into_inner", since = "1.39.0")]
     #[inline(always)]
     pub fn into_inner(pin: Pin<P>) -> P {
         pin.pointer
@@ -569,7 +569,7 @@ impl<P: Deref> Pin<P> {
     ///
     /// [`Unpin`]: ../../std/marker/trait.Unpin.html
     /// [`Pin::into_inner`]: #method.into_inner
-    #[unstable(feature = "pin_into_inner", issue = "60245")]
+    #[stable(feature = "pin_into_inner", since = "1.39.0")]
     #[inline(always)]
     pub unsafe fn into_inner_unchecked(pin: Pin<P>) -> P {
         pin.pointer
diff --git a/src/libcore/result.rs b/src/libcore/result.rs
index 8c60a9c1b50..ed40a5f31d9 100644
--- a/src/libcore/result.rs
+++ b/src/libcore/result.rs
@@ -820,6 +820,87 @@ impl<T, E> Result<T, E> {
     }
 }
 
+impl<T: Copy, E> Result<&T, E> {
+    /// Maps a `Result<&T, E>` to a `Result<T, E>` by copying the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// let val = 12;
+    /// let x: Result<&i32, i32> = Ok(&val);
+    /// assert_eq!(x, Ok(&12));
+    /// let copied = x.copied();
+    /// assert_eq!(copied, Ok(12));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E> {
+        self.map(|&t| t)
+    }
+}
+
+impl<T: Copy, E> Result<&mut T, E> {
+    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by copying the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_copied)]
+    /// let mut val = 12;
+    /// let x: Result<&mut i32, i32> = Ok(&mut val);
+    /// assert_eq!(x, Ok(&mut 12));
+    /// let copied = x.copied();
+    /// assert_eq!(copied, Ok(12));
+    /// ```
+    #[unstable(feature = "result_copied", reason = "newly added", issue = "63168")]
+    pub fn copied(self) -> Result<T, E> {
+        self.map(|&mut t| t)
+    }
+}
+
+impl<T: Clone, E> Result<&T, E> {
+    /// Maps a `Result<&T, E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// let val = 12;
+    /// let x: Result<&i32, i32> = Ok(&val);
+    /// assert_eq!(x, Ok(&12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Ok(12));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E> {
+        self.map(|t| t.clone())
+    }
+}
+
+impl<T: Clone, E> Result<&mut T, E> {
+    /// Maps a `Result<&mut T, E>` to a `Result<T, E>` by cloning the contents of the
+    /// `Ok` part.
+    ///
+    /// # Examples
+    ///
+    /// ```
+    /// #![feature(result_cloned)]
+    /// let mut val = 12;
+    /// let x: Result<&mut i32, i32> = Ok(&mut val);
+    /// assert_eq!(x, Ok(&mut 12));
+    /// let cloned = x.cloned();
+    /// assert_eq!(cloned, Ok(12));
+    /// ```
+    #[unstable(feature = "result_cloned", reason = "newly added", issue = "63168")]
+    pub fn cloned(self) -> Result<T, E> {
+        self.map(|t| t.clone())
+    }
+}
+
+
 impl<T, E: fmt::Debug> Result<T, E> {
     /// Unwraps a result, yielding the content of an [`Ok`].
     ///
diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs
index 3a4f76852a0..8e0658d87c1 100644
--- a/src/libcore/tests/iter.rs
+++ b/src/libcore/tests/iter.rs
@@ -1689,6 +1689,12 @@ fn test_rposition() {
 }
 
 #[test]
+fn test_rev_rposition() {
+    let v = [0, 0, 1, 1];
+    assert_eq!(v.iter().rev().rposition(|&x| x == 1), Some(1));
+}
+
+#[test]
 #[should_panic]
 fn test_rposition_panic() {
     let v: [(Box<_>, Box<_>); 4] =
diff --git a/src/libcore/unicode/mod.rs b/src/libcore/unicode/mod.rs
index 272727def61..a3ec9fd51f0 100644
--- a/src/libcore/unicode/mod.rs
+++ b/src/libcore/unicode/mod.rs
@@ -13,8 +13,3 @@ pub mod derived_property {
 pub mod conversions {
     pub use crate::unicode::tables::conversions::{to_lower, to_upper};
 }
-
-// For use in libsyntax
-pub mod property {
-    pub use crate::unicode::tables::property::Pattern_White_Space;
-}
diff --git a/src/libcore/unicode/tables.rs b/src/libcore/unicode/tables.rs
index 3fae3a46ada..5b5be485431 100644
--- a/src/libcore/unicode/tables.rs
+++ b/src/libcore/unicode/tables.rs
@@ -890,384 +890,9 @@ pub(crate) mod derived_property {
         Uppercase_table.lookup(c)
     }
 
-    const XID_Continue_table: &super::BoolTrie = &super::BoolTrie {
-        r1: [
-            0x03ff000000000000, 0x07fffffe87fffffe, 0x04a0040000000000, 0xff7fffffff7fffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
-            0xffffffffffffffff, 0xb8dfffffffffffff, 0xfffffffbffffd7c0, 0xffbfffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffcfb, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xffffffff027fffff, 0xbffffffffffe01ff, 0x000787ffffff00b6,
-            0xffffffff07ff0000, 0xffffc3ffffffffff, 0xffffffffffffffff, 0x9ffffdff9fefffff,
-            0xffffffffffff0000, 0xffffffffffffe7ff, 0x0003ffffffffffff, 0x243fffffffffffff
-        ],
-        r2: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-            24, 25, 26, 27, 28, 29, 30, 31, 4, 32, 33, 34, 4, 4, 4, 4, 4, 35, 36, 37, 38, 39, 40,
-            41, 42, 4, 4, 4, 4, 4, 4, 4, 4, 43, 44, 45, 46, 47, 4, 48, 49, 50, 51, 52, 53, 54, 55,
-            56, 57, 58, 59, 60, 4, 61, 4, 62, 63, 64, 65, 66, 4, 4, 4, 67, 4, 4, 4, 4, 68, 69, 70,
-            71, 72, 73, 74, 75, 76, 77, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 79, 80, 4, 81, 82, 83, 84, 85, 60, 60, 60, 60, 60, 60, 60, 60, 86,
-            42, 87, 88, 89, 4, 90, 91, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 52, 60, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 92, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 93, 94, 4, 4, 4, 4, 95, 96, 4, 97, 98, 4, 99, 100, 101, 62, 4, 102, 103,
-            104, 4, 105, 106, 107, 4, 108, 109, 110, 4, 111, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 112, 113, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60,
-            60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 4, 4, 4, 4, 4, 103, 4, 114,
-            115, 116, 97, 117, 4, 118, 4, 4, 119, 120, 121, 122, 123, 124, 4, 125, 126, 127, 128,
-            129
-        ],
-        r3: &[
-            0x00003fffffffffff, 0x000007ff0fffffff, 0x3fdfffff00000000, 0xfffffffbfff80000,
-            0xffffffffffffffff, 0xfffeffcfffffffff, 0xf3c5fdfffff99fef, 0x5003ffcfb080799f,
-            0xd36dfdfffff987ee, 0x003fffc05e023987, 0xf3edfdfffffbbfee, 0xfe00ffcf00013bbf,
-            0xf3edfdfffff99fee, 0x0002ffcfb0c0399f, 0xc3ffc718d63dc7ec, 0x0000ffc000813dc7,
-            0xe3fffdfffffddfff, 0x0000ffcf07603ddf, 0xf3effdfffffddfef, 0x0006ffcf40603ddf,
-            0xfffffffffffddfef, 0xfc00ffcf80f07ddf, 0x2ffbfffffc7fffec, 0x000cffc0ff5f847f,
-            0x07fffffffffffffe, 0x0000000003ff7fff, 0x3fffffaffffff7d6, 0x00000000f3ff3f5f,
-            0xc2a003ff03000001, 0xfffe1ffffffffeff, 0x1ffffffffeffffdf, 0x0000000000000040,
-            0xffffffffffff03ff, 0xffffffff3fffffff, 0xf7ffffffffff20bf, 0xffffffff3d7f3dff,
-            0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0003fe00e7ffffff,
-            0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
-            0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x001fffff001fdfff, 0x000ddfff000fffff,
-            0x000003ff308fffff, 0xffffffff03ff3800, 0x01ffffffffffffff, 0xffff07ffffffffff,
-            0x003fffffffffffff, 0x0fff0fff7fffffff, 0x001f3fffffffffc0, 0xffff0fffffffffff,
-            0x0000000007ff03ff, 0xffffffff0fffffff, 0x9fffffff7fffffff, 0x3fff008003ff03ff,
-            0x0000000000000000, 0x000ff80003ff0fff, 0x000fffffffffffff, 0x00ffffffffffffff,
-            0x3fffffffffffe3ff, 0xe7ffffffffff01ff, 0x07fffffffff70000, 0xfbffffffffffffff,
-            0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff, 0x1fdc1fff0fcf1fdc,
-            0x8000000000000000, 0x8002000000100001, 0x000000001fff0000, 0x0001ffe21fff0000,
-            0xf3fffd503f2ffc84, 0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff,
-            0xffffffff7fffffff, 0x000ff81fffffffff, 0xffff20bfffffffff, 0x800080ffffffffff,
-            0x7f7f7f7f007fffff, 0xffffffff7f7f7f7f, 0x1f3efffe000000e0, 0xfffffffee67fffff,
-            0xf7ffffffffffffff, 0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000,
-            0x0000ffffffffffff, 0x0000000000001fff, 0x3fffffffffff0000, 0x00000fffffff1fff,
-            0xbff0ffffffffffff, 0x0003ffffffffffff, 0xfffffffcff800000, 0xfffffffffffff9ff,
-            0xff8000000000007c, 0x000000ffffffffff, 0xe8ffffff03ff003f, 0xffff3fffffffffff,
-            0x1fffffff000fffff, 0x7fffffff03ff8001, 0x007fffffffffffff, 0xfc7fffff03ff3fff,
-            0x007cffff38000007, 0xffff7f7f007e7e7e, 0xffff00fff7ffffff, 0x03ff37ffffffffff,
-            0xffff000fffffffff, 0x0ffffffffffff87f, 0x0000000003ffffff, 0x5f7ffdffe0f8007f,
-            0xffffffffffffffdb, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
-            0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0x0018ffff0000ffff,
-            0xaa8a00000000e000, 0x1fffffffffffffff, 0x87fffffe03ff0000, 0xffffffc007fffffe,
-            0x7fffffffffffffff, 0x000000001cfcfcfc
-        ],
-        r4: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
-            14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 17, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-        ],
-        r5: &[
-            0, 1, 2, 3, 4, 5, 4, 6, 4, 4, 7, 8, 9, 10, 11, 12, 2, 2, 13, 14, 15, 16, 4, 4, 2, 2, 2,
-            2, 17, 18, 4, 4, 19, 20, 21, 22, 23, 4, 24, 4, 25, 26, 27, 28, 29, 30, 31, 4, 2, 32, 33,
-            33, 34, 4, 4, 4, 4, 4, 4, 4, 35, 36, 4, 37, 2, 38, 3, 39, 40, 41, 2, 42, 43, 4, 44, 45,
-            46, 47, 4, 4, 2, 48, 2, 49, 4, 4, 50, 51, 2, 52, 53, 54, 55, 4, 4, 4, 3, 4, 56, 57, 4,
-            4, 58, 59, 60, 61, 62, 53, 4, 4, 4, 4, 63, 64, 65, 4, 66, 67, 68, 4, 4, 4, 4, 37, 4, 4,
-            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 69, 4, 2, 70, 2, 2, 2, 71, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 70, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 72, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 2, 2, 2, 2, 2, 2, 2, 53, 73, 4, 74, 17, 75, 76, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2,
-            4, 4, 2, 77, 78, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 80, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 33, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 21, 81, 2, 2, 2, 2,
-            2, 82, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 83, 84, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 85, 86, 4, 4, 87, 4, 4, 4, 4, 4, 4, 2, 88, 89, 90, 91, 92, 2, 2, 2, 2, 93, 94, 95,
-            96, 97, 98, 4, 4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 102, 4, 4, 4, 103, 104, 4, 4, 4, 4, 4, 105, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 106, 2, 107, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 108, 109, 110, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 111, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 11,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 112, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 113, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 114, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 115, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-        ],
-        r6: &[
-            0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
-            0x0000000000000000, 0x001fffffffffffff, 0x2000000000000000, 0xffffffff1fffffff,
-            0x000000010001ffff, 0xffffe000ffffffff, 0x07ffffffffff07ff, 0xffffffff3fffffff,
-            0x00000000003eff0f, 0xffff03ff3fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff,
-            0x0000000fffffffff, 0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f,
-            0x007fffff003fffff, 0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff,
-            0xc0ffffffffffffff, 0x873ffffffeeff06f, 0x1fffffff00000000, 0x000000001fffffff,
-            0x0000007ffffffeff, 0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff,
-            0x00000000000001ff, 0x0007ffffffffffff, 0x03ff00ffffffffff, 0xffff00801fffffff,
-            0x000000000001ffff, 0x007fffff00000000, 0x8000ffc00000007f, 0x03ff01ffffff0000,
-            0xffdfffffffffffff, 0x004fffffffff0070, 0x0000000017ff1e1f, 0x40fffffffffbffff,
-            0xffff01ffbfffbd7f, 0x03ff07ffffffffff, 0xfbedfdfffff99fef, 0x001f1fcfe081399f,
-            0x00000000c3ff07ff, 0x0000000003ff00bf, 0xff3fffffffffffff, 0x000000003f000001,
-            0x0000000003ff0011, 0x01ffffffffffffff, 0x00000000000003ff, 0x03ff0fffe7ffffff,
-            0xffffffff00000000, 0x800003ffffffffff, 0xfffffcff00000000, 0x0000001bfcffffff,
-            0x7fffffffffffffff, 0xffffffffffff0080, 0x0000000023ffffff, 0xff7ffffffffffdff,
-            0xfffc000003ff0001, 0x007ffefffffcffff, 0xb47ffffffffffb7f, 0xfffffdbf03ff00ff,
-            0x000003ff01fb7fff, 0x0000000003ffffff, 0x00007fffffffffff, 0x000000000000000f,
-            0x000000000000007f, 0x000003ff7fffffff, 0x001f3fffffff0000, 0xe0fffff803ff000f,
-            0x000000000000ffff, 0xffffffffffff87ff, 0x00000000ffff80ff, 0x0000000b00000000,
-            0x00ffffffffffffff, 0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff,
-            0x0000000063ff01ff, 0xf807e3e000000000, 0x00003c0000000fe7, 0x000000000000001c,
-            0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
-            0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
-            0xffff7fffffff7fff, 0xfffffdfffffffdff, 0xffffffffffffcff7, 0xf87fffffffffffff,
-            0x00201fffffffffff, 0x0000fffef8000010, 0x000007dbf9ffff7f, 0x3fff1fffffffffff,
-            0x00000000000043ff, 0x03ffffffffffffff, 0x00000000007f001f, 0x0000000003ff0fff,
-            0x0af7fe96ffffffef, 0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff,
-            0xffff0003ffffffff, 0x00000001ffffffff, 0x000000003fffffff, 0x0000ffffffffffff
-        ],
-    };
-
-    pub fn XID_Continue(c: char) -> bool {
-        XID_Continue_table.lookup(c)
-    }
-
-    const XID_Start_table: &super::BoolTrie = &super::BoolTrie {
-        r1: [
-            0x0000000000000000, 0x07fffffe07fffffe, 0x0420040000000000, 0xff7fffffff7fffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xffffffffffffffff, 0x0000501f0003ffc3,
-            0x0000000000000000, 0xb8df000000000000, 0xfffffffbffffd740, 0xffbfffffffffffff,
-            0xffffffffffffffff, 0xffffffffffffffff, 0xfffffffffffffc03, 0xffffffffffffffff,
-            0xfffeffffffffffff, 0xffffffff027fffff, 0x00000000000001ff, 0x000787ffffff0000,
-            0xffffffff00000000, 0xfffec000000007ff, 0xffffffffffffffff, 0x9c00c060002fffff,
-            0x0000fffffffd0000, 0xffffffffffffe000, 0x0002003fffffffff, 0x043007fffffffc00
-        ],
-        r2: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23,
-            24, 23, 25, 26, 27, 28, 29, 3, 30, 31, 32, 33, 34, 34, 34, 34, 34, 35, 36, 37, 38, 39,
-            40, 41, 42, 34, 34, 34, 34, 34, 34, 34, 34, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-            54, 55, 56, 57, 58, 59, 60, 3, 61, 62, 63, 64, 65, 66, 67, 68, 34, 34, 34, 3, 34, 34,
-            34, 34, 69, 70, 71, 72, 3, 73, 74, 3, 75, 76, 77, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 78,
-            79, 34, 80, 81, 82, 83, 84, 3, 3, 3, 3, 3, 3, 3, 3, 85, 42, 86, 87, 88, 34, 89, 90, 3,
-            3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 53, 3, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 91, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 92, 93, 34, 34, 34, 34, 94,
-            95, 96, 91, 97, 34, 98, 99, 100, 48, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110,
-            111, 112, 34, 113, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34, 34,
-            34, 34, 34, 114, 115, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,
-            3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 34, 34, 34, 34, 34,
-            116, 34, 117, 118, 119, 120, 121, 34, 122, 34, 34, 123, 124, 125, 126, 3, 127, 34, 128,
-            129, 130, 131, 132
-        ],
-        r3: &[
-            0x00000110043fffff, 0x000007ff01ffffff, 0x3fdfffff00000000, 0x0000000000000000,
-            0x23fffffffffffff0, 0xfffe0003ff010000, 0x23c5fdfffff99fe1, 0x10030003b0004000,
-            0x036dfdfffff987e0, 0x001c00005e000000, 0x23edfdfffffbbfe0, 0x0200000300010000,
-            0x23edfdfffff99fe0, 0x00020003b0000000, 0x03ffc718d63dc7e8, 0x0000000000010000,
-            0x23fffdfffffddfe0, 0x0000000307000000, 0x23effdfffffddfe1, 0x0006000340000000,
-            0x27fffffffffddfe0, 0xfc00000380704000, 0x2ffbfffffc7fffe0, 0x000000000000007f,
-            0x0005fffffffffffe, 0x2005ffaffffff7d6, 0x00000000f000005f, 0x0000000000000001,
-            0x00001ffffffffeff, 0x0000000000001f00, 0x800007ffffffffff, 0xffe1c0623c3f0000,
-            0xffffffff00004003, 0xf7ffffffffff20bf, 0xffffffffffffffff, 0xffffffff3d7f3dff,
-            0x7f3dffffffff3dff, 0xffffffffff7fff3d, 0xffffffffff3dffff, 0x0000000007ffffff,
-            0xffffffff0000ffff, 0x3f3fffffffffffff, 0xfffffffffffffffe, 0xffff9fffffffffff,
-            0xffffffff07fffffe, 0x01ffc7ffffffffff, 0x0003ffff0003dfff, 0x0001dfff0003ffff,
-            0x000fffffffffffff, 0x0000000010800000, 0xffffffff00000000, 0x01ffffffffffffff,
-            0xffff05ffffffffff, 0x003fffffffffffff, 0x000000007fffffff, 0x001f3fffffff0000,
-            0xffff0fffffffffff, 0x00000000000003ff, 0xffffffff007fffff, 0x00000000001fffff,
-            0x0000008000000000, 0x000fffffffffffe0, 0x0000000000000fe0, 0xfc00c001fffffff8,
-            0x0000003fffffffff, 0x0000000fffffffff, 0x3ffffffffc00e000, 0xe7ffffffffff01ff,
-            0x046fde0000000000, 0xffffffff3f3fffff, 0x3fffffffaaff3f3f, 0x5fdfffffffffffff,
-            0x1fdc1fff0fcf1fdc, 0x8002000000000000, 0x000000001fff0000, 0xf3fffd503f2ffc84,
-            0xffffffff000043e0, 0x00000000000001ff, 0xffff7fffffffffff, 0xffffffff7fffffff,
-            0x000c781fffffffff, 0xffff20bfffffffff, 0x000080ffffffffff, 0x7f7f7f7f007fffff,
-            0x000000007f7f7f7f, 0x1f3e03fe000000e0, 0xfffffffee07fffff, 0xf7ffffffffffffff,
-            0xfffeffffffffffe0, 0x07ffffff00007fff, 0xffff000000000000, 0x0000ffffffffffff,
-            0x0000000000001fff, 0x3fffffffffff0000, 0x00000c00ffff1fff, 0x80007fffffffffff,
-            0xffffffff3fffffff, 0xfffffffcff800000, 0xfffffffffffff9ff, 0xff8000000000007c,
-            0x00000007fffff7bb, 0x000ffffffffffffc, 0x68fc000000000000, 0xffff003ffffffc00,
-            0x1fffffff0000007f, 0x0007fffffffffff0, 0x7c00ffdf00008000, 0x000001ffffffffff,
-            0xc47fffff00000ff7, 0x3e62ffffffffffff, 0x001c07ff38000005, 0xffff7f7f007e7e7e,
-            0xffff00fff7ffffff, 0x00000007ffffffff, 0xffff000fffffffff, 0x0ffffffffffff87f,
-            0xffff3fffffffffff, 0x0000000003ffffff, 0x5f7ffdffa0f8007f, 0xffffffffffffffdb,
-            0x0003ffffffffffff, 0xfffffffffff80000, 0xfffffff03fffffff, 0x3fffffffffffffff,
-            0xffffffffffff0000, 0xfffffffffffcffff, 0x03ff0000000000ff, 0xaa8a000000000000,
-            0x1fffffffffffffff, 0x07fffffe00000000, 0xffffffc007fffffe, 0x7fffffff3fffffff,
-            0x000000001cfcfcfc
-        ],
-        r4: [
-            0, 1, 2, 3, 4, 5, 6, 7, 8, 5, 5, 9, 5, 10, 11, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 12, 13,
-            14, 7, 15, 16, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
-            5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
-        ],
-        r5: &[
-            0, 1, 2, 3, 4, 5, 4, 4, 4, 4, 6, 7, 8, 9, 10, 11, 2, 2, 12, 13, 14, 15, 4, 4, 2, 2, 2,
-            2, 16, 17, 4, 4, 18, 19, 20, 21, 22, 4, 23, 4, 24, 25, 26, 27, 28, 29, 30, 4, 2, 31, 32,
-            32, 15, 4, 4, 4, 4, 4, 4, 4, 33, 34, 4, 35, 36, 4, 37, 38, 39, 40, 41, 42, 43, 4, 44,
-            20, 45, 46, 4, 4, 5, 47, 48, 49, 4, 4, 50, 51, 48, 52, 53, 4, 54, 4, 4, 4, 55, 4, 56,
-            57, 4, 4, 58, 59, 60, 61, 62, 63, 4, 4, 4, 4, 64, 65, 66, 4, 67, 68, 69, 4, 4, 4, 4, 70,
-            4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 71, 4, 2, 50, 2, 2, 2, 72, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 50, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 73, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 63, 20, 4, 74, 48, 75, 66, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 2, 4, 4, 2, 76, 77, 78, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 79, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            32, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 20, 80, 2,
-            2, 2, 2, 2, 81, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 82, 83, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 84, 85, 86, 87, 88, 2, 2, 2, 2, 89, 90,
-            91, 92, 93, 94, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 95, 96, 4, 4, 4, 4, 4, 55, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 97, 2, 98, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 99, 100, 101, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 102, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 5, 2, 2, 2, 10, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 103,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
-            2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 104, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 2, 2, 2, 2, 2, 2, 2, 2, 105, 4, 4, 4, 4, 4, 4,
-            4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4
-        ],
-        r6: &[
-            0xb7ffff7fffffefff, 0x000000003fff3fff, 0xffffffffffffffff, 0x07ffffffffffffff,
-            0x0000000000000000, 0x001fffffffffffff, 0xffffffff1fffffff, 0x000000000001ffff,
-            0xffffe000ffffffff, 0x003fffffffff07ff, 0xffffffff3fffffff, 0x00000000003eff0f,
-            0xffff00003fffffff, 0x0fffffffff0fffff, 0xffff00ffffffffff, 0x0000000fffffffff,
-            0x007fffffffffffff, 0x000000ff003fffff, 0x91bffffffffffd3f, 0x007fffff003fffff,
-            0x000000007fffffff, 0x0037ffff00000000, 0x03ffffff003fffff, 0xc0ffffffffffffff,
-            0x003ffffffeef0001, 0x1fffffff00000000, 0x000000001fffffff, 0x0000001ffffffeff,
-            0x003fffffffffffff, 0x0007ffff003fffff, 0x000000000003ffff, 0x00000000000001ff,
-            0x0007ffffffffffff, 0xffff00801fffffff, 0x000000000000003f, 0x007fffff00000000,
-            0x00fffffffffffff8, 0x0000fffffffffff8, 0x000001ffffff0000, 0x0000007ffffffff8,
-            0x0047ffffffff0010, 0x0007fffffffffff8, 0x000000001400001e, 0x00000ffffffbffff,
-            0xffff01ffbfffbd7f, 0x23edfdfffff99fe0, 0x00000003e0010000, 0x0000000080000780,
-            0x0000ffffffffffff, 0x00000000000000b0, 0x00007fffffffffff, 0x000000000f000000,
-            0x0000000000000010, 0x010007ffffffffff, 0x0000000007ffffff, 0x00000fffffffffff,
-            0xffffffff00000000, 0x80000000ffffffff, 0xfffffcff00000000, 0x0000000a0001ffff,
-            0x0407fffffffff801, 0xfffffffff0010000, 0x00000000200003ff, 0x01ffffffffffffff,
-            0x00007ffffffffdff, 0xfffc000000000001, 0x000000000000ffff, 0x0001fffffffffb7f,
-            0xfffffdbf00000040, 0x00000000010003ff, 0x0007ffff00000000, 0x0000000003ffffff,
-            0x000000000000000f, 0x000000000000007f, 0x00003fffffff0000, 0xe0fffff80000000f,
-            0x00000000000107ff, 0x00000000fff80000, 0x0000000b00000000, 0x00ffffffffffffff,
-            0xffff00f000070000, 0x0fffffffffffffff, 0x1fff07ffffffffff, 0x0000000003ff01ff,
-            0xffffffffffdfffff, 0xebffde64dfffffff, 0xffffffffffffffef, 0x7bffffffdfdfe7bf,
-            0xfffffffffffdfc5f, 0xffffff3fffffffff, 0xf7fffffff7fffffd, 0xffdfffffffdfffff,
-            0xffff7fffffff7fff, 0xfffffdfffffffdff, 0x0000000000000ff7, 0x3f801fffffffffff,
-            0x0000000000004000, 0x000000000000001f, 0x000000000000080f, 0x0af7fe96ffffffef,
-            0x5ef7f796aa96ea84, 0x0ffffbee0ffffbff, 0x00000000007fffff, 0xffff0003ffffffff,
-            0x00000001ffffffff, 0x000000003fffffff
-        ],
-    };
-
-    pub fn XID_Start(c: char) -> bool {
-        XID_Start_table.lookup(c)
-    }
-
 }
 
 pub(crate) mod property {
-    const Pattern_White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
-        r1: &[
-            0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
-            1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3
-        ],
-        r2: &[
-            0x0000000100003e00, 0x0000000000000000, 0x0000000000000020, 0x000003000000c000
-        ],
-    };
-
-    pub fn Pattern_White_Space(c: char) -> bool {
-        Pattern_White_Space_table.lookup(c)
-    }
-
     const White_Space_table: &super::SmallBoolTrie = &super::SmallBoolTrie {
         r1: &[
             0, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
diff --git a/src/libcore/unicode/unicode.py b/src/libcore/unicode/unicode.py
index 6de5d9e033b..89894f7932d 100755
--- a/src/libcore/unicode/unicode.py
+++ b/src/libcore/unicode/unicode.py
@@ -728,7 +728,7 @@ def generate_property_module(mod, grouped_categories, category_subset):
 
     yield "pub(crate) mod %s {\n" % mod
     for cat in sorted(category_subset):
-        if cat in ("Cc", "White_Space", "Pattern_White_Space"):
+        if cat in ("Cc", "White_Space"):
             generator = generate_small_bool_trie("%s_table" % cat, grouped_categories[cat])
         else:
             generator = generate_bool_trie("%s_table" % cat, grouped_categories[cat])
@@ -841,19 +841,18 @@ def main():
     unicode_data = load_unicode_data(get_path(UnicodeFiles.UNICODE_DATA))
     load_special_casing(get_path(UnicodeFiles.SPECIAL_CASING), unicode_data)
 
-    want_derived = {"XID_Start", "XID_Continue", "Alphabetic", "Lowercase", "Uppercase",
+    want_derived = {"Alphabetic", "Lowercase", "Uppercase",
                     "Cased", "Case_Ignorable", "Grapheme_Extend"}
     derived = load_properties(get_path(UnicodeFiles.DERIVED_CORE_PROPERTIES), want_derived)
 
     props = load_properties(get_path(UnicodeFiles.PROPS),
-                            {"White_Space", "Join_Control", "Noncharacter_Code_Point",
-                             "Pattern_White_Space"})
+                            {"White_Space", "Join_Control", "Noncharacter_Code_Point"})
 
     # Category tables
     for (name, categories, category_subset) in (
             ("general_category", unicode_data.general_categories, ["N", "Cc"]),
             ("derived_property", derived, want_derived),
-            ("property", props, ["White_Space", "Pattern_White_Space"])
+            ("property", props, ["White_Space"])
     ):
         for fragment in generate_property_module(name, categories, category_subset):
             buf.write(fragment)
diff --git a/src/libfmt_macros/Cargo.toml b/src/libfmt_macros/Cargo.toml
index 82a9e34c065..fff4ec716df 100644
--- a/src/libfmt_macros/Cargo.toml
+++ b/src/libfmt_macros/Cargo.toml
@@ -10,4 +10,4 @@ path = "lib.rs"
 
 [dependencies]
 syntax_pos = { path = "../libsyntax_pos" }
-
+rustc_lexer = { path = "../librustc_lexer" }
diff --git a/src/libfmt_macros/lib.rs b/src/libfmt_macros/lib.rs
index 985abaf2c1b..f9c1be20b8b 100644
--- a/src/libfmt_macros/lib.rs
+++ b/src/libfmt_macros/lib.rs
@@ -597,12 +597,11 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses a word starting at the current position. A word is considered to
-    /// be an alphabetic character followed by any number of alphanumeric
-    /// characters.
+    /// Parses a word starting at the current position. A word is the same as
+    /// Rust identifier, except that it can't start with `_` character.
     fn word(&mut self) -> &'a str {
         let start = match self.cur.peek() {
-            Some(&(pos, c)) if c.is_xid_start() => {
+            Some(&(pos, c)) if c != '_' && rustc_lexer::is_id_start(c) => {
                 self.cur.next();
                 pos
             }
@@ -611,7 +610,7 @@ impl<'a> Parser<'a> {
             }
         };
         while let Some(&(pos, c)) = self.cur.peek() {
-            if c.is_xid_continue() {
+            if rustc_lexer::is_id_continue(c) {
                 self.cur.next();
             } else {
                 return &self.input[start..pos];
diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml
index 0222a3dde7a..a479fabafc0 100644
--- a/src/librustc/Cargo.toml
+++ b/src/librustc/Cargo.toml
@@ -21,7 +21,7 @@ scoped-tls = "1.0"
 log = { version = "0.4", features = ["release_max_level_info", "std"] }
 rustc-rayon = "0.2.0"
 rustc-rayon-core = "0.2.0"
-polonius-engine  = "0.9.0"
+polonius-engine  = "0.10.0"
 rustc_apfloat = { path = "../librustc_apfloat" }
 rustc_target = { path = "../librustc_target" }
 rustc_macros = { path = "../librustc_macros" }
diff --git a/src/librustc/error_codes.rs b/src/librustc/error_codes.rs
index 2d09013f675..937a9ea6c1b 100644
--- a/src/librustc/error_codes.rs
+++ b/src/librustc/error_codes.rs
@@ -39,7 +39,7 @@ Generally, `Self: Sized` is used to indicate that the trait should not be used
 as a trait object. If the trait comes from your own crate, consider removing
 this restriction.
 
-### Method references the `Self` type in its arguments or return type
+### Method references the `Self` type in its parameters or return type
 
 This happens when a trait has a method like the following:
 
diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs
index 773bb8dde06..b8bd1d73fc2 100644
--- a/src/librustc/hir/map/collector.rs
+++ b/src/librustc/hir/map/collector.rs
@@ -186,7 +186,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
             });
 
         let mut upstream_crates: Vec<_> = cstore.crates_untracked().iter().map(|&cnum| {
-            let name = cstore.crate_name_untracked(cnum).as_str();
+            let name = cstore.crate_name_untracked(cnum).as_interned_str();
             let disambiguator = cstore.crate_disambiguator_untracked(cnum).to_fingerprint();
             let hash = cstore.crate_hash_untracked(cnum);
             (name, disambiguator, hash)
diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs
index 05e2c7854b4..ddfca3a4cfb 100644
--- a/src/librustc/ich/impls_syntax.rs
+++ b/src/librustc/ich/impls_syntax.rs
@@ -9,7 +9,7 @@ use std::mem;
 use syntax::ast;
 use syntax::feature_gate;
 use syntax::parse::token;
-use syntax::symbol::{InternedString, LocalInternedString};
+use syntax::symbol::InternedString;
 use syntax::tokenstream;
 use syntax_pos::SourceFile;
 
@@ -39,27 +39,6 @@ impl<'a> ToStableHashKey<StableHashingContext<'a>> for InternedString {
     }
 }
 
-impl<'a> HashStable<StableHashingContext<'a>> for LocalInternedString {
-    #[inline]
-    fn hash_stable<W: StableHasherResult>(&self,
-                                          hcx: &mut StableHashingContext<'a>,
-                                          hasher: &mut StableHasher<W>) {
-        let s: &str = &**self;
-        s.hash_stable(hcx, hasher);
-    }
-}
-
-impl<'a> ToStableHashKey<StableHashingContext<'a>> for LocalInternedString {
-    type KeyType = LocalInternedString;
-
-    #[inline]
-    fn to_stable_hash_key(&self,
-                          _: &StableHashingContext<'a>)
-                          -> LocalInternedString {
-        self.clone()
-    }
-}
-
 impl<'a> HashStable<StableHashingContext<'a>> for ast::Name {
     #[inline]
     fn hash_stable<W: StableHasherResult>(&self,
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index e684ccfeeb7..5883be6e268 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1136,12 +1136,19 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
         if let Some((expected, found)) = expected_found {
             match (terr, is_simple_error, expected == found) {
                 (&TypeError::Sorts(ref values), false, true) => {
+                    let sort_string = | a_type: Ty<'tcx> |
+                        if let ty::Opaque(def_id, _) = a_type.sty {
+                            format!(" (opaque type at {})", self.tcx.sess.source_map()
+                                .mk_substr_filename(self.tcx.def_span(def_id)))
+                        } else {
+                            format!(" ({})", a_type.sort_string(self.tcx))
+                        };
                     diag.note_expected_found_extra(
                         &"type",
                         expected,
                         found,
-                        &format!(" ({})", values.expected.sort_string(self.tcx)),
-                        &format!(" ({})", values.found.sort_string(self.tcx)),
+                        &sort_string(values.expected),
+                        &sort_string(values.found),
                     );
                 }
                 (_, false, _) => {
@@ -1627,7 +1634,7 @@ impl<'tcx> ObligationCause<'tcx> {
             MainFunctionType => Error0580("main function has wrong type"),
             StartFunctionType => Error0308("start function has wrong type"),
             IntrinsicType => Error0308("intrinsic has wrong type"),
-            MethodReceiver => Error0308("mismatched method receiver"),
+            MethodReceiver => Error0308("mismatched `self` parameter type"),
 
             // In the case where we have no more specific thing to
             // say, also take a look at the error code, maybe we can
diff --git a/src/librustc/lint/context.rs b/src/librustc/lint/context.rs
index affda256322..77df93080cd 100644
--- a/src/librustc/lint/context.rs
+++ b/src/librustc/lint/context.rs
@@ -33,7 +33,7 @@ use crate::util::common::time;
 use std::default::Default as StdDefault;
 use syntax::ast;
 use syntax::edition;
-use syntax_pos::{MultiSpan, Span, symbol::{LocalInternedString, Symbol}};
+use syntax_pos::{MultiSpan, Span, symbol::Symbol};
 use errors::DiagnosticBuilder;
 use crate::hir;
 use crate::hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
@@ -405,7 +405,7 @@ impl LintStore {
     pub fn check_lint_name(
         &self,
         lint_name: &str,
-        tool_name: Option<LocalInternedString>,
+        tool_name: Option<Symbol>,
     ) -> CheckLintNameResult<'_> {
         let complete_name = if let Some(tool_name) = tool_name {
             format!("{}::{}", tool_name, lint_name)
diff --git a/src/librustc/lint/levels.rs b/src/librustc/lint/levels.rs
index 139f4343117..cbc6dbdba7e 100644
--- a/src/librustc/lint/levels.rs
+++ b/src/librustc/lint/levels.rs
@@ -291,7 +291,7 @@ impl<'a> LintLevelsBuilder<'a> {
                         continue;
                     }
 
-                    Some(tool_ident.as_str())
+                    Some(tool_ident.name)
                 } else {
                     None
                 };
diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs
index 5ac99ba1470..8956cbb2bae 100644
--- a/src/librustc/mir/mod.rs
+++ b/src/librustc/mir/mod.rs
@@ -1808,6 +1808,23 @@ pub enum ProjectionElem<V, T> {
     Downcast(Option<Symbol>, VariantIdx),
 }
 
+impl<V, T> ProjectionElem<V, T> {
+    /// Returns `true` if the target of this projection may refer to a different region of memory
+    /// than the base.
+    fn is_indirect(&self) -> bool {
+        match self {
+            Self::Deref => true,
+
+            | Self::Field(_, _)
+            | Self::Index(_)
+            | Self::ConstantIndex { .. }
+            | Self::Subslice { .. }
+            | Self::Downcast(_, _)
+            => false
+        }
+    }
+}
+
 /// Alias for projections as they appear in places, where the base is a place
 /// and the index is a local.
 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
@@ -1869,6 +1886,14 @@ impl<'tcx> Place<'tcx> {
         }
     }
 
+    /// Returns `true` if this `Place` contains a `Deref` projection.
+    ///
+    /// If `Place::is_indirect` returns false, the caller knows that the `Place` refers to the
+    /// same region of memory as its base.
+    pub fn is_indirect(&self) -> bool {
+        self.iterate(|_, mut projections| projections.any(|proj| proj.elem.is_indirect()))
+    }
+
     /// Finds the innermost `Local` from this `Place`, *if* it is either a local itself or
     /// a single deref of a local.
     //
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index b38e1f5f839..03cc00d87e3 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -1384,7 +1384,10 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut reported_violations = FxHashSet::default();
         for violation in violations {
             if reported_violations.insert(violation.clone()) {
-                err.note(&violation.error_msg());
+                match violation.span() {
+                    Some(span) => err.span_label(span, violation.error_msg()),
+                    None => err.note(&violation.error_msg()),
+                };
             }
         }
         Some(err)
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 7ea7bf0257c..f7f459cd27f 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -20,7 +20,7 @@ use std::borrow::Cow;
 use std::iter::{self};
 use syntax::ast::{self};
 use syntax::symbol::InternedString;
-use syntax_pos::Span;
+use syntax_pos::{Span, DUMMY_SP};
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
 pub enum ObjectSafetyViolation {
@@ -32,10 +32,10 @@ pub enum ObjectSafetyViolation {
     SupertraitSelf,
 
     /// Method has something illegal.
-    Method(ast::Name, MethodViolationCode),
+    Method(ast::Name, MethodViolationCode, Span),
 
     /// Associated const.
-    AssocConst(ast::Name),
+    AssocConst(ast::Name, Span),
 }
 
 impl ObjectSafetyViolation {
@@ -46,22 +46,35 @@ impl ObjectSafetyViolation {
             ObjectSafetyViolation::SupertraitSelf =>
                 "the trait cannot use `Self` as a type parameter \
                  in the supertraits or where-clauses".into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod) =>
-                format!("method `{}` has no receiver", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf) =>
-                format!("method `{}` references the `Self` type \
-                         in its arguments or return type", name).into(),
-            ObjectSafetyViolation::Method(name,
-                                            MethodViolationCode::WhereClauseReferencesSelf(_)) =>
-                format!("method `{}` references the `Self` type in where clauses", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic) =>
+            ObjectSafetyViolation::Method(name, MethodViolationCode::StaticMethod, _) =>
+                format!("associated function `{}` has no `self` parameter", name).into(),
+            ObjectSafetyViolation::Method(name, MethodViolationCode::ReferencesSelf, _) => format!(
+                "method `{}` references the `Self` type in its parameters or return type",
+                name,
+            ).into(),
+            ObjectSafetyViolation::Method(
+                name,
+                MethodViolationCode::WhereClauseReferencesSelf,
+                _,
+            ) => format!("method `{}` references the `Self` type in where clauses", name).into(),
+            ObjectSafetyViolation::Method(name, MethodViolationCode::Generic, _) =>
                 format!("method `{}` has generic type parameters", name).into(),
-            ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver) =>
-                format!("method `{}`'s receiver cannot be dispatched on", name).into(),
-            ObjectSafetyViolation::AssocConst(name) =>
+            ObjectSafetyViolation::Method(name, MethodViolationCode::UndispatchableReceiver, _) =>
+                format!("method `{}`'s `self` parameter cannot be dispatched on", name).into(),
+            ObjectSafetyViolation::AssocConst(name, _) =>
                 format!("the trait cannot contain associated consts like `{}`", name).into(),
         }
     }
+
+    pub fn span(&self) -> Option<Span> {
+        // When `span` comes from a separate crate, it'll be `DUMMY_SP`. Treat it as `None` so
+        // diagnostics use a `note` instead of a `span_label`.
+        match *self {
+            ObjectSafetyViolation::AssocConst(_, span) |
+            ObjectSafetyViolation::Method(_, _, span) if span != DUMMY_SP => Some(span),
+            _ => None,
+        }
+    }
 }
 
 /// Reasons a method might not be object-safe.
@@ -74,7 +87,7 @@ pub enum MethodViolationCode {
     ReferencesSelf,
 
     /// e.g., `fn foo(&self) where Self: Clone`
-    WhereClauseReferencesSelf(Span),
+    WhereClauseReferencesSelf,
 
     /// e.g., `fn foo<A>()`
     Generic,
@@ -88,9 +101,10 @@ impl<'tcx> TyCtxt<'tcx> {
     /// astconv -- currently, `Self` in supertraits. This is needed
     /// because `object_safety_violations` can't be used during
     /// type collection.
-    pub fn astconv_object_safety_violations(self, trait_def_id: DefId)
-                                            -> Vec<ObjectSafetyViolation>
-    {
+    pub fn astconv_object_safety_violations(
+        self,
+        trait_def_id: DefId,
+    ) -> Vec<ObjectSafetyViolation> {
         debug_assert!(self.generics_of(trait_def_id).has_self);
         let violations = traits::supertrait_def_ids(self, trait_def_id)
             .filter(|&def_id| self.predicates_reference_self(def_id, true))
@@ -128,7 +142,7 @@ impl<'tcx> TyCtxt<'tcx> {
         }
 
         match self.virtual_call_violation_for_method(trait_def_id, method) {
-            None | Some(MethodViolationCode::WhereClauseReferencesSelf(_)) => true,
+            None | Some(MethodViolationCode::WhereClauseReferencesSelf) => true,
             Some(_) => false,
         }
     }
@@ -138,12 +152,15 @@ impl<'tcx> TyCtxt<'tcx> {
         let mut violations: Vec<_> = self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Method)
             .filter_map(|item|
-                self.object_safety_violation_for_method(trait_def_id, &item)
-                    .map(|code| ObjectSafetyViolation::Method(item.ident.name, code))
+                self.object_safety_violation_for_method(trait_def_id, &item).map(|code| {
+                    ObjectSafetyViolation::Method(item.ident.name, code, item.ident.span)
+                })
             ).filter(|violation| {
-                if let ObjectSafetyViolation::Method(_,
-                    MethodViolationCode::WhereClauseReferencesSelf(span)) = violation
-                {
+                if let ObjectSafetyViolation::Method(
+                    _,
+                    MethodViolationCode::WhereClauseReferencesSelf,
+                    span,
+                ) = violation {
                     // Using `CRATE_NODE_ID` is wrong, but it's hard to get a more precise id.
                     // It's also hard to get a use site span, so we use the method definition span.
                     self.lint_node_note(
@@ -169,7 +186,7 @@ impl<'tcx> TyCtxt<'tcx> {
 
         violations.extend(self.associated_items(trait_def_id)
             .filter(|item| item.kind == ty::AssocKind::Const)
-            .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name)));
+            .map(|item| ObjectSafetyViolation::AssocConst(item.ident.name, item.ident.span)));
 
         debug!("object_safety_violations_for_trait(trait_def_id={:?}) = {:?}",
                trait_def_id,
@@ -325,8 +342,7 @@ impl<'tcx> TyCtxt<'tcx> {
                 .visit_tys_shallow(|t| {
                     self.contains_illegal_self_type_reference(trait_def_id, t)
                 }) {
-            let span = self.def_span(method.def_id);
-            return Some(MethodViolationCode::WhereClauseReferencesSelf(span));
+            return Some(MethodViolationCode::WhereClauseReferencesSelf);
         }
 
         let receiver_ty = self.liberate_late_bound_regions(
diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs
index 0a42b6b46f2..5a988d9509e 100644
--- a/src/librustc/traits/on_unimplemented.rs
+++ b/src/librustc/traits/on_unimplemented.rs
@@ -9,10 +9,9 @@ use syntax::ast::{MetaItem, NestedMetaItem};
 use syntax::attr;
 use syntax::symbol::{Symbol, kw, sym};
 use syntax_pos::Span;
-use syntax_pos::symbol::LocalInternedString;
 
 #[derive(Clone, Debug)]
-pub struct OnUnimplementedFormatString(LocalInternedString);
+pub struct OnUnimplementedFormatString(Symbol);
 
 #[derive(Debug)]
 pub struct OnUnimplementedDirective {
@@ -89,19 +88,19 @@ impl<'tcx> OnUnimplementedDirective {
             if item.check_name(sym::message) && message.is_none() {
                 if let Some(message_) = item.value_str() {
                     message = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, message_.as_str(), span)?);
+                        tcx, trait_def_id, message_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::label) && label.is_none() {
                 if let Some(label_) = item.value_str() {
                     label = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, label_.as_str(), span)?);
+                        tcx, trait_def_id, label_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::note) && note.is_none() {
                 if let Some(note_) = item.value_str() {
                     note = Some(OnUnimplementedFormatString::try_parse(
-                        tcx, trait_def_id, note_.as_str(), span)?);
+                        tcx, trait_def_id, note_, span)?);
                     continue;
                 }
             } else if item.check_name(sym::on) && is_root &&
@@ -154,7 +153,7 @@ impl<'tcx> OnUnimplementedDirective {
                 message: None,
                 subcommands: vec![],
                 label: Some(OnUnimplementedFormatString::try_parse(
-                    tcx, trait_def_id, value.as_str(), attr.span)?),
+                    tcx, trait_def_id, value, attr.span)?),
                 note: None,
             }))
         } else {
@@ -218,7 +217,7 @@ impl<'tcx> OnUnimplementedFormatString {
     fn try_parse(
         tcx: TyCtxt<'tcx>,
         trait_def_id: DefId,
-        from: LocalInternedString,
+        from: Symbol,
         err_sp: Span,
     ) -> Result<Self, ErrorReported> {
         let result = OnUnimplementedFormatString(from);
@@ -234,7 +233,8 @@ impl<'tcx> OnUnimplementedFormatString {
     ) -> Result<(), ErrorReported> {
         let name = tcx.item_name(trait_def_id);
         let generics = tcx.generics_of(trait_def_id);
-        let parser = Parser::new(&self.0, None, vec![], false);
+        let s = self.0.as_str();
+        let parser = Parser::new(&s, None, vec![], false);
         let mut result = Ok(());
         for token in parser {
             match token {
@@ -294,7 +294,8 @@ impl<'tcx> OnUnimplementedFormatString {
         }).collect::<FxHashMap<Symbol, String>>();
         let empty_string = String::new();
 
-        let parser = Parser::new(&self.0, None, vec![], false);
+        let s = self.0.as_str();
+        let parser = Parser::new(&s, None, vec![], false);
         parser.map(|p|
             match p {
                 Piece::String(s) => s,
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 56505c04f0f..2da50f37409 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -46,7 +46,7 @@ use std::ops::Range;
 use syntax::ast::{self, Name, Ident, NodeId};
 use syntax::attr;
 use syntax::ext::hygiene::ExpnId;
-use syntax::symbol::{kw, sym, Symbol, LocalInternedString, InternedString};
+use syntax::symbol::{kw, sym, Symbol, InternedString};
 use syntax_pos::Span;
 
 use smallvec;
@@ -3386,10 +3386,6 @@ impl SymbolName {
             name: InternedString::intern(name)
         }
     }
-
-    pub fn as_str(&self) -> LocalInternedString {
-        self.name.as_str()
-    }
 }
 
 impl fmt::Display for SymbolName {
diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs
index 7a77418050c..a08c82a0ae8 100644
--- a/src/librustc/ty/util.rs
+++ b/src/librustc/ty/util.rs
@@ -709,8 +709,10 @@ impl<'tcx> TyCtxt<'tcx> {
                 substs: SubstsRef<'tcx>,
             ) -> Option<Ty<'tcx>> {
                 if self.found_recursion {
-                    None
-                } else if self.seen_opaque_tys.insert(def_id) {
+                    return None;
+                }
+                let substs = substs.fold_with(self);
+                if self.seen_opaque_tys.insert(def_id) {
                     let generic_ty = self.tcx.type_of(def_id);
                     let concrete_ty = generic_ty.subst(self.tcx, substs);
                     let expanded_ty = self.fold_ty(concrete_ty);
diff --git a/src/librustc_codegen_llvm/builder.rs b/src/librustc_codegen_llvm/builder.rs
index 894e5c2fd3d..e13a5ecc2eb 100644
--- a/src/librustc_codegen_llvm/builder.rs
+++ b/src/librustc_codegen_llvm/builder.rs
@@ -5,7 +5,6 @@ use crate::context::CodegenCx;
 use crate::type_::Type;
 use crate::type_of::LayoutLlvmExt;
 use crate::value::Value;
-use syntax::symbol::LocalInternedString;
 use rustc_codegen_ssa::common::{IntPredicate, TypeKind, RealPredicate};
 use rustc_codegen_ssa::MemFlags;
 use libc::{c_uint, c_char};
@@ -24,6 +23,7 @@ use std::ffi::CStr;
 use std::ops::{Deref, Range};
 use std::ptr;
 use std::iter::TrustedLen;
+use syntax::symbol::Symbol;
 
 // All Builders must have an llfn associated with them
 #[must_use]
@@ -561,7 +561,7 @@ impl BuilderMethods<'a, 'tcx> for Builder<'a, 'll, 'tcx> {
 
         let align = dest.align.restrict_for_offset(dest.layout.field(self.cx(), 0).size);
         cg_elem.val.store(&mut body_bx,
-            PlaceRef::new_sized(current, cg_elem.layout, align));
+            PlaceRef::new_sized_aligned(current, cg_elem.layout, align));
 
         let next = body_bx.inbounds_gep(current, &[self.const_usize(1)]);
         body_bx.br(header_bx.llbb());
@@ -1082,8 +1082,8 @@ impl StaticBuilderMethods for Builder<'a, 'll, 'tcx> {
 
     fn static_panic_msg(
         &mut self,
-        msg: Option<LocalInternedString>,
-        filename: LocalInternedString,
+        msg: Option<Symbol>,
+        filename: Symbol,
         line: Self::Value,
         col: Self::Value,
         kind: &str,
diff --git a/src/librustc_codegen_llvm/callee.rs b/src/librustc_codegen_llvm/callee.rs
index 2c0a6f631b7..35d5107842d 100644
--- a/src/librustc_codegen_llvm/callee.rs
+++ b/src/librustc_codegen_llvm/callee.rs
@@ -37,7 +37,7 @@ pub fn get_fn(
         return llfn;
     }
 
-    let sym = tcx.symbol_name(instance).as_str();
+    let sym = tcx.symbol_name(instance).name.as_str();
     debug!("get_fn({:?}: {:?}) => {}", instance, sig, sym);
 
     // Create a fn pointer with the substituted signature.
diff --git a/src/librustc_codegen_llvm/common.rs b/src/librustc_codegen_llvm/common.rs
index 19f18088579..6fbea9646b8 100644
--- a/src/librustc_codegen_llvm/common.rs
+++ b/src/librustc_codegen_llvm/common.rs
@@ -17,7 +17,7 @@ use rustc_codegen_ssa::mir::place::PlaceRef;
 
 use libc::{c_uint, c_char};
 
-use syntax::symbol::LocalInternedString;
+use syntax::symbol::Symbol;
 use syntax::ast::Mutability;
 
 pub use crate::context::CodegenCx;
@@ -122,7 +122,7 @@ impl CodegenCx<'ll, 'tcx> {
 
     fn const_cstr(
         &self,
-        s: LocalInternedString,
+        s: Symbol,
         null_terminated: bool,
     ) -> &'ll Value {
         unsafe {
@@ -130,9 +130,10 @@ impl CodegenCx<'ll, 'tcx> {
                 return llval;
             }
 
+            let s_str = s.as_str();
             let sc = llvm::LLVMConstStringInContext(self.llcx,
-                                                    s.as_ptr() as *const c_char,
-                                                    s.len() as c_uint,
+                                                    s_str.as_ptr() as *const c_char,
+                                                    s_str.len() as c_uint,
                                                     !null_terminated as Bool);
             let sym = self.generate_local_symbol_name("str");
             let g = self.define_global(&sym[..], self.val_ty(sc)).unwrap_or_else(||{
@@ -147,8 +148,8 @@ impl CodegenCx<'ll, 'tcx> {
         }
     }
 
-    pub fn const_str_slice(&self, s: LocalInternedString) -> &'ll Value {
-        let len = s.len();
+    pub fn const_str_slice(&self, s: Symbol) -> &'ll Value {
+        let len = s.as_str().len();
         let cs = consts::ptrcast(self.const_cstr(s, false),
             self.type_ptr_to(self.layout_of(self.tcx.mk_str()).llvm_type(self)));
         self.const_fat_ptr(cs, self.const_usize(len as u64))
@@ -348,7 +349,7 @@ impl ConstMethods<'tcx> for CodegenCx<'ll, 'tcx> {
             )};
             self.const_bitcast(llval, llty)
         };
-        PlaceRef::new_sized(llval, layout, alloc.align)
+        PlaceRef::new_sized(llval, layout)
     }
 
     fn const_ptrcast(&self, val: &'ll Value, ty: &'ll Type) -> &'ll Value {
diff --git a/src/librustc_codegen_llvm/consts.rs b/src/librustc_codegen_llvm/consts.rs
index 958666cb885..e71d1fc1692 100644
--- a/src/librustc_codegen_llvm/consts.rs
+++ b/src/librustc_codegen_llvm/consts.rs
@@ -11,12 +11,11 @@ use rustc::mir::interpret::{ConstValue, Allocation, read_target_uint,
     Pointer, ErrorHandled, GlobalId};
 use rustc::mir::mono::MonoItem;
 use rustc::hir::Node;
-use syntax_pos::Span;
 use rustc_target::abi::HasDataLayout;
-use syntax::symbol::sym;
-use syntax_pos::symbol::LocalInternedString;
 use rustc::ty::{self, Ty, Instance};
 use rustc_codegen_ssa::traits::*;
+use syntax::symbol::{Symbol, sym};
+use syntax_pos::Span;
 
 use rustc::ty::layout::{self, Size, Align, LayoutOf};
 
@@ -122,10 +121,11 @@ fn check_and_apply_linkage(
     cx: &CodegenCx<'ll, 'tcx>,
     attrs: &CodegenFnAttrs,
     ty: Ty<'tcx>,
-    sym: LocalInternedString,
+    sym: Symbol,
     span: Span
 ) -> &'ll Value {
     let llty = cx.layout_of(ty).llvm_type(cx);
+    let sym = sym.as_str();
     if let Some(linkage) = attrs.linkage {
         debug!("get_static: sym={} linkage={:?}", sym, linkage);
 
@@ -221,7 +221,7 @@ impl CodegenCx<'ll, 'tcx> {
                  def_id);
 
         let ty = instance.ty(self.tcx);
-        let sym = self.tcx.symbol_name(instance).as_str();
+        let sym = self.tcx.symbol_name(instance).name.as_symbol();
 
         debug!("get_static: sym={} instance={:?}", sym, instance);
 
@@ -232,11 +232,12 @@ impl CodegenCx<'ll, 'tcx> {
                 Node::Item(&hir::Item {
                     ref attrs, span, node: hir::ItemKind::Static(..), ..
                 }) => {
-                    if self.get_declared_value(&sym[..]).is_some() {
+                    let sym_str = sym.as_str();
+                    if self.get_declared_value(&sym_str).is_some() {
                         span_bug!(span, "Conflicting symbol names for static?");
                     }
 
-                    let g = self.define_global(&sym[..], llty).unwrap();
+                    let g = self.define_global(&sym_str, llty).unwrap();
 
                     if !self.tcx.is_reachable_non_generic(def_id) {
                         unsafe {
diff --git a/src/librustc_codegen_llvm/context.rs b/src/librustc_codegen_llvm/context.rs
index a2aaaddf093..58ce9703909 100644
--- a/src/librustc_codegen_llvm/context.rs
+++ b/src/librustc_codegen_llvm/context.rs
@@ -29,7 +29,7 @@ use std::cell::{Cell, RefCell};
 use std::iter;
 use std::str;
 use std::sync::Arc;
-use syntax::symbol::LocalInternedString;
+use syntax::symbol::Symbol;
 use syntax::source_map::{DUMMY_SP, Span};
 use crate::abi::Abi;
 
@@ -52,7 +52,7 @@ pub struct CodegenCx<'ll, 'tcx> {
     pub vtables:
         RefCell<FxHashMap<(Ty<'tcx>, Option<ty::PolyExistentialTraitRef<'tcx>>), &'ll Value>>,
     /// Cache of constant strings,
-    pub const_cstr_cache: RefCell<FxHashMap<LocalInternedString, &'ll Value>>,
+    pub const_cstr_cache: RefCell<FxHashMap<Symbol, &'ll Value>>,
 
     /// Reverse-direction for const ptrs cast from globals.
     /// Key is a Value holding a *T,
diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs
index 928532a1f47..d0b607bd88e 100644
--- a/src/librustc_codegen_llvm/debuginfo/metadata.rs
+++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs
@@ -2251,7 +2251,7 @@ pub fn create_global_var_metadata(
         None
     } else {
         let linkage_name = mangled_name_of_instance(cx, Instance::mono(tcx, def_id));
-        Some(SmallCStr::new(&linkage_name.as_str()))
+        Some(SmallCStr::new(&linkage_name.name.as_str()))
     };
 
     let global_align = cx.align_of(variable_type);
diff --git a/src/librustc_codegen_llvm/debuginfo/mod.rs b/src/librustc_codegen_llvm/debuginfo/mod.rs
index 548ea0b1036..cad2bcdc05f 100644
--- a/src/librustc_codegen_llvm/debuginfo/mod.rs
+++ b/src/librustc_codegen_llvm/debuginfo/mod.rs
@@ -290,7 +290,7 @@ impl DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
         let scope_line = span_start(self, span).line;
 
         let function_name = CString::new(name).unwrap();
-        let linkage_name = SmallCStr::new(&linkage_name.as_str());
+        let linkage_name = SmallCStr::new(&linkage_name.name.as_str());
 
         let mut flags = DIFlags::FlagPrototyped;
 
diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs
index 9483ffca448..fc0b9ffd11d 100644
--- a/src/librustc_codegen_llvm/intrinsic.rs
+++ b/src/librustc_codegen_llvm/intrinsic.rs
@@ -101,7 +101,7 @@ impl IntrinsicCallMethods<'tcx> for Builder<'a, 'll, 'tcx> {
         let name = &*tcx.item_name(def_id).as_str();
 
         let llret_ty = self.layout_of(ret_ty).llvm_type(self);
-        let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout, fn_ty.ret.layout.align.abi);
+        let result = PlaceRef::new_sized(llresult, fn_ty.ret.layout);
 
         let simple = get_simple_intrinsic(self, name);
         let llval = match name {
diff --git a/src/librustc_codegen_ssa/back/symbol_export.rs b/src/librustc_codegen_ssa/back/symbol_export.rs
index 2d9220f897c..7e700e68194 100644
--- a/src/librustc_codegen_ssa/back/symbol_export.rs
+++ b/src/librustc_codegen_ssa/back/symbol_export.rs
@@ -121,7 +121,7 @@ fn reachable_non_generics_provider(
         })
         .map(|def_id| {
             let export_level = if special_runtime_crate {
-                let name = tcx.symbol_name(Instance::mono(tcx, def_id)).as_str();
+                let name = tcx.symbol_name(Instance::mono(tcx, def_id)).name.as_str();
                 // We can probably do better here by just ensuring that
                 // it has hidden visibility rather than public
                 // visibility, as this is primarily here to ensure it's
diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs
index d2a7571fde1..c41e4639846 100644
--- a/src/librustc_codegen_ssa/mir/block.rs
+++ b/src/librustc_codegen_ssa/mir/block.rs
@@ -14,7 +14,7 @@ use crate::traits::*;
 
 use std::borrow::Cow;
 
-use syntax::symbol::LocalInternedString;
+use syntax::symbol::Symbol;
 use syntax_pos::Pos;
 
 use super::{FunctionCx, LocalRef};
@@ -397,7 +397,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // Get the location information.
         let loc = bx.sess().source_map().lookup_char_pos(span.lo());
-        let filename = LocalInternedString::intern(&loc.file.name.to_string());
+        let filename = Symbol::intern(&loc.file.name.to_string());
         let line = bx.const_u32(loc.line as u32);
         let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
 
@@ -418,8 +418,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     vec![file_line_col, index, len])
             }
             _ => {
-                let str = msg.description();
-                let msg_str = LocalInternedString::intern(str);
+                let msg_str = Symbol::intern(msg.description());
                 let msg_file_line_col = bx.static_panic_msg(
                     Some(msg_str),
                     filename,
@@ -531,7 +530,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             let layout = bx.layout_of(ty);
             if layout.abi.is_uninhabited() {
                 let loc = bx.sess().source_map().lookup_char_pos(span.lo());
-                let filename = LocalInternedString::intern(&loc.file.name.to_string());
+                let filename = Symbol::intern(&loc.file.name.to_string());
                 let line = bx.const_u32(loc.line as u32);
                 let col = bx.const_u32(loc.col.to_usize() as u32 + 1);
 
@@ -539,7 +538,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                     "Attempted to instantiate uninhabited type {}",
                     ty
                 );
-                let msg_str = LocalInternedString::intern(&str);
+                let msg_str = Symbol::intern(&str);
                 let msg_file_line_col = bx.static_panic_msg(
                     Some(msg_str),
                     filename,
@@ -989,7 +988,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         // Handle both by-ref and immediate tuples.
         if let Ref(llval, None, align) = tuple.val {
-            let tuple_ptr = PlaceRef::new_sized(llval, tuple.layout, align);
+            let tuple_ptr = PlaceRef::new_sized_aligned(llval, tuple.layout, align);
             for i in 0..tuple.layout.fields.count() {
                 let field_ptr = tuple_ptr.project_field(bx, i);
                 let field = bx.load_operand(field_ptr);
@@ -1203,7 +1202,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         let llty = bx.backend_type(src.layout);
         let cast_ptr = bx.pointercast(dst.llval, bx.type_ptr_to(llty));
         let align = src.layout.align.abi.min(dst.align);
-        src.val.store(bx, PlaceRef::new_sized(cast_ptr, src.layout, align));
+        src.val.store(bx, PlaceRef::new_sized_aligned(cast_ptr, src.layout, align));
     }
 
 
diff --git a/src/librustc_codegen_ssa/mir/mod.rs b/src/librustc_codegen_ssa/mir/mod.rs
index 32bcdebc1c4..8acb3ba0626 100644
--- a/src/librustc_codegen_ssa/mir/mod.rs
+++ b/src/librustc_codegen_ssa/mir/mod.rs
@@ -289,7 +289,7 @@ pub fn codegen_mir<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
                 if local == mir::RETURN_PLACE && fx.fn_ty.ret.is_indirect() {
                     debug!("alloc: {:?} (return place) -> place", local);
                     let llretptr = bx.get_param(0);
-                    LocalRef::Place(PlaceRef::new_sized(llretptr, layout, layout.align.abi))
+                    LocalRef::Place(PlaceRef::new_sized(llretptr, layout))
                 } else if memory_locals.contains(local) {
                     debug!("alloc: {:?} -> place", local);
                     if layout.is_unsized() {
@@ -548,7 +548,7 @@ fn arg_local_refs<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>>(
             let llarg = bx.get_param(llarg_idx);
             bx.set_value_name(llarg, &name);
             llarg_idx += 1;
-            PlaceRef::new_sized(llarg, arg.layout, arg.layout.align.abi)
+            PlaceRef::new_sized(llarg, arg.layout)
         } else if arg.is_unsized_indirect() {
             // As the storage for the indirect argument lives during
             // the whole function call, we just copy the fat pointer.
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs
index 254b73da442..a8ab3ea10ed 100644
--- a/src/librustc_codegen_ssa/mir/operand.rs
+++ b/src/librustc_codegen_ssa/mir/operand.rs
@@ -485,7 +485,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         bx.load_operand(PlaceRef::new_sized(
                             bx.cx().const_undef(bx.cx().type_ptr_to(bx.cx().backend_type(layout))),
                             layout,
-                            layout.align.abi,
                         ))
                     })
             }
diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs
index ac72928a896..b8e10d34302 100644
--- a/src/librustc_codegen_ssa/mir/place.rs
+++ b/src/librustc_codegen_ssa/mir/place.rs
@@ -30,6 +30,19 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
     pub fn new_sized(
         llval: V,
         layout: TyLayout<'tcx>,
+    ) -> PlaceRef<'tcx, V> {
+        assert!(!layout.is_unsized());
+        PlaceRef {
+            llval,
+            llextra: None,
+            layout,
+            align: layout.align.abi
+        }
+    }
+
+    pub fn new_sized_aligned(
+        llval: V,
+        layout: TyLayout<'tcx>,
         align: Align,
     ) -> PlaceRef<'tcx, V> {
         assert!(!layout.is_unsized());
@@ -45,14 +58,13 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         bx: &mut Bx,
         llval: V,
         layout: TyLayout<'tcx>,
-        align: Align,
     ) -> PlaceRef<'tcx, V> {
         assert!(!bx.cx().type_has_metadata(layout.ty));
         PlaceRef {
             llval,
             llextra: None,
             layout,
-            align
+            align: layout.align.abi
         }
     }
 
@@ -64,7 +76,7 @@ impl<'a, 'tcx, V: CodegenObject> PlaceRef<'tcx, V> {
         debug!("alloca({:?}: {:?})", name, layout);
         assert!(!layout.is_unsized(), "tried to statically allocate unsized place");
         let tmp = bx.alloca(bx.cx().backend_type(layout), name, layout.align.abi);
-        Self::new_sized(tmp, layout, layout.align.abi)
+        Self::new_sized(tmp, layout)
     }
 
     /// Returns a place for an indirect reference to an unsized place.
@@ -482,7 +494,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         let llval = bx.cx().const_undef(
                             bx.cx().type_ptr_to(bx.cx().backend_type(layout))
                         );
-                        PlaceRef::new_sized(llval, layout, layout.align.abi)
+                        PlaceRef::new_sized(llval, layout)
                     }
                 }
             }
@@ -498,7 +510,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 // with a static that is an extern_type.
                 let layout = cx.layout_of(self.monomorphize(&ty));
                 let static_ = bx.get_static(*def_id);
-                PlaceRef::new_thin_place(bx, static_, layout, layout.align.abi)
+                PlaceRef::new_thin_place(bx, static_, layout)
             },
             mir::PlaceRef {
                 base,
diff --git a/src/librustc_codegen_ssa/mir/rvalue.rs b/src/librustc_codegen_ssa/mir/rvalue.rs
index 9da1e5024ba..e0ad2527229 100644
--- a/src/librustc_codegen_ssa/mir/rvalue.rs
+++ b/src/librustc_codegen_ssa/mir/rvalue.rs
@@ -71,7 +71,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                         scratch.storage_dead(&mut bx);
                     }
                     OperandValue::Ref(llref, None, align) => {
-                        let source = PlaceRef::new_sized(llref, operand.layout, align);
+                        let source = PlaceRef::new_sized_aligned(llref, operand.layout, align);
                         base::coerce_unsized_into(&mut bx, source, dest);
                     }
                     OperandValue::Ref(_, Some(_), _) => {
diff --git a/src/librustc_codegen_ssa/mono_item.rs b/src/librustc_codegen_ssa/mono_item.rs
index 4446f1a3a5c..5801963c101 100644
--- a/src/librustc_codegen_ssa/mono_item.rs
+++ b/src/librustc_codegen_ssa/mono_item.rs
@@ -58,7 +58,7 @@ impl<'a, 'tcx: 'a> MonoItemExt<'a, 'tcx> for MonoItem<'tcx> {
                self.to_raw_string(),
                cx.codegen_unit().name());
 
-        let symbol_name = self.symbol_name(cx.tcx()).as_str();
+        let symbol_name = self.symbol_name(cx.tcx()).name.as_str();
 
         debug!("symbol {}", &symbol_name);
 
diff --git a/src/librustc_codegen_ssa/traits/statics.rs b/src/librustc_codegen_ssa/traits/statics.rs
index 6983311d797..73c4c053979 100644
--- a/src/librustc_codegen_ssa/traits/statics.rs
+++ b/src/librustc_codegen_ssa/traits/statics.rs
@@ -1,5 +1,5 @@
 use super::BackendTypes;
-use syntax_pos::symbol::LocalInternedString;
+use syntax_pos::symbol::Symbol;
 use rustc::hir::def_id::DefId;
 use rustc::ty::layout::Align;
 
@@ -12,8 +12,8 @@ pub trait StaticBuilderMethods: BackendTypes {
     fn get_static(&mut self, def_id: DefId) -> Self::Value;
     fn static_panic_msg(
         &mut self,
-        msg: Option<LocalInternedString>,
-        filename: LocalInternedString,
+        msg: Option<Symbol>,
+        filename: Symbol,
         line: Self::Value,
         col: Self::Value,
         kind: &str,
diff --git a/src/librustc_codegen_utils/symbol_names_test.rs b/src/librustc_codegen_utils/symbol_names_test.rs
index f562744dbe7..51269be4e9f 100644
--- a/src/librustc_codegen_utils/symbol_names_test.rs
+++ b/src/librustc_codegen_utils/symbol_names_test.rs
@@ -40,7 +40,7 @@ impl SymbolNamesTest<'tcx> {
                 let instance = Instance::mono(tcx, def_id);
                 let mangled = self.tcx.symbol_name(instance);
                 tcx.sess.span_err(attr.span, &format!("symbol-name({})", mangled));
-                if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.as_str()) {
+                if let Ok(demangling) = rustc_demangle::try_demangle(&mangled.name.as_str()) {
                     tcx.sess.span_err(attr.span, &format!("demangling({})", demangling));
                     tcx.sess.span_err(attr.span, &format!("demangling-alt({:#})", demangling));
                 }
diff --git a/src/librustc_lexer/Cargo.toml b/src/librustc_lexer/Cargo.toml
index 0dbcda618ec..675d3065c5b 100644
--- a/src/librustc_lexer/Cargo.toml
+++ b/src/librustc_lexer/Cargo.toml
@@ -4,12 +4,12 @@ name = "rustc_lexer"
 version = "0.1.0"
 edition = "2018"
 
-# Note that this crate purposefully does not depend on other rustc crates
-[dependencies]
-unicode-xid = { version = "0.1.0", optional = true }
-
 # Note: do not remove this blank `[lib]` section.
 # This will be used when publishing this crate as `rustc-ap-rustc_lexer`.
 [lib]
 doctest = false
 name = "rustc_lexer"
+
+# Note that this crate purposefully does not depend on other rustc crates
+[dependencies]
+unicode-xid = "0.2.0"
diff --git a/src/librustc_lexer/src/lib.rs b/src/librustc_lexer/src/lib.rs
index 41b47befaf1..30a5175d8cd 100644
--- a/src/librustc_lexer/src/lib.rs
+++ b/src/librustc_lexer/src/lib.rs
@@ -1,6 +1,5 @@
-// We want to be able to build this crate with a stable compiler, so feature
-// flags should be optional.
-#![cfg_attr(not(feature = "unicode-xid"), feature(unicode_internals))]
+// We want to be able to build this crate with a stable compiler, so no
+// `#![feature]` attributes should be added.
 
 mod cursor;
 pub mod unescape;
@@ -103,6 +102,62 @@ pub fn tokenize(mut input: &str) -> impl Iterator<Item = Token> + '_ {
     })
 }
 
+// See [UAX #31](http://unicode.org/reports/tr31) for definitions of these
+// classes.
+
+/// True if `c` is considered a whitespace according to Rust language definition.
+pub fn is_whitespace(c: char) -> bool {
+    // This is Pattern_White_Space.
+    //
+    // Note that this set is stable (ie, it doesn't change with different
+    // Unicode versions), so it's ok to just hard-code the values.
+
+    match c {
+        // Usual ASCII suspects
+        | '\u{0009}' // \t
+        | '\u{000A}' // \n
+        | '\u{000B}' // vertical tab
+        | '\u{000C}' // form feed
+        | '\u{000D}' // \r
+        | '\u{0020}' // space
+
+        // NEXT LINE from latin1
+        | '\u{0085}'
+
+        // Bidi markers
+        | '\u{200E}' // LEFT-TO-RIGHT MARK
+        | '\u{200F}' // RIGHT-TO-LEFT MARK
+
+        // Dedicated whitespace characters from Unicode
+        | '\u{2028}' // LINE SEPARATOR
+        | '\u{2029}' // PARAGRAPH SEPARATOR
+            => true,
+        _ => false,
+    }
+}
+
+/// True if `c` is valid as a first character of an identifier.
+pub fn is_id_start(c: char) -> bool {
+    // This is XID_Start OR '_' (which formally is not a XID_Start).
+    // We also add fast-path for ascii idents
+    ('a' <= c && c <= 'z')
+        || ('A' <= c && c <= 'Z')
+        || c == '_'
+        || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
+}
+
+/// True if `c` is valid as a non-first character of an identifier.
+pub fn is_id_continue(c: char) -> bool {
+    // This is exactly XID_Continue.
+    // We also add fast-path for ascii idents
+    ('a' <= c && c <= 'z')
+        || ('A' <= c && c <= 'Z')
+        || ('0' <= c && c <= '9')
+        || c == '_'
+        || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
+}
+
+
 impl Cursor<'_> {
     fn advance_token(&mut self) -> Token {
         let first_char = self.bump().unwrap();
@@ -112,9 +167,9 @@ impl Cursor<'_> {
                 '*' => self.block_comment(),
                 _ => Slash,
             },
-            c if character_properties::is_whitespace(c) => self.whitespace(),
+            c if is_whitespace(c) => self.whitespace(),
             'r' => match (self.nth_char(0), self.nth_char(1)) {
-                ('#', c1) if character_properties::is_id_start(c1) => self.raw_ident(),
+                ('#', c1) if is_id_start(c1) => self.raw_ident(),
                 ('#', _) | ('"', _) => {
                     let (n_hashes, started, terminated) = self.raw_double_quoted_string();
                     let suffix_start = self.len_consumed();
@@ -159,7 +214,7 @@ impl Cursor<'_> {
                 }
                 _ => self.ident(),
             },
-            c if character_properties::is_id_start(c) => self.ident(),
+            c if is_id_start(c) => self.ident(),
             c @ '0'..='9' => {
                 let literal_kind = self.number(c);
                 let suffix_start = self.len_consumed();
@@ -247,8 +302,8 @@ impl Cursor<'_> {
     }
 
     fn whitespace(&mut self) -> TokenKind {
-        debug_assert!(character_properties::is_whitespace(self.prev()));
-        while character_properties::is_whitespace(self.nth_char(0)) {
+        debug_assert!(is_whitespace(self.prev()));
+        while is_whitespace(self.nth_char(0)) {
             self.bump();
         }
         Whitespace
@@ -258,19 +313,19 @@ impl Cursor<'_> {
         debug_assert!(
             self.prev() == 'r'
                 && self.nth_char(0) == '#'
-                && character_properties::is_id_start(self.nth_char(1))
+                && is_id_start(self.nth_char(1))
         );
         self.bump();
         self.bump();
-        while character_properties::is_id_continue(self.nth_char(0)) {
+        while is_id_continue(self.nth_char(0)) {
             self.bump();
         }
         RawIdent
     }
 
     fn ident(&mut self) -> TokenKind {
-        debug_assert!(character_properties::is_id_start(self.prev()));
-        while character_properties::is_id_continue(self.nth_char(0)) {
+        debug_assert!(is_id_start(self.prev()));
+        while is_id_continue(self.nth_char(0)) {
             self.bump();
         }
         Ident
@@ -315,7 +370,7 @@ impl Cursor<'_> {
             // integer literal followed by field/method access or a range pattern
             // (`0..2` and `12.foo()`)
             '.' if self.nth_char(1) != '.'
-                && !character_properties::is_id_start(self.nth_char(1)) =>
+                && !is_id_start(self.nth_char(1)) =>
             {
                 // might have stuff after the ., and if it does, it needs to start
                 // with a number
@@ -345,7 +400,7 @@ impl Cursor<'_> {
     fn lifetime_or_char(&mut self) -> TokenKind {
         debug_assert!(self.prev() == '\'');
         let mut starts_with_number = false;
-        if (character_properties::is_id_start(self.nth_char(0))
+        if (is_id_start(self.nth_char(0))
             || self.nth_char(0).is_digit(10) && {
                 starts_with_number = true;
                 true
@@ -353,7 +408,7 @@ impl Cursor<'_> {
             && self.nth_char(1) != '\''
         {
             self.bump();
-            while character_properties::is_id_continue(self.nth_char(0)) {
+            while is_id_continue(self.nth_char(0)) {
                 self.bump();
             }
 
@@ -495,66 +550,13 @@ impl Cursor<'_> {
     }
 
     fn eat_literal_suffix(&mut self) {
-        if !character_properties::is_id_start(self.nth_char(0)) {
+        if !is_id_start(self.nth_char(0)) {
             return;
         }
         self.bump();
 
-        while character_properties::is_id_continue(self.nth_char(0)) {
+        while is_id_continue(self.nth_char(0)) {
             self.bump();
         }
     }
 }
-
-pub mod character_properties {
-    // this is Pattern_White_Space
-    #[cfg(feature = "unicode-xid")]
-    pub fn is_whitespace(c: char) -> bool {
-        match c {
-            '\u{0009}' | '\u{000A}' | '\u{000B}' | '\u{000C}' | '\u{000D}' | '\u{0020}'
-            | '\u{0085}' | '\u{200E}' | '\u{200F}' | '\u{2028}' | '\u{2029}' => true,
-            _ => false,
-        }
-    }
-
-    #[cfg(not(feature = "unicode-xid"))]
-    pub fn is_whitespace(c: char) -> bool {
-        core::unicode::property::Pattern_White_Space(c)
-    }
-
-    // this is XID_Start OR '_' (which formally is not a XID_Start)
-    #[cfg(feature = "unicode-xid")]
-    pub fn is_id_start(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || c == '_'
-            || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_start(c))
-    }
-
-    #[cfg(not(feature = "unicode-xid"))]
-    pub fn is_id_start(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || c == '_'
-            || (c > '\x7f' && c.is_xid_start())
-    }
-
-    // this is XID_Continue
-    #[cfg(feature = "unicode-xid")]
-    pub fn is_id_continue(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || ('0' <= c && c <= '9')
-            || c == '_'
-            || (c > '\x7f' && unicode_xid::UnicodeXID::is_xid_continue(c))
-    }
-
-    #[cfg(not(feature = "unicode-xid"))]
-    pub fn is_id_continue(c: char) -> bool {
-        ('a' <= c && c <= 'z')
-            || ('A' <= c && c <= 'Z')
-            || ('0' <= c && c <= '9')
-            || c == '_'
-            || (c > '\x7f' && c.is_xid_continue())
-    }
-}
diff --git a/src/librustc_lint/unused.rs b/src/librustc_lint/unused.rs
index 90e46771396..39c0698aeec 100644
--- a/src/librustc_lint/unused.rs
+++ b/src/librustc_lint/unused.rs
@@ -398,18 +398,37 @@ impl UnusedParens {
         }
     }
 
-    fn check_unused_parens_pat(&self,
-                                cx: &EarlyContext<'_>,
-                                value: &ast::Pat,
-                                msg: &str) {
-        if let ast::PatKind::Paren(_) = value.node {
+    fn check_unused_parens_pat(
+        &self,
+        cx: &EarlyContext<'_>,
+        value: &ast::Pat,
+        avoid_or: bool,
+        avoid_mut: bool,
+    ) {
+        use ast::{PatKind, BindingMode::ByValue, Mutability::Mutable};
+
+        if let PatKind::Paren(inner) = &value.node {
+            match inner.node {
+                // The lint visitor will visit each subpattern of `p`. We do not want to lint
+                // any range pattern no matter where it occurs in the pattern. For something like
+                // `&(a..=b)`, there is a recursive `check_pat` on `a` and `b`, but we will assume
+                // that if there are unnecessary parens they serve a purpose of readability.
+                PatKind::Range(..) => return,
+                // Avoid `p0 | .. | pn` if we should.
+                PatKind::Or(..) if avoid_or => return,
+                // Avoid `mut x` and `mut x @ p` if we should:
+                PatKind::Ident(ByValue(Mutable), ..) if avoid_mut => return,
+                // Otherwise proceed with linting.
+                _ => {}
+            }
+
             let pattern_text = if let Ok(snippet) = cx.sess().source_map()
                 .span_to_snippet(value.span) {
                     snippet
                 } else {
                     pprust::pat_to_string(value)
                 };
-            Self::remove_outer_parens(cx, value.span, &pattern_text, msg, (false, false));
+            Self::remove_outer_parens(cx, value.span, &pattern_text, "pattern", (false, false));
         }
     }
 
@@ -474,6 +493,13 @@ impl EarlyLintPass for UnusedParens {
     fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) {
         use syntax::ast::ExprKind::*;
         let (value, msg, followed_by_block, left_pos, right_pos) = match e.node {
+            Let(ref pats, ..) => {
+                for p in pats {
+                    self.check_unused_parens_pat(cx, p, false, false);
+                }
+                return;
+            }
+
             If(ref cond, ref block, ..) => {
                 let left = e.span.lo() + syntax_pos::BytePos(2);
                 let right = block.span.lo();
@@ -486,7 +512,8 @@ impl EarlyLintPass for UnusedParens {
                 (cond, "`while` condition", true, Some(left), Some(right))
             },
 
-            ForLoop(_, ref cond, ref block, ..) => {
+            ForLoop(ref pat, ref cond, ref block, ..) => {
+                self.check_unused_parens_pat(cx, pat, false, false);
                 (cond, "`for` head expression", true, None, Some(block.span.lo()))
             }
 
@@ -531,26 +558,46 @@ impl EarlyLintPass for UnusedParens {
     }
 
     fn check_pat(&mut self, cx: &EarlyContext<'_>, p: &ast::Pat) {
-        use ast::PatKind::{Paren, Range};
-        // The lint visitor will visit each subpattern of `p`. We do not want to lint any range
-        // pattern no matter where it occurs in the pattern. For something like `&(a..=b)`, there
-        // is a recursive `check_pat` on `a` and `b`, but we will assume that if there are
-        // unnecessary parens they serve a purpose of readability.
-        if let Paren(ref pat) = p.node {
-            match pat.node {
-                Range(..) => {}
-                _ => self.check_unused_parens_pat(cx, &p, "pattern")
-            }
+        use ast::{PatKind::*, Mutability};
+        match &p.node {
+            // Do not lint on `(..)` as that will result in the other arms being useless.
+            Paren(_)
+            // The other cases do not contain sub-patterns.
+            | Wild | Rest | Lit(..) | Mac(..) | Range(..) | Ident(.., None) | Path(..) => return,
+            // These are list-like patterns; parens can always be removed.
+            TupleStruct(_, ps) | Tuple(ps) | Slice(ps) | Or(ps) => for p in ps {
+                self.check_unused_parens_pat(cx, p, false, false);
+            },
+            Struct(_, fps, _) => for f in fps {
+                self.check_unused_parens_pat(cx, &f.pat, false, false);
+            },
+            // Avoid linting on `i @ (p0 | .. | pn)` and `box (p0 | .. | pn)`, #64106.
+            Ident(.., Some(p)) | Box(p) => self.check_unused_parens_pat(cx, p, true, false),
+            // Avoid linting on `&(mut x)` as `&mut x` has a different meaning, #55342.
+            // Also avoid linting on `& mut? (p0 | .. | pn)`, #64106.
+            Ref(p, m) => self.check_unused_parens_pat(cx, p, true, *m == Mutability::Immutable),
         }
     }
 
     fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
         if let ast::StmtKind::Local(ref local) = s.node {
+            self.check_unused_parens_pat(cx, &local.pat, false, false);
+
             if let Some(ref value) = local.init {
                 self.check_unused_parens_expr(cx, &value, "assigned value", false, None, None);
             }
         }
     }
+
+    fn check_param(&mut self, cx: &EarlyContext<'_>, param: &ast::Param) {
+        self.check_unused_parens_pat(cx, &param.pat, true, false);
+    }
+
+    fn check_arm(&mut self, cx: &EarlyContext<'_>, arm: &ast::Arm) {
+        for p in &arm.pats {
+            self.check_unused_parens_pat(cx, p, false, false);
+        }
+    }
 }
 
 declare_lint! {
diff --git a/src/librustc_llvm/build.rs b/src/librustc_llvm/build.rs
index 40ddd651642..62a3757757b 100644
--- a/src/librustc_llvm/build.rs
+++ b/src/librustc_llvm/build.rs
@@ -54,7 +54,7 @@ fn main() {
     // LLVM are compiled the same way, but for us that's typically the case.
     //
     // We *want* detect this cross compiling situation by asking llvm-config
-    // what it's host-target is. If that's not the TARGET, then we're cross
+    // what its host-target is. If that's not the TARGET, then we're cross
     // compiling. Unfortunately `llvm-config` seems either be buggy, or we're
     // misconfiguring it, because the `i686-pc-windows-gnu` build of LLVM will
     // report itself with a `--host-target` of `x86_64-pc-windows-gnu`. This
@@ -62,7 +62,7 @@ fn main() {
     // havoc ensues.
     //
     // In any case, if we're cross compiling, this generally just means that we
-    // can't trust all the output of llvm-config becaues it might be targeted
+    // can't trust all the output of llvm-config because it might be targeted
     // for the host rather than the target. As a result a bunch of blocks below
     // are gated on `if !is_crossed`
     let target = env::var("TARGET").expect("TARGET was not set");
@@ -166,7 +166,7 @@ fn main() {
 
     let (llvm_kind, llvm_link_arg) = detect_llvm_link();
 
-    // Link in all LLVM libraries, if we're uwring the "wrong" llvm-config then
+    // Link in all LLVM libraries, if we're using the "wrong" llvm-config then
     // we don't pick up system libs because unfortunately they're for the host
     // of llvm-config, not the target that we're attempting to link.
     let mut cmd = Command::new(&llvm_config);
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index db212408d8e..f430f01542e 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1354,7 +1354,7 @@ impl EncodeContext<'tcx> {
         let def_id = self.tcx.hir().local_def_id(macro_def.hir_id);
         Entry {
             kind: EntryKind::MacroDef(self.lazy(MacroDef {
-                body: pprust::tokens_to_string(macro_def.body.clone()),
+                body: pprust::tts_to_string(macro_def.body.clone()),
                 legacy: macro_def.legacy,
             })),
             visibility: self.lazy(ty::Visibility::Public),
diff --git a/src/librustc_mir/Cargo.toml b/src/librustc_mir/Cargo.toml
index 21008c73728..e02736078b5 100644
--- a/src/librustc_mir/Cargo.toml
+++ b/src/librustc_mir/Cargo.toml
@@ -15,11 +15,12 @@ either = "1.5.0"
 dot = { path = "../libgraphviz", package = "graphviz" }
 log = "0.4"
 log_settings = "0.1.1"
-polonius-engine  = "0.9.0"
+polonius-engine  = "0.10.0"
 rustc = { path = "../librustc" }
 rustc_target = { path = "../librustc_target" }
 rustc_data_structures = { path = "../librustc_data_structures" }
 rustc_errors = { path = "../librustc_errors" }
+rustc_lexer = { path = "../librustc_lexer" }
 rustc_serialize = { path = "../libserialize", package = "serialize" }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs
index 251d4b727c7..9f25e98052e 100644
--- a/src/librustc_mir/borrow_check/error_reporting.rs
+++ b/src/librustc_mir/borrow_check/error_reporting.rs
@@ -336,7 +336,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
         let local = &self.body.local_decls[local_index];
         match local.name {
             Some(name) if !local.from_compiler_desugaring() => {
-                buf.push_str(name.as_str().get());
+                buf.push_str(&name.as_str());
                 Ok(())
             }
             _ => Err(()),
diff --git a/src/librustc_mir/borrow_check/flows.rs b/src/librustc_mir/borrow_check/flows.rs
index bb217a1f965..4400e0c8395 100644
--- a/src/librustc_mir/borrow_check/flows.rs
+++ b/src/librustc_mir/borrow_check/flows.rs
@@ -12,7 +12,7 @@ use crate::borrow_check::location::LocationIndex;
 use polonius_engine::Output;
 
 use crate::dataflow::indexes::BorrowIndex;
-use crate::dataflow::move_paths::HasMoveData;
+use crate::dataflow::move_paths::{HasMoveData, MovePathIndex};
 use crate::dataflow::Borrows;
 use crate::dataflow::EverInitializedPlaces;
 use crate::dataflow::MaybeUninitializedPlaces;
@@ -21,7 +21,7 @@ use either::Either;
 use std::fmt;
 use std::rc::Rc;
 
-crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local>;
+crate type PoloniusOutput = Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
 
 // (forced to be `pub` due to its use as an associated type below.)
 crate struct Flows<'b, 'tcx> {
diff --git a/src/librustc_mir/borrow_check/move_errors.rs b/src/librustc_mir/borrow_check/move_errors.rs
index f10ff71b15e..0d13db2f5a4 100644
--- a/src/librustc_mir/borrow_check/move_errors.rs
+++ b/src/librustc_mir/borrow_check/move_errors.rs
@@ -1,5 +1,3 @@
-use core::unicode::property::Pattern_White_Space;
-
 use rustc::mir::*;
 use rustc::ty;
 use rustc_errors::{DiagnosticBuilder,Applicability};
@@ -526,7 +524,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
                         let suggestion;
                         let to_remove;
                         if pat_snippet.starts_with("mut")
-                            && pat_snippet["mut".len()..].starts_with(Pattern_White_Space)
+                            && pat_snippet["mut".len()..].starts_with(rustc_lexer::is_whitespace)
                         {
                             suggestion = pat_snippet["mut".len()..].trim_start();
                             to_remove = "&mut";
diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs
index 5a5534922aa..8f2ce80aafa 100644
--- a/src/librustc_mir/borrow_check/mutability_errors.rs
+++ b/src/librustc_mir/borrow_check/mutability_errors.rs
@@ -1,4 +1,3 @@
-use core::unicode::property::Pattern_White_Space;
 use rustc::hir;
 use rustc::hir::Node;
 use rustc::mir::{self, BindingForm, ClearCrossCrate, Local, Location, Body};
@@ -715,7 +714,7 @@ fn annotate_struct_field(
 fn suggest_ref_mut(tcx: TyCtxt<'_>, binding_span: Span) -> Option<String> {
     let hi_src = tcx.sess.source_map().span_to_snippet(binding_span).ok()?;
     if hi_src.starts_with("ref")
-        && hi_src["ref".len()..].starts_with(Pattern_White_Space)
+        && hi_src["ref".len()..].starts_with(rustc_lexer::is_whitespace)
     {
         let replacement = format!("ref mut{}", &hi_src["ref".len()..]);
         Some(replacement)
diff --git a/src/librustc_mir/borrow_check/nll/facts.rs b/src/librustc_mir/borrow_check/nll/facts.rs
index 05451cdfb83..f0beb4d3ae3 100644
--- a/src/librustc_mir/borrow_check/nll/facts.rs
+++ b/src/librustc_mir/borrow_check/nll/facts.rs
@@ -1,5 +1,5 @@
 use crate::borrow_check::location::{LocationIndex, LocationTable};
-use crate::dataflow::indexes::BorrowIndex;
+use crate::dataflow::indexes::{BorrowIndex, MovePathIndex};
 use polonius_engine::AllFacts as PoloniusAllFacts;
 use polonius_engine::Atom;
 use rustc::mir::Local;
@@ -11,7 +11,7 @@ use std::fs::{self, File};
 use std::io::Write;
 use std::path::Path;
 
-crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local>;
+crate type AllFacts = PoloniusAllFacts<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>;
 
 crate trait AllFactsExt {
     /// Returns `true` if there is a need to gather `AllFacts` given the
@@ -58,14 +58,17 @@ impl AllFactsExt for AllFacts {
                 cfg_edge,
                 killed,
                 outlives,
-                region_live_at,
                 invalidates,
                 var_used,
                 var_defined,
                 var_drop_used,
                 var_uses_region,
                 var_drops_region,
-                var_initialized_on_exit,
+                child,
+                path_belongs_to_var,
+                initialized_at,
+                moved_out_at,
+                path_accessed_at,
             ])
         }
         Ok(())
@@ -84,6 +87,12 @@ impl Atom for LocationIndex {
     }
 }
 
+impl Atom for MovePathIndex {
+    fn index(self) -> usize {
+        Idx::index(self)
+    }
+}
+
 struct FactWriter<'w> {
     location_table: &'w LocationTable,
     dir: &'w Path,
diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs
index 11ec154e5b5..1ff3228afa3 100644
--- a/src/librustc_mir/borrow_check/nll/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/mod.rs
@@ -4,14 +4,15 @@ use crate::borrow_check::nll::facts::AllFactsExt;
 use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
 use crate::borrow_check::nll::region_infer::values::RegionValueElements;
 use crate::dataflow::indexes::BorrowIndex;
-use crate::dataflow::move_paths::MoveData;
+use crate::dataflow::move_paths::{InitLocation, MoveData, MovePathIndex, InitKind};
 use crate::dataflow::FlowAtLocation;
 use crate::dataflow::MaybeInitializedPlaces;
 use crate::transform::MirSource;
 use crate::borrow_check::Upvar;
 use rustc::hir::def_id::DefId;
 use rustc::infer::InferCtxt;
-use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Local, Body, Promoted};
+use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements,
+                 Local, Location, Body, LocalKind, BasicBlock, Promoted};
 use rustc::ty::{self, RegionKind, RegionVid};
 use rustc_data_structures::indexed_vec::IndexVec;
 use rustc_errors::Diagnostic;
@@ -69,6 +70,85 @@ pub(in crate::borrow_check) fn replace_regions_in_mir<'cx, 'tcx>(
     universal_regions
 }
 
+
+// This function populates an AllFacts instance with base facts related to
+// MovePaths and needed for the move analysis.
+fn populate_polonius_move_facts(
+    all_facts: &mut AllFacts,
+    move_data: &MoveData<'_>,
+    location_table: &LocationTable,
+    body: &Body<'_>) {
+    all_facts
+        .path_belongs_to_var
+        .extend(
+            move_data
+                .rev_lookup
+                .iter_locals_enumerated()
+                .map(|(v, &m)| (m, v)));
+
+    for (child, move_path) in move_data.move_paths.iter_enumerated() {
+        all_facts
+            .child
+            .extend(
+                move_path
+                    .parents(&move_data.move_paths)
+                    .iter()
+                    .map(|&parent| (child, parent)));
+    }
+
+    // initialized_at
+    for init in move_data.inits.iter() {
+
+        match init.location {
+            InitLocation::Statement(location) => {
+                let block_data = &body[location.block];
+                let is_terminator = location.statement_index == block_data.statements.len();
+
+                if is_terminator && init.kind == InitKind::NonPanicPathOnly {
+                    // We are at the terminator of an init that has a panic path,
+                    // and where the init should not happen on panic
+
+                    for &successor in block_data.terminator().successors() {
+                        if body[successor].is_cleanup {
+                            continue;
+                        }
+
+                        // The initialization happened in (or rather, when arriving at)
+                        // the successors, but not in the unwind block.
+                        let first_statement = Location { block: successor, statement_index: 0};
+                        all_facts
+                            .initialized_at
+                            .push((init.path, location_table.start_index(first_statement)));
+                    }
+
+                } else {
+                    // In all other cases, the initialization just happens at the
+                    // midpoint, like any other effect.
+                    all_facts.initialized_at.push((init.path, location_table.mid_index(location)));
+                }
+            },
+            // Arguments are initialized on function entry
+            InitLocation::Argument(local) => {
+                assert!(body.local_kind(local) == LocalKind::Arg);
+                let fn_entry = Location {block: BasicBlock::from_u32(0u32), statement_index: 0 };
+                all_facts.initialized_at.push((init.path, location_table.start_index(fn_entry)));
+
+            }
+        }
+    }
+
+
+    // moved_out_at
+    // deinitialisation is assumed to always happen!
+    all_facts
+        .moved_out_at
+        .extend(
+            move_data
+                .moves
+                .iter()
+                .map(|mo| (mo.path, location_table.mid_index(mo.source))));
+}
+
 /// Computes the (non-lexical) regions from the input MIR.
 ///
 /// This may result in errors being reported.
@@ -87,7 +167,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
     errors_buffer: &mut Vec<Diagnostic>,
 ) -> (
     RegionInferenceContext<'tcx>,
-    Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local>>>,
+    Option<Rc<Output<RegionVid, BorrowIndex, LocationIndex, Local, MovePathIndex>>>,
     Option<ClosureRegionRequirements<'tcx>>,
 ) {
     let mut all_facts = if AllFacts::enabled(infcx.tcx) {
@@ -123,6 +203,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
         all_facts
             .universal_region
             .extend(universal_regions.universal_regions());
+        populate_polonius_move_facts(all_facts, move_data, location_table, body);
     }
 
     // Create the region inference context, taking ownership of the
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
index 2a066538cc2..049d83bb22f 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/local_use_map.rs
@@ -1,7 +1,7 @@
 use crate::borrow_check::nll::region_infer::values::{PointIndex, RegionValueElements};
 use crate::util::liveness::{categorize, DefUse};
 use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Local, Location, Body};
+use rustc::mir::{Body, Local, Location};
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
 use rustc_data_structures::vec_linked_list as vll;
 
@@ -72,16 +72,10 @@ impl LocalUseMap {
 
         let mut locals_with_use_data: IndexVec<Local, bool> =
             IndexVec::from_elem_n(false, body.local_decls.len());
-        live_locals
-            .iter()
-            .for_each(|&local| locals_with_use_data[local] = true);
-
-        LocalUseMapBuild {
-            local_use_map: &mut local_use_map,
-            elements,
-            locals_with_use_data,
-        }
-        .visit_body(body);
+        live_locals.iter().for_each(|&local| locals_with_use_data[local] = true);
+
+        LocalUseMapBuild { local_use_map: &mut local_use_map, elements, locals_with_use_data }
+            .visit_body(body);
 
         local_use_map
     }
@@ -151,10 +145,8 @@ impl LocalUseMapBuild<'_> {
         location: Location,
     ) {
         let point_index = elements.point_from_location(location);
-        let appearance_index = appearances.push(Appearance {
-            point_index,
-            next: *first_appearance,
-        });
+        let appearance_index =
+            appearances.push(Appearance { point_index, next: *first_appearance });
         *first_appearance = Some(appearance_index);
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
index 8970009b6ee..3f2ec1ba970 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs
@@ -58,9 +58,9 @@ pub(super) fn generate<'tcx>(
     };
 
     if !live_locals.is_empty() {
-        trace::trace(typeck, body, elements, flow_inits, move_data, live_locals, location_table);
+        trace::trace(typeck, body, elements, flow_inits, move_data, live_locals);
 
-        polonius::populate_var_liveness_facts(typeck, body, location_table);
+        polonius::populate_access_facts(typeck, body, location_table, move_data);
     }
 }
 
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
index 20d7ec55e3e..d61464b3f38 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/polonius.rs
@@ -1,22 +1,28 @@
 use crate::borrow_check::location::{LocationIndex, LocationTable};
+use crate::dataflow::indexes::MovePathIndex;
+use crate::dataflow::move_paths::{LookupResult, MoveData};
 use crate::util::liveness::{categorize, DefUse};
-use rustc::mir::visit::{PlaceContext, Visitor};
-use rustc::mir::{Body, Local, Location};
+use rustc::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
+use rustc::mir::{Body, Local, Location, Place};
 use rustc::ty::subst::Kind;
 use rustc::ty::Ty;
 
 use super::TypeChecker;
 
 type VarPointRelations = Vec<(Local, LocationIndex)>;
+type MovePathPointRelations = Vec<(MovePathIndex, LocationIndex)>;
 
-struct LivenessPointFactsExtractor<'me> {
+struct UseFactsExtractor<'me> {
     var_defined: &'me mut VarPointRelations,
     var_used: &'me mut VarPointRelations,
     location_table: &'me LocationTable,
+    var_drop_used: &'me mut VarPointRelations,
+    move_data: &'me MoveData<'me>,
+    path_accessed_at: &'me mut MovePathPointRelations,
 }
 
 // A Visitor to walk through the MIR and extract point-wise facts
-impl LivenessPointFactsExtractor<'_> {
+impl UseFactsExtractor<'_> {
     fn location_to_index(&self, location: Location) -> LocationIndex {
         self.location_table.mid_index(location)
     }
@@ -30,15 +36,50 @@ impl LivenessPointFactsExtractor<'_> {
         debug!("LivenessFactsExtractor::insert_use()");
         self.var_used.push((local, self.location_to_index(location)));
     }
+
+    fn insert_drop_use(&mut self, local: Local, location: Location) {
+        debug!("LivenessFactsExtractor::insert_drop_use()");
+        self.var_drop_used.push((local, self.location_to_index(location)));
+    }
+
+    fn insert_path_access(&mut self, path: MovePathIndex, location: Location) {
+        debug!("LivenessFactsExtractor::insert_path_access({:?}, {:?})", path, location);
+        self.path_accessed_at.push((path, self.location_to_index(location)));
+    }
+
+    fn place_to_mpi(&self, place: &Place<'_>) -> Option<MovePathIndex> {
+        match self.move_data.rev_lookup.find(place.as_ref()) {
+            LookupResult::Exact(mpi) => Some(mpi),
+            LookupResult::Parent(mmpi) => mmpi,
+        }
+    }
 }
 
-impl Visitor<'tcx> for LivenessPointFactsExtractor<'_> {
+impl Visitor<'tcx> for UseFactsExtractor<'_> {
     fn visit_local(&mut self, &local: &Local, context: PlaceContext, location: Location) {
         match categorize(context) {
             Some(DefUse::Def) => self.insert_def(local, location),
             Some(DefUse::Use) => self.insert_use(local, location),
+            Some(DefUse::Drop) => self.insert_drop_use(local, location),
+            _ => (),
+        }
+    }
+
+    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) {
+        self.super_place(place, context, location);
+        match context {
+            PlaceContext::NonMutatingUse(_) => {
+                if let Some(mpi) = self.place_to_mpi(place) {
+                    self.insert_path_access(mpi, location);
+                }
+            }
+
+            PlaceContext::MutatingUse(MutatingUseContext::Borrow) => {
+                if let Some(mpi) = self.place_to_mpi(place) {
+                    self.insert_path_access(mpi, location);
+                }
+            }
             _ => (),
-            // NOTE: Drop handling is now done in trace()
         }
     }
 }
@@ -54,23 +95,27 @@ fn add_var_uses_regions(typeck: &mut TypeChecker<'_, 'tcx>, local: Local, ty: Ty
     });
 }
 
-pub(super) fn populate_var_liveness_facts(
+pub(super) fn populate_access_facts(
     typeck: &mut TypeChecker<'_, 'tcx>,
-    mir: &Body<'tcx>,
+    body: &Body<'tcx>,
     location_table: &LocationTable,
+    move_data: &MoveData<'_>,
 ) {
     debug!("populate_var_liveness_facts()");
 
     if let Some(facts) = typeck.borrowck_context.all_facts.as_mut() {
-        LivenessPointFactsExtractor {
+        UseFactsExtractor {
             var_defined: &mut facts.var_defined,
             var_used: &mut facts.var_used,
+            var_drop_used: &mut facts.var_drop_used,
+            path_accessed_at: &mut facts.path_accessed_at,
             location_table,
+            move_data,
         }
-        .visit_body(mir);
+        .visit_body(body);
     }
 
-    for (local, local_decl) in mir.local_decls.iter_enumerated() {
+    for (local, local_decl) in body.local_decls.iter_enumerated() {
         add_var_uses_regions(typeck, local, local_decl.ty);
     }
 }
diff --git a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
index 039ed939ada..9b55881cb1b 100644
--- a/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
+++ b/src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs
@@ -1,4 +1,3 @@
-use crate::borrow_check::location::LocationTable;
 use crate::borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
 use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
 use crate::borrow_check::nll::type_check::liveness::polonius;
@@ -38,7 +37,6 @@ pub(super) fn trace(
     flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
     move_data: &MoveData<'tcx>,
     live_locals: Vec<Local>,
-    location_table: &LocationTable,
 ) {
     debug!("trace()");
 
@@ -52,7 +50,6 @@ pub(super) fn trace(
         local_use_map,
         move_data,
         drop_data: FxHashMap::default(),
-        location_table,
     };
 
     LivenessResults::new(cx).compute_for_all_locals(live_locals);
@@ -82,9 +79,6 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
     /// Index indicating where each variable is assigned, used, or
     /// dropped.
     local_use_map: &'me LocalUseMap,
-
-    /// Maps between a MIR Location and a LocationIndex
-    location_table: &'me LocationTable,
 }
 
 struct DropData<'tcx> {
@@ -131,12 +125,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
         for local in live_locals {
             self.reset_local_state();
             self.add_defs_for(local);
-
-            // FIXME: this is temporary until we can generate our own initialization
-            if self.cx.typeck.borrowck_context.all_facts.is_some() {
-                self.add_polonius_var_initialized_on_exit_for(local)
-            }
-
             self.compute_use_live_points_for(local);
             self.compute_drop_live_points_for(local);
 
@@ -157,63 +145,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
         }
     }
 
-    // WARNING: panics if self.cx.typeck.borrowck_context.all_facts != None
-    //
-    // FIXME: this analysis (the initialization tracking) should be
-    // done in Polonius, but isn't yet.
-    fn add_polonius_var_initialized_on_exit_for(&mut self, local: Local) {
-        let move_path = self.cx.move_data.rev_lookup.find_local(local);
-        let facts = self.cx.typeck.borrowck_context.all_facts.as_mut().unwrap();
-        for block in self.cx.body.basic_blocks().indices() {
-            debug!("polonius: generating initialization facts for {:?} in {:?}", local, block);
-
-            // iterate through the block, applying the effects of each statement
-            // up to and including location, and populate `var_initialized_on_exit`
-            self.cx.flow_inits.reset_to_entry_of(block);
-            let start_location = Location { block, statement_index: 0 };
-            self.cx.flow_inits.apply_local_effect(start_location);
-
-            for statement_index in 0..self.cx.body[block].statements.len() {
-                let current_location = Location { block, statement_index };
-
-                self.cx.flow_inits.reconstruct_statement_effect(current_location);
-
-                // statement has not yet taken effect:
-                if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                    facts
-                        .var_initialized_on_exit
-                        .push((local, self.cx.location_table.start_index(current_location)));
-                }
-
-                // statement has now taken effect
-                self.cx.flow_inits.apply_local_effect(current_location);
-
-                if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                    facts
-                        .var_initialized_on_exit
-                        .push((local, self.cx.location_table.mid_index(current_location)));
-                }
-            }
-
-            let terminator_location = self.cx.body.terminator_loc(block);
-
-            if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                facts
-                    .var_initialized_on_exit
-                    .push((local, self.cx.location_table.start_index(terminator_location)));
-            }
-
-            // apply the effects of the terminator and push it if needed
-            self.cx.flow_inits.reset_to_exit_of(block);
-
-            if self.cx.flow_inits.has_any_child_of(move_path).is_some() {
-                facts
-                    .var_initialized_on_exit
-                    .push((local, self.cx.location_table.mid_index(terminator_location)));
-            }
-        }
-    }
-
     /// Clear the value of fields that are "per local variable".
     fn reset_local_state(&mut self) {
         self.defs.clear();
@@ -273,11 +204,6 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
             debug_assert_eq!(self.cx.body.terminator_loc(location.block), location,);
 
             if self.cx.initialized_at_terminator(location.block, mpi) {
-                // FIXME: this analysis (the initialization tracking) should be
-                // done in Polonius, but isn't yet.
-                if let Some(facts) = self.cx.typeck.borrowck_context.all_facts {
-                    facts.var_drop_used.push((local, self.cx.location_table.mid_index(location)));
-                }
                 if self.drop_live_at.insert(drop_point) {
                     self.drop_locations.push(location);
                     self.stack.push(drop_point);
@@ -468,13 +394,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
     ) {
         debug!("add_use_live_facts_for(value={:?})", value);
 
-        Self::make_all_regions_live(
-            self.elements,
-            &mut self.typeck,
-            value,
-            live_at,
-            self.location_table,
-        )
+        Self::make_all_regions_live(self.elements, &mut self.typeck, value, live_at)
     }
 
     /// Some variable with type `live_ty` is "drop live" at `location`
@@ -525,13 +445,7 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
         // All things in the `outlives` array may be touched by
         // the destructor and must be live at this point.
         for &kind in &drop_data.dropck_result.kinds {
-            Self::make_all_regions_live(
-                self.elements,
-                &mut self.typeck,
-                kind,
-                live_at,
-                self.location_table,
-            );
+            Self::make_all_regions_live(self.elements, &mut self.typeck, kind, live_at);
 
             polonius::add_var_drops_regions(&mut self.typeck, dropped_local, &kind);
         }
@@ -542,7 +456,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
         typeck: &mut TypeChecker<'_, 'tcx>,
         value: impl TypeFoldable<'tcx>,
         live_at: &HybridBitSet<PointIndex>,
-        location_table: &LocationTable,
     ) {
         debug!("make_all_regions_live(value={:?})", value);
         debug!(
@@ -559,15 +472,6 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
                 .constraints
                 .liveness_constraints
                 .add_elements(live_region_vid, live_at);
-
-            // FIXME: remove this when we can generate our own region-live-at reliably
-            if let Some(facts) = typeck.borrowck_context.all_facts {
-                for point in live_at.iter() {
-                    let loc = elements.to_location(point);
-                    facts.region_live_at.push((live_region_vid, location_table.start_index(loc)));
-                    facts.region_live_at.push((live_region_vid, location_table.mid_index(loc)));
-                }
-            }
         });
     }
 
diff --git a/src/librustc_mir/borrow_check/path_utils.rs b/src/librustc_mir/borrow_check/path_utils.rs
index 43a012e1494..bac08090817 100644
--- a/src/librustc_mir/borrow_check/path_utils.rs
+++ b/src/librustc_mir/borrow_check/path_utils.rs
@@ -3,7 +3,7 @@ use crate::borrow_check::places_conflict;
 use crate::borrow_check::AccessDepth;
 use crate::dataflow::indexes::BorrowIndex;
 use rustc::mir::{BasicBlock, Location, Body, Place, PlaceBase};
-use rustc::mir::{ProjectionElem, BorrowKind};
+use rustc::mir::BorrowKind;
 use rustc::ty::{self, TyCtxt};
 use rustc_data_structures::graph::dominators::Dominators;
 
@@ -133,20 +133,11 @@ pub(super) fn is_active<'tcx>(
 /// Determines if a given borrow is borrowing local data
 /// This is called for all Yield statements on movable generators
 pub(super) fn borrow_of_local_data(place: &Place<'_>) -> bool {
-    place.iterate(|place_base, place_projection| {
-        match place_base {
-            PlaceBase::Static(..) => return false,
-            PlaceBase::Local(..) => {},
-        }
-
-        for proj in place_projection {
-            // Reborrow of already borrowed data is ignored
-            // Any errors will be caught on the initial borrow
-            if proj.elem == ProjectionElem::Deref {
-                return false;
-            }
-        }
+    match place.base {
+        PlaceBase::Static(_) => false,
 
-        true
-    })
+        // Reborrow of already borrowed data is ignored
+        // Any errors will be caught on the initial borrow
+        PlaceBase::Local(_) => !place.is_indirect(),
+    }
 }
diff --git a/src/librustc_mir/dataflow/impls/borrowed_locals.rs b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
index d94ebdbae24..1c43a553cc3 100644
--- a/src/librustc_mir/dataflow/impls/borrowed_locals.rs
+++ b/src/librustc_mir/dataflow/impls/borrowed_locals.rs
@@ -93,19 +93,10 @@ struct BorrowedLocalsVisitor<'gk> {
 }
 
 fn find_local(place: &Place<'_>) -> Option<Local> {
-    place.iterate(|place_base, place_projection| {
-        for proj in place_projection {
-            if proj.elem == ProjectionElem::Deref {
-                return None;
-            }
-        }
-
-        if let PlaceBase::Local(local) = place_base {
-            Some(*local)
-        } else {
-            None
-        }
-    })
+    match place.base {
+        PlaceBase::Local(local) if !place.is_indirect() => Some(local),
+        _ => None,
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for BorrowedLocalsVisitor<'_> {
diff --git a/src/librustc_mir/dataflow/move_paths/abs_domain.rs b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
index b26547c4ff7..d97f3b74172 100644
--- a/src/librustc_mir/dataflow/move_paths/abs_domain.rs
+++ b/src/librustc_mir/dataflow/move_paths/abs_domain.rs
@@ -11,7 +11,7 @@
 //! `a[x]` would still overlap them both. But that is not this
 //! representation does today.)
 
-use rustc::mir::{Local, PlaceElem, Operand, ProjectionElem};
+use rustc::mir::{Local, Operand, PlaceElem, ProjectionElem};
 use rustc::ty::Ty;
 
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
@@ -26,36 +26,36 @@ pub trait Lift {
 }
 impl<'tcx> Lift for Operand<'tcx> {
     type Abstract = AbstractOperand;
-    fn lift(&self) -> Self::Abstract { AbstractOperand }
+    fn lift(&self) -> Self::Abstract {
+        AbstractOperand
+    }
 }
 impl Lift for Local {
     type Abstract = AbstractOperand;
-    fn lift(&self) -> Self::Abstract { AbstractOperand }
+    fn lift(&self) -> Self::Abstract {
+        AbstractOperand
+    }
 }
 impl<'tcx> Lift for Ty<'tcx> {
     type Abstract = AbstractType;
-    fn lift(&self) -> Self::Abstract { AbstractType }
+    fn lift(&self) -> Self::Abstract {
+        AbstractType
+    }
 }
 impl<'tcx> Lift for PlaceElem<'tcx> {
     type Abstract = AbstractElem;
     fn lift(&self) -> Self::Abstract {
         match *self {
-            ProjectionElem::Deref =>
-                ProjectionElem::Deref,
-            ProjectionElem::Field(ref f, ty) =>
-                ProjectionElem::Field(f.clone(), ty.lift()),
-            ProjectionElem::Index(ref i) =>
-                ProjectionElem::Index(i.lift()),
-            ProjectionElem::Subslice {from, to} =>
-                ProjectionElem::Subslice { from: from, to: to },
-            ProjectionElem::ConstantIndex {offset,min_length,from_end} =>
-                ProjectionElem::ConstantIndex {
-                    offset,
-                    min_length,
-                    from_end,
-                },
-            ProjectionElem::Downcast(a, u) =>
-                ProjectionElem::Downcast(a, u.clone()),
+            ProjectionElem::Deref => ProjectionElem::Deref,
+            ProjectionElem::Field(ref f, ty) => ProjectionElem::Field(f.clone(), ty.lift()),
+            ProjectionElem::Index(ref i) => ProjectionElem::Index(i.lift()),
+            ProjectionElem::Subslice { from, to } => {
+                ProjectionElem::Subslice { from: from, to: to }
+            }
+            ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
+                ProjectionElem::ConstantIndex { offset, min_length, from_end }
+            }
+            ProjectionElem::Downcast(a, u) => ProjectionElem::Downcast(a, u.clone()),
         }
     }
 }
diff --git a/src/librustc_mir/dataflow/move_paths/builder.rs b/src/librustc_mir/dataflow/move_paths/builder.rs
index 366b96b53b4..81451c2500c 100644
--- a/src/librustc_mir/dataflow/move_paths/builder.rs
+++ b/src/librustc_mir/dataflow/move_paths/builder.rs
@@ -1,16 +1,18 @@
-use rustc::ty::{self, TyCtxt};
-use rustc::mir::*;
 use rustc::mir::tcx::RvalueInitializationState;
-use rustc_data_structures::indexed_vec::{IndexVec};
-use smallvec::{SmallVec, smallvec};
+use rustc::mir::*;
+use rustc::ty::{self, TyCtxt};
+use rustc_data_structures::indexed_vec::IndexVec;
+use smallvec::{smallvec, SmallVec};
 
 use std::collections::hash_map::Entry;
 use std::mem;
 
 use super::abs_domain::Lift;
-use super::{LocationMap, MoveData, MovePath, MovePathLookup, MovePathIndex, MoveOut, MoveOutIndex};
-use super::{MoveError, InitIndex, Init, InitLocation, LookupResult, InitKind};
 use super::IllegalMoveOriginKind::*;
+use super::{Init, InitIndex, InitKind, InitLocation, LookupResult, MoveError};
+use super::{
+    LocationMap, MoveData, MoveOut, MoveOutIndex, MovePath, MovePathIndex, MovePathLookup,
+};
 
 struct MoveDataBuilder<'a, 'tcx> {
     body: &'a Body<'tcx>,
@@ -33,15 +35,19 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
                 moves: IndexVec::new(),
                 loc_map: LocationMap::new(body),
                 rev_lookup: MovePathLookup {
-                    locals: body.local_decls.indices().map(|i| {
-                        Self::new_move_path(
-                            &mut move_paths,
-                            &mut path_map,
-                            &mut init_path_map,
-                            None,
-                            Place::from(i),
-                        )
-                    }).collect(),
+                    locals: body
+                        .local_decls
+                        .indices()
+                        .map(|i| {
+                            Self::new_move_path(
+                                &mut move_paths,
+                                &mut path_map,
+                                &mut init_path_map,
+                                None,
+                                Place::from(i),
+                            )
+                        })
+                        .collect(),
                     projections: Default::default(),
                 },
                 move_paths,
@@ -49,27 +55,22 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
                 inits: IndexVec::new(),
                 init_loc_map: LocationMap::new(body),
                 init_path_map,
-            }
+            },
         }
     }
 
-    fn new_move_path(move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
-                     path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
-                     init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
-                     parent: Option<MovePathIndex>,
-                     place: Place<'tcx>)
-                     -> MovePathIndex
-    {
-        let move_path = move_paths.push(MovePath {
-            next_sibling: None,
-            first_child: None,
-            parent,
-            place,
-        });
+    fn new_move_path(
+        move_paths: &mut IndexVec<MovePathIndex, MovePath<'tcx>>,
+        path_map: &mut IndexVec<MovePathIndex, SmallVec<[MoveOutIndex; 4]>>,
+        init_path_map: &mut IndexVec<MovePathIndex, SmallVec<[InitIndex; 4]>>,
+        parent: Option<MovePathIndex>,
+        place: Place<'tcx>,
+    ) -> MovePathIndex {
+        let move_path =
+            move_paths.push(MovePath { next_sibling: None, first_child: None, parent, place });
 
         if let Some(parent) = parent {
-            let next_sibling =
-                mem::replace(&mut move_paths[parent].first_child, Some(move_path));
+            let next_sibling = mem::replace(&mut move_paths[parent].first_child, Some(move_path));
             move_paths[move_path].next_sibling = next_sibling;
         }
 
@@ -91,9 +92,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
     /// problematic for borrowck.
     ///
     /// Maybe we should have separate "borrowck" and "moveck" modes.
-    fn move_path_for(&mut self, place: &Place<'tcx>)
-                     -> Result<MovePathIndex, MoveError<'tcx>>
-    {
+    fn move_path_for(&mut self, place: &Place<'tcx>) -> Result<MovePathIndex, MoveError<'tcx>> {
         debug!("lookup({:?})", place);
         place.iterate(|place_base, place_projection| {
             let mut base = match place_base {
@@ -108,39 +107,46 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 let tcx = self.builder.tcx;
                 let place_ty = Place::ty_from(place_base, &proj.base, body, tcx).ty;
                 match place_ty.sty {
-                    ty::Ref(..) | ty::RawPtr(..) =>
+                    ty::Ref(..) | ty::RawPtr(..) => {
                         return Err(MoveError::cannot_move_out_of(
                             self.loc,
                             BorrowedContent {
                                 target_place: Place {
                                     base: place_base.clone(),
                                     projection: Some(Box::new(proj.clone())),
-                                }
-                            })),
-                    ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() =>
-                        return Err(MoveError::cannot_move_out_of(self.loc,
-                                                                 InteriorOfTypeWithDestructor {
-                            container_ty: place_ty
-                        })),
+                                },
+                            },
+                        ));
+                    }
+                    ty::Adt(adt, _) if adt.has_dtor(tcx) && !adt.is_box() => {
+                        return Err(MoveError::cannot_move_out_of(
+                            self.loc,
+                            InteriorOfTypeWithDestructor { container_ty: place_ty },
+                        ));
+                    }
                     // move out of union - always move the entire union
-                    ty::Adt(adt, _) if adt.is_union() =>
-                        return Err(MoveError::UnionMove { path: base }),
-                    ty::Slice(_) =>
+                    ty::Adt(adt, _) if adt.is_union() => {
+                        return Err(MoveError::UnionMove { path: base });
+                    }
+                    ty::Slice(_) => {
                         return Err(MoveError::cannot_move_out_of(
                             self.loc,
                             InteriorOfSliceOrArray {
-                                ty: place_ty, is_index: match proj.elem {
+                                ty: place_ty,
+                                is_index: match proj.elem {
                                     ProjectionElem::Index(..) => true,
-                                    _ => false
+                                    _ => false,
                                 },
-                            })),
+                            },
+                        ));
+                    }
                     ty::Array(..) => match proj.elem {
-                        ProjectionElem::Index(..) =>
+                        ProjectionElem::Index(..) => {
                             return Err(MoveError::cannot_move_out_of(
                                 self.loc,
-                                InteriorOfSliceOrArray {
-                                    ty: place_ty, is_index: true
-                                })),
+                                InteriorOfSliceOrArray { ty: place_ty, is_index: true },
+                            ));
+                        }
                         _ => {
                             // FIXME: still badly broken
                         }
@@ -186,7 +192,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
 impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
     fn finalize(
-        self
+        self,
     ) -> Result<MoveData<'tcx>, (MoveData<'tcx>, Vec<(Place<'tcx>, MoveError<'tcx>)>)> {
         debug!("{}", {
             debug!("moves for {:?}:", self.body.span);
@@ -200,11 +206,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             "done dumping moves"
         });
 
-        if !self.errors.is_empty() {
-            Err((self.data, self.errors))
-        } else {
-            Ok(self.data)
-        }
+        if !self.errors.is_empty() { Err((self.data, self.errors)) } else { Ok(self.data) }
     }
 }
 
@@ -222,10 +224,7 @@ pub(super) fn gather_moves<'tcx>(
             builder.gather_statement(source, stmt);
         }
 
-        let terminator_loc = Location {
-            block: bb,
-            statement_index: block.statements.len()
-        };
+        let terminator_loc = Location { block: bb, statement_index: block.statements.len() };
         builder.gather_terminator(terminator_loc, block.terminator());
     }
 
@@ -238,11 +237,12 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
             let path = self.data.rev_lookup.locals[arg];
 
             let init = self.data.inits.push(Init {
-                path, kind: InitKind::Deep, location: InitLocation::Argument(arg),
+                path,
+                kind: InitKind::Deep,
+                location: InitLocation::Argument(arg),
             });
 
-            debug!("gather_args: adding init {:?} of {:?} for argument {:?}",
-                init, path, arg);
+            debug!("gather_args: adding init {:?} of {:?} for argument {:?}", init, path, arg);
 
             self.data.init_path_map[path].push(init);
         }
@@ -297,26 +297,26 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
             StatementKind::StorageDead(local) => {
                 self.gather_move(&Place::from(local));
             }
-            StatementKind::SetDiscriminant{ .. } => {
-                span_bug!(stmt.source_info.span,
-                          "SetDiscriminant should not exist during borrowck");
+            StatementKind::SetDiscriminant { .. } => {
+                span_bug!(
+                    stmt.source_info.span,
+                    "SetDiscriminant should not exist during borrowck"
+                );
             }
-            StatementKind::Retag { .. } |
-            StatementKind::AscribeUserType(..) |
-            StatementKind::Nop => {}
+            StatementKind::Retag { .. }
+            | StatementKind::AscribeUserType(..)
+            | StatementKind::Nop => {}
         }
     }
 
     fn gather_rvalue(&mut self, rvalue: &Rvalue<'tcx>) {
         match *rvalue {
-            Rvalue::Use(ref operand) |
-            Rvalue::Repeat(ref operand, _) |
-            Rvalue::Cast(_, ref operand, _) |
-            Rvalue::UnaryOp(_, ref operand) => {
-                self.gather_operand(operand)
-            }
-            Rvalue::BinaryOp(ref _binop, ref lhs, ref rhs) |
-            Rvalue::CheckedBinaryOp(ref _binop, ref lhs, ref rhs) => {
+            Rvalue::Use(ref operand)
+            | Rvalue::Repeat(ref operand, _)
+            | Rvalue::Cast(_, ref operand, _)
+            | Rvalue::UnaryOp(_, ref operand) => self.gather_operand(operand),
+            Rvalue::BinaryOp(ref _binop, ref lhs, ref rhs)
+            | Rvalue::CheckedBinaryOp(ref _binop, ref lhs, ref rhs) => {
                 self.gather_operand(lhs);
                 self.gather_operand(rhs);
             }
@@ -325,11 +325,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                     self.gather_operand(operand);
                 }
             }
-            Rvalue::Ref(..) |
-            Rvalue::Discriminant(..) |
-            Rvalue::Len(..) |
-            Rvalue::NullaryOp(NullOp::SizeOf, _) |
-            Rvalue::NullaryOp(NullOp::Box, _) => {
+            Rvalue::Ref(..)
+            | Rvalue::Discriminant(..)
+            | Rvalue::Len(..)
+            | Rvalue::NullaryOp(NullOp::SizeOf, _)
+            | Rvalue::NullaryOp(NullOp::Box, _) => {
                 // This returns an rvalue with uninitialized contents. We can't
                 // move out of it here because it is an rvalue - assignments always
                 // completely initialize their place.
@@ -346,13 +346,13 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
     fn gather_terminator(&mut self, term: &Terminator<'tcx>) {
         match term.kind {
-            TerminatorKind::Goto { target: _ } |
-            TerminatorKind::Resume |
-            TerminatorKind::Abort |
-            TerminatorKind::GeneratorDrop |
-            TerminatorKind::FalseEdges { .. } |
-            TerminatorKind::FalseUnwind { .. } |
-            TerminatorKind::Unreachable => { }
+            TerminatorKind::Goto { target: _ }
+            | TerminatorKind::Resume
+            | TerminatorKind::Abort
+            | TerminatorKind::GeneratorDrop
+            | TerminatorKind::FalseEdges { .. }
+            | TerminatorKind::FalseUnwind { .. }
+            | TerminatorKind::Unreachable => {}
 
             TerminatorKind::Return => {
                 self.gather_move(&Place::RETURN_PLACE);
@@ -399,9 +399,9 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
 
     fn gather_operand(&mut self, operand: &Operand<'tcx>) {
         match *operand {
-            Operand::Constant(..) |
-            Operand::Copy(..) => {} // not-a-move
-            Operand::Move(ref place) => { // a move
+            Operand::Constant(..) | Operand::Copy(..) => {} // not-a-move
+            Operand::Move(ref place) => {
+                // a move
                 self.gather_move(place);
             }
         }
@@ -419,8 +419,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
         };
         let move_out = self.builder.data.moves.push(MoveOut { path: path, source: self.loc });
 
-        debug!("gather_move({:?}, {:?}): adding move {:?} of {:?}",
-               self.loc, place, move_out, path);
+        debug!(
+            "gather_move({:?}, {:?}): adding move {:?} of {:?}",
+            self.loc, place, move_out, path
+        );
 
         self.builder.data.path_map[path].push(move_out);
         self.builder.data.loc_map[self.loc].push(move_out);
@@ -452,8 +454,10 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
                 kind,
             });
 
-            debug!("gather_init({:?}, {:?}): adding init {:?} of {:?}",
-               self.loc, place, init, path);
+            debug!(
+                "gather_init({:?}, {:?}): adding init {:?} of {:?}",
+                self.loc, place, init, path
+            );
 
             self.builder.data.init_path_map[path].push(init);
             self.builder.data.init_loc_map[self.loc].push(init);
diff --git a/src/librustc_mir/dataflow/move_paths/mod.rs b/src/librustc_mir/dataflow/move_paths/mod.rs
index e5a19572170..5028e965091 100644
--- a/src/librustc_mir/dataflow/move_paths/mod.rs
+++ b/src/librustc_mir/dataflow/move_paths/mod.rs
@@ -1,9 +1,10 @@
-use rustc::ty::{Ty, TyCtxt};
+use core::slice::Iter;
 use rustc::mir::*;
+use rustc::ty::{Ty, TyCtxt};
 use rustc::util::nodemap::FxHashMap;
-use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use rustc_data_structures::indexed_vec::{Enumerated, Idx, IndexVec};
 use smallvec::SmallVec;
-use syntax_pos::{Span};
+use syntax_pos::Span;
 
 use std::fmt;
 use std::ops::{Index, IndexMut};
@@ -137,12 +138,17 @@ impl<T> IndexMut<Location> for LocationMap<T> {
     }
 }
 
-impl<T> LocationMap<T> where T: Default + Clone {
+impl<T> LocationMap<T>
+where
+    T: Default + Clone,
+{
     fn new(body: &Body<'_>) -> Self {
         LocationMap {
-            map: body.basic_blocks().iter().map(|block| {
-                vec![T::default(); block.statements.len()+1]
-            }).collect()
+            map: body
+                .basic_blocks()
+                .iter()
+                .map(|block| vec![T::default(); block.statements.len() + 1])
+                .collect(),
         }
     }
 }
@@ -178,7 +184,6 @@ pub struct Init {
     pub kind: InitKind,
 }
 
-
 /// Initializations can be from an argument or from a statement. Arguments
 /// do not have locations, in those cases the `Local` is kept..
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
@@ -224,7 +229,7 @@ pub struct MovePathLookup {
     /// subsequent search so that it is solely relative to that
     /// base-place). For the remaining lookup, we map the projection
     /// elem to the associated MovePathIndex.
-    projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>
+    projections: FxHashMap<(MovePathIndex, AbstractElem), MovePathIndex>,
 }
 
 mod builder;
@@ -232,7 +237,7 @@ mod builder;
 #[derive(Copy, Clone, Debug)]
 pub enum LookupResult {
     Exact(MovePathIndex),
-    Parent(Option<MovePathIndex>)
+    Parent(Option<MovePathIndex>),
 }
 
 impl MovePathLookup {
@@ -262,6 +267,12 @@ impl MovePathLookup {
     pub fn find_local(&self, local: Local) -> MovePathIndex {
         self.locals[local]
     }
+
+    /// An enumerated iterator of `local`s and their associated
+    /// `MovePathIndex`es.
+    pub fn iter_locals_enumerated(&self) -> Enumerated<Local, Iter<'_, MovePathIndex>> {
+        self.locals.iter_enumerated()
+    }
 }
 
 #[derive(Debug)]
@@ -289,7 +300,7 @@ pub(crate) enum IllegalMoveOriginKind<'tcx> {
     InteriorOfTypeWithDestructor { container_ty: Ty<'tcx> },
 
     /// Illegal move due to attempt to move out of a slice or array.
-    InteriorOfSliceOrArray { ty: Ty<'tcx>, is_index: bool, },
+    InteriorOfSliceOrArray { ty: Ty<'tcx>, is_index: bool },
 }
 
 #[derive(Debug)]
@@ -318,11 +329,15 @@ impl<'tcx> MoveData<'tcx> {
     pub fn base_local(&self, mut mpi: MovePathIndex) -> Option<Local> {
         loop {
             let path = &self.move_paths[mpi];
-            if let Place {
-                base: PlaceBase::Local(l),
-                projection: None,
-            } = path.place { return Some(l); }
-            if let Some(parent) = path.parent { mpi = parent; continue } else { return None }
+            if let Place { base: PlaceBase::Local(l), projection: None } = path.place {
+                return Some(l);
+            }
+            if let Some(parent) = path.parent {
+                mpi = parent;
+                continue;
+            } else {
+                return None;
+            }
         }
     }
 }
diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs
index 23c9e7fdf67..f358bb00f4d 100644
--- a/src/librustc_mir/interpret/place.rs
+++ b/src/librustc_mir/interpret/place.rs
@@ -585,8 +585,9 @@ where
         use rustc::mir::StaticKind;
 
         Ok(match place_static.kind {
-            StaticKind::Promoted(promoted, _) => {
-                let instance = self.frame().instance;
+            StaticKind::Promoted(promoted, promoted_substs) => {
+                let substs = self.subst_from_frame_and_normalize_erasing_regions(promoted_substs);
+                let instance = ty::Instance::new(place_static.def_id, substs);
                 self.const_eval_raw(GlobalId {
                     instance,
                     promoted: Some(promoted),
diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs
index ad9db4e0aa8..c193911247e 100644
--- a/src/librustc_mir/monomorphize/partitioning.rs
+++ b/src/librustc_mir/monomorphize/partitioning.rs
@@ -777,7 +777,7 @@ where
             debug!("CodegenUnit {}:", cgu.name());
 
             for (mono_item, linkage) in cgu.items() {
-                let symbol_name = mono_item.symbol_name(tcx).as_str();
+                let symbol_name = mono_item.symbol_name(tcx).name.as_str();
                 let symbol_hash_start = symbol_name.rfind('h');
                 let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
                                                    .unwrap_or("<no hash>");
diff --git a/src/librustc_mir/transform/const_prop.rs b/src/librustc_mir/transform/const_prop.rs
index f261fdc268b..e4b186736e2 100644
--- a/src/librustc_mir/transform/const_prop.rs
+++ b/src/librustc_mir/transform/const_prop.rs
@@ -405,13 +405,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                 }
 
                 let arg = self.eval_operand(arg, source_info)?;
+                let oflo_check = self.tcx.sess.overflow_checks();
                 let val = self.use_ecx(source_info, |this| {
                     let prim = this.ecx.read_immediate(arg)?;
                     match op {
                         UnOp::Neg => {
-                            // Need to do overflow check here: For actual CTFE, MIR
-                            // generation emits code that does this before calling the op.
-                            if prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
+                            // We check overflow in debug mode already
+                            // so should only check in release mode.
+                            if !oflo_check
+                            && prim.layout.ty.is_signed()
+                            && prim.to_bits()? == (1 << (prim.layout.size.bits() - 1)) {
                                 throw_panic!(OverflowNeg)
                             }
                         }
@@ -485,7 +488,9 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         Scalar::from_bool(overflow).into(),
                     )
                 } else {
-                    if overflow {
+                    // We check overflow in debug mode already
+                    // so should only check in release mode.
+                    if !self.tcx.sess.overflow_checks() && overflow {
                         let err = err_panic!(Overflow(op)).into();
                         let _: Option<()> = self.use_ecx(source_info, |_| Err(err));
                         return None;
diff --git a/src/librustc_target/spec/linux_kernel_base.rs b/src/librustc_target/spec/linux_kernel_base.rs
new file mode 100644
index 00000000000..fae44836fa8
--- /dev/null
+++ b/src/librustc_target/spec/linux_kernel_base.rs
@@ -0,0 +1,26 @@
+use crate::spec::{LinkArgs, LinkerFlavor, PanicStrategy, RelroLevel, TargetOptions};
+use std::default::Default;
+
+pub fn opts() -> TargetOptions {
+    let mut pre_link_args = LinkArgs::new();
+    pre_link_args.insert(
+        LinkerFlavor::Gcc,
+        vec!["-Wl,--as-needed".to_string(), "-Wl,-z,noexecstack".to_string()],
+    );
+
+    TargetOptions {
+        disable_redzone: true,
+        panic_strategy: PanicStrategy::Abort,
+        stack_probes: true,
+        eliminate_frame_pointer: false,
+        linker_is_gnu: true,
+        position_independent_executables: true,
+        needs_plt: true,
+        relro_level: RelroLevel::Full,
+        relocation_model: "static".to_string(),
+        target_family: Some("unix".to_string()),
+        pre_link_args,
+
+        ..Default::default()
+    }
+}
diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs
index 539e28f7088..503d8a08b6f 100644
--- a/src/librustc_target/spec/mod.rs
+++ b/src/librustc_target/spec/mod.rs
@@ -53,6 +53,7 @@ mod freebsd_base;
 mod haiku_base;
 mod hermit_base;
 mod linux_base;
+mod linux_kernel_base;
 mod linux_musl_base;
 mod openbsd_base;
 mod netbsd_base;
@@ -386,6 +387,8 @@ supported_targets! {
     ("thumbv7neon-linux-androideabi", thumbv7neon_linux_androideabi),
     ("aarch64-linux-android", aarch64_linux_android),
 
+    ("x86_64-linux-kernel", x86_64_linux_kernel),
+
     ("aarch64-unknown-freebsd", aarch64_unknown_freebsd),
     ("armv6-unknown-freebsd", armv6_unknown_freebsd),
     ("armv7-unknown-freebsd", armv7_unknown_freebsd),
diff --git a/src/librustc_target/spec/x86_64_linux_kernel.rs b/src/librustc_target/spec/x86_64_linux_kernel.rs
new file mode 100644
index 00000000000..a80b021208e
--- /dev/null
+++ b/src/librustc_target/spec/x86_64_linux_kernel.rs
@@ -0,0 +1,31 @@
+// This defines the amd64 target for the Linux Kernel. See the linux-kernel-base module for
+// generic Linux kernel options.
+
+use crate::spec::{LinkerFlavor, Target, TargetResult};
+
+pub fn target() -> TargetResult {
+    let mut base = super::linux_kernel_base::opts();
+    base.cpu = "x86-64".to_string();
+    base.max_atomic_width = Some(64);
+    base.features =
+        "-mmx,-sse,-sse2,-sse3,-ssse3,-sse4.1,-sse4.2,-3dnow,-3dnowa,-avx,-avx2,+soft-float"
+            .to_string();
+    base.code_model = Some("kernel".to_string());
+    base.pre_link_args.get_mut(&LinkerFlavor::Gcc).unwrap().push("-m64".to_string());
+
+    Ok(Target {
+        // FIXME: Some dispute, the linux-on-clang folks think this should use "Linux"
+        llvm_target: "x86_64-elf".to_string(),
+        target_endian: "little".to_string(),
+        target_pointer_width: "64".to_string(),
+        target_c_int_width: "32".to_string(),
+        data_layout: "e-m:e-i64:64-f80:128-n8:16:32:64-S128".to_string(),
+        target_os: "none".to_string(),
+        target_env: "gnu".to_string(),
+        target_vendor: "unknown".to_string(),
+        arch: "x86_64".to_string(),
+        linker_flavor: LinkerFlavor::Gcc,
+
+        options: base,
+    })
+}
diff --git a/src/librustc_typeck/check/expr.rs b/src/librustc_typeck/check/expr.rs
index fbaa9904d83..9644815f805 100644
--- a/src/librustc_typeck/check/expr.rs
+++ b/src/librustc_typeck/check/expr.rs
@@ -19,7 +19,7 @@ use crate::astconv::AstConv as _;
 
 use errors::{Applicability, DiagnosticBuilder};
 use syntax::ast;
-use syntax::symbol::{Symbol, LocalInternedString, kw, sym};
+use syntax::symbol::{Symbol, kw, sym};
 use syntax::source_map::Span;
 use syntax::util::lev_distance::find_best_match_for_name;
 use rustc::hir;
@@ -1244,7 +1244,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             _ => {
                 // prevent all specified fields from being suggested
-                let skip_fields = skip_fields.iter().map(|ref x| x.ident.as_str());
+                let skip_fields = skip_fields.iter().map(|ref x| x.ident.name);
                 if let Some(field_name) = Self::suggest_field_name(
                     variant,
                     &field.ident.as_str(),
@@ -1288,11 +1288,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     // Return an hint about the closest match in field names
     fn suggest_field_name(variant: &'tcx ty::VariantDef,
                           field: &str,
-                          skip: Vec<LocalInternedString>)
+                          skip: Vec<Symbol>)
                           -> Option<Symbol> {
         let names = variant.fields.iter().filter_map(|field| {
             // ignore already set fields and private fields from non-local crates
-            if skip.iter().any(|x| *x == field.ident.as_str()) ||
+            if skip.iter().any(|&x| x == field.ident.name) ||
                (!variant.def_id.is_local() && field.vis != Visibility::Public)
             {
                 None
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 16903304a14..d8d01624f1d 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1420,8 +1420,8 @@ fn check_opaque_for_cycles<'tcx>(
                 tcx.sess, span, E0733,
                 "recursion in an `async fn` requires boxing",
             )
-            .span_label(span, "an `async fn` cannot invoke itself directly")
-            .note("a recursive `async fn` must be rewritten to return a boxed future.")
+            .span_label(span, "recursive `async fn`")
+            .note("a recursive `async fn` must be rewritten to return a boxed `dyn Future`.")
             .emit();
         } else {
             let mut err = struct_span_err!(
@@ -3687,6 +3687,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
+    /// If `expr` is a `match` expression that has only one non-`!` arm, use that arm's tail
+    /// expression's `Span`, otherwise return `expr.span`. This is done to give better errors
+    /// when given code like the following:
+    /// ```text
+    /// if false { return 0i32; } else { 1u32 }
+    /// //                               ^^^^ point at this instead of the whole `if` expression
+    /// ```
+    fn get_expr_coercion_span(&self, expr: &hir::Expr) -> syntax_pos::Span {
+        if let hir::ExprKind::Match(_, arms, _) = &expr.node {
+            let arm_spans: Vec<Span> = arms.iter().filter_map(|arm| {
+                self.in_progress_tables
+                    .and_then(|tables| tables.borrow().node_type_opt(arm.body.hir_id))
+                    .and_then(|arm_ty| {
+                        if arm_ty.is_never() {
+                            None
+                        } else {
+                            Some(match &arm.body.node {
+                                // Point at the tail expression when possible.
+                                hir::ExprKind::Block(block, _) => block.expr
+                                    .as_ref()
+                                    .map(|e| e.span)
+                                    .unwrap_or(block.span),
+                                _ => arm.body.span,
+                            })
+                        }
+                    })
+            }).collect();
+            if arm_spans.len() == 1 {
+                return arm_spans[0];
+            }
+        }
+        expr.span
+    }
+
     fn check_block_with_expected(
         &self,
         blk: &'tcx hir::Block,
@@ -3746,12 +3780,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let coerce = ctxt.coerce.as_mut().unwrap();
             if let Some(tail_expr_ty) = tail_expr_ty {
                 let tail_expr = tail_expr.unwrap();
-                let cause = self.cause(tail_expr.span,
-                                       ObligationCauseCode::BlockTailExpression(blk.hir_id));
-                coerce.coerce(self,
-                              &cause,
-                              tail_expr,
-                              tail_expr_ty);
+                let span = self.get_expr_coercion_span(tail_expr);
+                let cause = self.cause(span, ObligationCauseCode::BlockTailExpression(blk.hir_id));
+                coerce.coerce(self, &cause, tail_expr, tail_expr_ty);
             } else {
                 // Subtle: if there is no explicit tail expression,
                 // that is typically equivalent to a tail expression
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index f95b3e44bf0..ac8ee43dd08 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -762,19 +762,19 @@ fn check_opaque_types<'fcx, 'tcx>(
     substituted_predicates
 }
 
+const HELP_FOR_SELF_TYPE: &str =
+    "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
+     `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
+     of the previous types except `Self`)";
+
 fn check_method_receiver<'fcx, 'tcx>(
     fcx: &FnCtxt<'fcx, 'tcx>,
     method_sig: &hir::MethodSig,
     method: &ty::AssocItem,
     self_ty: Ty<'tcx>,
 ) {
-    const HELP_FOR_SELF_TYPE: &str =
-        "consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, \
-         `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one \
-         of the previous types except `Self`)";
     // Check that the method has a valid receiver type, given the type `Self`.
-    debug!("check_method_receiver({:?}, self_ty={:?})",
-           method, self_ty);
+    debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty);
 
     if !method.method_has_self_argument {
         return;
@@ -805,12 +805,7 @@ fn check_method_receiver<'fcx, 'tcx>(
     if fcx.tcx.features().arbitrary_self_types {
         if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) {
             // Report error; `arbitrary_self_types` was enabled.
-            fcx.tcx.sess.diagnostic().mut_span_err(
-                span, &format!("invalid method receiver type: {:?}", receiver_ty)
-            ).note("type of `self` must be `Self` or a type that dereferences to it")
-            .help(HELP_FOR_SELF_TYPE)
-            .code(DiagnosticId::Error("E0307".into()))
-            .emit();
+            e0307(fcx, span, receiver_ty);
         }
     } else {
         if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) {
@@ -830,17 +825,22 @@ fn check_method_receiver<'fcx, 'tcx>(
                 .emit();
             } else {
                 // Report error; would not have worked with `arbitrary_self_types`.
-                fcx.tcx.sess.diagnostic().mut_span_err(
-                    span, &format!("invalid method receiver type: {:?}", receiver_ty)
-                ).note("type must be `Self` or a type that dereferences to it")
-                .help(HELP_FOR_SELF_TYPE)
-                .code(DiagnosticId::Error("E0307".into()))
-                .emit();
+                e0307(fcx, span, receiver_ty);
             }
         }
     }
 }
 
+fn e0307(fcx: &FnCtxt<'fcx, 'tcx>, span: Span, receiver_ty: Ty<'_>) {
+    fcx.tcx.sess.diagnostic().mut_span_err(
+        span,
+        &format!("invalid `self` parameter type: {:?}", receiver_ty)
+    ).note("type of `self` must be `Self` or a type that dereferences to it")
+    .help(HELP_FOR_SELF_TYPE)
+    .code(DiagnosticId::Error("E0307".into()))
+    .emit();
+}
+
 /// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If
 /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly
 /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more
diff --git a/src/librustc_typeck/error_codes.rs b/src/librustc_typeck/error_codes.rs
index b52183d4b1b..093446d2853 100644
--- a/src/librustc_typeck/error_codes.rs
+++ b/src/librustc_typeck/error_codes.rs
@@ -212,7 +212,7 @@ match string {
 E0033: r##"
 This error indicates that a pointer to a trait type cannot be implicitly
 dereferenced by a pattern. Every trait defines a type, but because the
-size of trait implementors isn't fixed, this type has no compile-time size.
+size of trait implementers isn't fixed, this type has no compile-time size.
 Therefore, all accesses to trait types must be through pointers. If you
 encounter this error you should try to avoid dereferencing the pointer.
 
@@ -2425,6 +2425,87 @@ struct Bar<S, T> { x: Foo<S, T> }
 ```
 "##,
 
+E0307: r##"
+This error indicates that the `self` parameter in a method has an invalid
+"reciever type".
+
+Methods take a special first parameter, of which there are three variants:
+`self`, `&self`, and `&mut self`. These are syntactic sugar for
+`self: Self`, `self: &Self`, and `self: &mut Self` respectively.
+
+```
+# struct Foo;
+trait Trait {
+    fn foo(&self);
+//         ^^^^^ `self` here is a reference to the receiver object
+}
+
+impl Trait for Foo {
+    fn foo(&self) {}
+//         ^^^^^ the receiver type is `&Foo`
+}
+```
+
+The type `Self` acts as an alias to the type of the current trait
+implementer, or "receiver type". Besides the already mentioned `Self`,
+`&Self` and `&mut Self` valid receiver types, the following are also valid:
+`self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, and `self: Pin<P>`
+(where P is one of the previous types except `Self`). Note that `Self` can
+also be the underlying implementing type, like `Foo` in the following
+example:
+
+```
+# struct Foo;
+# trait Trait {
+#     fn foo(&self);
+# }
+impl Trait for Foo {
+    fn foo(self: &Foo) {}
+}
+```
+
+E0307 will be emitted by the compiler when using an invalid reciver type,
+like in the following example:
+
+```compile_fail,E0307
+# struct Foo;
+# struct Bar;
+# trait Trait {
+#     fn foo(&self);
+# }
+impl Trait for Foo {
+    fn foo(self: &Bar) {}
+}
+```
+
+The nightly feature [Arbintrary self types][AST] extends the accepted
+set of receiver types to also include any type that can dereference to
+`Self`:
+
+```
+#![feature(arbitrary_self_types)]
+
+struct Foo;
+struct Bar;
+
+// Because you can dereference `Bar` into `Foo`...
+impl std::ops::Deref for Bar {
+    type Target = Foo;
+
+    fn deref(&self) -> &Foo {
+        &Foo
+    }
+}
+
+impl Foo {
+    fn foo(self: Bar) {}
+//         ^^^^^^^^^ ...it can be used as the receiver type
+}
+```
+
+[AST]: https://doc.rust-lang.org/unstable-book/language-features/arbitrary-self-types.html
+"##,
+
 E0321: r##"
 A cross-crate opt-out trait was implemented on something which wasn't a struct
 or enum type. Erroneous code example:
@@ -4851,7 +4932,6 @@ register_diagnostics! {
 //  E0247,
 //  E0248, // value used as a type, now reported earlier during resolution as E0412
 //  E0249,
-    E0307, // invalid method `self` type
 //  E0319, // trait impls for defaulted traits allowed just for structs/enums
 //  E0372, // coherence not object safe
     E0377, // the trait `CoerceUnsized` may only be implemented for a coercion
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index 637c6ef8e8e..309e5575ee4 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -344,7 +344,7 @@ if (!DOMTokenList.prototype.remove) {
             var set_fragment = function(name) {
                 if (browserSupportsHistoryApi()) {
                     history.replaceState(null, null, "#" + name);
-                    window.hashchange();
+                    highlightSourceLines(null);
                 } else {
                     location.replace("#" + name);
                 }
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index dfa0db0d23b..301946733dc 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -33,6 +33,7 @@ extern crate rustc_interface;
 extern crate rustc_metadata;
 extern crate rustc_target;
 extern crate rustc_typeck;
+extern crate rustc_lexer;
 extern crate serialize;
 extern crate syntax;
 extern crate syntax_pos;
diff --git a/src/librustdoc/passes/check_code_block_syntax.rs b/src/librustdoc/passes/check_code_block_syntax.rs
index 5c4159433c7..32044e48b6f 100644
--- a/src/librustdoc/passes/check_code_block_syntax.rs
+++ b/src/librustdoc/passes/check_code_block_syntax.rs
@@ -81,7 +81,7 @@ impl<'a, 'tcx> SyntaxChecker<'a, 'tcx> {
                 // We couldn't calculate the span of the markdown block that had the error, so our
                 // diagnostics are going to be a bit lacking.
                 let mut diag = self.cx.sess().struct_span_warn(
-                    super::span_of_attrs(&item.attrs),
+                    super::span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
                     "doc comment contains an invalid Rust code block",
                 );
 
diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs
index c73c46472d8..2951b2ccb2a 100644
--- a/src/librustdoc/passes/collect_intra_doc_links.rs
+++ b/src/librustdoc/passes/collect_intra_doc_links.rs
@@ -465,7 +465,7 @@ fn resolution_failure(
         }
     };
     let attrs = &item.attrs;
-    let sp = span_of_attrs(attrs);
+    let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
 
     let mut diag = cx.tcx.struct_span_lint_hir(
         lint::builtin::INTRA_DOC_LINK_RESOLUTION_FAILURE,
@@ -517,7 +517,7 @@ fn ambiguity_error(
         }
     };
     let attrs = &item.attrs;
-    let sp = span_of_attrs(attrs);
+    let sp = span_of_attrs(attrs).unwrap_or(item.source.span());
 
     let mut msg = format!("`{}` is ", path_str);
 
diff --git a/src/librustdoc/passes/mod.rs b/src/librustdoc/passes/mod.rs
index 641a6df2214..49a34c7e462 100644
--- a/src/librustdoc/passes/mod.rs
+++ b/src/librustdoc/passes/mod.rs
@@ -339,7 +339,7 @@ pub fn look_for_tests<'tcx>(
     find_testable_code(&dox, &mut tests, ErrorCodes::No);
 
     if check_missing_code == true && tests.found_tests == 0 {
-        let sp = span_of_attrs(&item.attrs).substitute_dummy(item.source.span());
+        let sp = span_of_attrs(&item.attrs).unwrap_or(item.source.span());
         let mut diag = cx.tcx.struct_span_lint_hir(
             lint::builtin::MISSING_DOC_CODE_EXAMPLES,
             hir_id,
@@ -352,20 +352,23 @@ pub fn look_for_tests<'tcx>(
         let mut diag = cx.tcx.struct_span_lint_hir(
             lint::builtin::PRIVATE_DOC_TESTS,
             hir_id,
-            span_of_attrs(&item.attrs),
+            span_of_attrs(&item.attrs).unwrap_or(item.source.span()),
             "Documentation test in private item");
         diag.emit();
     }
 }
 
 /// Returns a span encompassing all the given attributes.
-crate fn span_of_attrs(attrs: &clean::Attributes) -> Span {
+crate fn span_of_attrs(attrs: &clean::Attributes) -> Option<Span> {
     if attrs.doc_strings.is_empty() {
-        return DUMMY_SP;
+        return None;
     }
     let start = attrs.doc_strings[0].span();
+    if start == DUMMY_SP {
+        return None;
+    }
     let end = attrs.doc_strings.last().expect("No doc strings provided").span();
-    start.to(end)
+    Some(start.to(end))
 }
 
 /// Attempts to match a range of bytes from parsed markdown to a `Span` in the source code.
@@ -391,7 +394,7 @@ crate fn source_span_for_markdown_range(
     let snippet = cx
         .sess()
         .source_map()
-        .span_to_snippet(span_of_attrs(attrs))
+        .span_to_snippet(span_of_attrs(attrs)?)
         .ok()?;
 
     let starting_line = markdown[..md_range.start].matches('\n').count();
@@ -441,10 +444,8 @@ crate fn source_span_for_markdown_range(
         }
     }
 
-    let sp = span_of_attrs(attrs).from_inner(InnerSpan::new(
+    Some(span_of_attrs(attrs)?.from_inner(InnerSpan::new(
         md_range.start + start_bytes,
         md_range.end + start_bytes + end_bytes,
-    ));
-
-    Some(sp)
+    )))
 }
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index adcc9930b6c..000d2843adc 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -763,8 +763,8 @@ impl Tester for Collector {
             // We use these headings as test names, so it's good if
             // they're valid identifiers.
             let name = name.chars().enumerate().map(|(i, c)| {
-                    if (i == 0 && c.is_xid_start()) ||
-                        (i != 0 && c.is_xid_continue()) {
+                    if (i == 0 && rustc_lexer::is_id_start(c)) ||
+                        (i != 0 && rustc_lexer::is_id_continue(c)) {
                         c
                     } else {
                         '_'
diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs
index 5060f368229..0386dbd490d 100644
--- a/src/libstd/io/mod.rs
+++ b/src/libstd/io/mod.rs
@@ -371,6 +371,14 @@ where
     loop {
         if g.len == g.buf.len() {
             unsafe {
+                // FIXME(danielhenrymantilla): #42788
+                //
+                //   - This creates a (mut) reference to a slice of
+                //     _uninitialized_ integers, which is **undefined behavior**
+                //
+                //   - Only the standard library gets to soundly "ignore" this,
+                //     based on its privileged knowledge of unstable rustc
+                //     internals;
                 g.buf.reserve(reservation_size(r));
                 let capacity = g.buf.capacity();
                 g.buf.set_len(capacity);
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index c3882bacf87..71050b0dcd1 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -244,7 +244,6 @@
 #![feature(cfg_target_has_atomic)]
 #![feature(cfg_target_thread_local)]
 #![feature(char_error_internals)]
-#![feature(checked_duration_since)]
 #![feature(clamp)]
 #![feature(compiler_builtins_lib)]
 #![feature(concat_idents)]
diff --git a/src/libstd/sys/sgx/condvar.rs b/src/libstd/sys/sgx/condvar.rs
index 000bb19f269..cc1c04a83e7 100644
--- a/src/libstd/sys/sgx/condvar.rs
+++ b/src/libstd/sys/sgx/condvar.rs
@@ -27,8 +27,7 @@ impl Condvar {
 
     pub unsafe fn wait(&self, mutex: &Mutex) {
         let guard = self.inner.lock();
-        mutex.unlock();
-        WaitQueue::wait(guard);
+        WaitQueue::wait(guard, || mutex.unlock());
         mutex.lock()
     }
 
diff --git a/src/libstd/sys/sgx/mutex.rs b/src/libstd/sys/sgx/mutex.rs
index f325fb1dd58..662da8b3f66 100644
--- a/src/libstd/sys/sgx/mutex.rs
+++ b/src/libstd/sys/sgx/mutex.rs
@@ -22,7 +22,7 @@ impl Mutex {
         let mut guard = self.inner.lock();
         if *guard.lock_var() {
             // Another thread has the lock, wait
-            WaitQueue::wait(guard)
+            WaitQueue::wait(guard, ||{})
             // Another thread has passed the lock to us
         } else {
             // We are just now obtaining the lock
@@ -83,7 +83,7 @@ impl ReentrantMutex {
         match guard.lock_var().owner {
             Some(tcs) if tcs != thread::current() => {
                 // Another thread has the lock, wait
-                WaitQueue::wait(guard);
+                WaitQueue::wait(guard, ||{});
                 // Another thread has passed the lock to us
             },
             _ => {
diff --git a/src/libstd/sys/sgx/rwlock.rs b/src/libstd/sys/sgx/rwlock.rs
index 30c47e44eef..e2f94b1d928 100644
--- a/src/libstd/sys/sgx/rwlock.rs
+++ b/src/libstd/sys/sgx/rwlock.rs
@@ -31,7 +31,7 @@ impl RWLock {
         if *wguard.lock_var() || !wguard.queue_empty() {
             // Another thread has or is waiting for the write lock, wait
             drop(wguard);
-            WaitQueue::wait(rguard);
+            WaitQueue::wait(rguard, ||{});
             // Another thread has passed the lock to us
         } else {
             // No waiting writers, acquire the read lock
@@ -62,7 +62,7 @@ impl RWLock {
         if *wguard.lock_var() || rguard.lock_var().is_some() {
             // Another thread has the lock, wait
             drop(rguard);
-            WaitQueue::wait(wguard);
+            WaitQueue::wait(wguard, ||{});
             // Another thread has passed the lock to us
         } else {
             // We are just now obtaining the lock
@@ -97,6 +97,7 @@ impl RWLock {
             if let Ok(mut wguard) = WaitQueue::notify_one(wguard) {
                 // A writer was waiting, pass the lock
                 *wguard.lock_var_mut() = true;
+                wguard.drop_after(rguard);
             } else {
                 // No writers were waiting, the lock is released
                 rtassert!(rguard.queue_empty());
@@ -117,21 +118,26 @@ impl RWLock {
         rguard: SpinMutexGuard<'_, WaitVariable<Option<NonZeroUsize>>>,
         wguard: SpinMutexGuard<'_, WaitVariable<bool>>,
     ) {
-        if let Err(mut wguard) = WaitQueue::notify_one(wguard) {
-            // No writers waiting, release the write lock
-            *wguard.lock_var_mut() = false;
-            if let Ok(mut rguard) = WaitQueue::notify_all(rguard) {
-                // One or more readers were waiting, pass the lock to them
-                if let NotifiedTcs::All { count } = rguard.notified_tcs() {
-                    *rguard.lock_var_mut() = Some(count)
+        match WaitQueue::notify_one(wguard) {
+            Err(mut wguard) => {
+                // No writers waiting, release the write lock
+                *wguard.lock_var_mut() = false;
+                if let Ok(mut rguard) = WaitQueue::notify_all(rguard) {
+                    // One or more readers were waiting, pass the lock to them
+                    if let NotifiedTcs::All { count } = rguard.notified_tcs() {
+                        *rguard.lock_var_mut() = Some(count)
+                    } else {
+                        unreachable!() // called notify_all
+                    }
+                    rguard.drop_after(wguard);
                 } else {
-                    unreachable!() // called notify_all
+                    // No readers waiting, the lock is released
                 }
-            } else {
-                // No readers waiting, the lock is released
+            },
+            Ok(wguard) => {
+                // There was a thread waiting for write, just pass the lock
+                wguard.drop_after(rguard);
             }
-        } else {
-            // There was a thread waiting for write, just pass the lock
         }
     }
 
diff --git a/src/libstd/sys/sgx/waitqueue.rs b/src/libstd/sys/sgx/waitqueue.rs
index d542f9b4101..3cb40e509b6 100644
--- a/src/libstd/sys/sgx/waitqueue.rs
+++ b/src/libstd/sys/sgx/waitqueue.rs
@@ -98,6 +98,12 @@ impl<'a, T> WaitGuard<'a, T> {
     pub fn notified_tcs(&self) -> NotifiedTcs {
         self.notified_tcs
     }
+
+    /// Drop this `WaitGuard`, after dropping another `guard`.
+    pub fn drop_after<U>(self, guard: U) {
+        drop(guard);
+        drop(self);
+    }
 }
 
 impl<'a, T> Deref for WaitGuard<'a, T> {
@@ -140,7 +146,7 @@ impl WaitQueue {
     /// until a wakeup event.
     ///
     /// This function does not return until this thread has been awoken.
-    pub fn wait<T>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>) {
+    pub fn wait<T, F: FnOnce()>(mut guard: SpinMutexGuard<'_, WaitVariable<T>>, before_wait: F) {
         // very unsafe: check requirements of UnsafeList::push
         unsafe {
             let mut entry = UnsafeListEntry::new(SpinMutex::new(WaitEntry {
@@ -149,6 +155,7 @@ impl WaitQueue {
             }));
             let entry = guard.queue.inner.push(&mut entry);
             drop(guard);
+            before_wait();
             while !entry.lock().wake {
                 // don't panic, this would invalidate `entry` during unwinding
                 let eventset = rtunwrap!(Ok, usercalls::wait(EV_UNPARK, WAIT_INDEFINITE));
@@ -545,7 +552,7 @@ mod tests {
             assert!(WaitQueue::notify_one(wq2.lock()).is_ok());
         });
 
-        WaitQueue::wait(locked);
+        WaitQueue::wait(locked, ||{});
 
         t1.join().unwrap();
     }
diff --git a/src/libstd/time.rs b/src/libstd/time.rs
index 98371b9ba3d..d59085cd44a 100644
--- a/src/libstd/time.rs
+++ b/src/libstd/time.rs
@@ -221,7 +221,6 @@ impl Instant {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(checked_duration_since)]
     /// use std::time::{Duration, Instant};
     /// use std::thread::sleep;
     ///
@@ -231,7 +230,7 @@ impl Instant {
     /// println!("{:?}", new_now.checked_duration_since(now));
     /// println!("{:?}", now.checked_duration_since(new_now)); // None
     /// ```
-    #[unstable(feature = "checked_duration_since", issue = "58402")]
+    #[stable(feature = "checked_duration_since", since = "1.39.0")]
     pub fn checked_duration_since(&self, earlier: Instant) -> Option<Duration> {
         self.0.checked_sub_instant(&earlier.0)
     }
@@ -242,7 +241,6 @@ impl Instant {
     /// # Examples
     ///
     /// ```no_run
-    /// #![feature(checked_duration_since)]
     /// use std::time::{Duration, Instant};
     /// use std::thread::sleep;
     ///
@@ -252,7 +250,7 @@ impl Instant {
     /// println!("{:?}", new_now.saturating_duration_since(now));
     /// println!("{:?}", now.saturating_duration_since(new_now)); // 0ns
     /// ```
-    #[unstable(feature = "checked_duration_since", issue = "58402")]
+    #[stable(feature = "checked_duration_since", since = "1.39.0")]
     pub fn saturating_duration_since(&self, earlier: Instant) -> Duration {
         self.checked_duration_since(earlier).unwrap_or(Duration::new(0, 0))
     }
diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs
index e9a55af52e8..5de39c8d14d 100644
--- a/src/libsyntax/diagnostics/plugin.rs
+++ b/src/libsyntax/diagnostics/plugin.rs
@@ -6,7 +6,7 @@ use crate::ext::base::{ExtCtxt, MacEager, MacResult};
 use crate::parse::token::{self, Token};
 use crate::ptr::P;
 use crate::symbol::kw;
-use crate::tokenstream::{TokenTree};
+use crate::tokenstream::{TokenTree, TokenStream};
 
 use smallvec::smallvec;
 use syntax_pos::Span;
@@ -27,12 +27,11 @@ pub type ErrorMap = BTreeMap<Name, ErrorInfo>;
 
 pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                    span: Span,
-                                   token_tree: &[TokenTree])
+                                   tts: TokenStream)
                                    -> Box<dyn MacResult+'cx> {
-    let code = match token_tree {
-        [
-            TokenTree::Token(Token { kind: token::Ident(code, _), .. })
-        ] => code,
+    assert_eq!(tts.len(), 1);
+    let code = match tts.into_trees().next() {
+        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
         _ => unreachable!()
     };
 
@@ -62,20 +61,21 @@ pub fn expand_diagnostic_used<'cx>(ecx: &'cx mut ExtCtxt<'_>,
 
 pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                        span: Span,
-                                       token_tree: &[TokenTree])
+                                       tts: TokenStream)
                                        -> Box<dyn MacResult+'cx> {
-    let (code, description) = match  token_tree {
-        [
-            TokenTree::Token(Token { kind: token::Ident(code, _), .. })
-        ] => {
-            (*code, None)
-        },
-        [
-            TokenTree::Token(Token { kind: token::Ident(code, _), .. }),
-            TokenTree::Token(Token { kind: token::Comma, .. }),
-            TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..})
-        ] => {
-            (*code, Some(*symbol))
+    assert!(tts.len() == 1 || tts.len() == 3);
+    let mut cursor = tts.into_trees();
+    let code = match cursor.next() {
+        Some(TokenTree::Token(Token { kind: token::Ident(code, _), .. })) => code,
+        _ => unreachable!()
+    };
+    let description = match  (cursor.next(), cursor.next()) {
+        (None, None) => None,
+        (
+            Some(TokenTree::Token(Token { kind: token::Comma, .. })),
+            Some(TokenTree::Token(Token { kind: token::Literal(token::Lit { symbol, .. }), ..}))
+        ) => {
+            Some(symbol)
         },
         _ => unreachable!()
     };
@@ -121,12 +121,12 @@ pub fn expand_register_diagnostic<'cx>(ecx: &'cx mut ExtCtxt<'_>,
 
 pub fn expand_build_diagnostic_array<'cx>(ecx: &'cx mut ExtCtxt<'_>,
                                           span: Span,
-                                          token_tree: &[TokenTree])
+                                          tts: TokenStream)
                                           -> Box<dyn MacResult+'cx> {
-    assert_eq!(token_tree.len(), 3);
-    let ident = match &token_tree[2] {
+    assert_eq!(tts.len(), 3);
+    let ident = match tts.into_trees().nth(2) {
         // DIAGNOSTICS ident.
-        &TokenTree::Token(Token { kind: token::Ident(name, _), span })
+        Some(TokenTree::Token(Token { kind: token::Ident(name, _), span }))
         => Ident::new(name, span),
         _ => unreachable!()
     };
diff --git a/src/libsyntax/ext/base.rs b/src/libsyntax/ext/base.rs
index 5d68983d7cb..109ba041016 100644
--- a/src/libsyntax/ext/base.rs
+++ b/src/libsyntax/ext/base.rs
@@ -10,7 +10,7 @@ use crate::parse::token;
 use crate::ptr::P;
 use crate::symbol::{kw, sym, Ident, Symbol};
 use crate::{ThinVec, MACRO_ARGUMENTS};
-use crate::tokenstream::{self, TokenStream, TokenTree};
+use crate::tokenstream::{self, TokenStream};
 use crate::visit::Visitor;
 
 use errors::{DiagnosticBuilder, DiagnosticId};
@@ -235,18 +235,18 @@ pub trait TTMacroExpander {
 }
 
 pub type MacroExpanderFn =
-    for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, &[tokenstream::TokenTree])
+    for<'cx> fn(&'cx mut ExtCtxt<'_>, Span, TokenStream)
                 -> Box<dyn MacResult+'cx>;
 
 impl<F> TTMacroExpander for F
-    where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, &[tokenstream::TokenTree])
+    where F: for<'cx> Fn(&'cx mut ExtCtxt<'_>, Span, TokenStream)
     -> Box<dyn MacResult+'cx>
 {
     fn expand<'cx>(
         &self,
         ecx: &'cx mut ExtCtxt<'_>,
         span: Span,
-        input: TokenStream,
+        mut input: TokenStream,
     ) -> Box<dyn MacResult+'cx> {
         struct AvoidInterpolatedIdents;
 
@@ -268,10 +268,8 @@ impl<F> TTMacroExpander for F
                 mut_visit::noop_visit_mac(mac, self)
             }
         }
-
-        let input: Vec<_> =
-            input.trees().map(|mut tt| { AvoidInterpolatedIdents.visit_tt(&mut tt); tt }).collect();
-        (*self)(ecx, span, &input)
+        AvoidInterpolatedIdents.visit_tts(&mut input);
+        (*self)(ecx, span, input)
     }
 }
 
@@ -677,7 +675,7 @@ impl SyntaxExtension {
     }
 
     pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
-        fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: &[TokenTree])
+        fn expander<'cx>(_: &'cx mut ExtCtxt<'_>, span: Span, _: TokenStream)
                          -> Box<dyn MacResult + 'cx> {
             DummyResult::any(span)
         }
@@ -811,9 +809,8 @@ impl<'a> ExtCtxt<'a> {
     pub fn monotonic_expander<'b>(&'b mut self) -> expand::MacroExpander<'b, 'a> {
         expand::MacroExpander::new(self, true)
     }
-
-    pub fn new_parser_from_tts(&self, tts: &[tokenstream::TokenTree]) -> parser::Parser<'a> {
-        parse::stream_to_parser(self.parse_sess, tts.iter().cloned().collect(), MACRO_ARGUMENTS)
+    pub fn new_parser_from_tts(&self, stream: TokenStream) -> parser::Parser<'a> {
+        parse::stream_to_parser(self.parse_sess, stream, MACRO_ARGUMENTS)
     }
     pub fn source_map(&self) -> &'a SourceMap { self.parse_sess.source_map() }
     pub fn parse_sess(&self) -> &'a parse::ParseSess { self.parse_sess }
@@ -1019,7 +1016,7 @@ pub fn expr_to_string(cx: &mut ExtCtxt<'_>, expr: P<ast::Expr>, err_msg: &str)
 /// done as rarely as possible).
 pub fn check_zero_tts(cx: &ExtCtxt<'_>,
                       sp: Span,
-                      tts: &[tokenstream::TokenTree],
+                      tts: TokenStream,
                       name: &str) {
     if !tts.is_empty() {
         cx.span_err(sp, &format!("{} takes no arguments", name));
@@ -1030,7 +1027,7 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>,
 /// expect exactly one string literal, or emit an error and return `None`.
 pub fn get_single_str_from_tts(cx: &mut ExtCtxt<'_>,
                                sp: Span,
-                               tts: &[tokenstream::TokenTree],
+                               tts: TokenStream,
                                name: &str)
                                -> Option<String> {
     let mut p = cx.new_parser_from_tts(tts);
@@ -1053,7 +1050,7 @@ pub fn get_single_str_from_tts(cx: &mut ExtCtxt<'_>,
 /// parsing error, emit a non-fatal error and return `None`.
 pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>,
                           sp: Span,
-                          tts: &[tokenstream::TokenTree]) -> Option<Vec<P<ast::Expr>>> {
+                          tts: TokenStream) -> Option<Vec<P<ast::Expr>>> {
     let mut p = cx.new_parser_from_tts(tts);
     let mut es = Vec::new();
     while p.token != token::Eof {
diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs
index 7b4a5167446..4fd0c367288 100644
--- a/src/libsyntax/ext/expand.rs
+++ b/src/libsyntax/ext/expand.rs
@@ -701,7 +701,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         path: &Path,
         span: Span,
     ) -> AstFragment {
-        let mut parser = self.cx.new_parser_from_tts(&toks.into_trees().collect::<Vec<_>>());
+        let mut parser = self.cx.new_parser_from_tts(toks);
         match parser.parse_ast_fragment(kind, false) {
             Ok(fragment) => {
                 parser.ensure_complete_parse(path, kind.name(), span);
diff --git a/src/libsyntax/ext/proc_macro_server.rs b/src/libsyntax/ext/proc_macro_server.rs
index 1a26b17dac7..544ec789d80 100644
--- a/src/libsyntax/ext/proc_macro_server.rs
+++ b/src/libsyntax/ext/proc_macro_server.rs
@@ -322,8 +322,7 @@ impl Ident {
     fn is_valid(string: &str) -> bool {
         let mut chars = string.chars();
         if let Some(start) = chars.next() {
-            (start == '_' || start.is_xid_start())
-                && chars.all(|cont| cont == '_' || cont.is_xid_continue())
+            rustc_lexer::is_id_start(start) && chars.all(rustc_lexer::is_id_continue)
         } else {
             false
         }
diff --git a/src/libsyntax/parse/parser/expr.rs b/src/libsyntax/parse/parser/expr.rs
index 5b9f0f1df67..e502a08f4b2 100644
--- a/src/libsyntax/parse/parser/expr.rs
+++ b/src/libsyntax/parse/parser/expr.rs
@@ -889,6 +889,36 @@ impl<'a> Parser<'a> {
                     hi = path.span;
                     return Ok(self.mk_expr(lo.to(hi), ExprKind::Path(Some(qself), path), attrs));
                 }
+                if self.token.is_path_start() {
+                    let path = self.parse_path(PathStyle::Expr)?;
+
+                    // `!`, as an operator, is prefix, so we know this isn't that
+                    if self.eat(&token::Not) {
+                        // MACRO INVOCATION expression
+                        let (delim, tts) = self.expect_delimited_token_tree()?;
+                        hi = self.prev_span;
+                        ex = ExprKind::Mac(Mac {
+                            path,
+                            tts,
+                            delim,
+                            span: lo.to(hi),
+                            prior_type_ascription: self.last_type_ascription,
+                        });
+                    } else if self.check(&token::OpenDelim(token::Brace)) {
+                        if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
+                            return expr;
+                        } else {
+                            hi = path.span;
+                            ex = ExprKind::Path(None, path);
+                        }
+                    } else {
+                        hi = path.span;
+                        ex = ExprKind::Path(None, path);
+                    }
+
+                    let expr = self.mk_expr(lo.to(hi), ex, attrs);
+                    return self.maybe_recover_from_bad_qpath(expr, true);
+                }
                 if self.check_keyword(kw::Move) || self.check_keyword(kw::Static) {
                     return self.parse_lambda_expr(attrs);
                 }
@@ -1007,32 +1037,6 @@ impl<'a> Parser<'a> {
                     let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?;
                     hi = await_hi;
                     ex = e_kind;
-                } else if self.token.is_path_start() {
-                    let path = self.parse_path(PathStyle::Expr)?;
-
-                    // `!`, as an operator, is prefix, so we know this isn't that
-                    if self.eat(&token::Not) {
-                        // MACRO INVOCATION expression
-                        let (delim, tts) = self.expect_delimited_token_tree()?;
-                        hi = self.prev_span;
-                        ex = ExprKind::Mac(Mac {
-                            path,
-                            tts,
-                            delim,
-                            span: lo.to(hi),
-                            prior_type_ascription: self.last_type_ascription,
-                        });
-                    } else if self.check(&token::OpenDelim(token::Brace)) {
-                        if let Some(expr) = self.maybe_parse_struct_expr(lo, &path, &attrs) {
-                            return expr;
-                        } else {
-                            hi = path.span;
-                            ex = ExprKind::Path(None, path);
-                        }
-                    } else {
-                        hi = path.span;
-                        ex = ExprKind::Path(None, path);
-                    }
                 } else {
                     if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
                         // Don't complain about bare semicolons after unclosed braces
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index bead941b20d..37305055e62 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -356,11 +356,7 @@ pub fn tt_to_string(tt: tokenstream::TokenTree) -> String {
     to_string(|s| s.print_tt(tt, false))
 }
 
-pub fn tts_to_string(tts: &[tokenstream::TokenTree]) -> String {
-    tokens_to_string(tts.iter().cloned().collect())
-}
-
-pub fn tokens_to_string(tokens: TokenStream) -> String {
+pub fn tts_to_string(tokens: TokenStream) -> String {
     to_string(|s| s.print_tts(tokens, false))
 }
 
diff --git a/src/libsyntax/tests.rs b/src/libsyntax/tests.rs
index c472212bc20..9b90b31f2d2 100644
--- a/src/libsyntax/tests.rs
+++ b/src/libsyntax/tests.rs
@@ -63,7 +63,7 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
             (None, None) => return true,
             (None, _) => return false,
             (Some(&a), None) => {
-                if is_pattern_whitespace(a) {
+                if rustc_lexer::is_whitespace(a) {
                     break // trailing whitespace check is out of loop for borrowck
                 } else {
                     return false
@@ -72,11 +72,11 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
             (Some(&a), Some(&b)) => (a, b)
         };
 
-        if is_pattern_whitespace(a) && is_pattern_whitespace(b) {
+        if rustc_lexer::is_whitespace(a) && rustc_lexer::is_whitespace(b) {
             // skip whitespace for a and b
             scan_for_non_ws_or_end(&mut a_iter);
             scan_for_non_ws_or_end(&mut b_iter);
-        } else if is_pattern_whitespace(a) {
+        } else if rustc_lexer::is_whitespace(a) {
             // skip whitespace for a
             scan_for_non_ws_or_end(&mut a_iter);
         } else if a == b {
@@ -88,20 +88,16 @@ crate fn matches_codepattern(a : &str, b : &str) -> bool {
     }
 
     // check if a has *only* trailing whitespace
-    a_iter.all(is_pattern_whitespace)
+    a_iter.all(rustc_lexer::is_whitespace)
 }
 
 /// Advances the given peekable `Iterator` until it reaches a non-whitespace character
 fn scan_for_non_ws_or_end<I: Iterator<Item = char>>(iter: &mut Peekable<I>) {
-    while iter.peek().copied().map(|c| is_pattern_whitespace(c)) == Some(true) {
+    while iter.peek().copied().map(|c| rustc_lexer::is_whitespace(c)) == Some(true) {
         iter.next();
     }
 }
 
-fn is_pattern_whitespace(c: char) -> bool {
-    rustc_lexer::character_properties::is_whitespace(c)
-}
-
 /// Identify a position in the text by the Nth occurrence of a string.
 struct Position {
     string: &'static str,
diff --git a/src/libsyntax/tokenstream.rs b/src/libsyntax/tokenstream.rs
index 0d9f3769ce9..48055358619 100644
--- a/src/libsyntax/tokenstream.rs
+++ b/src/libsyntax/tokenstream.rs
@@ -506,7 +506,7 @@ impl Cursor {
 
 impl fmt::Display for TokenStream {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
-        f.write_str(&pprust::tokens_to_string(self.clone()))
+        f.write_str(&pprust::tts_to_string(self.clone()))
     }
 }
 
diff --git a/src/libsyntax_ext/Cargo.toml b/src/libsyntax_ext/Cargo.toml
index 73310df305b..791ee94b4fa 100644
--- a/src/libsyntax_ext/Cargo.toml
+++ b/src/libsyntax_ext/Cargo.toml
@@ -18,3 +18,4 @@ rustc_target = { path = "../librustc_target" }
 smallvec = { version = "0.6.7", features = ["union", "may_dangle"] }
 syntax = { path = "../libsyntax" }
 syntax_pos = { path = "../libsyntax_pos" }
+rustc_lexer = { path = "../librustc_lexer" }
diff --git a/src/libsyntax_ext/asm.rs b/src/libsyntax_ext/asm.rs
index 28f907441d8..328b307361d 100644
--- a/src/libsyntax_ext/asm.rs
+++ b/src/libsyntax_ext/asm.rs
@@ -8,13 +8,12 @@ use errors::DiagnosticBuilder;
 
 use syntax::ast;
 use syntax::ext::base::{self, *};
-use syntax::parse;
 use syntax::parse::token::{self, Token};
 use syntax::ptr::P;
 use syntax::symbol::{kw, sym, Symbol};
 use syntax::ast::AsmDialect;
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::{self, TokenStream};
 use syntax::{span_err, struct_span_err};
 
 enum State {
@@ -43,7 +42,7 @@ const OPTIONS: &[Symbol] = &[sym::volatile, sym::alignstack, sym::intel];
 
 pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        sp: Span,
-                       tts: &[tokenstream::TokenTree])
+                       tts: TokenStream)
                        -> Box<dyn base::MacResult + 'cx> {
     let mut inline_asm = match parse_inline_asm(cx, sp, tts) {
         Ok(Some(inline_asm)) => inline_asm,
@@ -71,20 +70,20 @@ pub fn expand_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
 fn parse_inline_asm<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Result<Option<ast::InlineAsm>, DiagnosticBuilder<'a>> {
     // Split the tts before the first colon, to avoid `asm!("x": y)`  being
     // parsed as `asm!(z)` with `z = "x": y` which is type ascription.
-    let first_colon = tts.iter()
+    let first_colon = tts.trees()
         .position(|tt| {
-            match *tt {
+            match tt {
                 tokenstream::TokenTree::Token(Token { kind: token::Colon, .. }) |
                 tokenstream::TokenTree::Token(Token { kind: token::ModSep, .. }) => true,
                 _ => false,
             }
         })
         .unwrap_or(tts.len());
-    let mut p = cx.new_parser_from_tts(&tts[first_colon..]);
+    let mut p = cx.new_parser_from_tts(tts.trees().skip(first_colon).collect());
     let mut asm = kw::Invalid;
     let mut asm_str_style = None;
     let mut outputs = Vec::new();
@@ -110,7 +109,8 @@ fn parse_inline_asm<'a>(
                     ));
                 }
                 // Nested parser, stop before the first colon (see above).
-                let mut p2 = cx.new_parser_from_tts(&tts[..first_colon]);
+                let mut p2 =
+                    cx.new_parser_from_tts(tts.trees().take(first_colon).collect());
 
                 if p2.token == token::Eof {
                     let mut err =
@@ -129,12 +129,8 @@ fn parse_inline_asm<'a>(
                 // This is most likely malformed.
                 if p2.token != token::Eof {
                     let mut extra_tts = p2.parse_all_token_trees()?;
-                    extra_tts.extend(tts[first_colon..].iter().cloned());
-                    p = parse::stream_to_parser(
-                        cx.parse_sess,
-                        extra_tts.into_iter().collect(),
-                        Some("inline assembly"),
-                    );
+                    extra_tts.extend(tts.trees().skip(first_colon));
+                    p = cx.new_parser_from_tts(extra_tts.into_iter().collect());
                 }
 
                 asm = s;
diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs
index 84583d0e5ec..001996e1db7 100644
--- a/src/libsyntax_ext/assert.rs
+++ b/src/libsyntax_ext/assert.rs
@@ -13,7 +13,7 @@ use syntax_pos::{Span, DUMMY_SP};
 pub fn expand_assert<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn MacResult + 'cx> {
     let Assert { cond_expr, custom_message } = match parse_assert(cx, sp, tts) {
         Ok(assert) => assert,
@@ -59,9 +59,9 @@ struct Assert {
 fn parse_assert<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[TokenTree]
+    stream: TokenStream
 ) -> Result<Assert, DiagnosticBuilder<'a>> {
-    let mut parser = cx.new_parser_from_tts(tts);
+    let mut parser = cx.new_parser_from_tts(stream);
 
     if parser.token == token::Eof {
         let mut err = cx.struct_span_err(sp, "macro requires a boolean expression as an argument");
diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs
index 21cee8ae1cb..0342e442df2 100644
--- a/src/libsyntax_ext/cfg.rs
+++ b/src/libsyntax_ext/cfg.rs
@@ -7,14 +7,14 @@ use errors::DiagnosticBuilder;
 use syntax::ast;
 use syntax::ext::base::{self, *};
 use syntax::attr;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use syntax::parse::token;
 use syntax_pos::Span;
 
 pub fn expand_cfg(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let sp = cx.with_legacy_ctxt(sp);
 
@@ -33,7 +33,7 @@ pub fn expand_cfg(
 fn parse_cfg<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Result<ast::MetaItem, DiagnosticBuilder<'a>> {
     let mut p = cx.new_parser_from_tts(tts);
 
diff --git a/src/libsyntax_ext/compile_error.rs b/src/libsyntax_ext/compile_error.rs
index 59d3f2c9c78..24f3a66d4ae 100644
--- a/src/libsyntax_ext/compile_error.rs
+++ b/src/libsyntax_ext/compile_error.rs
@@ -2,11 +2,11 @@
 
 use syntax::ext::base::{self, *};
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 pub fn expand_compile_error<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
-                              tts: &[tokenstream::TokenTree])
+                              tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {
     let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
         None => return DummyResult::any(sp),
diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs
index ffa5154ca0c..fc56dff65e4 100644
--- a/src/libsyntax_ext/concat.rs
+++ b/src/libsyntax_ext/concat.rs
@@ -1,14 +1,14 @@
 use syntax::ast;
 use syntax::ext::base::{self, DummyResult};
 use syntax::symbol::Symbol;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 use std::string::String;
 
-pub fn expand_syntax_ext(
+pub fn expand_concat(
     cx: &mut base::ExtCtxt<'_>,
     sp: syntax_pos::Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'static> {
     let es = match base::get_exprs_from_tts(cx, sp, tts) {
         Some(e) => e,
diff --git a/src/libsyntax_ext/concat_idents.rs b/src/libsyntax_ext/concat_idents.rs
index 96677072d1b..6391b62b58d 100644
--- a/src/libsyntax_ext/concat_idents.rs
+++ b/src/libsyntax_ext/concat_idents.rs
@@ -6,21 +6,21 @@ use syntax::parse::token::{self, Token};
 use syntax::ptr::P;
 use syntax_pos::Span;
 use syntax_pos::symbol::Symbol;
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 
-pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
-                              sp: Span,
-                              tts: &[TokenTree])
-                              -> Box<dyn base::MacResult + 'cx> {
+pub fn expand_concat_idents<'cx>(cx: &'cx mut ExtCtxt<'_>,
+                                 sp: Span,
+                                 tts: TokenStream)
+                                 -> Box<dyn base::MacResult + 'cx> {
     if tts.is_empty() {
         cx.span_err(sp, "concat_idents! takes 1 or more arguments.");
         return DummyResult::any(sp);
     }
 
     let mut res_str = String::new();
-    for (i, e) in tts.iter().enumerate() {
+    for (i, e) in tts.into_trees().enumerate() {
         if i & 1 == 1 {
-            match *e {
+            match e {
                 TokenTree::Token(Token { kind: token::Comma, .. }) => {}
                 _ => {
                     cx.span_err(sp, "concat_idents! expecting comma.");
@@ -28,7 +28,7 @@ pub fn expand_syntax_ext<'cx>(cx: &'cx mut ExtCtxt<'_>,
                 }
             }
         } else {
-            match *e {
+            match e {
                 TokenTree::Token(Token { kind: token::Ident(name, _), .. }) =>
                     res_str.push_str(&name.as_str()),
                 _ => {
diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs
index 6343d218de8..179b7fe00a9 100644
--- a/src/libsyntax_ext/env.rs
+++ b/src/libsyntax_ext/env.rs
@@ -7,13 +7,13 @@ use syntax::ast::{self, Ident, GenericArg};
 use syntax::ext::base::{self, *};
 use syntax::symbol::{kw, sym, Symbol};
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 use std::env;
 
 pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
-                              tts: &[tokenstream::TokenTree])
+                              tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {
     let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
         None => return DummyResult::any(sp),
@@ -45,7 +45,7 @@ pub fn expand_option_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
 
 pub fn expand_env<'cx>(cx: &'cx mut ExtCtxt<'_>,
                        sp: Span,
-                       tts: &[tokenstream::TokenTree])
+                       tts: TokenStream)
                        -> Box<dyn base::MacResult + 'cx> {
     let mut exprs = match get_exprs_from_tts(cx, sp, tts) {
         Some(ref exprs) if exprs.is_empty() => {
diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs
index 47394c02b41..ad275f421af 100644
--- a/src/libsyntax_ext/format.rs
+++ b/src/libsyntax_ext/format.rs
@@ -11,7 +11,7 @@ use syntax::ext::base::{self, *};
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax::symbol::{Symbol, sym};
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use syntax_pos::{MultiSpan, Span};
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
@@ -126,7 +126,7 @@ struct Context<'a, 'b> {
 fn parse_args<'a>(
     ecx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree]
+    tts: TokenStream,
 ) -> Result<(P<ast::Expr>, Vec<P<ast::Expr>>, FxHashMap<Symbol, usize>), DiagnosticBuilder<'a>> {
     let mut args = Vec::<P<ast::Expr>>::new();
     let mut names = FxHashMap::<Symbol, usize>::default();
@@ -794,7 +794,7 @@ impl<'a, 'b> Context<'a, 'b> {
 fn expand_format_args_impl<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     mut sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
     nl: bool,
 ) -> Box<dyn base::MacResult + 'cx> {
     sp = ecx.with_def_site_ctxt(sp);
@@ -812,7 +812,7 @@ fn expand_format_args_impl<'cx>(
 pub fn expand_format_args<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     expand_format_args_impl(ecx, sp, tts, false)
 }
@@ -820,7 +820,7 @@ pub fn expand_format_args<'cx>(
 pub fn expand_format_args_nl<'cx>(
     ecx: &'cx mut ExtCtxt<'_>,
     sp: Span,
-    tts: &[tokenstream::TokenTree],
+    tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     expand_format_args_impl(ecx, sp, tts, true)
 }
diff --git a/src/libsyntax_ext/global_asm.rs b/src/libsyntax_ext/global_asm.rs
index a8b61593db7..6140f0df58a 100644
--- a/src/libsyntax_ext/global_asm.rs
+++ b/src/libsyntax_ext/global_asm.rs
@@ -16,12 +16,12 @@ use syntax::ext::base::{self, *};
 use syntax::parse::token;
 use syntax::ptr::P;
 use syntax_pos::Span;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use smallvec::smallvec;
 
 pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
                               sp: Span,
-                              tts: &[tokenstream::TokenTree]) -> Box<dyn base::MacResult + 'cx> {
+                              tts: TokenStream) -> Box<dyn base::MacResult + 'cx> {
     match parse_global_asm(cx, sp, tts) {
         Ok(Some(global_asm)) => {
             MacEager::items(smallvec![P(ast::Item {
@@ -45,7 +45,7 @@ pub fn expand_global_asm<'cx>(cx: &'cx mut ExtCtxt<'_>,
 fn parse_global_asm<'a>(
     cx: &mut ExtCtxt<'a>,
     sp: Span,
-    tts: &[tokenstream::TokenTree]
+    tts: TokenStream
 ) -> Result<Option<ast::GlobalAsm>, DiagnosticBuilder<'a>> {
     let mut p = cx.new_parser_from_tts(tts);
 
diff --git a/src/libsyntax_ext/lib.rs b/src/libsyntax_ext/lib.rs
index 1a617691662..26ef80b2b06 100644
--- a/src/libsyntax_ext/lib.rs
+++ b/src/libsyntax_ext/lib.rs
@@ -67,8 +67,8 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
         cfg: cfg::expand_cfg,
         column: source_util::expand_column,
         compile_error: compile_error::expand_compile_error,
-        concat_idents: concat_idents::expand_syntax_ext,
-        concat: concat::expand_syntax_ext,
+        concat_idents: concat_idents::expand_concat_idents,
+        concat: concat::expand_concat,
         env: env::expand_env,
         file: source_util::expand_file,
         format_args_nl: format::expand_format_args_nl,
@@ -78,7 +78,7 @@ pub fn register_builtin_macros(resolver: &mut dyn syntax::ext::base::Resolver, e
         include_str: source_util::expand_include_str,
         include: source_util::expand_include,
         line: source_util::expand_line,
-        log_syntax: log_syntax::expand_syntax_ext,
+        log_syntax: log_syntax::expand_log_syntax,
         module_path: source_util::expand_mod,
         option_env: env::expand_option_env,
         stringify: source_util::expand_stringify,
diff --git a/src/libsyntax_ext/log_syntax.rs b/src/libsyntax_ext/log_syntax.rs
index cbdfd08b497..92130bfaf68 100644
--- a/src/libsyntax_ext/log_syntax.rs
+++ b/src/libsyntax_ext/log_syntax.rs
@@ -1,11 +1,11 @@
 use syntax::ext::base;
 use syntax::print;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 use syntax_pos;
 
-pub fn expand_syntax_ext<'cx>(_cx: &'cx mut base::ExtCtxt<'_>,
+pub fn expand_log_syntax<'cx>(_cx: &'cx mut base::ExtCtxt<'_>,
                               sp: syntax_pos::Span,
-                              tts: &[tokenstream::TokenTree])
+                              tts: TokenStream)
                               -> Box<dyn base::MacResult + 'cx> {
     println!("{}", print::pprust::tts_to_string(tts));
 
diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs
index e008ed710e4..9dc9d66b86f 100644
--- a/src/libsyntax_ext/source_util.rs
+++ b/src/libsyntax_ext/source_util.rs
@@ -4,7 +4,7 @@ use syntax::parse::{self, token, DirectoryOwnership};
 use syntax::print::pprust;
 use syntax::ptr::P;
 use syntax::symbol::Symbol;
-use syntax::tokenstream;
+use syntax::tokenstream::TokenStream;
 
 use smallvec::SmallVec;
 use syntax_pos::{self, Pos, Span};
@@ -16,7 +16,7 @@ use rustc_data_structures::sync::Lrc;
 // a given file into the current one.
 
 /// line!(): expands to the current line number
-pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                    -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "line!");
 
@@ -27,7 +27,7 @@ pub fn expand_line(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree
 }
 
 /* column!(): expands to the current column number */
-pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                   -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "column!");
 
@@ -40,7 +40,7 @@ pub fn expand_column(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTr
 /// file!(): expands to the current filename */
 /// The source_file (`loc.file`) contains a bunch more information we could spit
 /// out if we wanted.
-pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                    -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "file!");
 
@@ -49,13 +49,13 @@ pub fn expand_file(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree
     base::MacEager::expr(cx.expr_str(topmost, Symbol::intern(&loc.file.name.to_string())))
 }
 
-pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_stringify(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                         -> Box<dyn base::MacResult+'static> {
     let s = pprust::tts_to_string(tts);
     base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
 }
 
-pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                   -> Box<dyn base::MacResult+'static> {
     base::check_zero_tts(cx, sp, tts, "module_path!");
     let mod_path = &cx.current_expansion.module.mod_path;
@@ -67,7 +67,7 @@ pub fn expand_mod(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree]
 /// include! : parse the given file as an expr
 /// This is generally a bad idea because it's going to behave
 /// unhygienically.
-pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                            -> Box<dyn base::MacResult+'cx> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
         Some(f) => f,
@@ -105,7 +105,7 @@ pub fn expand_include<'cx>(cx: &'cx mut ExtCtxt<'_>, sp: Span, tts: &[tokenstrea
 }
 
 // include_str! : read the given file, insert it as a literal string expr
-pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                           -> Box<dyn base::MacResult+'static> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
         Some(f) => f,
@@ -130,7 +130,7 @@ pub fn expand_include_str(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::To
     }
 }
 
-pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::TokenTree])
+pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: TokenStream)
                             -> Box<dyn base::MacResult+'static> {
     let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
         Some(f) => f,
diff --git a/src/libsyntax_ext/trace_macros.rs b/src/libsyntax_ext/trace_macros.rs
index 0dce8a36f4c..d83c24046d9 100644
--- a/src/libsyntax_ext/trace_macros.rs
+++ b/src/libsyntax_ext/trace_macros.rs
@@ -1,20 +1,27 @@
 use syntax::ext::base::{self, ExtCtxt};
 use syntax::symbol::kw;
 use syntax_pos::Span;
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 
 pub fn expand_trace_macros(cx: &mut ExtCtxt<'_>,
                            sp: Span,
-                           tt: &[TokenTree])
+                           tt: TokenStream)
                            -> Box<dyn base::MacResult + 'static> {
-    match tt {
-        [TokenTree::Token(token)] if token.is_keyword(kw::True) => {
-            cx.set_trace_macros(true);
-        }
-        [TokenTree::Token(token)] if token.is_keyword(kw::False) => {
-            cx.set_trace_macros(false);
-        }
-        _ => cx.span_err(sp, "trace_macros! accepts only `true` or `false`"),
+    let mut cursor = tt.into_trees();
+    let mut err = false;
+    let value = match &cursor.next() {
+        Some(TokenTree::Token(token)) if token.is_keyword(kw::True) => true,
+        Some(TokenTree::Token(token)) if token.is_keyword(kw::False) => false,
+        _ => {
+            err = true;
+            false
+        },
+    };
+    err |= cursor.next().is_some();
+    if err {
+        cx.span_err(sp, "trace_macros! accepts only `true` or `false`")
+    } else {
+        cx.set_trace_macros(value);
     }
 
     base::DummyResult::any_valid(sp)
diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs
index f44716e013e..3a4dc1f5a09 100644
--- a/src/libsyntax_pos/symbol.rs
+++ b/src/libsyntax_pos/symbol.rs
@@ -818,10 +818,14 @@ impl Ident {
         with_interner(|interner| interner.is_gensymed(self.name))
     }
 
+    /// Convert the name to a `LocalInternedString`. This is a slowish
+    /// operation because it requires locking the symbol interner.
     pub fn as_str(self) -> LocalInternedString {
         self.name.as_str()
     }
 
+    /// Convert the name to an `InternedString`. This is a slowish operation
+    /// because it requires locking the symbol interner.
     pub fn as_interned_str(self) -> InternedString {
         self.name.as_interned_str()
     }
@@ -916,6 +920,25 @@ impl Symbol {
         with_interner(|interner| interner.intern(string))
     }
 
+    /// Access the symbol's chars. This is a slowish operation because it
+    /// requires locking the symbol interner.
+    pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
+        with_interner(|interner| {
+            f(interner.get(self))
+        })
+    }
+
+    /// Access two symbols' chars. This is a slowish operation because it
+    /// requires locking the symbol interner, but it is faster than calling
+    /// `with()` twice.
+    fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: Symbol, f: F) -> R {
+        with_interner(|interner| {
+            f(interner.get(self), interner.get(other))
+        })
+    }
+
+    /// Convert to a `LocalInternedString`. This is a slowish operation because
+    /// it requires locking the symbol interner.
     pub fn as_str(self) -> LocalInternedString {
         with_interner(|interner| unsafe {
             LocalInternedString {
@@ -924,6 +947,8 @@ impl Symbol {
         })
     }
 
+    /// Convert to an `InternedString`. This is a slowish operation because it
+    /// requires locking the symbol interner.
     pub fn as_interned_str(self) -> InternedString {
         with_interner(|interner| InternedString {
             symbol: interner.interned(self)
@@ -1152,39 +1177,11 @@ fn with_interner<T, F: FnOnce(&mut Interner) -> T>(f: F) -> T {
 // FIXME: ensure that the interner outlives any thread which uses
 // `LocalInternedString`, by creating a new thread right after constructing the
 // interner.
-#[derive(Clone, Copy, Hash, PartialOrd, Eq, Ord)]
+#[derive(Clone, Copy, Eq, PartialOrd, Ord)]
 pub struct LocalInternedString {
     string: &'static str,
 }
 
-impl LocalInternedString {
-    /// Maps a string to its interned representation.
-    pub fn intern(string: &str) -> Self {
-        let string = with_interner(|interner| {
-            let symbol = interner.intern(string);
-            interner.strings[symbol.0.as_usize()]
-        });
-        LocalInternedString {
-            string: unsafe { std::mem::transmute::<&str, &str>(string) }
-        }
-    }
-
-    pub fn as_interned_str(self) -> InternedString {
-        InternedString {
-            symbol: Symbol::intern(self.string)
-        }
-    }
-
-    #[inline]
-    pub fn get(&self) -> &str {
-        // This returns a valid string since we ensure that `self` outlives the interner
-        // by creating the interner on a thread which outlives threads which can access it.
-        // This type cannot move to a thread which outlives the interner since it does
-        // not implement Send.
-        self.string
-    }
-}
-
 impl<U: ?Sized> std::convert::AsRef<U> for LocalInternedString
 where
     str: std::convert::AsRef<U>
@@ -1246,18 +1243,6 @@ impl fmt::Display for LocalInternedString {
     }
 }
 
-impl Decodable for LocalInternedString {
-    fn decode<D: Decoder>(d: &mut D) -> Result<LocalInternedString, D::Error> {
-        Ok(LocalInternedString::intern(&d.read_str()?))
-    }
-}
-
-impl Encodable for LocalInternedString {
-    fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(self.string)
-    }
-}
-
 /// An alternative to `Symbol` that is focused on string contents. It has two
 /// main differences to `Symbol`.
 ///
@@ -1285,28 +1270,19 @@ impl InternedString {
     }
 
     pub fn with<F: FnOnce(&str) -> R, R>(self, f: F) -> R {
-        let str = with_interner(|interner| {
-            interner.get(self.symbol) as *const str
-        });
-        // This is safe because the interner keeps string alive until it is dropped.
-        // We can access it because we know the interner is still alive since we use a
-        // scoped thread local to access it, and it was alive at the beginning of this scope
-        unsafe { f(&*str) }
+        self.symbol.with(f)
     }
 
     fn with2<F: FnOnce(&str, &str) -> R, R>(self, other: &InternedString, f: F) -> R {
-        let (self_str, other_str) = with_interner(|interner| {
-            (interner.get(self.symbol) as *const str,
-             interner.get(other.symbol) as *const str)
-        });
-        // This is safe for the same reason that `with` is safe.
-        unsafe { f(&*self_str, &*other_str) }
+        self.symbol.with2(other.symbol, f)
     }
 
     pub fn as_symbol(self) -> Symbol {
         self.symbol
     }
 
+    /// Convert to a `LocalInternedString`. This is a slowish operation because it
+    /// requires locking the symbol interner.
     pub fn as_str(self) -> LocalInternedString {
         self.symbol.as_str()
     }
diff --git a/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs b/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs
new file mode 100644
index 00000000000..5c4a01ee3a7
--- /dev/null
+++ b/src/test/rustdoc/auxiliary/through-proc-macro-aux.rs
@@ -0,0 +1,20 @@
+// force-host
+// no-prefer-dynamic
+#![crate_type = "proc-macro"]
+#![crate_name="some_macros"]
+
+extern crate proc_macro;
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn first(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    item // This doesn't erase the spans.
+}
+
+#[proc_macro_attribute]
+pub fn second(_attr: TokenStream, item: TokenStream) -> TokenStream {
+    // Make a new `TokenStream` to erase the spans:
+    let mut out: TokenStream = TokenStream::new();
+    out.extend(item);
+    out
+}
diff --git a/src/test/rustdoc/through-proc-macro.rs b/src/test/rustdoc/through-proc-macro.rs
new file mode 100644
index 00000000000..348c9eea2dc
--- /dev/null
+++ b/src/test/rustdoc/through-proc-macro.rs
@@ -0,0 +1,12 @@
+// aux-build:through-proc-macro-aux.rs
+// build-aux-docs
+#![warn(intra_doc_link_resolution_failure)]
+extern crate some_macros;
+
+#[some_macros::second]
+pub enum Boom {
+    /// [Oooops]
+    Bam,
+}
+
+fn main() {}
diff --git a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
index 027025b72b3..2b57e9289b5 100644
--- a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
+++ b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs
@@ -15,12 +15,12 @@ extern crate rustc;
 extern crate rustc_driver;
 
 use syntax::parse::token::{self, Token};
-use syntax::tokenstream::TokenTree;
+use syntax::tokenstream::{TokenTree, TokenStream};
 use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager};
 use syntax_pos::Span;
 use rustc_driver::plugin::Registry;
 
-fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
+fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: TokenStream)
         -> Box<dyn MacResult + 'static> {
 
     static NUMERALS: &'static [(&'static str, usize)] = &[
@@ -36,7 +36,7 @@ fn expand_rn(cx: &mut ExtCtxt, sp: Span, args: &[TokenTree])
         return DummyResult::any(sp);
     }
 
-    let text = match args[0] {
+    let text = match args.into_trees().next().unwrap() {
         TokenTree::Token(Token { kind: token::Ident(s, _), .. }) => s.to_string(),
         _ => {
             cx.span_err(sp, "argument should be a single identifier");
diff --git a/src/test/ui/associated-const/associated-const-in-trait.stderr b/src/test/ui/associated-const/associated-const-in-trait.stderr
index dff268a55c9..a5d7fc5b702 100644
--- a/src/test/ui/associated-const/associated-const-in-trait.stderr
+++ b/src/test/ui/associated-const/associated-const-in-trait.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/associated-const-in-trait.rs:9:6
    |
+LL |     const N: usize;
+   |           - the trait cannot contain associated consts like `N`
+...
 LL | impl dyn Trait {
    |      ^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
-   = note: the trait cannot contain associated consts like `N`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs
new file mode 100644
index 00000000000..bb2a61f03ce
--- /dev/null
+++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.rs
@@ -0,0 +1,13 @@
+// edition:2018
+// Test that impl trait does not allow creating recursive types that are
+// otherwise forbidden when using `async` and `await`.
+
+async fn rec_1() { //~ ERROR recursion in an `async fn`
+    rec_2().await;
+}
+
+async fn rec_2() { //~ ERROR recursion in an `async fn`
+    rec_1().await;
+}
+
+fn main() {}
diff --git a/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr
new file mode 100644
index 00000000000..9249308936e
--- /dev/null
+++ b/src/test/ui/async-await/mutually-recursive-async-impl-trait-type.stderr
@@ -0,0 +1,19 @@
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/mutually-recursive-async-impl-trait-type.rs:5:18
+   |
+LL | async fn rec_1() {
+   |                  ^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
+
+error[E0733]: recursion in an `async fn` requires boxing
+  --> $DIR/mutually-recursive-async-impl-trait-type.rs:9:18
+   |
+LL | async fn rec_2() {
+   |                  ^ recursive `async fn`
+   |
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0733`.
diff --git a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
index 8781a9c444d..9ee01402180 100644
--- a/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
+++ b/src/test/ui/async-await/recursive-async-impl-trait-type.stderr
@@ -2,9 +2,9 @@ error[E0733]: recursion in an `async fn` requires boxing
   --> $DIR/recursive-async-impl-trait-type.rs:5:40
    |
 LL | async fn recursive_async_function() -> () {
-   |                                        ^^ an `async fn` cannot invoke itself directly
+   |                                        ^^ recursive `async fn`
    |
-   = note: a recursive `async fn` must be rewritten to return a boxed future.
+   = note: a recursive `async fn` must be rewritten to return a boxed `dyn Future`.
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
index c38d7456a99..18a7cea95bd 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.old.stderr
@@ -1,10 +1,10 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
    |
+LL | trait NotObjectSafe { fn eq(&self, other: Self); }
+   |                          -- method `eq` references the `Self` type in its parameters or return type
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
    |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
-   |
-   = note: method `eq` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
index c38d7456a99..18a7cea95bd 100644
--- a/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
+++ b/src/test/ui/coherence/coherence-impl-trait-for-trait-object-safe.re.stderr
@@ -1,10 +1,10 @@
 error[E0038]: the trait `NotObjectSafe` cannot be made into an object
   --> $DIR/coherence-impl-trait-for-trait-object-safe.rs:11:6
    |
+LL | trait NotObjectSafe { fn eq(&self, other: Self); }
+   |                          -- method `eq` references the `Self` type in its parameters or return type
 LL | impl NotObjectSafe for dyn NotObjectSafe { }
    |      ^^^^^^^^^^^^^ the trait `NotObjectSafe` cannot be made into an object
-   |
-   = note: method `eq` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/consts/const-err2.rs b/src/test/ui/consts/const-err2.rs
index a5f685a159b..ecbcc2a4b49 100644
--- a/src/test/ui/consts/const-err2.rs
+++ b/src/test/ui/consts/const-err2.rs
@@ -5,6 +5,7 @@
 
 #![feature(rustc_attrs)]
 #![allow(exceeding_bitshifts)]
+
 #![deny(const_err)]
 
 fn black_box<T>(_: T) {
@@ -21,7 +22,7 @@ fn main() {
     let d = 42u8 - (42u8 + 1);
     //~^ ERROR const_err
     let _e = [5u8][1];
-    //~^ ERROR const_err
+    //~^ ERROR index out of bounds
     black_box(a);
     black_box(b);
     black_box(c);
diff --git a/src/test/ui/consts/const-err2.stderr b/src/test/ui/consts/const-err2.stderr
index 659c3afc618..1d84d44dc27 100644
--- a/src/test/ui/consts/const-err2.stderr
+++ b/src/test/ui/consts/const-err2.stderr
@@ -1,35 +1,35 @@
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:15:13
+  --> $DIR/const-err2.rs:16:13
    |
 LL |     let a = -std::i8::MIN;
    |             ^^^^^^^^^^^^^ attempt to negate with overflow
    |
 note: lint level defined here
-  --> $DIR/const-err2.rs:8:9
+  --> $DIR/const-err2.rs:9:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:17:13
+  --> $DIR/const-err2.rs:18:13
    |
 LL |     let b = 200u8 + 200u8 + 200u8;
    |             ^^^^^^^^^^^^^ attempt to add with overflow
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:19:13
+  --> $DIR/const-err2.rs:20:13
    |
 LL |     let c = 200u8 * 4;
    |             ^^^^^^^^^ attempt to multiply with overflow
 
 error: this expression will panic at runtime
-  --> $DIR/const-err2.rs:21:13
+  --> $DIR/const-err2.rs:22:13
    |
 LL |     let d = 42u8 - (42u8 + 1);
    |             ^^^^^^^^^^^^^^^^^ attempt to subtract with overflow
 
 error: index out of bounds: the len is 1 but the index is 1
-  --> $DIR/const-err2.rs:23:14
+  --> $DIR/const-err2.rs:24:14
    |
 LL |     let _e = [5u8][1];
    |              ^^^^^^^^
diff --git a/src/test/ui/consts/const-err3.rs b/src/test/ui/consts/const-err3.rs
new file mode 100644
index 00000000000..a9cf04cda7a
--- /dev/null
+++ b/src/test/ui/consts/const-err3.rs
@@ -0,0 +1,30 @@
+// needed because negating int::MIN will behave differently between
+// optimized compilation and unoptimized compilation and thus would
+// lead to different lints being emitted
+// compile-flags: -C overflow-checks=on -O
+
+#![feature(rustc_attrs)]
+#![allow(exceeding_bitshifts)]
+
+#![deny(const_err)]
+
+fn black_box<T>(_: T) {
+    unimplemented!()
+}
+
+fn main() {
+    let a = -std::i8::MIN;
+    //~^ ERROR const_err
+    let b = 200u8 + 200u8 + 200u8;
+    //~^ ERROR const_err
+    let c = 200u8 * 4;
+    //~^ ERROR const_err
+    let d = 42u8 - (42u8 + 1);
+    //~^ ERROR const_err
+    let _e = [5u8][1];
+    //~^ ERROR const_err
+    black_box(a);
+    black_box(b);
+    black_box(c);
+    black_box(d);
+}
diff --git a/src/test/ui/consts/const-err3.stderr b/src/test/ui/consts/const-err3.stderr
new file mode 100644
index 00000000000..0602707be70
--- /dev/null
+++ b/src/test/ui/consts/const-err3.stderr
@@ -0,0 +1,38 @@
+error: attempt to negate with overflow
+  --> $DIR/const-err3.rs:16:13
+   |
+LL |     let a = -std::i8::MIN;
+   |             ^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/const-err3.rs:9:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to add with overflow
+  --> $DIR/const-err3.rs:18:13
+   |
+LL |     let b = 200u8 + 200u8 + 200u8;
+   |             ^^^^^^^^^^^^^
+
+error: attempt to multiply with overflow
+  --> $DIR/const-err3.rs:20:13
+   |
+LL |     let c = 200u8 * 4;
+   |             ^^^^^^^^^
+
+error: attempt to subtract with overflow
+  --> $DIR/const-err3.rs:22:13
+   |
+LL |     let d = 42u8 - (42u8 + 1);
+   |             ^^^^^^^^^^^^^^^^^
+
+error: index out of bounds: the len is 1 but the index is 1
+  --> $DIR/const-err3.rs:24:14
+   |
+LL |     let _e = [5u8][1];
+   |              ^^^^^^^^
+
+error: aborting due to 5 previous errors
+
diff --git a/src/test/ui/consts/const-eval/promoted_errors.rs b/src/test/ui/consts/const-eval/promoted_errors.rs
index cd989731452..45941398f4b 100644
--- a/src/test/ui/consts/const-eval/promoted_errors.rs
+++ b/src/test/ui/consts/const-eval/promoted_errors.rs
@@ -5,7 +5,7 @@
 fn main() {
     println!("{}", 0u32 - 1);
     let _x = 0u32 - 1;
-    //~^ ERROR this expression will panic at runtime [const_err]
+    //~^ ERROR const_err
     println!("{}", 1/(1-1));
     //~^ ERROR attempt to divide by zero [const_err]
     //~| ERROR reaching this expression at runtime will panic or abort [const_err]
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.rs b/src/test/ui/consts/const-eval/promoted_errors2.rs
new file mode 100644
index 00000000000..7adb394144b
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors2.rs
@@ -0,0 +1,22 @@
+// compile-flags: -C overflow-checks=on -O
+
+#![deny(const_err)]
+
+fn main() {
+    println!("{}", 0u32 - 1);
+    //~^ ERROR attempt to subtract with overflow
+    let _x = 0u32 - 1;
+    //~^ ERROR attempt to subtract with overflow
+    println!("{}", 1/(1-1));
+    //~^ ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
+    let _x = 1/(1-1);
+    //~^ ERROR const_err
+    //~| ERROR const_err
+    println!("{}", 1/(false as u32));
+    //~^ ERROR attempt to divide by zero [const_err]
+    //~| ERROR reaching this expression at runtime will panic or abort [const_err]
+    let _x = 1/(false as u32);
+    //~^ ERROR const_err
+    //~| ERROR const_err
+}
diff --git a/src/test/ui/consts/const-eval/promoted_errors2.stderr b/src/test/ui/consts/const-eval/promoted_errors2.stderr
new file mode 100644
index 00000000000..2819e6e8fdb
--- /dev/null
+++ b/src/test/ui/consts/const-eval/promoted_errors2.stderr
@@ -0,0 +1,68 @@
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors2.rs:6:20
+   |
+LL |     println!("{}", 0u32 - 1);
+   |                    ^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/promoted_errors2.rs:3:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to subtract with overflow
+  --> $DIR/promoted_errors2.rs:8:14
+   |
+LL |     let _x = 0u32 - 1;
+   |              ^^^^^^^^
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:10:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^
+
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors2.rs:10:20
+   |
+LL |     println!("{}", 1/(1-1));
+   |                    ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:13:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors2.rs:13:14
+   |
+LL |     let _x = 1/(1-1);
+   |              ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:16:20
+   |
+LL |     println!("{}", 1/(false as u32));
+   |                    ^^^^^^^^^^^^^^^^
+
+error: reaching this expression at runtime will panic or abort
+  --> $DIR/promoted_errors2.rs:16:20
+   |
+LL |     println!("{}", 1/(false as u32));
+   |                    ^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/promoted_errors2.rs:19:14
+   |
+LL |     let _x = 1/(false as u32);
+   |              ^^^^^^^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/promoted_errors2.rs:19:14
+   |
+LL |     let _x = 1/(false as u32);
+   |              ^^^^^^^^^^^^^^^^ attempt to divide by zero
+
+error: aborting due to 10 previous errors
+
diff --git a/src/test/ui/consts/issue-64059-2.rs b/src/test/ui/consts/issue-64059-2.rs
new file mode 100644
index 00000000000..38911c3dcf6
--- /dev/null
+++ b/src/test/ui/consts/issue-64059-2.rs
@@ -0,0 +1,6 @@
+// compile-flags: -C overflow-checks=on -O
+// run-pass
+
+fn main() {
+    let _ = -(-0.0);
+}
diff --git a/src/test/ui/consts/issue-64059.rs b/src/test/ui/consts/issue-64059.rs
new file mode 100644
index 00000000000..c4c895fef66
--- /dev/null
+++ b/src/test/ui/consts/issue-64059.rs
@@ -0,0 +1,5 @@
+// run-pass
+
+fn main() {
+    let _ = -(-0.0);
+}
diff --git a/src/test/ui/did_you_mean/issue-40006.stderr b/src/test/ui/did_you_mean/issue-40006.stderr
index 87e48cd1e1c..5b384045a48 100644
--- a/src/test/ui/did_you_mean/issue-40006.stderr
+++ b/src/test/ui/did_you_mean/issue-40006.stderr
@@ -61,8 +61,9 @@ error[E0038]: the trait `X` cannot be made into an object
    |
 LL | impl dyn X {
    |      ^^^^^ the trait `X` cannot be made into an object
-   |
-   = note: method `xxx` has no receiver
+...
+LL |     fn xxx() { ### }
+   |        --- associated function `xxx` has no `self` parameter
 
 error: aborting due to 9 previous errors
 
diff --git a/src/test/ui/error-codes/E0033-teach.rs b/src/test/ui/error-codes/E0033-teach.rs
index 6a27b07fa8b..19439651394 100644
--- a/src/test/ui/error-codes/E0033-teach.rs
+++ b/src/test/ui/error-codes/E0033-teach.rs
@@ -1,14 +1,13 @@
 // compile-flags: -Z teach
 
 trait SomeTrait {
-    fn foo();
+    fn foo(); //~ associated function `foo` has no `self` parameter
 }
 
 fn main() {
     let trait_obj: &dyn SomeTrait = SomeTrait;
     //~^ ERROR expected value, found trait `SomeTrait`
     //~| ERROR E0038
-    //~| method `foo` has no receiver
 
     let &invalid = trait_obj;
     //~^ ERROR E0033
diff --git a/src/test/ui/error-codes/E0033-teach.stderr b/src/test/ui/error-codes/E0033-teach.stderr
index fb630de7fc1..80f3d4441bd 100644
--- a/src/test/ui/error-codes/E0033-teach.stderr
+++ b/src/test/ui/error-codes/E0033-teach.stderr
@@ -7,13 +7,14 @@ LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
 error[E0038]: the trait `SomeTrait` cannot be made into an object
   --> $DIR/E0033-teach.rs:8:20
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
    |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
-   |
-   = note: method `foo` has no receiver
 
 error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
-  --> $DIR/E0033-teach.rs:13:9
+  --> $DIR/E0033-teach.rs:12:9
    |
 LL |     let &invalid = trait_obj;
    |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
diff --git a/src/test/ui/error-codes/E0033.rs b/src/test/ui/error-codes/E0033.rs
index 582600e110b..e5f0530f45f 100644
--- a/src/test/ui/error-codes/E0033.rs
+++ b/src/test/ui/error-codes/E0033.rs
@@ -1,12 +1,11 @@
 trait SomeTrait {
-    fn foo();
+    fn foo(); //~ associated function `foo` has no `self` parameter
 }
 
 fn main() {
     let trait_obj: &dyn SomeTrait = SomeTrait;
     //~^ ERROR expected value, found trait `SomeTrait`
     //~| ERROR E0038
-    //~| method `foo` has no receiver
 
     let &invalid = trait_obj;
     //~^ ERROR E0033
diff --git a/src/test/ui/error-codes/E0033.stderr b/src/test/ui/error-codes/E0033.stderr
index fe9f45d86a6..c2843796cc8 100644
--- a/src/test/ui/error-codes/E0033.stderr
+++ b/src/test/ui/error-codes/E0033.stderr
@@ -7,13 +7,14 @@ LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
 error[E0038]: the trait `SomeTrait` cannot be made into an object
   --> $DIR/E0033.rs:6:20
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let trait_obj: &dyn SomeTrait = SomeTrait;
    |                    ^^^^^^^^^^^^^^ the trait `SomeTrait` cannot be made into an object
-   |
-   = note: method `foo` has no receiver
 
 error[E0033]: type `&dyn SomeTrait` cannot be dereferenced
-  --> $DIR/E0033.rs:11:9
+  --> $DIR/E0033.rs:10:9
    |
 LL |     let &invalid = trait_obj;
    |         ^^^^^^^^ type `&dyn SomeTrait` cannot be dereferenced
diff --git a/src/test/ui/error-codes/E0038.stderr b/src/test/ui/error-codes/E0038.stderr
index e3d7593e42a..5c4d6d53c46 100644
--- a/src/test/ui/error-codes/E0038.stderr
+++ b/src/test/ui/error-codes/E0038.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Trait` cannot be made into an object
   --> $DIR/E0038.rs:5:1
    |
+LL |     fn foo(&self) -> Self;
+   |        --- method `foo` references the `Self` type in its parameters or return type
+...
 LL | fn call_foo(x: Box<dyn Trait>) {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait` cannot be made into an object
-   |
-   = note: method `foo` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs b/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs
index 82c64bcf6a7..9ab8e13893b 100644
--- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs
+++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.rs
@@ -6,11 +6,11 @@ struct Foo<'a,'b> {
 impl<'a,'b> Foo<'a,'b> {
     fn bar(self:
            Foo<'b,'a>
-    //~^ ERROR mismatched method receiver
+    //~^ ERROR mismatched `self` parameter type
     //~| expected type `Foo<'a, 'b>`
     //~| found type `Foo<'b, 'a>`
     //~| lifetime mismatch
-    //~| ERROR mismatched method receiver
+    //~| ERROR mismatched `self` parameter type
     //~| expected type `Foo<'a, 'b>`
     //~| found type `Foo<'b, 'a>`
     //~| lifetime mismatch
diff --git a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
index e6f9eded9a4..4bf2d573d4f 100644
--- a/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
+++ b/src/test/ui/explicit/explicit-self-lifetime-mismatch.stderr
@@ -1,4 +1,4 @@
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/explicit-self-lifetime-mismatch.rs:8:12
    |
 LL |            Foo<'b,'a>
@@ -17,7 +17,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl<'a,'b> Foo<'a,'b> {
    |      ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/explicit-self-lifetime-mismatch.rs:8:12
    |
 LL |            Foo<'b,'a>
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs
new file mode 100644
index 00000000000..cfd9c0ec5b4
--- /dev/null
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.rs
@@ -0,0 +1,25 @@
+// Test that impl trait does not allow creating recursive types that are
+// otherwise forbidden. Even when there's an opaque type in another crate
+// hiding this.
+
+fn id<T>(t: T) -> impl Sized { t }
+
+fn recursive_id() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    id(recursive_id2())
+}
+
+fn recursive_id2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    id(recursive_id())
+}
+
+fn wrap<T>(t: T) -> impl Sized { (t,) }
+
+fn recursive_wrap() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    wrap(recursive_wrap2())
+}
+
+fn recursive_wrap2() -> impl Sized { //~ ERROR opaque type expands to a recursive type
+    wrap(recursive_wrap())
+}
+
+fn main() {}
diff --git a/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr
new file mode 100644
index 00000000000..7572c6c1bf0
--- /dev/null
+++ b/src/test/ui/impl-trait/recursive-impl-trait-type--through-non-recursize.stderr
@@ -0,0 +1,35 @@
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:7:22
+   |
+LL | fn recursive_id() -> impl Sized {
+   |                      ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: type resolves to itself
+
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:11:23
+   |
+LL | fn recursive_id2() -> impl Sized {
+   |                       ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: type resolves to itself
+
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:17:24
+   |
+LL | fn recursive_wrap() -> impl Sized {
+   |                        ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: expanded type is `((impl Sized,),)`
+
+error[E0720]: opaque type expands to a recursive type
+  --> $DIR/recursive-impl-trait-type--through-non-recursize.rs:21:25
+   |
+LL | fn recursive_wrap2() -> impl Sized {
+   |                         ^^^^^^^^^^ expands to a recursive type
+   |
+   = note: expanded type is `((impl Sized,),)`
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/src/test/ui/issues/issue-17740.rs b/src/test/ui/issues/issue-17740.rs
index c131b895849..b47568400c3 100644
--- a/src/test/ui/issues/issue-17740.rs
+++ b/src/test/ui/issues/issue-17740.rs
@@ -4,11 +4,11 @@ struct Foo<'a> {
 
 impl <'a> Foo<'a>{
     fn bar(self: &mut Foo) {
-    //~^ mismatched method receiver
+    //~^ mismatched `self` parameter type
     //~| expected type `Foo<'a>`
     //~| found type `Foo<'_>`
     //~| lifetime mismatch
-    //~| mismatched method receiver
+    //~| mismatched `self` parameter type
     //~| expected type `Foo<'a>`
     //~| found type `Foo<'_>`
     //~| lifetime mismatch
diff --git a/src/test/ui/issues/issue-17740.stderr b/src/test/ui/issues/issue-17740.stderr
index 7ab0fa4d818..b8a0a067631 100644
--- a/src/test/ui/issues/issue-17740.stderr
+++ b/src/test/ui/issues/issue-17740.stderr
@@ -1,4 +1,4 @@
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17740.rs:6:18
    |
 LL |     fn bar(self: &mut Foo) {
@@ -23,7 +23,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl <'a> Foo<'a>{
    |       ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17740.rs:6:18
    |
 LL |     fn bar(self: &mut Foo) {
diff --git a/src/test/ui/issues/issue-17905-2.rs b/src/test/ui/issues/issue-17905-2.rs
index 259d9450189..44279cc867b 100644
--- a/src/test/ui/issues/issue-17905-2.rs
+++ b/src/test/ui/issues/issue-17905-2.rs
@@ -6,8 +6,8 @@ impl Pair<
     isize
 > {
     fn say(self: &Pair<&str, isize>) {
-//~^ ERROR mismatched method receiver
-//~| ERROR mismatched method receiver
+//~^ ERROR mismatched `self` parameter type
+//~| ERROR mismatched `self` parameter type
         println!("{:?}", self);
     }
 }
diff --git a/src/test/ui/issues/issue-17905-2.stderr b/src/test/ui/issues/issue-17905-2.stderr
index e3909e0c125..585bc9c1488 100644
--- a/src/test/ui/issues/issue-17905-2.stderr
+++ b/src/test/ui/issues/issue-17905-2.stderr
@@ -1,4 +1,4 @@
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17905-2.rs:8:18
    |
 LL |     fn say(self: &Pair<&str, isize>) {
@@ -21,7 +21,7 @@ note: ...does not necessarily outlive the lifetime '_ as defined on the impl at
 LL |     &str,
    |     ^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/issue-17905-2.rs:8:18
    |
 LL |     fn say(self: &Pair<&str, isize>) {
diff --git a/src/test/ui/issues/issue-18959.stderr b/src/test/ui/issues/issue-18959.stderr
index 63c33b7f447..d5e7092801e 100644
--- a/src/test/ui/issues/issue-18959.stderr
+++ b/src/test/ui/issues/issue-18959.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-18959.rs:11:1
    |
+LL | pub trait Foo { fn foo<T>(&self, ext_thing: &T); }
+   |                    --- method `foo` has generic type parameters
+...
 LL | fn foo(b: &dyn Bar) {
    | ^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `foo` has generic type parameters
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-19380.stderr b/src/test/ui/issues/issue-19380.stderr
index 27e3ff57bf9..92bfdf1f26e 100644
--- a/src/test/ui/issues/issue-19380.stderr
+++ b/src/test/ui/issues/issue-19380.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Qiz` cannot be made into an object
   --> $DIR/issue-19380.rs:11:3
    |
+LL |   fn qiz();
+   |      --- associated function `qiz` has no `self` parameter
+...
 LL |   foos: &'static [&'static (dyn Qiz + 'static)]
    |   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Qiz` cannot be made into an object
-   |
-   = note: method `qiz` has no receiver
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/issues/issue-19538.stderr b/src/test/ui/issues/issue-19538.stderr
index e5da0a9b0da..5415a45f7d6 100644
--- a/src/test/ui/issues/issue-19538.stderr
+++ b/src/test/ui/issues/issue-19538.stderr
@@ -1,18 +1,21 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-19538.rs:17:15
    |
+LL |     fn foo<T>(&self, val: T);
+   |        --- method `foo` has generic type parameters
+...
 LL |     let test: &mut dyn Bar = &mut thing;
    |               ^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `foo` has generic type parameters
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/issue-19538.rs:17:30
    |
+LL |     fn foo<T>(&self, val: T);
+   |        --- method `foo` has generic type parameters
+...
 LL |     let test: &mut dyn Bar = &mut thing;
    |                              ^^^^^^^^^^ the trait `Bar` cannot be made into an object
    |
-   = note: method `foo` has generic type parameters
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&mut dyn Bar>` for `&mut Thing`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/issues/issue-50781.stderr b/src/test/ui/issues/issue-50781.stderr
index c98f78c51ee..02475ea97e3 100644
--- a/src/test/ui/issues/issue-50781.stderr
+++ b/src/test/ui/issues/issue-50781.stderr
@@ -1,8 +1,8 @@
 error: the trait `X` cannot be made into an object
-  --> $DIR/issue-50781.rs:6:5
+  --> $DIR/issue-50781.rs:6:8
    |
 LL |     fn foo(&self) where Self: Trait;
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |        ^^^
    |
 note: lint level defined here
   --> $DIR/issue-50781.rs:1:9
diff --git a/src/test/ui/issues/issue-56806.rs b/src/test/ui/issues/issue-56806.rs
index b6454e578e6..b1dac26d65a 100644
--- a/src/test/ui/issues/issue-56806.rs
+++ b/src/test/ui/issues/issue-56806.rs
@@ -1,7 +1,6 @@
 pub trait Trait {
     fn dyn_instead_of_self(self: Box<dyn Trait>);
-    //~^ ERROR invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
+    //~^ ERROR invalid `self` parameter type
 }
 
-pub fn main() {
-}
+pub fn main() {}
diff --git a/src/test/ui/issues/issue-56806.stderr b/src/test/ui/issues/issue-56806.stderr
index fae6a26720f..a4f9aadcfef 100644
--- a/src/test/ui/issues/issue-56806.stderr
+++ b/src/test/ui/issues/issue-56806.stderr
@@ -1,11 +1,12 @@
-error[E0307]: invalid method receiver type: std::boxed::Box<(dyn Trait + 'static)>
+error[E0307]: invalid `self` parameter type: std::boxed::Box<(dyn Trait + 'static)>
   --> $DIR/issue-56806.rs:2:34
    |
 LL |     fn dyn_instead_of_self(self: Box<dyn Trait>);
    |                                  ^^^^^^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0307`.
diff --git a/src/test/ui/issues/issue-8460-const.rs b/src/test/ui/issues/issue-8460-const.rs
index 611d280f774..4637814b277 100644
--- a/src/test/ui/issues/issue-8460-const.rs
+++ b/src/test/ui/issues/issue-8460-const.rs
@@ -1,3 +1,5 @@
+// compile-flags: -O
+
 #![deny(const_err)]
 
 use std::{isize, i8, i16, i32, i64};
diff --git a/src/test/ui/issues/issue-8460-const.stderr b/src/test/ui/issues/issue-8460-const.stderr
index 31b1da4f804..7e5a22e651e 100644
--- a/src/test/ui/issues/issue-8460-const.stderr
+++ b/src/test/ui/issues/issue-8460-const.stderr
@@ -1,245 +1,245 @@
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:7:36
+  --> $DIR/issue-8460-const.rs:9:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
    |
 note: lint level defined here
-  --> $DIR/issue-8460-const.rs:1:9
+  --> $DIR/issue-8460-const.rs:3:9
    |
 LL | #![deny(const_err)]
    |         ^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:7:36
+  --> $DIR/issue-8460-const.rs:9:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:10:36
+  --> $DIR/issue-8460-const.rs:12:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:10:36
+  --> $DIR/issue-8460-const.rs:12:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:13:36
+  --> $DIR/issue-8460-const.rs:15:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:13:36
+  --> $DIR/issue-8460-const.rs:15:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:16:36
+  --> $DIR/issue-8460-const.rs:18:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:16:36
+  --> $DIR/issue-8460-const.rs:18:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide with overflow
-  --> $DIR/issue-8460-const.rs:19:36
+  --> $DIR/issue-8460-const.rs:21:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:19:36
+  --> $DIR/issue-8460-const.rs:21:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to divide with overflow
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:24:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:22:36
+  --> $DIR/issue-8460-const.rs:24:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:27:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:25:36
+  --> $DIR/issue-8460-const.rs:27:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:30:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:28:36
+  --> $DIR/issue-8460-const.rs:30:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:33:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:31:36
+  --> $DIR/issue-8460-const.rs:33:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to divide by zero
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:36:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:34:36
+  --> $DIR/issue-8460-const.rs:36:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to divide by zero
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:37:36
+  --> $DIR/issue-8460-const.rs:39:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:37:36
+  --> $DIR/issue-8460-const.rs:39:36
    |
 LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:42:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:40:36
+  --> $DIR/issue-8460-const.rs:42:36
    |
 LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:43:36
+  --> $DIR/issue-8460-const.rs:45:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:43:36
+  --> $DIR/issue-8460-const.rs:45:36
    |
 LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:46:36
+  --> $DIR/issue-8460-const.rs:48:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:46:36
+  --> $DIR/issue-8460-const.rs:48:36
    |
 LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with overflow
-  --> $DIR/issue-8460-const.rs:49:36
+  --> $DIR/issue-8460-const.rs:51:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:49:36
+  --> $DIR/issue-8460-const.rs:51:36
    |
 LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
    |                                    ^^^^^^^^^^^^^ attempt to calculate the remainder with overflow
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:54:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:52:36
+  --> $DIR/issue-8460-const.rs:54:36
    |
 LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
    |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:57:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:55:36
+  --> $DIR/issue-8460-const.rs:57:36
    |
 LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
    |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:60:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:58:36
+  --> $DIR/issue-8460-const.rs:60:36
    |
 LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:63:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:61:36
+  --> $DIR/issue-8460-const.rs:63:36
    |
 LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
 
 error: attempt to calculate the remainder with a divisor of zero
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:66:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^
 
 error: this expression will panic at runtime
-  --> $DIR/issue-8460-const.rs:64:36
+  --> $DIR/issue-8460-const.rs:66:36
    |
 LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
    |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
diff --git a/src/test/ui/issues/issue-8460-const2.rs b/src/test/ui/issues/issue-8460-const2.rs
new file mode 100644
index 00000000000..c3f53e3298b
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const2.rs
@@ -0,0 +1,59 @@
+// compile-flags: -C overflow-checks=on -O
+
+#![deny(const_err)]
+
+use std::{isize, i8, i16, i32, i64};
+use std::thread;
+
+fn main() {
+    assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+    //~^ ERROR attempt to divide with overflow
+    assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+    //~^ ERROR attempt to divide by zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with overflow
+    assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+    assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+    //~^ ERROR attempt to calculate the remainder with a divisor of zero
+    //~| ERROR this expression will panic at runtime
+}
diff --git a/src/test/ui/issues/issue-8460-const2.stderr b/src/test/ui/issues/issue-8460-const2.stderr
new file mode 100644
index 00000000000..b688ec13677
--- /dev/null
+++ b/src/test/ui/issues/issue-8460-const2.stderr
@@ -0,0 +1,188 @@
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:9:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^
+   |
+note: lint level defined here
+  --> $DIR/issue-8460-const2.rs:3:9
+   |
+LL | #![deny(const_err)]
+   |         ^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:11:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:13:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:15:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide with overflow
+  --> $DIR/issue-8460-const2.rs:17:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN / -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:19:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+   |                                    ^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:19:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize / 0; }).join().is_err());
+   |                                    ^^^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:22:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+   |                                    ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:22:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 / 0; }).join().is_err());
+   |                                    ^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:25:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:25:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:28:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:28:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to divide by zero
+  --> $DIR/issue-8460-const2.rs:31:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:31:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 / 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to divide by zero
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:34:36
+   |
+LL |     assert!(thread::spawn(move|| { isize::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:36:36
+   |
+LL |     assert!(thread::spawn(move|| { i8::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:38:36
+   |
+LL |     assert!(thread::spawn(move|| { i16::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:40:36
+   |
+LL |     assert!(thread::spawn(move|| { i32::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with overflow
+  --> $DIR/issue-8460-const2.rs:42:36
+   |
+LL |     assert!(thread::spawn(move|| { i64::MIN % -1; }).join().is_err());
+   |                                    ^^^^^^^^^^^^^
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:44:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+   |                                    ^^^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:44:36
+   |
+LL |     assert!(thread::spawn(move|| { 1isize % 0; }).join().is_err());
+   |                                    ^^^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:47:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+   |                                    ^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:47:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i8 % 0; }).join().is_err());
+   |                                    ^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:50:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:50:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i16 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:53:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:53:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i32 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: attempt to calculate the remainder with a divisor of zero
+  --> $DIR/issue-8460-const2.rs:56:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+   |                                    ^^^^^^^^
+
+error: this expression will panic at runtime
+  --> $DIR/issue-8460-const2.rs:56:36
+   |
+LL |     assert!(thread::spawn(move|| { 1i64 % 0; }).join().is_err());
+   |                                    ^^^^^^^^ attempt to calculate the remainder with a divisor of zero
+
+error: aborting due to 30 previous errors
+
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.rs b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
index eda9e2cdfaa..c442c39fe01 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.rs
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.rs
@@ -1,25 +1,75 @@
-// build-pass (FIXME(62277): could be check-pass?)
+#![feature(box_patterns)]
+
+#![feature(or_patterns)]
+//~^ WARN the feature `or_patterns` is incomplete
 
 #![allow(ellipsis_inclusive_range_patterns)]
 #![allow(unreachable_patterns)]
 #![allow(unused_variables)]
-#![warn(unused_parens)]
+#![deny(unused_parens)]
+
+fn lint_on_top_level() {
+    let (a) = 0; //~ ERROR unnecessary parentheses around pattern
+    for (a) in 0..1 {} //~ ERROR unnecessary parentheses around pattern
+    if let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    while let (a) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    fn foo((a): u8) {} //~ ERROR unnecessary parentheses around pattern
+    let _ = |(a): u8| 0; //~ ERROR unnecessary parentheses around pattern
+}
+
+// Don't lint in these cases (#64106).
+fn or_patterns_no_lint() {
+    match Box::new(0) {
+        box (0 | 1) => {} // Should not lint as `box 0 | 1` binds as `(box 0) | 1`.
+        _ => {}
+    }
+
+    match 0 {
+        x @ (0 | 1) => {} // Should not lint as `x @ 0 | 1` binds as `(x @ 0) | 1`.
+        _ => {}
+    }
+
+    if let &(0 | 1) = &0 {} // Should also not lint.
+    if let &mut (0 | 1) = &mut 0 {} // Same.
+
+    fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
+    //~^ ERROR identifier `a` is bound more than once
+
+    let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
+    //~^ ERROR identifier `a` is bound more than once
+}
+
+fn or_patterns_will_lint() {
+    if let (0 | 1) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    if let ((0 | 1),) = (0,) {} //~ ERROR unnecessary parentheses around pattern
+    if let [(0 | 1)] = [0] {} //~ ERROR unnecessary parentheses around pattern
+    if let 0 | (1 | 2) = 0 {} //~ ERROR unnecessary parentheses around pattern
+    struct TS(u8);
+    if let TS((0 | 1)) = TS(0) {} //~ ERROR unnecessary parentheses around pattern
+    struct NS { f: u8 }
+    if let NS { f: (0 | 1) } = (NS { f: 0 }) {} //~ ERROR unnecessary parentheses around pattern
+}
+
+// Don't lint on `&(mut x)` because `&mut x` means something else (#55342).
+fn deref_mut_binding_no_lint() {
+    let &(mut x) = &0;
+}
 
 fn main() {
     match 1 {
-        (_) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (y) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (ref r) => {}     //~ WARNING: unnecessary parentheses around pattern
-        (e @ 1...2) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        (1...2) => {}     // Non ambiguous range pattern should not warn
+        (_) => {} //~ ERROR unnecessary parentheses around pattern
+        (y) => {} //~ ERROR unnecessary parentheses around pattern
+        (ref r) => {} //~ ERROR unnecessary parentheses around pattern
+        (e @ 1...2) => {} //~ ERROR unnecessary parentheses around pattern
+        (1...2) => {} // Non ambiguous range pattern should not warn
         e @ (3...4) => {} // Non ambiguous range pattern should not warn
     }
 
     match &1 {
-        (e @ &(1...2)) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        &(_) => {}           //~ WARNING: unnecessary parentheses around pattern
-        e @ &(1...2) => {}   // Ambiguous range pattern should not warn
-        &(1...2) => {}       // Ambiguous range pattern should not warn
+        (e @ &(1...2)) => {} //~ ERROR unnecessary parentheses around pattern
+        &(_) => {} //~ ERROR unnecessary parentheses around pattern
+        e @ &(1...2) => {} // Ambiguous range pattern should not warn
+        &(1...2) => {} // Ambiguous range pattern should not warn
     }
 
     match &1 {
@@ -28,19 +78,19 @@ fn main() {
     }
 
     match 1 {
-        (_) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (y) => {}         //~ WARNING: unnecessary parentheses around pattern
-        (ref r) => {}     //~ WARNING: unnecessary parentheses around pattern
-        (e @ 1..=2) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        (1..=2) => {}     // Non ambiguous range pattern should not warn
+        (_) => {} //~ ERROR unnecessary parentheses around pattern
+        (y) => {} //~ ERROR unnecessary parentheses around pattern
+        (ref r) => {} //~ ERROR unnecessary parentheses around pattern
+        (e @ 1..=2) => {} //~ ERROR unnecessary parentheses around pattern
+        (1..=2) => {} // Non ambiguous range pattern should not warn
         e @ (3..=4) => {} // Non ambiguous range pattern should not warn
     }
 
     match &1 {
-        (e @ &(1..=2)) => {} //~ WARNING: unnecessary parentheses around outer pattern
-        &(_) => {}           //~ WARNING: unnecessary parentheses around pattern
-        e @ &(1..=2) => {}   // Ambiguous range pattern should not warn
-        &(1..=2) => {}       // Ambiguous range pattern should not warn
+        (e @ &(1..=2)) => {} //~ ERROR unnecessary parentheses around pattern
+        &(_) => {} //~ ERROR unnecessary parentheses around pattern
+        e @ &(1..=2) => {} // Ambiguous range pattern should not warn
+        &(1..=2) => {} // Ambiguous range pattern should not warn
     }
 
     match &1 {
diff --git a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
index 3b312198952..a3e0fb938b3 100644
--- a/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
+++ b/src/test/ui/lint/issue-54538-unused-parens-lint.stderr
@@ -1,78 +1,173 @@
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:10:9
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:35:25
    |
-LL |         (_) => {}
+LL |     fn foo((Ok(a) | Err(a)): Result<u8, u8>) {} // Doesn't parse if we remove parens for now.
+   |                         ^ used in a pattern more than once
+
+error[E0416]: identifier `a` is bound more than once in the same pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:38:27
+   |
+LL |     let _ = |(Ok(a) | Err(a)): Result<u8, u8>| 1; // `|Ok(a) | Err(a)| 1` parses as bit-or.
+   |                           ^ used in a pattern more than once
+
+warning: the feature `or_patterns` is incomplete and may cause the compiler to crash
+  --> $DIR/issue-54538-unused-parens-lint.rs:3:12
+   |
+LL | #![feature(or_patterns)]
+   |            ^^^^^^^^^^^
+   |
+   = note: `#[warn(incomplete_features)]` on by default
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:12:9
+   |
+LL |     let (a) = 0;
    |         ^^^ help: remove these parentheses
    |
 note: lint level defined here
-  --> $DIR/issue-54538-unused-parens-lint.rs:6:9
+  --> $DIR/issue-54538-unused-parens-lint.rs:9:9
    |
-LL | #![warn(unused_parens)]
+LL | #![deny(unused_parens)]
    |         ^^^^^^^^^^^^^
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:11:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:13:9
+   |
+LL |     for (a) in 0..1 {}
+   |         ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:14:12
+   |
+LL |     if let (a) = 0 {}
+   |            ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:15:15
+   |
+LL |     while let (a) = 0 {}
+   |               ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:16:12
+   |
+LL |     fn foo((a): u8) {}
+   |            ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:17:14
+   |
+LL |     let _ = |(a): u8| 0;
+   |              ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:43:12
+   |
+LL |     if let (0 | 1) = 0 {}
+   |            ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:44:13
+   |
+LL |     if let ((0 | 1),) = (0,) {}
+   |             ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:45:13
+   |
+LL |     if let [(0 | 1)] = [0] {}
+   |             ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:46:16
+   |
+LL |     if let 0 | (1 | 2) = 0 {}
+   |                ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:48:15
+   |
+LL |     if let TS((0 | 1)) = TS(0) {}
+   |               ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:50:20
+   |
+LL |     if let NS { f: (0 | 1) } = (NS { f: 0 }) {}
+   |                    ^^^^^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:60:9
+   |
+LL |         (_) => {}
+   |         ^^^ help: remove these parentheses
+
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:61:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:12:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:62:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:13:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:63:9
    |
 LL |         (e @ 1...2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:19:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:69:9
    |
 LL |         (e @ &(1...2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:20:10
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:70:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:31:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:81:9
    |
 LL |         (_) => {}
    |         ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:32:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:82:9
    |
 LL |         (y) => {}
    |         ^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:33:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:83:9
    |
 LL |         (ref r) => {}
    |         ^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:34:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:84:9
    |
 LL |         (e @ 1..=2) => {}
    |         ^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:40:9
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:90:9
    |
 LL |         (e @ &(1..=2)) => {}
    |         ^^^^^^^^^^^^^^ help: remove these parentheses
 
-warning: unnecessary parentheses around pattern
-  --> $DIR/issue-54538-unused-parens-lint.rs:41:10
+error: unnecessary parentheses around pattern
+  --> $DIR/issue-54538-unused-parens-lint.rs:91:10
    |
 LL |         &(_) => {}
    |          ^^^ help: remove these parentheses
 
+error: aborting due to 26 previous errors
+
+For more information about this error, try `rustc --explain E0416`.
diff --git a/src/test/ui/object-safety/object-safety-associated-consts.stderr b/src/test/ui/object-safety/object-safety-associated-consts.stderr
index 55f9e3f9f13..7d5aa00356e 100644
--- a/src/test/ui/object-safety/object-safety-associated-consts.stderr
+++ b/src/test/ui/object-safety/object-safety-associated-consts.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-associated-consts.rs:9:1
    |
+LL |     const X: usize;
+   |           - the trait cannot contain associated consts like `X`
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: the trait cannot contain associated consts like `X`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/object-safety/object-safety-generics.stderr b/src/test/ui/object-safety/object-safety-generics.stderr
index d66cdb98448..b25e0052e41 100644
--- a/src/test/ui/object-safety/object-safety-generics.stderr
+++ b/src/test/ui/object-safety/object-safety-generics.stderr
@@ -1,18 +1,20 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:14:1
    |
+LL |     fn bar<T>(&self, t: T);
+   |        --- method `bar` has generic type parameters
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `bar` has generic type parameters
 
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-generics.rs:19:1
    |
+LL |     fn bar<T>(&self, t: T);
+   |        --- method `bar` has generic type parameters
+...
 LL | fn make_bar_explicit<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `bar` has generic type parameters
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/object-safety/object-safety-mentions-Self.stderr b/src/test/ui/object-safety/object-safety-mentions-Self.stderr
index c0c471c2b1e..971e79cb021 100644
--- a/src/test/ui/object-safety/object-safety-mentions-Self.stderr
+++ b/src/test/ui/object-safety/object-safety-mentions-Self.stderr
@@ -1,18 +1,20 @@
 error[E0038]: the trait `Bar` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:17:1
    |
+LL |     fn bar(&self, x: &Self);
+   |        --- method `bar` references the `Self` type in its parameters or return type
+...
 LL | fn make_bar<T:Bar>(t: &T) -> &dyn Bar {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Bar` cannot be made into an object
-   |
-   = note: method `bar` references the `Self` type in its arguments or return type
 
 error[E0038]: the trait `Baz` cannot be made into an object
   --> $DIR/object-safety-mentions-Self.rs:22:1
    |
+LL |     fn bar(&self) -> Self;
+   |        --- method `bar` references the `Self` type in its parameters or return type
+...
 LL | fn make_baz<T:Baz>(t: &T) -> &dyn Baz {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Baz` cannot be made into an object
-   |
-   = note: method `bar` references the `Self` type in its arguments or return type
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/object-safety/object-safety-no-static.stderr b/src/test/ui/object-safety/object-safety-no-static.stderr
index da8dd657c2a..0de783f60ea 100644
--- a/src/test/ui/object-safety/object-safety-no-static.stderr
+++ b/src/test/ui/object-safety/object-safety-no-static.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/object-safety-no-static.rs:8:1
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL | fn foo_implicit<T:Foo+'static>(b: Box<T>) -> Box<dyn Foo + 'static> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
-   |
-   = note: method `foo` has no receiver
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
index 95b40368143..58109be447e 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.rs
@@ -17,10 +17,10 @@ fn bar() -> impl std::fmt::Display {
 
 fn baz() -> impl std::fmt::Display {
     if false {
-    //~^ ERROR mismatched types
         return 0i32;
     } else {
         1u32
+        //~^ ERROR mismatched types
     }
 }
 
@@ -33,4 +33,33 @@ fn qux() -> impl std::fmt::Display {
     }
 }
 
+fn bat() -> impl std::fmt::Display {
+    match 13 {
+        0 => return 0i32,
+        _ => 1u32,
+        //~^ ERROR mismatched types
+    }
+}
+
+fn can() -> impl std::fmt::Display {
+    match 13 {
+    //~^ ERROR mismatched types
+        0 => return 0i32,
+        1 => 1u32,
+        _ => 2u32,
+    }
+}
+
+fn cat() -> impl std::fmt::Display {
+    match 13 {
+        0 => {
+            return 0i32;
+        }
+        _ => {
+            1u32
+            //~^ ERROR mismatched types
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
index ee1e36081e7..314ff84ae3c 100644
--- a/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
+++ b/src/test/ui/point-to-type-err-cause-on-impl-trait-return.stderr
@@ -29,18 +29,16 @@ LL |         return 1u32;
               found type `u32`
 
 error[E0308]: mismatched types
-  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:19:5
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:22:9
    |
-LL |   fn baz() -> impl std::fmt::Display {
-   |               ---------------------- expected because this return type...
-LL | /     if false {
-LL | |
-LL | |         return 0i32;
-   | |                ---- ...is found to be `i32` here
-LL | |     } else {
-LL | |         1u32
-LL | |     }
-   | |_____^ expected i32, found u32
+LL | fn baz() -> impl std::fmt::Display {
+   |             ---------------------- expected because this return type...
+LL |     if false {
+LL |         return 0i32;
+   |                ---- ...is found to be `i32` here
+LL |     } else {
+LL |         1u32
+   |         ^^^^ expected i32, found u32
    |
    = note: expected type `i32`
               found type `u32`
@@ -61,6 +59,52 @@ LL | |     }
    = note: expected type `i32`
               found type `u32`
 
-error: aborting due to 4 previous errors
+error[E0308]: mismatched types
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:39:14
+   |
+LL | fn bat() -> impl std::fmt::Display {
+   |             ---------------------- expected because this return type...
+LL |     match 13 {
+LL |         0 => return 0i32,
+   |                     ---- ...is found to be `i32` here
+LL |         _ => 1u32,
+   |              ^^^^ expected i32, found u32
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:45:5
+   |
+LL |   fn can() -> impl std::fmt::Display {
+   |               ---------------------- expected because this return type...
+LL | /     match 13 {
+LL | |
+LL | |         0 => return 0i32,
+   | |                     ---- ...is found to be `i32` here
+LL | |         1 => 1u32,
+LL | |         _ => 2u32,
+LL | |     }
+   | |_____^ expected i32, found u32
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error[E0308]: mismatched types
+  --> $DIR/point-to-type-err-cause-on-impl-trait-return.rs:59:13
+   |
+LL | fn cat() -> impl std::fmt::Display {
+   |             ---------------------- expected because this return type...
+...
+LL |             return 0i32;
+   |                    ---- ...is found to be `i32` here
+...
+LL |             1u32
+   |             ^^^^ expected i32, found u32
+   |
+   = note: expected type `i32`
+              found type `u32`
+
+error: aborting due to 7 previous errors
 
 For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/resolve/issue-3907-2.stderr b/src/test/ui/resolve/issue-3907-2.stderr
index 968c1f3e463..63ac11dc8ae 100644
--- a/src/test/ui/resolve/issue-3907-2.stderr
+++ b/src/test/ui/resolve/issue-3907-2.stderr
@@ -4,7 +4,7 @@ error[E0038]: the trait `issue_3907::Foo` cannot be made into an object
 LL | fn bar(_x: Foo) {}
    | ^^^^^^^^^^^^^^^ the trait `issue_3907::Foo` cannot be made into an object
    |
-   = note: method `bar` has no receiver
+   = note: associated function `bar` has no `self` parameter
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
index e885263aa80..04d924a9aed 100644
--- a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.rs
@@ -1,7 +1,5 @@
 // run-pass
-// ignore-cloudabi no processes
-// ignore-emscripten no processes
-// ignore-sgx no processes
+// check-run-results
 
 // Tests ensuring that `dbg!(expr)` has the expected run-time behavior.
 // as well as some compile time properties we expect.
@@ -18,7 +16,7 @@ struct Point<T> {
 #[derive(Debug, PartialEq)]
 struct NoCopy(usize);
 
-fn test() {
+fn main() {
     let a: Unit = dbg!(Unit);
     let _: Unit = dbg!(a);
     // We can move `a` because it's Copy.
@@ -67,81 +65,3 @@ fn test() {
     assert_eq!((1u8, 2u32, "Yeah"), dbg!(1u8, 2u32,
                                          "Yeah",));
 }
-
-fn validate_stderr(stderr: Vec<String>) {
-    assert_eq!(stderr, &[
-        ":22] Unit = Unit",
-
-        ":23] a = Unit",
-
-        ":29] Point{x: 42, y: 24,} = Point {",
-        "    x: 42,",
-        "    y: 24,",
-        "}",
-
-        ":30] b = Point {",
-        "    x: 42,",
-        "    y: 24,",
-        "}",
-
-        ":38]",
-
-        ":42] &a = NoCopy(",
-        "    1337,",
-        ")",
-
-        ":42] dbg!(& a) = NoCopy(",
-        "    1337,",
-        ")",
-        ":47] f(&42) = 42",
-
-        "before",
-        ":52] { foo += 1; eprintln!(\"before\"); 7331 } = 7331",
-
-        ":60] (\"Yeah\",) = (",
-        "    \"Yeah\",",
-        ")",
-
-        ":63] 1 = 1",
-        ":63] 2 = 2",
-
-        ":67] 1u8 = 1",
-        ":67] 2u32 = 2",
-        ":67] \"Yeah\" = \"Yeah\"",
-    ]);
-}
-
-fn main() {
-    // The following is a hack to deal with compiletest's inability
-    // to check the output (to stdout) of run-pass tests.
-    use std::env;
-    use std::process::Command;
-
-    let mut args = env::args();
-    let prog = args.next().unwrap();
-    let child = args.next();
-    if let Some("child") = child.as_ref().map(|s| &**s) {
-        // Only run the test if we've been spawned as 'child'
-        test()
-    } else {
-        // This essentially spawns as 'child' to run the tests
-        // and then it collects output of stderr and checks the output
-        // against what we expect.
-        let out = Command::new(&prog).arg("child").output().unwrap();
-        assert!(out.status.success());
-        assert!(out.stdout.is_empty());
-
-        let stderr = String::from_utf8(out.stderr).unwrap();
-        let stderr = stderr.lines().map(|mut s| {
-            if s.starts_with("[") {
-                // Strip `[` and file path:
-                s = s.trim_start_matches("[");
-                assert!(s.starts_with(file!()));
-                s = s.trim_start_matches(file!());
-            }
-            s.to_owned()
-        }).collect();
-
-        validate_stderr(stderr);
-    }
-}
diff --git a/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
new file mode 100644
index 00000000000..707b38cf37a
--- /dev/null
+++ b/src/test/ui/rfc-2361-dbg-macro/dbg-macro-expected-behavior.run.stderr
@@ -0,0 +1,28 @@
+[$DIR/dbg-macro-expected-behavior.rs:20] Unit = Unit
+[$DIR/dbg-macro-expected-behavior.rs:21] a = Unit
+[$DIR/dbg-macro-expected-behavior.rs:27] Point{x: 42, y: 24,} = Point {
+    x: 42,
+    y: 24,
+}
+[$DIR/dbg-macro-expected-behavior.rs:28] b = Point {
+    x: 42,
+    y: 24,
+}
+[$DIR/dbg-macro-expected-behavior.rs:36]
+[$DIR/dbg-macro-expected-behavior.rs:40] &a = NoCopy(
+    1337,
+)
+[$DIR/dbg-macro-expected-behavior.rs:40] dbg!(& a) = NoCopy(
+    1337,
+)
+[$DIR/dbg-macro-expected-behavior.rs:45] f(&42) = 42
+before
+[$DIR/dbg-macro-expected-behavior.rs:50] { foo += 1; eprintln!("before"); 7331 } = 7331
+[$DIR/dbg-macro-expected-behavior.rs:58] ("Yeah",) = (
+    "Yeah",
+)
+[$DIR/dbg-macro-expected-behavior.rs:61] 1 = 1
+[$DIR/dbg-macro-expected-behavior.rs:61] 2 = 2
+[$DIR/dbg-macro-expected-behavior.rs:65] 1u8 = 1
+[$DIR/dbg-macro-expected-behavior.rs:65] 2u32 = 2
+[$DIR/dbg-macro-expected-behavior.rs:65] "Yeah" = "Yeah"
diff --git a/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs b/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs
new file mode 100644
index 00000000000..b62cf31205f
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/auxiliary/ident-mac.rs
@@ -0,0 +1,11 @@
+// force-host
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::TokenStream;
+
+#[proc_macro_attribute]
+pub fn id(_: TokenStream, input: TokenStream) -> TokenStream { input }
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
new file mode 100644
index 00000000000..8defa26e48d
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.rs
@@ -0,0 +1,60 @@
+// aux-build:ident-mac.rs
+
+#![feature(param_attrs)]
+#![feature(c_variadic)]
+
+extern crate ident_mac;
+use ident_mac::id;
+
+struct W(u8);
+
+extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
+//~^ ERROR the attribute `id` is currently unknown to the compiler
+//~| ERROR the attribute `id` is currently unknown to the compiler
+
+unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
+//~^ ERROR the attribute `id` is currently unknown to the compiler
+
+type Alias = extern "C" fn(#[id] u8, #[id] ...);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+
+fn free(#[id] arg1: u8) {
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    let lam = |#[id] W(x), #[id] y| ();
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+}
+
+impl W {
+    fn inherent1(#[id] self, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn inherent2(#[id] &self, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+}
+
+trait A {
+    fn trait1(#[id] self, #[id] arg1: u8);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn trait2(#[id] &self, #[id] arg1: u8);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+    //~^ ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+    //~| ERROR the attribute `id` is currently unknown to the compiler
+}
+
+fn main() {}
diff --git a/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
new file mode 100644
index 00000000000..69b9a46b3d5
--- /dev/null
+++ b/src/test/ui/rfc-2565-param-attrs/proc-macro-cannot-be-used.stderr
@@ -0,0 +1,228 @@
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:11:21
+   |
+LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
+   |                     ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:11:38
+   |
+LL | extern "C" { fn ffi(#[id] arg1: i32, #[id] ...); }
+   |                                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:15:38
+   |
+LL | unsafe extern "C" fn cvar(arg1: i32, #[id] mut args: ...) {}
+   |                                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:18:28
+   |
+LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
+   |                            ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:18:38
+   |
+LL | type Alias = extern "C" fn(#[id] u8, #[id] ...);
+   |                                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:22:9
+   |
+LL | fn free(#[id] arg1: u8) {
+   |         ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:24:16
+   |
+LL |     let lam = |#[id] W(x), #[id] y| ();
+   |                ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:24:28
+   |
+LL |     let lam = |#[id] W(x), #[id] y| ();
+   |                            ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:30:18
+   |
+LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
+   |                  ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:30:30
+   |
+LL |     fn inherent1(#[id] self, #[id] arg1: u8) {}
+   |                              ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:33:18
+   |
+LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
+   |                  ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:33:31
+   |
+LL |     fn inherent2(#[id] &self, #[id] arg1: u8) {}
+   |                               ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:36:22
+   |
+LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
+   |                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:36:42
+   |
+LL |     fn inherent3<'a>(#[id] &'a mut self, #[id] arg1: u8) {}
+   |                                          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:39:22
+   |
+LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
+   |                      ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:39:45
+   |
+LL |     fn inherent4<'a>(#[id] self: Box<Self>, #[id] arg1: u8) {}
+   |                                             ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:45:15
+   |
+LL |     fn trait1(#[id] self, #[id] arg1: u8);
+   |               ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:45:27
+   |
+LL |     fn trait1(#[id] self, #[id] arg1: u8);
+   |                           ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:48:15
+   |
+LL |     fn trait2(#[id] &self, #[id] arg1: u8);
+   |               ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:48:28
+   |
+LL |     fn trait2(#[id] &self, #[id] arg1: u8);
+   |                            ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:51:19
+   |
+LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
+   |                   ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:51:39
+   |
+LL |     fn trait3<'a>(#[id] &'a mut self, #[id] arg1: u8);
+   |                                       ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:54:19
+   |
+LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+   |                   ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:54:42
+   |
+LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+   |                                          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error[E0658]: the attribute `id` is currently unknown to the compiler and may have meaning added to it in the future
+  --> $DIR/proc-macro-cannot-be-used.rs:54:58
+   |
+LL |     fn trait4<'a>(#[id] self: Box<Self>, #[id] arg1: u8, #[id] Vec<u8>);
+   |                                                          ^^^^^
+   |
+   = note: for more information, see https://github.com/rust-lang/rust/issues/29642
+   = help: add `#![feature(custom_attribute)]` to the crate attributes to enable
+
+error: aborting due to 25 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
index e45bc2657f1..e6eba377a95 100644
--- a/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
+++ b/src/test/ui/self/arbitrary-self-types-not-object-safe.stderr
@@ -1,18 +1,21 @@
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:31:32
    |
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |        --- method `foo`'s `self` parameter cannot be dispatched on
+...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |                                ^^^^^^^^^^^ the trait `Foo` cannot be made into an object
-   |
-   = note: method `foo`'s receiver cannot be dispatched on
 
 error[E0038]: the trait `Foo` cannot be made into an object
   --> $DIR/arbitrary-self-types-not-object-safe.rs:31:13
    |
+LL |     fn foo(self: &Rc<Self>) -> usize;
+   |        --- method `foo`'s `self` parameter cannot be dispatched on
+...
 LL |     let x = Rc::new(5usize) as Rc<dyn Foo>;
    |             ^^^^^^^^^^^^^^^ the trait `Foo` cannot be made into an object
    |
-   = note: method `foo`'s receiver cannot be dispatched on
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::rc::Rc<dyn Foo>>` for `std::rc::Rc<usize>`
 
 error: aborting due to 2 previous errors
diff --git a/src/test/ui/span/issue-27522.rs b/src/test/ui/span/issue-27522.rs
index 5c9893f64a6..7a0cfb679ed 100644
--- a/src/test/ui/span/issue-27522.rs
+++ b/src/test/ui/span/issue-27522.rs
@@ -3,7 +3,7 @@
 struct SomeType {}
 
 trait Foo {
-    fn handler(self: &SomeType); //~ ERROR invalid method receiver type
+    fn handler(self: &SomeType); //~ ERROR invalid `self` parameter type
 }
 
 fn main() {}
diff --git a/src/test/ui/span/issue-27522.stderr b/src/test/ui/span/issue-27522.stderr
index 88dfee1cada..8a254a96855 100644
--- a/src/test/ui/span/issue-27522.stderr
+++ b/src/test/ui/span/issue-27522.stderr
@@ -1,11 +1,12 @@
-error[E0307]: invalid method receiver type: &SomeType
+error[E0307]: invalid `self` parameter type: &SomeType
   --> $DIR/issue-27522.rs:6:22
    |
 LL |     fn handler(self: &SomeType);
    |                      ^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
 error: aborting due to previous error
 
+For more information about this error, try `rustc --explain E0307`.
diff --git a/src/test/ui/suggestions/opaque-type-error.stderr b/src/test/ui/suggestions/opaque-type-error.stderr
index 3c9ea05aece..450cbd4799f 100644
--- a/src/test/ui/suggestions/opaque-type-error.stderr
+++ b/src/test/ui/suggestions/opaque-type-error.stderr
@@ -10,8 +10,8 @@ LL | |         thing_two()
 LL | |     }.await
    | |_____- if and else have incompatible types
    |
-   = note: expected type `impl std::future::Future` (opaque type)
-              found type `impl std::future::Future` (opaque type)
+   = note: expected type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:8:19>)
+              found type `impl std::future::Future` (opaque type at <$DIR/opaque-type-error.rs:12:19>)
    = note: distinct uses of `impl Trait` result in different opaque types
    = help: if both `Future`s have the same `Output` type, consider `.await`ing on both of them
 
diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr
index ce2919c8e77..16ea7bdb080 100644
--- a/src/test/ui/traits/trait-item-privacy.stderr
+++ b/src/test/ui/traits/trait-item-privacy.stderr
@@ -110,12 +110,17 @@ LL |     C::A;
 error[E0038]: the trait `assoc_const::C` cannot be made into an object
   --> $DIR/trait-item-privacy.rs:101:5
    |
+LL |         const A: u8 = 0;
+   |               - the trait cannot contain associated consts like `A`
+...
+LL |         const B: u8 = 0;
+   |               - the trait cannot contain associated consts like `B`
+...
+LL |         const C: u8 = 0;
+   |               - the trait cannot contain associated consts like `C`
+...
 LL |     C::A;
    |     ^^^^ the trait `assoc_const::C` cannot be made into an object
-   |
-   = note: the trait cannot contain associated consts like `C`
-   = note: the trait cannot contain associated consts like `B`
-   = note: the trait cannot contain associated consts like `A`
 
 error[E0223]: ambiguous associated type
   --> $DIR/trait-item-privacy.rs:115:12
diff --git a/src/test/ui/traits/trait-object-safety.stderr b/src/test/ui/traits/trait-object-safety.stderr
index 68edc178705..3ac1e96b30c 100644
--- a/src/test/ui/traits/trait-object-safety.stderr
+++ b/src/test/ui/traits/trait-object-safety.stderr
@@ -1,19 +1,22 @@
 error[E0038]: the trait `Tr` cannot be made into an object
   --> $DIR/trait-object-safety.rs:15:22
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let _: &dyn Tr = &St;
    |                      ^^^ the trait `Tr` cannot be made into an object
    |
-   = note: method `foo` has no receiver
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<&dyn Tr>` for `&St`
 
 error[E0038]: the trait `Tr` cannot be made into an object
   --> $DIR/trait-object-safety.rs:15:12
    |
+LL |     fn foo();
+   |        --- associated function `foo` has no `self` parameter
+...
 LL |     let _: &dyn Tr = &St;
    |            ^^^^^^^ the trait `Tr` cannot be made into an object
-   |
-   = note: method `foo` has no receiver
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/traits/trait-test-2.stderr b/src/test/ui/traits/trait-test-2.stderr
index 5d5251925a1..83c2c065274 100644
--- a/src/test/ui/traits/trait-test-2.stderr
+++ b/src/test/ui/traits/trait-test-2.stderr
@@ -13,20 +13,25 @@ LL |     10.blah::<i32, i32>();
 error[E0038]: the trait `bar` cannot be made into an object
   --> $DIR/trait-test-2.rs:11:16
    |
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+   |                ---                    ---- method `blah` has generic type parameters
+   |                |
+   |                method `dup` references the `Self` type in its parameters or return type
+...
 LL |     (box 10 as Box<dyn bar>).dup();
    |                ^^^^^^^^^^^^ the trait `bar` cannot be made into an object
-   |
-   = note: method `dup` references the `Self` type in its arguments or return type
-   = note: method `blah` has generic type parameters
 
 error[E0038]: the trait `bar` cannot be made into an object
   --> $DIR/trait-test-2.rs:11:6
    |
+LL | trait bar { fn dup(&self) -> Self; fn blah<X>(&self); }
+   |                ---                    ---- method `blah` has generic type parameters
+   |                |
+   |                method `dup` references the `Self` type in its parameters or return type
+...
 LL |     (box 10 as Box<dyn bar>).dup();
    |      ^^^^^^ the trait `bar` cannot be made into an object
    |
-   = note: method `dup` references the `Self` type in its arguments or return type
-   = note: method `blah` has generic type parameters
    = note: required because of the requirements on the impl of `std::ops::CoerceUnsized<std::boxed::Box<dyn bar>>` for `std::boxed::Box<{integer}>`
 
 error: aborting due to 4 previous errors
diff --git a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
index 58727ea0fef..b315fe9df8a 100644
--- a/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
+++ b/src/test/ui/type/type-parameter-defaults-referencing-Self-ppaux.stderr
@@ -13,10 +13,11 @@ LL |     let y = x as dyn MyAdd<i32>;
 error[E0038]: the trait `MyAdd` cannot be made into an object
   --> $DIR/type-parameter-defaults-referencing-Self-ppaux.rs:14:18
    |
+LL | trait MyAdd<Rhs=Self> { fn add(&self, other: &Rhs) -> Self; }
+   |                            --- method `add` references the `Self` type in its parameters or return type
+...
 LL |     let y = x as dyn MyAdd<i32>;
    |                  ^^^^^^^^^^^^^^ the trait `MyAdd` cannot be made into an object
-   |
-   = note: method `add` references the `Self` type in its arguments or return type
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.rs b/src/test/ui/ufcs/ufcs-explicit-self-bad.rs
index c6ff94a5e76..bdb8e197fbe 100644
--- a/src/test/ui/ufcs/ufcs-explicit-self-bad.rs
+++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.rs
@@ -6,7 +6,7 @@ struct Foo {
 
 impl Foo {
     fn foo(self: isize, x: isize) -> isize {
-        //~^ ERROR invalid method receiver type
+        //~^ ERROR invalid `self` parameter type
         self.f + x
     }
 }
@@ -17,11 +17,11 @@ struct Bar<T> {
 
 impl<T> Bar<T> {
     fn foo(self: Bar<isize>, x: isize) -> isize {
-        //~^ ERROR invalid method receiver type
+        //~^ ERROR invalid `self` parameter type
         x
     }
     fn bar(self: &Bar<usize>, x: isize) -> isize {
-        //~^ ERROR invalid method receiver type
+        //~^ ERROR invalid `self` parameter type
         x
     }
 }
@@ -34,14 +34,14 @@ trait SomeTrait {
 
 impl<'a, T> SomeTrait for &'a Bar<T> {
     fn dummy1(self: &&'a Bar<T>) { }
-    fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched method receiver
-    //~^ ERROR mismatched method receiver
+    fn dummy2(self: &Bar<T>) {} //~ ERROR mismatched `self` parameter type
+    //~^ ERROR mismatched `self` parameter type
     fn dummy3(self: &&Bar<T>) {}
-    //~^ ERROR mismatched method receiver
+    //~^ ERROR mismatched `self` parameter type
     //~| expected type `&'a Bar<T>`
     //~| found type `&Bar<T>`
     //~| lifetime mismatch
-    //~| ERROR mismatched method receiver
+    //~| ERROR mismatched `self` parameter type
     //~| expected type `&'a Bar<T>`
     //~| found type `&Bar<T>`
     //~| lifetime mismatch
diff --git a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
index 6da20e37577..b2fe1b281fc 100644
--- a/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
+++ b/src/test/ui/ufcs/ufcs-explicit-self-bad.stderr
@@ -1,31 +1,31 @@
-error[E0307]: invalid method receiver type: isize
+error[E0307]: invalid `self` parameter type: isize
   --> $DIR/ufcs-explicit-self-bad.rs:8:18
    |
 LL |     fn foo(self: isize, x: isize) -> isize {
    |                  ^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0307]: invalid method receiver type: Bar<isize>
+error[E0307]: invalid `self` parameter type: Bar<isize>
   --> $DIR/ufcs-explicit-self-bad.rs:19:18
    |
 LL |     fn foo(self: Bar<isize>, x: isize) -> isize {
    |                  ^^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0307]: invalid method receiver type: &Bar<usize>
+error[E0307]: invalid `self` parameter type: &Bar<usize>
   --> $DIR/ufcs-explicit-self-bad.rs:23:18
    |
 LL |     fn bar(self: &Bar<usize>, x: isize) -> isize {
    |                  ^^^^^^^^^^^
    |
-   = note: type must be `Self` or a type that dereferences to it
+   = note: type of `self` must be `Self` or a type that dereferences to it
    = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
    |
 LL |     fn dummy2(self: &Bar<T>) {}
@@ -44,7 +44,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl<'a, T> SomeTrait for &'a Bar<T> {
    |      ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:37:21
    |
 LL |     fn dummy2(self: &Bar<T>) {}
@@ -63,7 +63,7 @@ note: ...does not necessarily outlive the anonymous lifetime #1 defined on the m
 LL |     fn dummy2(self: &Bar<T>) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:39:21
    |
 LL |     fn dummy3(self: &&Bar<T>) {}
@@ -82,7 +82,7 @@ note: ...does not necessarily outlive the lifetime 'a as defined on the impl at
 LL | impl<'a, T> SomeTrait for &'a Bar<T> {
    |      ^^
 
-error[E0308]: mismatched method receiver
+error[E0308]: mismatched `self` parameter type
   --> $DIR/ufcs-explicit-self-bad.rs:39:21
    |
 LL |     fn dummy3(self: &&Bar<T>) {}
@@ -103,4 +103,5 @@ LL |     fn dummy3(self: &&Bar<T>) {}
 
 error: aborting due to 7 previous errors
 
-For more information about this error, try `rustc --explain E0308`.
+Some errors have detailed explanations: E0307, E0308.
+For more information about an error, try `rustc --explain E0307`.
diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs b/src/test/ui/underscore-imports/auxiliary/duplicate.rs
index 92d741b6a26..92d741b6a26 100644
--- a/src/test/ui/rfc-2166-underscore-imports/auxiliary/duplicate.rs
+++ b/src/test/ui/underscore-imports/auxiliary/duplicate.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs b/src/test/ui/underscore-imports/auxiliary/underscore-imports.rs
index c335336bee8..c335336bee8 100644
--- a/src/test/ui/rfc-2166-underscore-imports/auxiliary/underscore-imports.rs
+++ b/src/test/ui/underscore-imports/auxiliary/underscore-imports.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.rs b/src/test/ui/underscore-imports/basic.rs
index 4766d75c8f4..4766d75c8f4 100644
--- a/src/test/ui/rfc-2166-underscore-imports/basic.rs
+++ b/src/test/ui/underscore-imports/basic.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/basic.stderr b/src/test/ui/underscore-imports/basic.stderr
index 9ca60e8e0a9..9ca60e8e0a9 100644
--- a/src/test/ui/rfc-2166-underscore-imports/basic.stderr
+++ b/src/test/ui/underscore-imports/basic.stderr
diff --git a/src/test/ui/underscore-imports/cycle.rs b/src/test/ui/underscore-imports/cycle.rs
new file mode 100644
index 00000000000..bacf9b2d5a9
--- /dev/null
+++ b/src/test/ui/underscore-imports/cycle.rs
@@ -0,0 +1,18 @@
+// Check that cyclic glob imports are allowed with underscore imports
+
+// check-pass
+
+mod x {
+    pub use crate::y::*;
+    pub use std::ops::Deref as _;
+}
+
+mod y {
+    pub use crate::x::*;
+    pub use std::ops::Deref as _;
+}
+
+pub fn main() {
+    use x::*;
+    (&0).deref();
+}
diff --git a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs b/src/test/ui/underscore-imports/duplicate.rs
index 3662a466ded..3662a466ded 100644
--- a/src/test/ui/rfc-2166-underscore-imports/duplicate.rs
+++ b/src/test/ui/underscore-imports/duplicate.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs b/src/test/ui/underscore-imports/intercrate.rs
index 1cccc67e9ab..1cccc67e9ab 100644
--- a/src/test/ui/rfc-2166-underscore-imports/intercrate.rs
+++ b/src/test/ui/underscore-imports/intercrate.rs
diff --git a/src/test/ui/underscore-imports/shadow.rs b/src/test/ui/underscore-imports/shadow.rs
new file mode 100644
index 00000000000..325f2001b9e
--- /dev/null
+++ b/src/test/ui/underscore-imports/shadow.rs
@@ -0,0 +1,23 @@
+// Check that underscore imports don't cause glob imports to be unshadowed
+
+mod a {
+    pub use std::ops::Deref as Shadow;
+}
+
+mod b {
+    pub use crate::a::*;
+    macro_rules! m {
+        ($i:ident) => { pub struct $i; }
+    }
+    m!(Shadow);
+}
+
+mod c {
+    use crate::b::Shadow as _; // Only imports the struct
+
+    fn f(x: &()) {
+        x.deref(); //~ ERROR no method named `deref` found
+    }
+}
+
+fn main() {}
diff --git a/src/test/ui/underscore-imports/shadow.stderr b/src/test/ui/underscore-imports/shadow.stderr
new file mode 100644
index 00000000000..92adca2c704
--- /dev/null
+++ b/src/test/ui/underscore-imports/shadow.stderr
@@ -0,0 +1,13 @@
+error[E0599]: no method named `deref` found for type `&()` in the current scope
+  --> $DIR/shadow.rs:19:11
+   |
+LL |         x.deref();
+   |           ^^^^^
+   |
+   = help: items from traits can only be used if the trait is in scope
+   = note: the following trait is implemented but not in scope, perhaps add a `use` for it:
+           `use std::ops::Deref;`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.rs b/src/test/ui/underscore-imports/unused-2018.rs
index d06a26a5f11..d06a26a5f11 100644
--- a/src/test/ui/rfc-2166-underscore-imports/unused-2018.rs
+++ b/src/test/ui/underscore-imports/unused-2018.rs
diff --git a/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr b/src/test/ui/underscore-imports/unused-2018.stderr
index 861b3f1d4fd..861b3f1d4fd 100644
--- a/src/test/ui/rfc-2166-underscore-imports/unused-2018.stderr
+++ b/src/test/ui/underscore-imports/unused-2018.stderr
diff --git a/src/test/ui/wf/wf-object-safe.stderr b/src/test/ui/wf/wf-object-safe.stderr
index 3b264ecd580..0d8441f87e7 100644
--- a/src/test/ui/wf/wf-object-safe.stderr
+++ b/src/test/ui/wf/wf-object-safe.stderr
@@ -1,10 +1,11 @@
 error[E0038]: the trait `A` cannot be made into an object
   --> $DIR/wf-object-safe.rs:9:13
    |
+LL |     fn foo(&self, _x: &Self);
+   |        --- method `foo` references the `Self` type in its parameters or return type
+...
 LL |     let _x: &dyn A;
    |             ^^^^^^ the trait `A` cannot be made into an object
-   |
-   = note: method `foo` references the `Self` type in its arguments or return type
 
 error: aborting due to previous error
 
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 22f7dd0495cd72ce2082d318d5a9b4dccb9c5b8
+Subproject fe0e5a48b75da2b405c8ce1ba2674e174ae11d5
diff --git a/src/tools/clippy b/src/tools/clippy
-Subproject 70e7d075df7b3e11e61fa99b30e1ede26cee6af
+Subproject aeadf1562c024d3c5421e61dc6b8d48c2d7902f
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index 66e030e9793..edb9eb7d860 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -333,10 +333,12 @@ pub fn expected_output_path(
     testpaths.file.with_extension(extension)
 }
 
-pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED];
+pub const UI_EXTENSIONS: &[&str] = &[UI_STDERR, UI_STDOUT, UI_FIXED, UI_RUN_STDERR, UI_RUN_STDOUT];
 pub const UI_STDERR: &str = "stderr";
 pub const UI_STDOUT: &str = "stdout";
 pub const UI_FIXED: &str = "fixed";
+pub const UI_RUN_STDERR: &str = "run.stderr";
+pub const UI_RUN_STDOUT: &str = "run.stdout";
 
 /// Absolute path to the directory where all output for all tests in the given
 /// `relative_dir` group should reside. Example:
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index 076ad87c70f..3ba8cffe2b5 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -137,6 +137,11 @@ impl EarlyProps {
                    config.parse_needs_sanitizer_support(ln) {
                     props.ignore = Ignore::Ignore;
                 }
+
+                if config.target == "wasm32-unknown-unknown" && config.parse_check_run_results(ln) {
+                    props.ignore = Ignore::Ignore;
+                }
+
             }
 
             if (config.mode == common::DebugInfoGdb || config.mode == common::DebugInfoGdbLldb) &&
@@ -326,6 +331,8 @@ pub struct TestProps {
     pub force_host: bool,
     // Check stdout for error-pattern output as well as stderr
     pub check_stdout: bool,
+    // Check stdout & stderr for output of run-pass test
+    pub check_run_results: bool,
     // For UI tests, allows compiler to generate arbitrary output to stdout
     pub dont_check_compiler_stdout: bool,
     // For UI tests, allows compiler to generate arbitrary output to stderr
@@ -388,6 +395,7 @@ impl TestProps {
             build_aux_docs: false,
             force_host: false,
             check_stdout: false,
+            check_run_results: false,
             dont_check_compiler_stdout: false,
             dont_check_compiler_stderr: false,
             no_prefer_dynamic: false,
@@ -468,6 +476,10 @@ impl TestProps {
                 self.check_stdout = config.parse_check_stdout(ln);
             }
 
+            if !self.check_run_results {
+                self.check_run_results = config.parse_check_run_results(ln);
+            }
+
             if !self.dont_check_compiler_stdout {
                 self.dont_check_compiler_stdout = config.parse_dont_check_compiler_stdout(ln);
             }
@@ -712,6 +724,10 @@ impl Config {
         self.parse_name_directive(line, "check-stdout")
     }
 
+    fn parse_check_run_results(&self, line: &str) -> bool {
+        self.parse_name_directive(line, "check-run-results")
+    }
+
     fn parse_dont_check_compiler_stdout(&self, line: &str) -> bool {
         self.parse_name_directive(line, "dont-check-compiler-stdout")
     }
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 26fdfe9d1ef..9a3d24facc2 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2,6 +2,7 @@
 
 use crate::common::{CompareMode, PassMode};
 use crate::common::{expected_output_path, UI_EXTENSIONS, UI_FIXED, UI_STDERR, UI_STDOUT};
+use crate::common::{UI_RUN_STDERR, UI_RUN_STDOUT};
 use crate::common::{output_base_dir, output_base_name, output_testname_unique};
 use crate::common::{Codegen, CodegenUnits, Rustdoc};
 use crate::common::{DebugInfoCdb, DebugInfoGdbLldb, DebugInfoGdb, DebugInfoLldb};
@@ -288,6 +289,11 @@ enum ReadFrom {
     Stdin(String),
 }
 
+enum TestOutput {
+    Compile,
+    Run,
+}
+
 impl<'test> TestCx<'test> {
     /// Code executed for each revision in turn (or, if there are no
     /// revisions, exactly once, with revision == None).
@@ -2948,6 +2954,61 @@ impl<'test> TestCx<'test> {
         }
     }
 
+    fn load_compare_outputs(&self, proc_res: &ProcRes,
+        output_kind: TestOutput, explicit_format: bool) -> usize {
+
+        let (stderr_kind, stdout_kind) = match output_kind {
+            TestOutput::Compile => (UI_STDERR, UI_STDOUT),
+            TestOutput::Run => (UI_RUN_STDERR, UI_RUN_STDOUT)
+        };
+
+        let expected_stderr = self.load_expected_output(stderr_kind);
+        let expected_stdout = self.load_expected_output(stdout_kind);
+
+        let normalized_stdout = match output_kind {
+            TestOutput::Run if self.config.remote_test_client.is_some() => {
+                // When tests are run using the remote-test-client, the string
+                // 'uploaded "$TEST_BUILD_DIR/<test_executable>, waiting for result"'
+                // is printed to stdout by the client and then captured in the ProcRes,
+                // so it needs to be removed when comparing the run-pass test execution output
+                lazy_static! {
+                    static ref REMOTE_TEST_RE: Regex = Regex::new(
+                        "^uploaded \"\\$TEST_BUILD_DIR(/[[:alnum:]_\\-]+)+\", waiting for result\n"
+                    ).unwrap();
+                }
+                REMOTE_TEST_RE.replace(
+                    &self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout),
+                    ""
+                ).to_string()
+            }
+            _ => self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout)
+        };
+
+        let stderr = if explicit_format {
+            proc_res.stderr.clone()
+        } else {
+            json::extract_rendered(&proc_res.stderr)
+        };
+
+        let normalized_stderr = self.normalize_output(&stderr, &self.props.normalize_stderr);
+        let mut errors = 0;
+        match output_kind {
+            TestOutput::Compile => {
+                if !self.props.dont_check_compiler_stdout {
+                    errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
+                }
+                if !self.props.dont_check_compiler_stderr {
+                    errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
+                }
+            }
+            TestOutput::Run => {
+                errors += self.compare_output(stdout_kind, &normalized_stdout, &expected_stdout);
+                errors += self.compare_output(stderr_kind, &normalized_stderr, &expected_stderr);
+            }
+        }
+        errors
+    }
+
     fn run_ui_test(&self) {
         // if the user specified a format in the ui test
         // print the output to the stderr file, otherwise extract
@@ -2960,32 +3021,13 @@ impl<'test> TestCx<'test> {
         let proc_res = self.compile_test();
         self.check_if_test_should_compile(&proc_res);
 
-        let expected_stderr = self.load_expected_output(UI_STDERR);
-        let expected_stdout = self.load_expected_output(UI_STDOUT);
         let expected_fixed = self.load_expected_output(UI_FIXED);
 
-        let normalized_stdout =
-            self.normalize_output(&proc_res.stdout, &self.props.normalize_stdout);
-
-        let stderr = if explicit {
-            proc_res.stderr.clone()
-        } else {
-            json::extract_rendered(&proc_res.stderr)
-        };
-
-        let normalized_stderr = self.normalize_output(&stderr, &self.props.normalize_stderr);
-
-        let mut errors = 0;
-        if !self.props.dont_check_compiler_stdout {
-            errors += self.compare_output("stdout", &normalized_stdout, &expected_stdout);
-        }
-        if !self.props.dont_check_compiler_stderr {
-            errors += self.compare_output("stderr", &normalized_stderr, &expected_stderr);
-        }
-
         let modes_to_prune = vec![CompareMode::Nll];
         self.prune_duplicate_outputs(&modes_to_prune);
 
+        let mut errors = self.load_compare_outputs(&proc_res, TestOutput::Compile, explicit);
+
         if self.config.compare_mode.is_some() {
             // don't test rustfix with nll right now
         } else if self.config.rustfix_coverage {
@@ -3063,7 +3105,17 @@ impl<'test> TestCx<'test> {
 
         if self.should_run_successfully() {
             let proc_res = self.exec_compiled_test();
-
+            let run_output_errors = if self.props.check_run_results {
+                self.load_compare_outputs(&proc_res, TestOutput::Run, explicit)
+            } else {
+                0
+            };
+            if run_output_errors > 0 {
+                self.fatal_proc_rec(
+                    &format!("{} errors occured comparing run output.", run_output_errors),
+                    &proc_res,
+                );
+            }
             if !proc_res.status.success() {
                 self.fatal_proc_rec("test run failed!", &proc_res);
             }
diff --git a/src/tools/tidy/src/features/tests.rs b/src/tools/tidy/src/features/tests.rs
index fa7a931ec86..994523ac1ab 100644
--- a/src/tools/tidy/src/features/tests.rs
+++ b/src/tools/tidy/src/features/tests.rs
@@ -2,8 +2,8 @@ use super::*;
 
 #[test]
 fn test_find_attr_val() {
-    let s = r#"#[unstable(feature = "checked_duration_since", issue = "58402")]"#;
-    assert_eq!(find_attr_val(s, "feature"), Some("checked_duration_since"));
+    let s = r#"#[unstable(feature = "tidy_test_never_used_anywhere_else", issue = "58402")]"#;
+    assert_eq!(find_attr_val(s, "feature"), Some("tidy_test_never_used_anywhere_else"));
     assert_eq!(find_attr_val(s, "issue"), Some("58402"));
     assert_eq!(find_attr_val(s, "since"), None);
 }