about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2021-03-09 09:43:55 +0000
committerbors <bors@rust-lang.org>2021-03-09 09:43:55 +0000
commit3a5d45f68cadc8fff4fbb557780f92b403b19c19 (patch)
tree2d80555f16636c76ee9e5d452078c13f19cc1f4a
parent4b9f5cc4c10a161047475cb9bbe02c4fda57fb07 (diff)
parent74de9db0ce515a26171c441cd808e6d872010f86 (diff)
downloadrust-3a5d45f68cadc8fff4fbb557780f92b403b19c19.tar.gz
rust-3a5d45f68cadc8fff4fbb557780f92b403b19c19.zip
Auto merge of #82929 - m-ou-se:rollup-7fwrewh, r=m-ou-se
Rollup of 8 pull requests

Successful merges:

 - #81127 (Improve sift_down performance in BinaryHeap)
 - #81879 (Added #[repr(transparent)] to core::cmp::Reverse)
 - #82048 (or-patterns: disallow in `let` bindings)
 - #82731 (Bump libc dependency of std to 0.2.88.)
 - #82799 (Add regression test for #75525)
 - #82841 (Change x64 size checks to not apply to x32.)
 - #82883 (Update Cargo)
 - #82887 (Update CONTRIBUTING.md)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
-rw-r--r--CONTRIBUTING.md30
-rw-r--r--Cargo.lock85
-rw-r--r--compiler/rustc_ast/src/ast.rs8
-rw-r--r--compiler/rustc_ast/src/token.rs4
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs2
-rw-r--r--compiler/rustc_errors/src/lib.rs2
-rw-r--r--compiler/rustc_hir/src/hir.rs2
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs2
-rw-r--r--compiler/rustc_infer/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs2
-rw-r--r--compiler/rustc_lint/src/unused.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs4
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs6
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs6
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs2
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs2
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs4
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs2
-rw-r--r--compiler/rustc_mir/src/interpret/operand.rs6
-rw-r--r--compiler/rustc_mir/src/interpret/place.rs10
-rw-r--r--compiler/rustc_mir_build/src/thir/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/item.rs5
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs184
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs8
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs2
-rw-r--r--library/alloc/src/collections/binary_heap.rs4
-rw-r--r--library/core/src/cmp.rs1
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--src/librustdoc/clean/types.rs2
-rw-r--r--src/test/codegen/issue-75525-bounds-checks.rs27
-rw-r--r--src/test/ui/or-patterns/already-bound-name.rs10
-rw-r--r--src/test/ui/or-patterns/already-bound-name.stderr66
-rw-r--r--src/test/ui/or-patterns/consistent-bindings.rs10
-rw-r--r--src/test/ui/or-patterns/const-fn.rs10
-rw-r--r--src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs1
-rw-r--r--src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr8
-rw-r--r--src/test/ui/or-patterns/feature-gate-or_patterns.rs2
-rw-r--r--src/test/ui/or-patterns/feature-gate-or_patterns.stderr38
-rw-r--r--src/test/ui/or-patterns/fn-param-wrap-parens.fixed2
-rw-r--r--src/test/ui/or-patterns/fn-param-wrap-parens.rs2
-rw-r--r--src/test/ui/or-patterns/fn-param-wrap-parens.stderr2
-rw-r--r--src/test/ui/or-patterns/inconsistent-modes.rs12
-rw-r--r--src/test/ui/or-patterns/inconsistent-modes.stderr82
-rw-r--r--src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs2
-rw-r--r--src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr10
-rw-r--r--src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs2
-rw-r--r--src/test/ui/or-patterns/let-pattern.rs2
-rw-r--r--src/test/ui/or-patterns/mismatched-bindings-async-fn.rs2
-rw-r--r--src/test/ui/or-patterns/mismatched-bindings-async-fn.stderr20
-rw-r--r--src/test/ui/or-patterns/missing-bindings.rs20
-rw-r--r--src/test/ui/or-patterns/missing-bindings.stderr172
-rw-r--r--src/test/ui/or-patterns/nested-undelimited-precedence.rs46
-rw-r--r--src/test/ui/or-patterns/nested-undelimited-precedence.stderr86
-rw-r--r--src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs4
-rw-r--r--src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr36
-rw-r--r--src/test/ui/or-patterns/or-patterns-default-binding-modes.rs8
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-fail.rs15
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr20
-rw-r--r--src/test/ui/or-patterns/or-patterns-syntactic-pass.rs22
-rw-r--r--src/test/ui/or-patterns/remove-leading-vert.fixed5
-rw-r--r--src/test/ui/or-patterns/remove-leading-vert.rs5
-rw-r--r--src/test/ui/or-patterns/remove-leading-vert.stderr10
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/loops.rs4
67 files changed, 752 insertions, 410 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index b600074c197..2827a46ae6f 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,8 +1,31 @@
 # Contributing to Rust
 
-Thank you for your interest in contributing to Rust!
+Thank you for your interest in contributing to Rust! There are many ways to contribute
+and we appreciate all of them.
 
-To get started, read the [Contributing to Rust] chapter of the [rustc-dev-guide].
+Documentation for contributing to Rust is located in the [Guide to Rustc Development](https://rustc-dev-guide.rust-lang.org/),
+commonly known as the [rustc-dev-guide]. Despite the name, this guide documents
+not just how to develop rustc (the Rust compiler), but also how to contribute to any part
+of the Rust project.
+
+To get started with contributing, please read the [Contributing to Rust] chapter of the guide.
+That chapter explains how to get your development environment set up and how to get help.
+
+## About the [rustc-dev-guide]
+
+The [rustc-dev-guide] is meant to help document how rustc –the Rust compiler– works,
+as well as to help new contributors get involved in rustc development. It is recommend
+to read and understand the [rustc-dev-guide] before making a contribution. This guide
+talks about the different bots in the Rust ecosystem, the Rust development tools,
+bootstrapping, the compiler architecture, source code representation, and more.
+
+## [Getting help](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions)
+
+There are many ways you can get help when you're stuck. Rust has many platforms for this:
+[internals], [rust-zulip], and [rust-discord]. It is recommended to ask for help on
+the [rust-zulip], but any of these platforms are a great way to seek help and even
+find a mentor! You can learn more about asking questions and getting help in the
+[Asking Questions](https://rustc-dev-guide.rust-lang.org/getting-started.html#asking-questions) chapter of the [rustc-dev-guide].
 
 ## Bug reports
 
@@ -13,3 +36,6 @@ refer to [this section][contributing-bug-reports] and [open an issue][issue temp
 [rustc-dev-guide]: https://rustc-dev-guide.rust-lang.org/
 [contributing-bug-reports]: https://rustc-dev-guide.rust-lang.org/contributing.html#bug-reports
 [issue template]: https://github.com/rust-lang/rust/issues/new/choose
+[internals]: https://internals.rust-lang.org
+[rust-discord]: http://discord.gg/rust-lang
+[rust-zulip]: https://rust-lang.zulipchat.com
diff --git a/Cargo.lock b/Cargo.lock
index c067fca5545..120403b3bf6 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -37,7 +37,7 @@ version = "0.0.0"
 dependencies = [
  "compiler_builtins",
  "core",
- "rand",
+ "rand 0.7.3",
  "rand_xorshift",
 ]
 
@@ -325,6 +325,7 @@ dependencies = [
  "openssl",
  "percent-encoding 2.1.0",
  "pretty_env_logger",
+ "rand 0.8.3",
  "rustc-workspace-hack",
  "rustfix",
  "same-file",
@@ -757,7 +758,7 @@ checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc"
 name = "core"
 version = "0.0.0"
 dependencies = [
- "rand",
+ "rand 0.7.3",
 ]
 
 [[package]]
@@ -1662,7 +1663,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3ca8957e71f04a205cb162508f9326aea04676c8dfd0711220190d6b83664f3f"
 dependencies = [
  "bitmaps",
- "rand_core",
+ "rand_core 0.5.1",
  "rand_xoshiro",
  "sized-chunks",
  "typenum",
@@ -1867,7 +1868,7 @@ dependencies = [
  "lazy_static",
  "log",
  "parking_lot",
- "rand",
+ "rand 0.7.3",
  "serde",
 ]
 
@@ -1912,9 +1913,9 @@ checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55"
 
 [[package]]
 name = "libc"
-version = "0.2.85"
+version = "0.2.88"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "7ccac4b00700875e6a07c6cde370d44d32fa01c5a65cdd2fca6858c479d28bb3"
+checksum = "03b07a082330a35e43f63177cc01689da34fbffa0105e1246cf0311472cac73a"
 dependencies = [
  "rustc-std-workspace-core",
 ]
@@ -2308,7 +2309,7 @@ dependencies = [
  "hex 0.4.2",
  "libc",
  "log",
- "rand",
+ "rand 0.7.3",
  "rustc-workspace-hack",
  "rustc_version",
  "shell-escape",
@@ -2508,7 +2509,7 @@ dependencies = [
  "log",
  "mio-named-pipes",
  "miow 0.3.6",
- "rand",
+ "rand 0.7.3",
  "tokio",
  "winapi 0.3.9",
 ]
@@ -2645,7 +2646,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "17367f0cc86f2d25802b2c26ee58a7b23faeccf78a396094c13dced0d0182526"
 dependencies = [
  "phf_shared",
- "rand",
+ "rand 0.7.3",
 ]
 
 [[package]]
@@ -2892,20 +2893,42 @@ checksum = "6a6b1679d49b24bbfe0c803429aa1874472f50d9b363131f0e89fc356b544d03"
 dependencies = [
  "getrandom 0.1.14",
  "libc",
- "rand_chacha",
- "rand_core",
- "rand_hc",
+ "rand_chacha 0.2.2",
+ "rand_core 0.5.1",
+ "rand_hc 0.2.0",
  "rand_pcg",
 ]
 
 [[package]]
+name = "rand"
+version = "0.8.3"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "0ef9e7e66b4468674bfcb0c81af8b7fa0bb154fa9f28eb840da5c447baeb8d7e"
+dependencies = [
+ "libc",
+ "rand_chacha 0.3.0",
+ "rand_core 0.6.2",
+ "rand_hc 0.3.0",
+]
+
+[[package]]
 name = "rand_chacha"
 version = "0.2.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "f4c8ed856279c9737206bf725bf36935d8666ead7aa69b52be55af369d193402"
 dependencies = [
  "ppv-lite86",
- "rand_core",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_chacha"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "e12735cf05c9e10bf21534da50a147b924d555dc7a547c42e6bb2d5b6017ae0d"
+dependencies = [
+ "ppv-lite86",
+ "rand_core 0.6.2",
 ]
 
 [[package]]
@@ -2918,12 +2941,30 @@ dependencies = [
 ]
 
 [[package]]
+name = "rand_core"
+version = "0.6.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "34cf66eb183df1c5876e2dcf6b13d57340741e8dc255b48e40a26de954d06ae7"
+dependencies = [
+ "getrandom 0.2.0",
+]
+
+[[package]]
 name = "rand_hc"
 version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "ca3129af7b92a17112d59ad498c6f81eaf463253766b90396d39ea7a39d6613c"
 dependencies = [
- "rand_core",
+ "rand_core 0.5.1",
+]
+
+[[package]]
+name = "rand_hc"
+version = "0.3.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "3190ef7066a446f2e7f42e239d161e905420ccab01eb967c9eb27d21b2322a73"
+dependencies = [
+ "rand_core 0.6.2",
 ]
 
 [[package]]
@@ -2932,7 +2973,7 @@ version = "0.2.1"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "16abd0c1b639e9eb4d7c50c0b8100b0d0f849be2349829c740fe8e6eb4816429"
 dependencies = [
- "rand_core",
+ "rand_core 0.5.1",
 ]
 
 [[package]]
@@ -2941,7 +2982,7 @@ version = "0.2.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "77d416b86801d23dde1aa643023b775c3a462efc0ed96443add11546cdf1dca8"
 dependencies = [
- "rand_core",
+ "rand_core 0.5.1",
 ]
 
 [[package]]
@@ -2950,7 +2991,7 @@ version = "0.4.0"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "a9fcdd2e881d02f1d9390ae47ad8e5696a9e4be7b547a1da2afbc61973217004"
 dependencies = [
- "rand_core",
+ "rand_core 0.5.1",
 ]
 
 [[package]]
@@ -3082,7 +3123,7 @@ dependencies = [
  "num_cpus",
  "ordslice",
  "racer",
- "rand",
+ "rand 0.7.3",
  "rayon",
  "regex",
  "rls-analysis",
@@ -3153,7 +3194,7 @@ dependencies = [
  "env_logger 0.7.1",
  "futures 0.3.12",
  "log",
- "rand",
+ "rand 0.7.3",
  "rls-data",
  "rls-ipc",
  "serde",
@@ -3933,7 +3974,7 @@ dependencies = [
 name = "rustc_incremental"
 version = "0.0.0"
 dependencies = [
- "rand",
+ "rand 0.7.3",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_fs_util",
@@ -4975,7 +5016,7 @@ dependencies = [
  "panic_abort",
  "panic_unwind",
  "profiler_builtins",
- "rand",
+ "rand 0.7.3",
  "rustc-demangle",
  "unwind",
  "wasi",
@@ -5106,7 +5147,7 @@ checksum = "7a6e24d9338a0a5be79593e2fa15a648add6138caa803e2d5bc782c371732ca9"
 dependencies = [
  "cfg-if 0.1.10",
  "libc",
- "rand",
+ "rand 0.7.3",
  "redox_syscall 0.1.57",
  "remove_dir_all",
  "winapi 0.3.9",
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 77a98f4c45c..d6297addc0c 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1073,7 +1073,7 @@ pub struct Expr {
 }
 
 // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Expr, 120);
 
 impl Expr {
@@ -2755,7 +2755,7 @@ pub enum ItemKind {
     MacroDef(MacroDef),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(ItemKind, 112);
 
 impl ItemKind {
@@ -2829,7 +2829,7 @@ pub enum AssocItemKind {
     MacCall(MacCall),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(AssocItemKind, 72);
 
 impl AssocItemKind {
@@ -2881,7 +2881,7 @@ pub enum ForeignItemKind {
     MacCall(MacCall),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(ForeignItemKind, 72);
 
 impl From<ForeignItemKind> for ItemKind {
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index 90bfb01d6c7..71792acb37d 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -244,7 +244,7 @@ pub enum TokenKind {
 }
 
 // `TokenKind` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(TokenKind, 16);
 
 #[derive(Clone, PartialEq, Encodable, Decodable, Debug, HashStable_Generic)]
@@ -682,7 +682,7 @@ pub enum Nonterminal {
 }
 
 // `Nonterminal` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Nonterminal, 48);
 
 #[derive(Debug, Copy, Clone, PartialEq, Encodable, Decodable)]
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 9ac05f316f0..c5c3142602b 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -189,7 +189,7 @@ pub struct TokenStream(pub(crate) Lrc<Vec<TreeAndSpacing>>);
 pub type TreeAndSpacing = (TokenTree, Spacing);
 
 // `TokenStream` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(TokenStream, 8);
 
 #[derive(Clone, Copy, Debug, PartialEq, Encodable, Decodable)]
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index a0be7442d59..1db39fbfba5 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -52,7 +52,7 @@ pub type PResult<'a, T> = Result<T, DiagnosticBuilder<'a>>;
 
 // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
 // (See also the comment on `DiagnosticBuilderInner`.)
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index 3cc501e423c..1938cdd1e46 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -3088,7 +3088,7 @@ impl<'hir> Node<'hir> {
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 mod size_asserts {
     rustc_data_structures::static_assert_size!(super::Block<'static>, 48);
     rustc_data_structures::static_assert_size!(super::Expr<'static>, 72);
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 09eecd715f0..3df58cb7857 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -408,7 +408,7 @@ pub enum SubregionOrigin<'tcx> {
 }
 
 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(SubregionOrigin<'_>, 32);
 
 /// Times when we replace late-bound regions with variables:
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index 3690a88c0d9..f9170ef5dc3 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -27,7 +27,7 @@
 
 #[macro_use]
 extern crate rustc_macros;
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 #[macro_use]
 extern crate rustc_data_structures;
 #[macro_use]
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index aaf5e958c26..0882d682e15 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -56,7 +56,7 @@ pub type PredicateObligation<'tcx> = Obligation<'tcx, ty::Predicate<'tcx>>;
 pub type TraitObligation<'tcx> = Obligation<'tcx, ty::PolyTraitPredicate<'tcx>>;
 
 // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(PredicateObligation<'_>, 32);
 
 pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index e222f82f20a..997b9136320 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -872,7 +872,7 @@ impl EarlyLintPass for UnusedParens {
 
     fn check_stmt(&mut self, cx: &EarlyContext<'_>, s: &ast::Stmt) {
         if let StmtKind::Local(ref local) = s.kind {
-            self.check_unused_parens_pat(cx, &local.pat, false, false);
+            self.check_unused_parens_pat(cx, &local.pat, true, false);
         }
 
         <Self as UnusedDelimLint>::check_stmt(self, cx, s)
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index 1589ab28e40..b2b969e9b34 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -40,7 +40,7 @@ pub fn struct_error<'tcx>(tcx: TyCtxtAt<'tcx>, msg: &str) -> DiagnosticBuilder<'
     struct_span_err!(tcx.sess, tcx.span, E0080, "{}", msg)
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(InterpErrorInfo<'_>, 8);
 
 /// Packages the kind of error we got from the const code interpreter
@@ -444,7 +444,7 @@ impl dyn MachineStopType {
     }
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(InterpError<'_>, 72);
 
 pub enum InterpError<'tcx> {
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 4bb39fe4a52..a07ccd4d2b5 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -44,7 +44,7 @@ pub enum ConstValue<'tcx> {
     },
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(ConstValue<'_>, 32);
 
 impl<'tcx> ConstValue<'tcx> {
@@ -111,7 +111,7 @@ pub enum Scalar<Tag = ()> {
     Ptr(Pointer<Tag>),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Scalar, 24);
 
 // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
@@ -509,7 +509,7 @@ pub enum ScalarMaybeUninit<Tag = ()> {
     Uninit,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(ScalarMaybeUninit, 24);
 
 impl<Tag> From<Scalar<Tag>> for ScalarMaybeUninit<Tag> {
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index f2023365780..42bbc9a0d95 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -951,7 +951,7 @@ pub struct LocalDecl<'tcx> {
 }
 
 // `LocalDecl` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(LocalDecl<'_>, 56);
 
 /// Extra information about a some locals that's used for diagnostics and for
@@ -1468,7 +1468,7 @@ pub struct Statement<'tcx> {
 }
 
 // `Statement` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Statement<'_>, 32);
 
 impl Statement<'_> {
@@ -1755,7 +1755,7 @@ impl<V, T> ProjectionElem<V, T> {
 pub type PlaceElem<'tcx> = ProjectionElem<Local, Ty<'tcx>>;
 
 // At least on 64 bit systems, `PlaceElem` should not be larger than two pointers.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(PlaceElem<'_>, 24);
 
 /// Alias for projections as they appear in `UserTypeProjection`, where we
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 3c7a6aa00c3..3961fd938be 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -17,7 +17,7 @@ pub struct PlaceTy<'tcx> {
 }
 
 // At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(PlaceTy<'_>, 16);
 
 impl<'tcx> PlaceTy<'tcx> {
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index 9deeaf462d6..0bd0a701fb2 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -340,7 +340,7 @@ impl ObligationCauseCode<'_> {
 }
 
 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(ObligationCauseCode<'_>, 32);
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index ed953b98113..e7b2c9efd63 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -23,7 +23,7 @@ pub struct Const<'tcx> {
     pub val: ConstKind<'tcx>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Const<'_>, 48);
 
 impl<'tcx> Const<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index a2638d8bdda..98c215407a8 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -37,7 +37,7 @@ pub enum ConstKind<'tcx> {
     Error(ty::DelaySpanBugEmitted),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(ConstKind<'_>, 40);
 
 impl<'tcx> ConstKind<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index c27a337554e..6b9186d476b 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -483,7 +483,7 @@ impl<'tcx> TyS<'tcx> {
 }
 
 // `TyS` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(TyS<'_>, 32);
 
 impl<'tcx> Ord for TyS<'tcx> {
@@ -1030,7 +1030,7 @@ crate struct PredicateInner<'tcx> {
     outer_exclusive_binder: ty::DebruijnIndex,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(PredicateInner<'_>, 40);
 
 #[derive(Clone, Copy, Lift)]
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 6c074d3af5c..2cd969d7a16 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -231,7 +231,7 @@ impl TyKind<'tcx> {
 }
 
 // `TyKind` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(TyKind<'_>, 24);
 
 /// A closure can be modeled as a struct that looks like:
diff --git a/compiler/rustc_mir/src/interpret/operand.rs b/compiler/rustc_mir/src/interpret/operand.rs
index 901ed6809f2..2c4aba19e4a 100644
--- a/compiler/rustc_mir/src/interpret/operand.rs
+++ b/compiler/rustc_mir/src/interpret/operand.rs
@@ -32,7 +32,7 @@ pub enum Immediate<Tag = ()> {
     ScalarPair(ScalarMaybeUninit<Tag>, ScalarMaybeUninit<Tag>),
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Immediate, 56);
 
 impl<Tag> From<ScalarMaybeUninit<Tag>> for Immediate<Tag> {
@@ -95,7 +95,7 @@ pub struct ImmTy<'tcx, Tag = ()> {
     pub layout: TyAndLayout<'tcx>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(ImmTy<'_>, 72);
 
 impl<Tag: Copy> std::fmt::Display for ImmTy<'tcx, Tag> {
@@ -162,7 +162,7 @@ pub struct OpTy<'tcx, Tag = ()> {
     pub layout: TyAndLayout<'tcx>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(OpTy<'_, ()>, 80);
 
 impl<'tcx, Tag> std::ops::Deref for OpTy<'tcx, Tag> {
diff --git a/compiler/rustc_mir/src/interpret/place.rs b/compiler/rustc_mir/src/interpret/place.rs
index 392f739e84f..7ba79e6f759 100644
--- a/compiler/rustc_mir/src/interpret/place.rs
+++ b/compiler/rustc_mir/src/interpret/place.rs
@@ -33,7 +33,7 @@ pub enum MemPlaceMeta<Tag = ()> {
     Poison,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(MemPlaceMeta, 24);
 
 impl<Tag> MemPlaceMeta<Tag> {
@@ -74,7 +74,7 @@ pub struct MemPlace<Tag = ()> {
     pub meta: MemPlaceMeta<Tag>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(MemPlace, 56);
 
 #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, HashStable)]
@@ -87,7 +87,7 @@ pub enum Place<Tag = ()> {
     Local { frame: usize, local: mir::Local },
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Place, 64);
 
 #[derive(Copy, Clone, Debug)]
@@ -96,7 +96,7 @@ pub struct PlaceTy<'tcx, Tag = ()> {
     pub layout: TyAndLayout<'tcx>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(PlaceTy<'_>, 80);
 
 impl<'tcx, Tag> std::ops::Deref for PlaceTy<'tcx, Tag> {
@@ -114,7 +114,7 @@ pub struct MPlaceTy<'tcx, Tag = ()> {
     pub layout: TyAndLayout<'tcx>,
 }
 
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(MPlaceTy<'_>, 72);
 
 impl<'tcx, Tag> std::ops::Deref for MPlaceTy<'tcx, Tag> {
diff --git a/compiler/rustc_mir_build/src/thir/mod.rs b/compiler/rustc_mir_build/src/thir/mod.rs
index ed3d3927825..ce0098fdf86 100644
--- a/compiler/rustc_mir_build/src/thir/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/mod.rs
@@ -96,7 +96,7 @@ crate enum StmtKind<'tcx> {
 }
 
 // `Expr` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Expr<'_>, 168);
 
 /// The Thir trait implementor lowers their expressions (`&'tcx H::Expr`)
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 9668a24bf8a..a28595e6fae 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1757,8 +1757,9 @@ impl<'a> Parser<'a> {
             let (pat, ty) = if is_name_required || this.is_named_param() {
                 debug!("parse_param_general parse_pat (is_name_required:{})", is_name_required);
 
-                let pat = this.parse_fn_param_pat()?;
-                if let Err(mut err) = this.expect(&token::Colon) {
+                let (pat, colon) = this.parse_fn_param_pat_colon()?;
+                if !colon {
+                    let mut err = this.unexpected::<()>().unwrap_err();
                     return if let Some(ident) =
                         this.parameter_without_type(&mut err, pat, is_name_required, first_param)
                     {
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 9e2e7359ca9..5a68afdfa59 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -31,6 +31,18 @@ pub enum RecoverComma {
     No,
 }
 
+/// The result of `eat_or_separator`. We want to distinguish which case we are in to avoid
+/// emitting duplicate diagnostics.
+#[derive(Debug, Clone, Copy)]
+enum EatOrResult {
+    /// We recovered from a trailing vert.
+    TrailingVert,
+    /// We ate an `|` (or `||` and recovered).
+    AteOr,
+    /// We did not eat anything (i.e. the current token is not `|` or `||`).
+    None,
+}
+
 impl<'a> Parser<'a> {
     /// Parses a pattern.
     ///
@@ -55,9 +67,26 @@ impl<'a> Parser<'a> {
         gate_or: GateOr,
         rc: RecoverComma,
     ) -> PResult<'a, P<Pat>> {
+        self.parse_pat_allow_top_alt_inner(expected, gate_or, rc).map(|(pat, _)| pat)
+    }
+
+    /// Returns the pattern and a bool indicating whether we recovered from a trailing vert (true =
+    /// recovered).
+    fn parse_pat_allow_top_alt_inner(
+        &mut self,
+        expected: Expected,
+        gate_or: GateOr,
+        rc: RecoverComma,
+    ) -> PResult<'a, (P<Pat>, bool)> {
+        // Keep track of whether we recovered from a trailing vert so that we can avoid duplicated
+        // suggestions (which bothers rustfix).
+        //
         // Allow a '|' before the pats (RFCs 1925, 2530, and 2535).
-        let leading_vert_span =
-            if self.eat_or_separator(None) { Some(self.prev_token.span) } else { None };
+        let (leading_vert_span, mut trailing_vert) = match self.eat_or_separator(None) {
+            EatOrResult::AteOr => (Some(self.prev_token.span), false),
+            EatOrResult::TrailingVert => (None, true),
+            EatOrResult::None => (None, false),
+        };
 
         // Parse the first pattern (`p_0`).
         let first_pat = self.parse_pat_no_top_alt(expected)?;
@@ -77,16 +106,24 @@ impl<'a> Parser<'a> {
                 // If there was a leading vert, treat this as an or-pattern. This improves
                 // diagnostics.
                 let span = leading_vert_span.to(self.prev_token.span);
-                return Ok(self.mk_pat(span, PatKind::Or(vec![first_pat])));
+                return Ok((self.mk_pat(span, PatKind::Or(vec![first_pat])), trailing_vert));
             }
 
-            return Ok(first_pat);
+            return Ok((first_pat, trailing_vert));
         }
 
         // Parse the patterns `p_1 | ... | p_n` where `n > 0`.
         let lo = leading_vert_span.unwrap_or(first_pat.span);
         let mut pats = vec![first_pat];
-        while self.eat_or_separator(Some(lo)) {
+        loop {
+            match self.eat_or_separator(Some(lo)) {
+                EatOrResult::AteOr => {}
+                EatOrResult::None => break,
+                EatOrResult::TrailingVert => {
+                    trailing_vert = true;
+                    break;
+                }
+            }
             let pat = self.parse_pat_no_top_alt(expected).map_err(|mut err| {
                 err.span_label(lo, WHILE_PARSING_OR_MSG);
                 err
@@ -101,15 +138,63 @@ impl<'a> Parser<'a> {
             self.sess.gated_spans.gate(sym::or_patterns, or_pattern_span);
         }
 
-        Ok(self.mk_pat(or_pattern_span, PatKind::Or(pats)))
+        Ok((self.mk_pat(or_pattern_span, PatKind::Or(pats)), trailing_vert))
     }
 
-    /// Parse the pattern for a function or function pointer parameter.
-    pub(super) fn parse_fn_param_pat(&mut self) -> PResult<'a, P<Pat>> {
-        // We actually do _not_ allow top-level or-patterns in function params, but we use
-        // `parse_pat_allow_top_alt` anyway so that we can detect when a user tries to use it. This
-        // allows us to print a better error message.
-        //
+    /// Parse a pattern and (maybe) a `Colon` in positions where a pattern may be followed by a
+    /// type annotation (e.g. for `let` bindings or `fn` params).
+    ///
+    /// Generally, this corresponds to `pat_no_top_alt` followed by an optional `Colon`. It will
+    /// eat the `Colon` token if one is present.
+    ///
+    /// The return value represents the parsed pattern and `true` if a `Colon` was parsed (`false`
+    /// otherwise).
+    pub(super) fn parse_pat_before_ty(
+        &mut self,
+        expected: Expected,
+        gate_or: GateOr,
+        rc: RecoverComma,
+        syntax_loc: &str,
+    ) -> PResult<'a, (P<Pat>, bool)> {
+        // We use `parse_pat_allow_top_alt` regardless of whether we actually want top-level
+        // or-patterns so that we can detect when a user tries to use it. This allows us to print a
+        // better error message.
+        let (pat, trailing_vert) = self.parse_pat_allow_top_alt_inner(expected, gate_or, rc)?;
+        let colon = self.eat(&token::Colon);
+
+        if let PatKind::Or(pats) = &pat.kind {
+            let msg = format!("top-level or-patterns are not allowed in {}", syntax_loc);
+            let (help, fix) = if pats.len() == 1 {
+                // If all we have is a leading vert, then print a special message. This is the case
+                // if `parse_pat_allow_top_alt` returns an or-pattern with one variant.
+                let msg = "remove the `|`";
+                let fix = pprust::pat_to_string(&pat);
+                (msg, fix)
+            } else {
+                let msg = "wrap the pattern in parentheses";
+                let fix = format!("({})", pprust::pat_to_string(&pat));
+                (msg, fix)
+            };
+
+            if trailing_vert {
+                // We already emitted an error and suggestion to remove the trailing vert. Don't
+                // emit again.
+                self.sess.span_diagnostic.delay_span_bug(pat.span, &msg);
+            } else {
+                self.struct_span_err(pat.span, &msg)
+                    .span_suggestion(pat.span, help, fix, Applicability::MachineApplicable)
+                    .emit();
+            }
+        }
+
+        Ok((pat, colon))
+    }
+
+    /// Parse the pattern for a function or function pointer parameter, followed by a colon.
+    ///
+    /// The return value represents the parsed pattern and `true` if a `Colon` was parsed (`false`
+    /// otherwise).
+    pub(super) fn parse_fn_param_pat_colon(&mut self) -> PResult<'a, (P<Pat>, bool)> {
         // In order to get good UX, we first recover in the case of a leading vert for an illegal
         // top-level or-pat. Normally, this means recovering both `|` and `||`, but in this case,
         // a leading `||` probably doesn't indicate an or-pattern attempt, so we handle that
@@ -128,53 +213,28 @@ impl<'a> Parser<'a> {
             self.bump();
         }
 
-        let pat = self.parse_pat_allow_top_alt(PARAM_EXPECTED, GateOr::No, RecoverComma::No)?;
-
-        if let PatKind::Or(..) = &pat.kind {
-            self.ban_illegal_fn_param_or_pat(&pat);
-        }
-
-        Ok(pat)
-    }
-
-    /// Ban `A | B` immediately in a parameter pattern and suggest wrapping in parens.
-    fn ban_illegal_fn_param_or_pat(&self, pat: &Pat) {
-        // If all we have a leading vert, then print a special message. This is the case if
-        // `parse_pat_allow_top_alt` returns an or-pattern with one variant.
-        let (msg, fix) = match &pat.kind {
-            PatKind::Or(pats) if pats.len() == 1 => {
-                let msg = "remove the leading `|`";
-                let fix = pprust::pat_to_string(pat);
-                (msg, fix)
-            }
-
-            _ => {
-                let msg = "wrap the pattern in parentheses";
-                let fix = format!("({})", pprust::pat_to_string(pat));
-                (msg, fix)
-            }
-        };
-
-        self.struct_span_err(pat.span, "an or-pattern parameter must be wrapped in parentheses")
-            .span_suggestion(pat.span, msg, fix, Applicability::MachineApplicable)
-            .emit();
+        self.parse_pat_before_ty(
+            PARAM_EXPECTED,
+            GateOr::No,
+            RecoverComma::No,
+            "function parameters",
+        )
     }
 
     /// Eat the or-pattern `|` separator.
     /// If instead a `||` token is encountered, recover and pretend we parsed `|`.
-    fn eat_or_separator(&mut self, lo: Option<Span>) -> bool {
+    fn eat_or_separator(&mut self, lo: Option<Span>) -> EatOrResult {
         if self.recover_trailing_vert(lo) {
-            return false;
-        }
-
-        match self.token.kind {
-            token::OrOr => {
-                // Found `||`; Recover and pretend we parsed `|`.
-                self.ban_unexpected_or_or(lo);
-                self.bump();
-                true
-            }
-            _ => self.eat(&token::BinOp(token::Or)),
+            EatOrResult::TrailingVert
+        } else if matches!(self.token.kind, token::OrOr) {
+            // Found `||`; Recover and pretend we parsed `|`.
+            self.ban_unexpected_or_or(lo);
+            self.bump();
+            EatOrResult::AteOr
+        } else if self.eat(&token::BinOp(token::Or)) {
+            EatOrResult::AteOr
+        } else {
+            EatOrResult::None
         }
     }
 
@@ -190,14 +250,14 @@ impl<'a> Parser<'a> {
             matches!(
                 &token.uninterpolate().kind,
                 token::FatArrow // e.g. `a | => 0,`.
-            | token::Ident(kw::If, false) // e.g. `a | if expr`.
-            | token::Eq // e.g. `let a | = 0`.
-            | token::Semi // e.g. `let a |;`.
-            | token::Colon // e.g. `let a | :`.
-            | token::Comma // e.g. `let (a |,)`.
-            | token::CloseDelim(token::Bracket) // e.g. `let [a | ]`.
-            | token::CloseDelim(token::Paren) // e.g. `let (a | )`.
-            | token::CloseDelim(token::Brace) // e.g. `let A { f: a | }`.
+                | token::Ident(kw::If, false) // e.g. `a | if expr`.
+                | token::Eq // e.g. `let a | = 0`.
+                | token::Semi // e.g. `let a |;`.
+                | token::Colon // e.g. `let a | :`.
+                | token::Comma // e.g. `let (a |,)`.
+                | token::CloseDelim(token::Bracket) // e.g. `let [a | ]`.
+                | token::CloseDelim(token::Paren) // e.g. `let (a | )`.
+                | token::CloseDelim(token::Brace) // e.g. `let A { f: a | }`.
             )
         });
         match (is_end_ahead, &self.token.kind) {
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index a0f9616f72a..f6599927c6e 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -13,7 +13,8 @@ use rustc_ast::token::{self, TokenKind};
 use rustc_ast::util::classify;
 use rustc_ast::AstLike;
 use rustc_ast::{AttrStyle, AttrVec, Attribute, MacCall, MacCallStmt, MacStmtStyle};
-use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt, StmtKind, DUMMY_NODE_ID};
+use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, Local, Stmt};
+use rustc_ast::{StmtKind, DUMMY_NODE_ID};
 use rustc_errors::{Applicability, PResult};
 use rustc_span::source_map::{BytePos, Span};
 use rustc_span::symbol::{kw, sym};
@@ -220,9 +221,10 @@ impl<'a> Parser<'a> {
     /// Parses a local variable declaration.
     fn parse_local(&mut self, attrs: AttrVec) -> PResult<'a, P<Local>> {
         let lo = self.prev_token.span;
-        let pat = self.parse_pat_allow_top_alt(None, GateOr::Yes, RecoverComma::Yes)?;
+        let (pat, colon) =
+            self.parse_pat_before_ty(None, GateOr::Yes, RecoverComma::Yes, "`let` bindings")?;
 
-        let (err, ty) = if self.eat(&token::Colon) {
+        let (err, ty) = if colon {
             // Save the state of the parser before parsing type normally, in case there is a `:`
             // instead of an `=` typo.
             let parser_snapshot_before_type = self.clone();
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index e1f8d59991f..aea3d8eef65 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -23,7 +23,7 @@
 
 #[macro_use]
 extern crate rustc_macros;
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 #[macro_use]
 extern crate rustc_data_structures;
 #[macro_use]
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 3c447a7d1f9..7d451fc2341 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -87,7 +87,7 @@ pub struct PendingPredicateObligation<'tcx> {
 }
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(PendingPredicateObligation<'_>, 56);
 
 impl<'a, 'tcx> FulfillmentContext<'tcx> {
diff --git a/library/alloc/src/collections/binary_heap.rs b/library/alloc/src/collections/binary_heap.rs
index 4377780e15f..b5e66d37ab4 100644
--- a/library/alloc/src/collections/binary_heap.rs
+++ b/library/alloc/src/collections/binary_heap.rs
@@ -566,7 +566,7 @@ impl<T: Ord> BinaryHeap<T> {
         let mut child = 2 * hole.pos() + 1;
 
         // Loop invariant: child == 2 * hole.pos() + 1.
-        while child < end - 1 {
+        while child <= end.saturating_sub(2) {
             // compare with the greater of the two children
             // SAFETY: child < end - 1 < self.len() and
             //  child + 1 < end <= self.len(), so they're valid indexes.
@@ -625,7 +625,7 @@ impl<T: Ord> BinaryHeap<T> {
         let mut child = 2 * hole.pos() + 1;
 
         // Loop invariant: child == 2 * hole.pos() + 1.
-        while child < end - 1 {
+        while child <= end.saturating_sub(2) {
             // SAFETY: child < end - 1 < self.len() and
             //  child + 1 < end <= self.len(), so they're valid indexes.
             //  child == 2 * hole.pos() + 1 != hole.pos() and
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index 4a15b185a83..5bab1fb93db 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -579,6 +579,7 @@ impl Ordering {
 /// ```
 #[derive(PartialEq, Eq, Debug, Copy, Clone, Default, Hash)]
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
+#[repr(transparent)]
 pub struct Reverse<T>(#[stable(feature = "reverse_cmp_key", since = "1.19.0")] pub T);
 
 #[stable(feature = "reverse_cmp_key", since = "1.19.0")]
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index 275fcc4c292..f0f5558fd16 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -16,7 +16,7 @@ cfg-if = { version = "0.1.8", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core" }
-libc = { version = "0.2.85", default-features = false, features = ['rustc-dep-of-std'] }
+libc = { version = "0.2.88", default-features = false, features = ['rustc-dep-of-std'] }
 compiler_builtins = { version = "0.1.39" }
 profiler_builtins = { path = "../profiler_builtins", optional = true }
 unwind = { path = "../unwind" }
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index a94ee918c24..2636467196a 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -93,7 +93,7 @@ crate struct Item {
 }
 
 // `Item` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(target_arch = "x86_64")]
+#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Item, 48);
 
 impl fmt::Debug for Item {
diff --git a/src/test/codegen/issue-75525-bounds-checks.rs b/src/test/codegen/issue-75525-bounds-checks.rs
new file mode 100644
index 00000000000..a03c63c1d09
--- /dev/null
+++ b/src/test/codegen/issue-75525-bounds-checks.rs
@@ -0,0 +1,27 @@
+// Regression test for #75525, verifies that no bounds checks are generated.
+
+// min-llvm-version: 12.0.0
+// compile-flags: -O
+
+#![crate_type = "lib"]
+
+// CHECK-LABEL: @f0
+// CHECK-NOT: panic
+#[no_mangle]
+pub fn f0(idx: usize, buf: &[u8; 10]) -> u8 {
+    if idx < 8 { buf[idx + 1] } else { 0 }
+}
+
+// CHECK-LABEL: @f1
+// CHECK-NOT: panic
+#[no_mangle]
+pub fn f1(idx: usize, buf: &[u8; 10]) -> u8 {
+    if idx > 5 && idx < 8 { buf[idx - 1] } else { 0 }
+}
+
+// CHECK-LABEL: @f2
+// CHECK-NOT: panic
+#[no_mangle]
+pub fn f2(idx: usize, buf: &[u8; 10]) -> u8 {
+    if idx > 5 && idx < 8 { buf[idx] } else { 0 }
+}
diff --git a/src/test/ui/or-patterns/already-bound-name.rs b/src/test/ui/or-patterns/already-bound-name.rs
index 726e17b7ec2..543d7c21c83 100644
--- a/src/test/ui/or-patterns/already-bound-name.rs
+++ b/src/test/ui/or-patterns/already-bound-name.rs
@@ -18,10 +18,10 @@ fn main() {
     let (A(a, _) | B(a), a) = (A(0, 1), 2);
     //~^ ERROR identifier `a` is bound more than once in the same pattern
 
-    let A(a, a) | B(a) = A(0, 1);
+    let (A(a, a) | B(a)) = A(0, 1);
     //~^ ERROR identifier `a` is bound more than once in the same pattern
 
-    let B(a) | A(a, a) = A(0, 1);
+    let (B(a) | A(a, a)) = A(0, 1);
     //~^ ERROR identifier `a` is bound more than once in the same pattern
 
     match A(0, 1) {
@@ -29,17 +29,17 @@ fn main() {
         //~^ ERROR identifier `a` is bound more than once in the same pattern
     }
 
-    let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
+    let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
     //~^ ERROR identifier `a` is bound more than once in the same pattern
     //~| ERROR identifier `a` is bound more than once in the same pattern
     //~| ERROR mismatched types
 
-    let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+    let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
     //~^ ERROR identifier `a` is bound more than once in the same pattern
     //~| ERROR identifier `a` is bound more than once in the same pattern
     //~| ERROR variable `a` is not bound in all patterns
 
-    let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
+    let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
     //~^ ERROR identifier `a` is bound more than once in the same pattern
     //~| ERROR identifier `a` is bound more than once in the same pattern
 }
diff --git a/src/test/ui/or-patterns/already-bound-name.stderr b/src/test/ui/or-patterns/already-bound-name.stderr
index 97933ca1229..483154a5e32 100644
--- a/src/test/ui/or-patterns/already-bound-name.stderr
+++ b/src/test/ui/or-patterns/already-bound-name.stderr
@@ -23,16 +23,16 @@ LL |     let (A(a, _) | B(a), a) = (A(0, 1), 2);
    |                          ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:21:14
+  --> $DIR/already-bound-name.rs:21:15
    |
-LL |     let A(a, a) | B(a) = A(0, 1);
-   |              ^ used in a pattern more than once
+LL |     let (A(a, a) | B(a)) = A(0, 1);
+   |               ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:24:21
+  --> $DIR/already-bound-name.rs:24:22
    |
-LL |     let B(a) | A(a, a) = A(0, 1);
-   |                     ^ used in a pattern more than once
+LL |     let (B(a) | A(a, a)) = A(0, 1);
+   |                      ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
   --> $DIR/already-bound-name.rs:28:21
@@ -41,55 +41,55 @@ LL |         B(a) | A(a, a) => {} // Let's ensure `match` has no funny business.
    |                     ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:32:36
+  --> $DIR/already-bound-name.rs:32:37
    |
-LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
-   |                                    ^ used in a pattern more than once
+LL |     let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
+   |                                     ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:32:46
+  --> $DIR/already-bound-name.rs:32:47
    |
-LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
-   |                                              ^ used in a pattern more than once
+LL |     let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
+   |                                               ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:37:36
+  --> $DIR/already-bound-name.rs:37:37
    |
-LL |     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
-   |                                    ^ used in a pattern more than once
+LL |     let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
+   |                                     ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:37:46
+  --> $DIR/already-bound-name.rs:37:47
    |
-LL |     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
-   |                                              ^ used in a pattern more than once
+LL |     let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
+   |                                               ^ used in a pattern more than once
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/already-bound-name.rs:37:9
+  --> $DIR/already-bound-name.rs:37:10
    |
-LL |     let B(_) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
-   |         ^^^^ pattern doesn't bind `a`        - variable not in all patterns
+LL |     let (B(_) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
+   |          ^^^^ pattern doesn't bind `a`        - variable not in all patterns
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:42:49
+  --> $DIR/already-bound-name.rs:42:50
    |
-LL |     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
-   |                                                 ^ used in a pattern more than once
+LL |     let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
+   |                                                  ^ used in a pattern more than once
 
 error[E0416]: identifier `a` is bound more than once in the same pattern
-  --> $DIR/already-bound-name.rs:42:59
+  --> $DIR/already-bound-name.rs:42:60
    |
-LL |     let B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a)) = B(B(1));
-   |                                                           ^ used in a pattern more than once
+LL |     let (B(A(a, _) | B(a)) | A(A(a, _) | B(a), A(a, _) | B(a))) = B(B(1));
+   |                                                            ^ used in a pattern more than once
 
 error[E0308]: mismatched types
-  --> $DIR/already-bound-name.rs:32:31
+  --> $DIR/already-bound-name.rs:32:32
    |
-LL |     let B(A(a, _) | B(a)) | A(a, A(a, _) | B(a)) = B(B(1));
-   |             -                 ^                    ------- this expression has type `E<E<{integer}>>`
-   |             |                 |
-   |             |                 expected integer, found enum `E`
-   |             first introduced with type `{integer}` here
+LL |     let (B(A(a, _) | B(a)) | A(a, A(a, _) | B(a))) = B(B(1));
+   |              -                 ^                     ------- this expression has type `E<E<{integer}>>`
+   |              |                 |
+   |              |                 expected integer, found enum `E`
+   |              first introduced with type `{integer}` here
    |
    = note: expected type `{integer}`
               found type `E<{integer}>`
diff --git a/src/test/ui/or-patterns/consistent-bindings.rs b/src/test/ui/or-patterns/consistent-bindings.rs
index 3ee57978bb0..853ddcf2412 100644
--- a/src/test/ui/or-patterns/consistent-bindings.rs
+++ b/src/test/ui/or-patterns/consistent-bindings.rs
@@ -8,9 +8,9 @@
 
 fn main() {
     // One level:
-    let Ok(a) | Err(a) = Ok(0);
-    let Ok(ref a) | Err(ref a) = Ok(0);
-    let Ok(ref mut a) | Err(ref mut a) = Ok(0);
+    let (Ok(a) | Err(a)) = Ok(0);
+    let (Ok(ref a) | Err(ref a)) = Ok(0);
+    let (Ok(ref mut a) | Err(ref mut a)) = Ok(0);
 
     // Two levels:
     enum Tri<S, T, U> {
@@ -20,10 +20,10 @@ fn main() {
     }
     use Tri::*;
 
-    let Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b))): Result<_, Result<_, _>> =
+    let (Ok((V1(a) | V2(a) | V3(a), b)) | Err(Ok((a, b)) | Err((a, b)))): Result<_, Result<_, _>> =
         Ok((V1(1), 1));
 
-    let Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b))): Result<
+    let (Ok((V1(a) | V2(a) | V3(a), ref b)) | Err(Ok((a, ref b)) | Err((a, ref b)))): Result<
         _,
         Result<_, _>,
     > = Ok((V1(1), 1));
diff --git a/src/test/ui/or-patterns/const-fn.rs b/src/test/ui/or-patterns/const-fn.rs
index f4af2f0d2dd..55c6f60915f 100644
--- a/src/test/ui/or-patterns/const-fn.rs
+++ b/src/test/ui/or-patterns/const-fn.rs
@@ -3,28 +3,28 @@
 
 const fn foo((Ok(a) | Err(a)): Result<i32, i32>) {
     let x = Ok(3);
-    let Ok(y) | Err(y) = x;
+    let (Ok(y) | Err(y)) = x;
 }
 
 const X: () = {
     let x = Ok(3);
-    let Ok(y) | Err(y) = x;
+    let (Ok(y) | Err(y)) = x;
 };
 
 static Y: () = {
     let x = Ok(3);
-    let Ok(y) | Err(y) = x;
+    let (Ok(y) | Err(y)) = x;
 };
 
 static mut Z: () = {
     let x = Ok(3);
-    let Ok(y) | Err(y) = x;
+    let (Ok(y) | Err(y)) = x;
 };
 
 fn main() {
     let _: [(); {
         let x = Ok(3);
-        let Ok(y) | Err(y) = x;
+        let (Ok(y) | Err(y)) = x;
         2
     }];
 }
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs
index a4ea4e25d86..6c592550ec2 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.rs
@@ -5,4 +5,5 @@ fn main() {}
 #[cfg(FALSE)]
 fn gated_leading_vert_in_let() {
     let | A; //~ ERROR or-patterns syntax is experimental
+    //~^ ERROR top-level or-patterns are not allowed
 }
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
index 499f60dd545..d556532cd6a 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns-leading-let.stderr
@@ -1,3 +1,9 @@
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
+   |
+LL |     let | A;
+   |         ^^^ help: remove the `|`: `A`
+
 error[E0658]: or-patterns syntax is experimental
   --> $DIR/feature-gate-or_patterns-leading-let.rs:7:9
    |
@@ -7,6 +13,6 @@ LL |     let | A;
    = note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns.rs b/src/test/ui/or-patterns/feature-gate-or_patterns.rs
index e638838147a..8bb45e606be 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns.rs
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns.rs
@@ -26,7 +26,9 @@ fn or_patterns() {
     // Gated:
 
     let | A | B; //~ ERROR or-patterns syntax is experimental
+    //~^ ERROR top-level or-patterns are not allowed
     let A | B; //~ ERROR or-patterns syntax is experimental
+    //~^ ERROR top-level or-patterns are not allowed
     for | A | B in 0 {} //~ ERROR or-patterns syntax is experimental
     for A | B in 0 {} //~ ERROR or-patterns syntax is experimental
     fn fun((A | B): _) {} //~ ERROR or-patterns syntax is experimental
diff --git a/src/test/ui/or-patterns/feature-gate-or_patterns.stderr b/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
index c01d17c0b3d..7988af5b942 100644
--- a/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
+++ b/src/test/ui/or-patterns/feature-gate-or_patterns.stderr
@@ -1,3 +1,15 @@
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/feature-gate-or_patterns.rs:28:9
+   |
+LL |     let | A | B;
+   |         ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
+
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/feature-gate-or_patterns.rs:30:9
+   |
+LL |     let A | B;
+   |         ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
+
 error[E0658]: or-patterns syntax is experimental
   --> $DIR/feature-gate-or_patterns.rs:5:14
    |
@@ -17,7 +29,7 @@ LL |     let | A | B;
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:29:9
+  --> $DIR/feature-gate-or_patterns.rs:30:9
    |
 LL |     let A | B;
    |         ^^^^^
@@ -26,7 +38,7 @@ LL |     let A | B;
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:30:9
+  --> $DIR/feature-gate-or_patterns.rs:32:9
    |
 LL |     for | A | B in 0 {}
    |         ^^^^^^^
@@ -35,7 +47,7 @@ LL |     for | A | B in 0 {}
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:31:9
+  --> $DIR/feature-gate-or_patterns.rs:33:9
    |
 LL |     for A | B in 0 {}
    |         ^^^^^
@@ -44,7 +56,7 @@ LL |     for A | B in 0 {}
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:32:13
+  --> $DIR/feature-gate-or_patterns.rs:34:13
    |
 LL |     fn fun((A | B): _) {}
    |             ^^^^^
@@ -53,7 +65,7 @@ LL |     fn fun((A | B): _) {}
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:33:15
+  --> $DIR/feature-gate-or_patterns.rs:35:15
    |
 LL |     let _ = |(A | B): u8| ();
    |               ^^^^^
@@ -62,7 +74,7 @@ LL |     let _ = |(A | B): u8| ();
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:34:10
+  --> $DIR/feature-gate-or_patterns.rs:36:10
    |
 LL |     let (A | B);
    |          ^^^^^
@@ -71,7 +83,7 @@ LL |     let (A | B);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:35:10
+  --> $DIR/feature-gate-or_patterns.rs:37:10
    |
 LL |     let (A | B,);
    |          ^^^^^
@@ -80,7 +92,7 @@ LL |     let (A | B,);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:36:11
+  --> $DIR/feature-gate-or_patterns.rs:38:11
    |
 LL |     let A(B | C);
    |           ^^^^^
@@ -89,7 +101,7 @@ LL |     let A(B | C);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:37:14
+  --> $DIR/feature-gate-or_patterns.rs:39:14
    |
 LL |     let E::V(B | C);
    |              ^^^^^
@@ -98,7 +110,7 @@ LL |     let E::V(B | C);
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:38:17
+  --> $DIR/feature-gate-or_patterns.rs:40:17
    |
 LL |     let S { f1: B | C, f2 };
    |                 ^^^^^
@@ -107,7 +119,7 @@ LL |     let S { f1: B | C, f2 };
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:39:20
+  --> $DIR/feature-gate-or_patterns.rs:41:20
    |
 LL |     let E::V { f1: B | C, f2 };
    |                    ^^^^^
@@ -116,7 +128,7 @@ LL |     let E::V { f1: B | C, f2 };
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
 error[E0658]: or-patterns syntax is experimental
-  --> $DIR/feature-gate-or_patterns.rs:40:10
+  --> $DIR/feature-gate-or_patterns.rs:42:10
    |
 LL |     let [A | B];
    |          ^^^^^
@@ -169,6 +181,6 @@ LL | accept_pat!([p | q]);
    = note: see issue #54883 <https://github.com/rust-lang/rust/issues/54883> for more information
    = help: add `#![feature(or_patterns)]` to the crate attributes to enable
 
-error: aborting due to 19 previous errors
+error: aborting due to 21 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/or-patterns/fn-param-wrap-parens.fixed b/src/test/ui/or-patterns/fn-param-wrap-parens.fixed
index bbc75d2b411..65e04325e16 100644
--- a/src/test/ui/or-patterns/fn-param-wrap-parens.fixed
+++ b/src/test/ui/or-patterns/fn-param-wrap-parens.fixed
@@ -11,4 +11,4 @@ enum E { A, B }
 use E::*;
 
 #[cfg(FALSE)]
-fn fun1((A | B): E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
+fn fun1((A | B): E) {} //~ ERROR top-level or-patterns are not allowed
diff --git a/src/test/ui/or-patterns/fn-param-wrap-parens.rs b/src/test/ui/or-patterns/fn-param-wrap-parens.rs
index 65b93dcbf74..aeb4a05ea80 100644
--- a/src/test/ui/or-patterns/fn-param-wrap-parens.rs
+++ b/src/test/ui/or-patterns/fn-param-wrap-parens.rs
@@ -11,4 +11,4 @@ enum E { A, B }
 use E::*;
 
 #[cfg(FALSE)]
-fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
+fn fun1(A | B: E) {} //~ ERROR top-level or-patterns are not allowed
diff --git a/src/test/ui/or-patterns/fn-param-wrap-parens.stderr b/src/test/ui/or-patterns/fn-param-wrap-parens.stderr
index 0e6424a4300..96193c17ae2 100644
--- a/src/test/ui/or-patterns/fn-param-wrap-parens.stderr
+++ b/src/test/ui/or-patterns/fn-param-wrap-parens.stderr
@@ -1,4 +1,4 @@
-error: an or-pattern parameter must be wrapped in parentheses
+error: top-level or-patterns are not allowed in function parameters
   --> $DIR/fn-param-wrap-parens.rs:14:9
    |
 LL | fn fun1(A | B: E) {}
diff --git a/src/test/ui/or-patterns/inconsistent-modes.rs b/src/test/ui/or-patterns/inconsistent-modes.rs
index fd5cb01ab42..2300e9f9f3b 100644
--- a/src/test/ui/or-patterns/inconsistent-modes.rs
+++ b/src/test/ui/or-patterns/inconsistent-modes.rs
@@ -4,23 +4,23 @@
 #![allow(non_camel_case_types)]
 fn main() {
     // One level:
-    let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
+    let (Ok(a) | Err(ref a)): Result<&u8, u8> = Ok(&0);
     //~^ ERROR variable `a` is bound inconsistently
-    let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
+    let (Ok(ref mut a) | Err(a)): Result<u8, &mut u8> = Ok(0);
     //~^ ERROR variable `a` is bound inconsistently
-    let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
+    let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
     //~^ ERROR variable `a` is bound inconsistently
     //~| ERROR mismatched types
-    let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
+    let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
     //~^ ERROR variable `a` is bound inconsistently
     //~| ERROR variable `b` is bound inconsistently
     //~| ERROR mismatched types
 
     // Two levels:
-    let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
+    let (Ok(Ok(a) | Err(a)) | Err(ref a)) = Err(0);
     //~^ ERROR variable `a` is bound inconsistently
 
     // Three levels:
-    let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1);
+    let (Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a)) = Err(&1);
     //~^ ERROR variable `a` is bound inconsistently
 }
diff --git a/src/test/ui/or-patterns/inconsistent-modes.stderr b/src/test/ui/or-patterns/inconsistent-modes.stderr
index 15790771043..99791431eaf 100644
--- a/src/test/ui/or-patterns/inconsistent-modes.stderr
+++ b/src/test/ui/or-patterns/inconsistent-modes.stderr
@@ -1,74 +1,74 @@
 error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
-  --> $DIR/inconsistent-modes.rs:7:25
+  --> $DIR/inconsistent-modes.rs:7:26
    |
-LL |     let Ok(a) | Err(ref a): Result<&u8, u8> = Ok(&0);
-   |            -            ^ bound in different ways
-   |            |
-   |            first binding
+LL |     let (Ok(a) | Err(ref a)): Result<&u8, u8> = Ok(&0);
+   |             -            ^ bound in different ways
+   |             |
+   |             first binding
 
 error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
-  --> $DIR/inconsistent-modes.rs:9:29
+  --> $DIR/inconsistent-modes.rs:9:30
    |
-LL |     let Ok(ref mut a) | Err(a): Result<u8, &mut u8> = Ok(0);
-   |                    -        ^ bound in different ways
-   |                    |
-   |                    first binding
+LL |     let (Ok(ref mut a) | Err(a)): Result<u8, &mut u8> = Ok(0);
+   |                     -        ^ bound in different ways
+   |                     |
+   |                     first binding
 
 error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
-  --> $DIR/inconsistent-modes.rs:11:33
+  --> $DIR/inconsistent-modes.rs:11:34
    |
-LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
-   |                - first binding  ^ bound in different ways
+LL |     let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
+   |                 - first binding  ^ bound in different ways
 
 error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
-  --> $DIR/inconsistent-modes.rs:14:39
+  --> $DIR/inconsistent-modes.rs:14:40
    |
-LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
-   |                 - first binding       ^ bound in different ways
+LL |     let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
+   |                  - first binding       ^ bound in different ways
 
 error[E0409]: variable `b` is bound inconsistently across alternatives separated by `|`
-  --> $DIR/inconsistent-modes.rs:14:46
+  --> $DIR/inconsistent-modes.rs:14:47
    |
-LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
-   |                    - first binding           ^ bound in different ways
+LL |     let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
+   |                     - first binding           ^ bound in different ways
 
 error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
-  --> $DIR/inconsistent-modes.rs:20:38
+  --> $DIR/inconsistent-modes.rs:20:39
    |
-LL |     let Ok(Ok(a) | Err(a)) | Err(ref a) = Err(0);
-   |                        -             ^ bound in different ways
-   |                        |
-   |                        first binding
+LL |     let (Ok(Ok(a) | Err(a)) | Err(ref a)) = Err(0);
+   |                         -             ^ bound in different ways
+   |                         |
+   |                         first binding
 
 error[E0409]: variable `a` is bound inconsistently across alternatives separated by `|`
-  --> $DIR/inconsistent-modes.rs:24:33
+  --> $DIR/inconsistent-modes.rs:24:34
    |
-LL |     let Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a) = Err(&1);
-   |                        -        ^ bound in different ways
-   |                        |
-   |                        first binding
+LL |     let (Ok([Ok((Ok(ref a) | Err(a),)) | Err(a)]) | Err(a)) = Err(&1);
+   |                         -        ^ bound in different ways
+   |                         |
+   |                         first binding
 
 error[E0308]: mismatched types
-  --> $DIR/inconsistent-modes.rs:11:25
+  --> $DIR/inconsistent-modes.rs:11:26
    |
-LL |     let Ok(ref a) | Err(ref mut a): Result<&u8, &mut u8> = Ok(&0);
-   |            -----        ^^^^^^^^^   -------------------- expected due to this
-   |            |            |
-   |            |            types differ in mutability
-   |            first introduced with type `&&u8` here
+LL |     let (Ok(ref a) | Err(ref mut a)): Result<&u8, &mut u8> = Ok(&0);
+   |             -----        ^^^^^^^^^    -------------------- expected due to this
+   |             |            |
+   |             |            types differ in mutability
+   |             first introduced with type `&&u8` here
    |
    = note: expected type `&&u8`
               found type `&mut &mut u8`
    = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
-  --> $DIR/inconsistent-modes.rs:14:31
+  --> $DIR/inconsistent-modes.rs:14:32
    |
-LL |     let Ok((ref a, b)) | Err((ref mut a, ref b)) = Ok((0, &0));
-   |             -----             ^^^^^^^^^            ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>`
-   |             |                 |
-   |             |                 types differ in mutability
-   |             first introduced with type `&{integer}` here
+LL |     let (Ok((ref a, b)) | Err((ref mut a, ref b))) = Ok((0, &0));
+   |              -----             ^^^^^^^^^             ----------- this expression has type `Result<({integer}, &{integer}), (_, _)>`
+   |              |                 |
+   |              |                 types differ in mutability
+   |              first introduced with type `&{integer}` here
    |
    = note: expected type `&{integer}`
               found type `&mut _`
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs
index 59533cefea6..8e83acc6dcb 100644
--- a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs
@@ -1,7 +1,7 @@
 #![feature(or_patterns)]
 
 fn main() {
-    let 0 | (1 | 2) = 0; //~ ERROR refutable pattern in local binding
+    let (0 | (1 | 2)) = 0; //~ ERROR refutable pattern in local binding
     match 0 {
         //~^ ERROR non-exhaustive patterns
         0 | (1 | 2) => {}
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
index 2acf1f41c6f..9ed942d9e0f 100644
--- a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier-non-exhaustive.stderr
@@ -1,16 +1,16 @@
 error[E0005]: refutable pattern in local binding: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
-  --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:9
+  --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:4:10
    |
-LL |     let 0 | (1 | 2) = 0;
-   |         ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
+LL |     let (0 | (1 | 2)) = 0;
+   |          ^^^^^^^^^^^ patterns `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
    |
    = note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
    = note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
    = note: the matched value is of type `i32`
 help: you might want to use `if let` to ignore the variant that isn't matched
    |
-LL |     if let 0 | (1 | 2) = 0 { /* */ }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |     if let (0 | (1 | 2)) = 0 { /* */ }
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error[E0004]: non-exhaustive patterns: `i32::MIN..=-1_i32` and `3_i32..=i32::MAX` not covered
   --> $DIR/issue-69875-should-have-been-expanded-earlier-non-exhaustive.rs:5:11
diff --git a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs
index 1de563dedbf..2f080ebf783 100644
--- a/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs
+++ b/src/test/ui/or-patterns/issue-69875-should-have-been-expanded-earlier.rs
@@ -3,7 +3,7 @@
 #![feature(or_patterns)]
 
 fn main() {
-    let 0 | (1 | _) = 0;
+    let (0 | (1 | _)) = 0;
     if let 0 | (1 | 2) = 0 {}
     if let x @ 0 | x @ (1 | 2) = 0 {}
 }
diff --git a/src/test/ui/or-patterns/let-pattern.rs b/src/test/ui/or-patterns/let-pattern.rs
index 07e37412ce8..7f22aa9d9f9 100644
--- a/src/test/ui/or-patterns/let-pattern.rs
+++ b/src/test/ui/or-patterns/let-pattern.rs
@@ -3,7 +3,7 @@
 // run-pass
 
 fn or_pat_let(x: Result<u32, u32>) -> u32 {
-    let Ok(y) | Err(y) = x;
+    let (Ok(y) | Err(y)) = x;
     y
 }
 
diff --git a/src/test/ui/or-patterns/mismatched-bindings-async-fn.rs b/src/test/ui/or-patterns/mismatched-bindings-async-fn.rs
index 5c5c68f81d1..cf98a472106 100644
--- a/src/test/ui/or-patterns/mismatched-bindings-async-fn.rs
+++ b/src/test/ui/or-patterns/mismatched-bindings-async-fn.rs
@@ -8,7 +8,7 @@ async fn a((x | s): String) {}
 //~| ERROR variable `s` is not bound in all patterns
 
 async fn b() {
-    let x | s = String::new();
+    let (x | s) = String::new();
     //~^ ERROR variable `x` is not bound in all patterns
     //~| ERROR variable `s` is not bound in all patterns
 }
diff --git a/src/test/ui/or-patterns/mismatched-bindings-async-fn.stderr b/src/test/ui/or-patterns/mismatched-bindings-async-fn.stderr
index 998577cf4b5..d5c77ee39c9 100644
--- a/src/test/ui/or-patterns/mismatched-bindings-async-fn.stderr
+++ b/src/test/ui/or-patterns/mismatched-bindings-async-fn.stderr
@@ -15,20 +15,20 @@ LL | async fn a((x | s): String) {}
    |             variable not in all patterns
 
 error[E0408]: variable `s` is not bound in all patterns
-  --> $DIR/mismatched-bindings-async-fn.rs:11:9
+  --> $DIR/mismatched-bindings-async-fn.rs:11:10
    |
-LL |     let x | s = String::new();
-   |         ^   - variable not in all patterns
-   |         |
-   |         pattern doesn't bind `s`
+LL |     let (x | s) = String::new();
+   |          ^   - variable not in all patterns
+   |          |
+   |          pattern doesn't bind `s`
 
 error[E0408]: variable `x` is not bound in all patterns
-  --> $DIR/mismatched-bindings-async-fn.rs:11:13
+  --> $DIR/mismatched-bindings-async-fn.rs:11:14
    |
-LL |     let x | s = String::new();
-   |         -   ^ pattern doesn't bind `x`
-   |         |
-   |         variable not in all patterns
+LL |     let (x | s) = String::new();
+   |          -   ^ pattern doesn't bind `x`
+   |          |
+   |          variable not in all patterns
 
 error: aborting due to 4 previous errors
 
diff --git a/src/test/ui/or-patterns/missing-bindings.rs b/src/test/ui/or-patterns/missing-bindings.rs
index 67cf52fa8c4..5dd1f16b655 100644
--- a/src/test/ui/or-patterns/missing-bindings.rs
+++ b/src/test/ui/or-patterns/missing-bindings.rs
@@ -17,7 +17,7 @@ fn check_handling_of_paths() {
     }
 
     use bar::foo::{alpha, charlie};
-    let alpha | beta | charlie = alpha; //~  ERROR variable `beta` is not bound in all patterns
+    let (alpha | beta | charlie) = alpha; //~  ERROR variable `beta` is not bound in all patterns
     match Some(alpha) {
         Some(alpha | beta) => {} //~ ERROR variable `beta` is not bound in all patterns
     }
@@ -31,19 +31,19 @@ fn check_misc_nesting() {
 
     // One level:
     const X: E<u8> = B(0);
-    let A(a, _) | _ = X; //~ ERROR variable `a` is not bound in all patterns
-    let _ | B(a) = X; //~ ERROR variable `a` is not bound in all patterns
-    let A(..) | B(a) = X; //~ ERROR variable `a` is not bound in all patterns
-    let A(a, _) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns
-    let A(_, a) | B(_) = X; //~ ERROR variable `a` is not bound in all patterns
-    let A(a, b) | B(a) = X; //~ ERROR variable `b` is not bound in all patterns
+    let (A(a, _) | _) = X; //~ ERROR variable `a` is not bound in all patterns
+    let (_ | B(a)) = X; //~ ERROR variable `a` is not bound in all patterns
+    let (A(..) | B(a)) = X; //~ ERROR variable `a` is not bound in all patterns
+    let (A(a, _) | B(_)) = X; //~ ERROR variable `a` is not bound in all patterns
+    let (A(_, a) | B(_)) = X; //~ ERROR variable `a` is not bound in all patterns
+    let (A(a, b) | B(a)) = X; //~ ERROR variable `b` is not bound in all patterns
 
     // Two levels:
     const Y: E<E<u8>> = B(B(0));
-    let A(A(..) | B(_), _) | B(a) = Y; //~ ERROR variable `a` is not bound in all patterns
-    let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
+    let (A(A(..) | B(_), _) | B(a)) = Y; //~ ERROR variable `a` is not bound in all patterns
+    let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
     //~^ ERROR variable `a` is not bound in all patterns
-    let A(A(a, b) | B(c), d) | B(e) = Y;
+    let (A(A(a, b) | B(c), d) | B(e)) = Y;
     //~^ ERROR variable `a` is not bound in all patterns
     //~| ERROR variable `a` is not bound in all patterns
     //~| ERROR variable `b` is not bound in all patterns
diff --git a/src/test/ui/or-patterns/missing-bindings.stderr b/src/test/ui/or-patterns/missing-bindings.stderr
index 57270e44123..4702bc6bbf3 100644
--- a/src/test/ui/or-patterns/missing-bindings.stderr
+++ b/src/test/ui/or-patterns/missing-bindings.stderr
@@ -1,11 +1,11 @@
 error[E0408]: variable `beta` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:20:9
+  --> $DIR/missing-bindings.rs:20:10
    |
-LL |     let alpha | beta | charlie = alpha;
-   |         ^^^^^   ----   ^^^^^^^ pattern doesn't bind `beta`
-   |         |       |
-   |         |       variable not in all patterns
-   |         pattern doesn't bind `beta`
+LL |     let (alpha | beta | charlie) = alpha;
+   |          ^^^^^   ----   ^^^^^^^ pattern doesn't bind `beta`
+   |          |       |
+   |          |       variable not in all patterns
+   |          pattern doesn't bind `beta`
 
 error[E0408]: variable `beta` is not bound in all patterns
   --> $DIR/missing-bindings.rs:22:14
@@ -16,132 +16,132 @@ LL |         Some(alpha | beta) => {}
    |              pattern doesn't bind `beta`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:34:19
+  --> $DIR/missing-bindings.rs:34:20
    |
-LL |     let A(a, _) | _ = X;
-   |           -       ^ pattern doesn't bind `a`
-   |           |
-   |           variable not in all patterns
+LL |     let (A(a, _) | _) = X;
+   |            -       ^ pattern doesn't bind `a`
+   |            |
+   |            variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:35:9
+  --> $DIR/missing-bindings.rs:35:10
    |
-LL |     let _ | B(a) = X;
-   |         ^     - variable not in all patterns
-   |         |
-   |         pattern doesn't bind `a`
+LL |     let (_ | B(a)) = X;
+   |          ^     - variable not in all patterns
+   |          |
+   |          pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:36:9
+  --> $DIR/missing-bindings.rs:36:10
    |
-LL |     let A(..) | B(a) = X;
-   |         ^^^^^     - variable not in all patterns
-   |         |
-   |         pattern doesn't bind `a`
+LL |     let (A(..) | B(a)) = X;
+   |          ^^^^^     - variable not in all patterns
+   |          |
+   |          pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:37:19
+  --> $DIR/missing-bindings.rs:37:20
    |
-LL |     let A(a, _) | B(_) = X;
-   |           -       ^^^^ pattern doesn't bind `a`
-   |           |
-   |           variable not in all patterns
+LL |     let (A(a, _) | B(_)) = X;
+   |            -       ^^^^ pattern doesn't bind `a`
+   |            |
+   |            variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:38:19
+  --> $DIR/missing-bindings.rs:38:20
    |
-LL |     let A(_, a) | B(_) = X;
-   |              -    ^^^^ pattern doesn't bind `a`
-   |              |
-   |              variable not in all patterns
+LL |     let (A(_, a) | B(_)) = X;
+   |               -    ^^^^ pattern doesn't bind `a`
+   |               |
+   |               variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:39:19
+  --> $DIR/missing-bindings.rs:39:20
    |
-LL |     let A(a, b) | B(a) = X;
-   |              -    ^^^^ pattern doesn't bind `b`
-   |              |
-   |              variable not in all patterns
+LL |     let (A(a, b) | B(a)) = X;
+   |               -    ^^^^ pattern doesn't bind `b`
+   |               |
+   |               variable not in all patterns
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:43:9
+  --> $DIR/missing-bindings.rs:43:10
    |
-LL |     let A(A(..) | B(_), _) | B(a) = Y;
-   |         ^^^^^^^^^^^^^^^^^^     - variable not in all patterns
-   |         |
-   |         pattern doesn't bind `a`
+LL |     let (A(A(..) | B(_), _) | B(a)) = Y;
+   |          ^^^^^^^^^^^^^^^^^^     - variable not in all patterns
+   |          |
+   |          pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:44:11
+  --> $DIR/missing-bindings.rs:44:12
    |
-LL |     let A(A(..) | B(a), _) | B(A(a, _) | B(a)) = Y;
-   |           ^^^^^     - variable not in all patterns
-   |           |
-   |           pattern doesn't bind `a`
+LL |     let (A(A(..) | B(a), _) | B(A(a, _) | B(a))) = Y;
+   |            ^^^^^     - variable not in all patterns
+   |            |
+   |            pattern doesn't bind `a`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:21
+  --> $DIR/missing-bindings.rs:46:22
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |             -       ^^^^ pattern doesn't bind `a`
-   |             |
-   |             variable not in all patterns
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |              -       ^^^^ pattern doesn't bind `a`
+   |              |
+   |              variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:21
+  --> $DIR/missing-bindings.rs:46:22
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |                -    ^^^^ pattern doesn't bind `b`
-   |                |
-   |                variable not in all patterns
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                 -    ^^^^ pattern doesn't bind `b`
+   |                 |
+   |                 variable not in all patterns
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:11
+  --> $DIR/missing-bindings.rs:46:12
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |           ^^^^^^^     - variable not in all patterns
-   |           |
-   |           pattern doesn't bind `c`
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |            ^^^^^^^     - variable not in all patterns
+   |            |
+   |            pattern doesn't bind `c`
 
 error[E0408]: variable `a` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:46:33
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |             -                  ^^^^ pattern doesn't bind `a`
-   |             |
-   |             variable not in all patterns
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |              -                  ^^^^ pattern doesn't bind `a`
+   |              |
+   |              variable not in all patterns
 
 error[E0408]: variable `b` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:46:33
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |                -               ^^^^ pattern doesn't bind `b`
-   |                |
-   |                variable not in all patterns
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                 -               ^^^^ pattern doesn't bind `b`
+   |                 |
+   |                 variable not in all patterns
 
 error[E0408]: variable `c` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:46:33
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |                       -        ^^^^ pattern doesn't bind `c`
-   |                       |
-   |                       variable not in all patterns
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                        -        ^^^^ pattern doesn't bind `c`
+   |                        |
+   |                        variable not in all patterns
 
 error[E0408]: variable `d` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:32
+  --> $DIR/missing-bindings.rs:46:33
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |                           -    ^^^^ pattern doesn't bind `d`
-   |                           |
-   |                           variable not in all patterns
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |                            -    ^^^^ pattern doesn't bind `d`
+   |                            |
+   |                            variable not in all patterns
 
 error[E0408]: variable `e` is not bound in all patterns
-  --> $DIR/missing-bindings.rs:46:9
+  --> $DIR/missing-bindings.rs:46:10
    |
-LL |     let A(A(a, b) | B(c), d) | B(e) = Y;
-   |         ^^^^^^^^^^^^^^^^^^^^     - variable not in all patterns
-   |         |
-   |         pattern doesn't bind `e`
+LL |     let (A(A(a, b) | B(c), d) | B(e)) = Y;
+   |          ^^^^^^^^^^^^^^^^^^^^     - variable not in all patterns
+   |          |
+   |          pattern doesn't bind `e`
 
 error[E0408]: variable `a` is not bound in all patterns
   --> $DIR/missing-bindings.rs:62:29
diff --git a/src/test/ui/or-patterns/nested-undelimited-precedence.rs b/src/test/ui/or-patterns/nested-undelimited-precedence.rs
new file mode 100644
index 00000000000..208662b1c42
--- /dev/null
+++ b/src/test/ui/or-patterns/nested-undelimited-precedence.rs
@@ -0,0 +1,46 @@
+// This test tests the precedence of `|` (or-patterns) undelimited nested patterns. In particular,
+// we want to reserve the syntactic space of a pattern followed by a type annotation for possible
+// future type ascription, so we need to make sure that any time a pattern is followed by type
+// annotation (for now), the pattern is not a top-level or-pattern. However, there are also a few
+// types of patterns that allow undelimited subpatterns that could cause the same ambiguity.
+// Currently, those should be impossible due to precedence rule. This test enforces that.
+
+#![feature(or_patterns)]
+
+enum E {
+    A,
+    B,
+}
+
+fn foo() {
+    use E::*;
+
+    // ok
+    let b @ (A | B): E = A;
+
+    let b @ A | B: E = A; //~ERROR `b` is not bound in all patterns
+    //~^ ERROR top-level or-patterns are not allowed
+}
+
+enum F {
+    A(usize),
+    B(usize),
+}
+
+fn bar() {
+    use F::*;
+
+    // ok
+    let (A(x) | B(x)): F = A(3);
+
+    let &A(_) | B(_): F = A(3); //~ERROR mismatched types
+    //~^ ERROR top-level or-patterns are not allowed
+    let &&A(_) | B(_): F = A(3); //~ERROR mismatched types
+    //~^ ERROR top-level or-patterns are not allowed
+    let &mut A(_) | B(_): F = A(3); //~ERROR mismatched types
+    //~^ ERROR top-level or-patterns are not allowed
+    let &&mut A(_) | B(_): F = A(3); //~ERROR mismatched types
+    //~^ ERROR top-level or-patterns are not allowed
+}
+
+fn main() {}
diff --git a/src/test/ui/or-patterns/nested-undelimited-precedence.stderr b/src/test/ui/or-patterns/nested-undelimited-precedence.stderr
new file mode 100644
index 00000000000..1d78d5193cb
--- /dev/null
+++ b/src/test/ui/or-patterns/nested-undelimited-precedence.stderr
@@ -0,0 +1,86 @@
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/nested-undelimited-precedence.rs:21:9
+   |
+LL |     let b @ A | B: E = A;
+   |         ^^^^^^^^^ help: wrap the pattern in parentheses: `(b @ A | B)`
+
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/nested-undelimited-precedence.rs:36:9
+   |
+LL |     let &A(_) | B(_): F = A(3);
+   |         ^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&A(_) | B(_))`
+
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/nested-undelimited-precedence.rs:38:9
+   |
+LL |     let &&A(_) | B(_): F = A(3);
+   |         ^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&A(_) | B(_))`
+
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/nested-undelimited-precedence.rs:40:9
+   |
+LL |     let &mut A(_) | B(_): F = A(3);
+   |         ^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&mut A(_) | B(_))`
+
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/nested-undelimited-precedence.rs:42:9
+   |
+LL |     let &&mut A(_) | B(_): F = A(3);
+   |         ^^^^^^^^^^^^^^^^^ help: wrap the pattern in parentheses: `(&&mut A(_) | B(_))`
+
+error[E0408]: variable `b` is not bound in all patterns
+  --> $DIR/nested-undelimited-precedence.rs:21:17
+   |
+LL |     let b @ A | B: E = A;
+   |         -       ^ pattern doesn't bind `b`
+   |         |
+   |         variable not in all patterns
+
+error[E0308]: mismatched types
+  --> $DIR/nested-undelimited-precedence.rs:36:9
+   |
+LL |     let &A(_) | B(_): F = A(3);
+   |         ^^^^^         - expected due to this
+   |         |
+   |         expected enum `F`, found reference
+   |
+   = note:   expected enum `F`
+           found reference `&_`
+
+error[E0308]: mismatched types
+  --> $DIR/nested-undelimited-precedence.rs:38:9
+   |
+LL |     let &&A(_) | B(_): F = A(3);
+   |         ^^^^^^         - expected due to this
+   |         |
+   |         expected enum `F`, found reference
+   |
+   = note:   expected enum `F`
+           found reference `&_`
+
+error[E0308]: mismatched types
+  --> $DIR/nested-undelimited-precedence.rs:40:9
+   |
+LL |     let &mut A(_) | B(_): F = A(3);
+   |         ^^^^^^^^^         - expected due to this
+   |         |
+   |         expected enum `F`, found `&mut _`
+   |
+   = note:           expected enum `F`
+           found mutable reference `&mut _`
+
+error[E0308]: mismatched types
+  --> $DIR/nested-undelimited-precedence.rs:42:9
+   |
+LL |     let &&mut A(_) | B(_): F = A(3);
+   |         ^^^^^^^^^^         - expected due to this
+   |         |
+   |         expected enum `F`, found reference
+   |
+   = note:   expected enum `F`
+           found reference `&_`
+
+error: aborting due to 10 previous errors
+
+Some errors have detailed explanations: E0308, E0408.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs
index 5ec7dc6962c..11c8a7b69f9 100644
--- a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs
+++ b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.rs
@@ -52,10 +52,10 @@ fn main() {
     = Some((0u8, Some((1u16, 2u32))))
     {}
 
-    let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
+    let (Blah::A(_, x, y) | Blah::B(x, y)) = Blah::A(1, 1, 2);
     //~^ ERROR mismatched types
 
-    let (x, y) | (y, x) = (0u8, 1u16);
+    let ((x, y) | (y, x)) = (0u8, 1u16);
     //~^ ERROR mismatched types
     //~| ERROR mismatched types
 
diff --git a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr
index 00dba053a59..26e14b539db 100644
--- a/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr
+++ b/src/test/ui/or-patterns/or-patterns-binding-type-mismatch.stderr
@@ -187,35 +187,35 @@ LL |     = Some((0u8, Some((1u16, 2u32))))
    = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
-  --> $DIR/or-patterns-binding-type-mismatch.rs:55:39
+  --> $DIR/or-patterns-binding-type-mismatch.rs:55:40
    |
-LL |     let Blah::A(_, x, y) | Blah::B(x, y) = Blah::A(1, 1, 2);
-   |                       -               ^    ---------------- this expression has type `Blah`
-   |                       |               |
-   |                       |               expected `usize`, found `isize`
-   |                       first introduced with type `usize` here
+LL |     let (Blah::A(_, x, y) | Blah::B(x, y)) = Blah::A(1, 1, 2);
+   |                        -               ^     ---------------- this expression has type `Blah`
+   |                        |               |
+   |                        |               expected `usize`, found `isize`
+   |                        first introduced with type `usize` here
    |
    = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
-  --> $DIR/or-patterns-binding-type-mismatch.rs:58:19
+  --> $DIR/or-patterns-binding-type-mismatch.rs:58:20
    |
-LL |     let (x, y) | (y, x) = (0u8, 1u16);
-   |             -     ^       ----------- this expression has type `(u8, u16)`
-   |             |     |
-   |             |     expected `u16`, found `u8`
-   |             first introduced with type `u16` here
+LL |     let ((x, y) | (y, x)) = (0u8, 1u16);
+   |              -     ^        ----------- this expression has type `(u8, u16)`
+   |              |     |
+   |              |     expected `u16`, found `u8`
+   |              first introduced with type `u16` here
    |
    = note: a binding must have the same type in all alternatives
 
 error[E0308]: mismatched types
-  --> $DIR/or-patterns-binding-type-mismatch.rs:58:22
+  --> $DIR/or-patterns-binding-type-mismatch.rs:58:23
    |
-LL |     let (x, y) | (y, x) = (0u8, 1u16);
-   |          -           ^    ----------- this expression has type `(u8, u16)`
-   |          |           |
-   |          |           expected `u8`, found `u16`
-   |          first introduced with type `u8` here
+LL |     let ((x, y) | (y, x)) = (0u8, 1u16);
+   |           -           ^     ----------- this expression has type `(u8, u16)`
+   |           |           |
+   |           |           expected `u8`, found `u16`
+   |           first introduced with type `u8` here
    |
    = note: a binding must have the same type in all alternatives
 
diff --git a/src/test/ui/or-patterns/or-patterns-default-binding-modes.rs b/src/test/ui/or-patterns/or-patterns-default-binding-modes.rs
index 3b6047c7be4..f98b038ae81 100644
--- a/src/test/ui/or-patterns/or-patterns-default-binding-modes.rs
+++ b/src/test/ui/or-patterns/or-patterns-default-binding-modes.rs
@@ -37,11 +37,11 @@ fn main() {
     if let &(Ok(x) | Err(x)) = res {
         drop::<u8>(x);
     }
-    let Ok(mut x) | &Err(mut x) = res;
+    let (Ok(mut x) | &Err(mut x)) = res;
     drop::<u8>(x);
     let &(Ok(x) | Err(x)) = res;
     drop::<u8>(x);
-    let Ok(x) | Err(x) = res;
+    let (Ok(x) | Err(x)) = res;
     drop::<&u8>(x);
     for Ok(mut x) | &Err(mut x) in std::iter::once(res) {
         drop::<u8>(x);
@@ -119,9 +119,9 @@ fn main() {
     }
 
     let tri = &Tri::A(&Ok(0));
-    let Tri::A(Ok(mut x) | Err(mut x))
+    let (Tri::A(Ok(mut x) | Err(mut x))
     | Tri::B(&Ok(mut x) | Err(mut x))
-    | &Tri::C(Ok(mut x) | Err(mut x)) = tri;
+    | &Tri::C(Ok(mut x) | Err(mut x))) = tri;
     drop::<u8>(x);
 
     match tri {
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
index cbc24eb26fa..27a5374ff18 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.rs
@@ -14,8 +14,19 @@ fn no_top_level_or_patterns() {
     //           -------- This looks like an or-pattern but is in fact `|A| (B: E | ())`.
 
     // ...and for now neither do we allow or-patterns at the top level of functions.
-    fn fun1(A | B: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
+    fn fun1(A | B: E) {}
+    //~^ ERROR top-level or-patterns are not allowed
 
     fn fun2(| A | B: E) {}
-    //~^ ERROR an or-pattern parameter must be wrapped in parentheses
+    //~^ ERROR top-level or-patterns are not allowed
+
+    // We don't allow top-level or-patterns before type annotation in let-statements because we
+    // want to reserve this syntactic space for possible future type ascription.
+    let A | B: E = A;
+    //~^ ERROR top-level or-patterns are not allowed
+
+    let | A | B: E = A;
+    //~^ ERROR top-level or-patterns are not allowed
+
+    let (A | B): E = A; // ok -- wrapped in parens
 }
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
index db4d827757b..929b2088f76 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-fail.stderr
@@ -1,15 +1,27 @@
-error: an or-pattern parameter must be wrapped in parentheses
+error: top-level or-patterns are not allowed in function parameters
   --> $DIR/or-patterns-syntactic-fail.rs:17:13
    |
 LL |     fn fun1(A | B: E) {}
    |             ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
 
-error: an or-pattern parameter must be wrapped in parentheses
-  --> $DIR/or-patterns-syntactic-fail.rs:19:13
+error: top-level or-patterns are not allowed in function parameters
+  --> $DIR/or-patterns-syntactic-fail.rs:20:13
    |
 LL |     fn fun2(| A | B: E) {}
    |             ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
 
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/or-patterns-syntactic-fail.rs:25:9
+   |
+LL |     let A | B: E = A;
+   |         ^^^^^ help: wrap the pattern in parentheses: `(A | B)`
+
+error: top-level or-patterns are not allowed in `let` bindings
+  --> $DIR/or-patterns-syntactic-fail.rs:28:9
+   |
+LL |     let | A | B: E = A;
+   |         ^^^^^^^ help: wrap the pattern in parentheses: `(A | B)`
+
 error[E0369]: no implementation for `E | ()`
   --> $DIR/or-patterns-syntactic-fail.rs:13:22
    |
@@ -20,6 +32,6 @@ LL |     let _ = |A | B: E| ();
    |
    = note: an implementation of `std::ops::BitOr` might be missing for `E`
 
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0369`.
diff --git a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
index 5fe72caf9c1..3da238f7b9a 100644
--- a/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
+++ b/src/test/ui/or-patterns/or-patterns-syntactic-pass.rs
@@ -23,11 +23,11 @@ accept_pat!([p | q]);
 #[cfg(FALSE)]
 fn or_patterns() {
     // Top level of `let`:
-    let | A | B;
-    let A | B;
-    let A | B: u8;
-    let A | B = 0;
-    let A | B: u8 = 0;
+    let (| A | B);
+    let (A | B);
+    let (A | B): u8;
+    let (A | B) = 0;
+    let (A | B): u8 = 0;
 
     // Top level of `for`:
     for | A | B in 0 {}
@@ -69,10 +69,10 @@ fn or_patterns() {
     let [A | B, .. | ..];
 
     // These bind as `(prefix p) | q` as opposed to `prefix (p | q)`:
-    let box 0 | 1; // Unstable; we *can* the precedence if we want.
-    let &0 | 1;
-    let &mut 0 | 1;
-    let x @ 0 | 1;
-    let ref x @ 0 | 1;
-    let ref mut x @ 0 | 1;
+    let (box 0 | 1); // Unstable; we *can* change the precedence if we want.
+    let (&0 | 1);
+    let (&mut 0 | 1);
+    let (x @ 0 | 1);
+    let (ref x @ 0 | 1);
+    let (ref mut x @ 0 | 1);
 }
diff --git a/src/test/ui/or-patterns/remove-leading-vert.fixed b/src/test/ui/or-patterns/remove-leading-vert.fixed
index c8fac4faa2a..d23858d42d1 100644
--- a/src/test/ui/or-patterns/remove-leading-vert.fixed
+++ b/src/test/ui/or-patterns/remove-leading-vert.fixed
@@ -9,7 +9,7 @@ fn main() {}
 
 #[cfg(FALSE)]
 fn leading() {
-    fn fun1( A: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
+    fn fun1( A: E) {} //~ ERROR top-level or-patterns are not allowed
     fn fun2(  A: E) {} //~ ERROR unexpected `||` before function parameter
     let ( | A): E;
     let ( | A): (E); //~ ERROR unexpected token `||` in pattern
@@ -40,6 +40,9 @@ fn trailing() {
         //~^ ERROR a trailing `|` is not allowed in an or-pattern
     }
 
+    // These test trailing-vert in `let` bindings, but they also test that we don't emit a
+    // duplicate suggestion that would confuse rustfix.
+
     let a  : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
     let a  = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
     let a  ; //~ ERROR a trailing `|` is not allowed in an or-pattern
diff --git a/src/test/ui/or-patterns/remove-leading-vert.rs b/src/test/ui/or-patterns/remove-leading-vert.rs
index 2cf6b27ab1a..e753765b3e7 100644
--- a/src/test/ui/or-patterns/remove-leading-vert.rs
+++ b/src/test/ui/or-patterns/remove-leading-vert.rs
@@ -9,7 +9,7 @@ fn main() {}
 
 #[cfg(FALSE)]
 fn leading() {
-    fn fun1( | A: E) {} //~ ERROR an or-pattern parameter must be wrapped in parentheses
+    fn fun1( | A: E) {} //~ ERROR top-level or-patterns are not allowed
     fn fun2( || A: E) {} //~ ERROR unexpected `||` before function parameter
     let ( | A): E;
     let ( || A): (E); //~ ERROR unexpected token `||` in pattern
@@ -40,6 +40,9 @@ fn trailing() {
         //~^ ERROR a trailing `|` is not allowed in an or-pattern
     }
 
+    // These test trailing-vert in `let` bindings, but they also test that we don't emit a
+    // duplicate suggestion that would confuse rustfix.
+
     let a | : u8 = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
     let a | = 0; //~ ERROR a trailing `|` is not allowed in an or-pattern
     let a | ; //~ ERROR a trailing `|` is not allowed in an or-pattern
diff --git a/src/test/ui/or-patterns/remove-leading-vert.stderr b/src/test/ui/or-patterns/remove-leading-vert.stderr
index 5c9efd44a18..0a2b143288d 100644
--- a/src/test/ui/or-patterns/remove-leading-vert.stderr
+++ b/src/test/ui/or-patterns/remove-leading-vert.stderr
@@ -1,8 +1,8 @@
-error: an or-pattern parameter must be wrapped in parentheses
+error: top-level or-patterns are not allowed in function parameters
   --> $DIR/remove-leading-vert.rs:12:14
    |
 LL |     fn fun1( | A: E) {}
-   |              ^^^ help: remove the leading `|`: `A`
+   |              ^^^ help: remove the `|`: `A`
 
 error: unexpected `||` before function parameter
   --> $DIR/remove-leading-vert.rs:13:14
@@ -135,7 +135,7 @@ LL |         | A | B | => {}
    |         while parsing this or-pattern starting here
 
 error: a trailing `|` is not allowed in an or-pattern
-  --> $DIR/remove-leading-vert.rs:43:11
+  --> $DIR/remove-leading-vert.rs:46:11
    |
 LL |     let a | : u8 = 0;
    |         - ^ help: remove the `|`
@@ -143,7 +143,7 @@ LL |     let a | : u8 = 0;
    |         while parsing this or-pattern starting here
 
 error: a trailing `|` is not allowed in an or-pattern
-  --> $DIR/remove-leading-vert.rs:44:11
+  --> $DIR/remove-leading-vert.rs:47:11
    |
 LL |     let a | = 0;
    |         - ^ help: remove the `|`
@@ -151,7 +151,7 @@ LL |     let a | = 0;
    |         while parsing this or-pattern starting here
 
 error: a trailing `|` is not allowed in an or-pattern
-  --> $DIR/remove-leading-vert.rs:45:11
+  --> $DIR/remove-leading-vert.rs:48:11
    |
 LL |     let a | ;
    |         - ^ help: remove the `|`
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject c68432f1e5cbbc09833699a951b1b5b059651df
+Subproject 970bc67c3775781b9708c8a36893576b9459c64
diff --git a/src/tools/clippy/clippy_lints/src/loops.rs b/src/tools/clippy/clippy_lints/src/loops.rs
index 63d9b7f8645..c89a0876575 100644
--- a/src/tools/clippy/clippy_lints/src/loops.rs
+++ b/src/tools/clippy/clippy_lints/src/loops.rs
@@ -885,7 +885,9 @@ struct MinifyingSugg<'a>(Sugg<'a>);
 
 impl<'a> MinifyingSugg<'a> {
     fn as_str(&self) -> &str {
-        let Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) = &self.0;
+        let s = match &self.0 {
+            Sugg::NonParen(s) | Sugg::MaybeParen(s) | Sugg::BinOp(_, s) => s,
+        };
         s.as_ref()
     }