about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/test/ui/asm/issue-99071.rs21
-rw-r--r--src/test/ui/asm/issue-99071.stderr8
-rw-r--r--src/test/ui/async-await/async-await-let-else.rs53
-rw-r--r--src/test/ui/async-await/async-await-let-else.stderr94
-rw-r--r--src/test/ui/layout/unsafe-cell-hides-niche.rs78
-rw-r--r--src/test/ui/let-else/let-else-binding-explicit-mut-annotated.stderr8
-rw-r--r--src/test/ui/let-else/let-else-check.stderr12
-rw-r--r--src/test/ui/let-else/let-else-non-diverging.stderr18
-rw-r--r--src/test/ui/let-else/let-else-ref-bindings.stderr16
-rw-r--r--src/test/ui/let-else/let-else-temporary-lifetime.rs25
-rw-r--r--src/test/ui/lint/clashing-extern-fn.rs4
-rw-r--r--src/test/ui/lint/clashing-extern-fn.stderr40
-rw-r--r--src/test/ui/parser/issues/issue-52496.stderr7
-rw-r--r--src/test/ui/parser/issues/issue-62973.stderr16
-rw-r--r--src/test/ui/parser/removed-syntax-with-2.rs2
-rw-r--r--src/test/ui/parser/removed-syntax-with-2.stderr4
-rw-r--r--src/test/ui/repr/feature-gate-no-niche.rs20
-rw-r--r--src/test/ui/repr/feature-gate-no-niche.stderr35
-rw-r--r--src/test/ui/repr/repr-no-niche-inapplicable-to-unions.rs14
-rw-r--r--src/test/ui/repr/repr-no-niche-inapplicable-to-unions.stderr19
-rw-r--r--src/test/ui/repr/repr-no-niche.rs327
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs1
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs5
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs8
27 files changed, 350 insertions, 492 deletions
diff --git a/src/test/ui/asm/issue-99071.rs b/src/test/ui/asm/issue-99071.rs
new file mode 100644
index 00000000000..bb6201861df
--- /dev/null
+++ b/src/test/ui/asm/issue-99071.rs
@@ -0,0 +1,21 @@
+// compile-flags: --target thumbv6m-none-eabi
+// needs-llvm-components: arm
+// needs-asm-support
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![no_core]
+#![crate_type = "rlib"]
+
+#[rustc_builtin_macro]
+macro_rules! asm {
+    () => {};
+}
+#[lang = "sized"]
+trait Sized {}
+
+pub fn foo() {
+    unsafe {
+        asm!("", in("r8") 0);
+        //~^ cannot use register `r8`: high registers (r8+) can only be used as clobbers in Thumb-1 code
+    }
+}
diff --git a/src/test/ui/asm/issue-99071.stderr b/src/test/ui/asm/issue-99071.stderr
new file mode 100644
index 00000000000..47386ffa4a8
--- /dev/null
+++ b/src/test/ui/asm/issue-99071.stderr
@@ -0,0 +1,8 @@
+error: cannot use register `r8`: high registers (r8+) can only be used as clobbers in Thumb-1 code
+  --> $DIR/issue-99071.rs:18:18
+   |
+LL |         asm!("", in("r8") 0);
+   |                  ^^^^^^^^^^
+
+error: aborting due to previous error
+
diff --git a/src/test/ui/async-await/async-await-let-else.rs b/src/test/ui/async-await/async-await-let-else.rs
new file mode 100644
index 00000000000..7ea07ae9add
--- /dev/null
+++ b/src/test/ui/async-await/async-await-let-else.rs
@@ -0,0 +1,53 @@
+// edition:2021
+#![feature(let_else)]
+use std::rc::Rc;
+
+async fn foo(x: Option<bool>) {
+    let Some(_) = x else {
+        let r = Rc::new(());
+        bar().await
+    };
+}
+
+async fn bar() -> ! {
+    panic!()
+}
+
+fn is_send<T: Send>(_: T) {}
+
+async fn foo2(x: Option<bool>) {
+    let Some(_) = x else {
+        bar2(Rc::new(())).await
+    };
+}
+
+async fn bar2<T>(_: T) -> ! {
+    panic!()
+}
+
+async fn foo3(x: Option<bool>) {
+    let Some(_) = x else {
+        (Rc::new(()), bar().await);
+        return;
+    };
+}
+
+async fn foo4(x: Option<bool>) {
+    let Some(_) = x else {
+        let r = Rc::new(());
+        bar().await;
+        println!("{:?}", r);
+        return;
+    };
+}
+
+fn main() {
+    is_send(foo(Some(true)));
+    //~^ ERROR future cannot be sent between threads safely
+    is_send(foo2(Some(true)));
+    //~^ ERROR future cannot be sent between threads safely
+    is_send(foo3(Some(true)));
+    //~^ ERROR future cannot be sent between threads safely
+    is_send(foo4(Some(true)));
+    //~^ ERROR future cannot be sent between threads safely
+}
diff --git a/src/test/ui/async-await/async-await-let-else.stderr b/src/test/ui/async-await/async-await-let-else.stderr
new file mode 100644
index 00000000000..4d23e27c426
--- /dev/null
+++ b/src/test/ui/async-await/async-await-let-else.stderr
@@ -0,0 +1,94 @@
+error: future cannot be sent between threads safely
+  --> $DIR/async-await-let-else.rs:45:13
+   |
+LL |     is_send(foo(Some(true)));
+   |             ^^^^^^^^^^^^^^^ future returned by `foo` is not `Send`
+   |
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/async-await-let-else.rs:8:14
+   |
+LL |         let r = Rc::new(());
+   |             - has type `Rc<()>` which is not `Send`
+LL |         bar().await
+   |              ^^^^^^ await occurs here, with `r` maybe used later
+LL |     };
+   |     - `r` is later dropped here
+note: required by a bound in `is_send`
+  --> $DIR/async-await-let-else.rs:16:15
+   |
+LL | fn is_send<T: Send>(_: T) {}
+   |               ^^^^ required by this bound in `is_send`
+
+error: future cannot be sent between threads safely
+  --> $DIR/async-await-let-else.rs:47:13
+   |
+LL |     is_send(foo2(Some(true)));
+   |             ^^^^^^^^^^^^^^^^ future returned by `foo2` is not `Send`
+   |
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/async-await-let-else.rs:20:26
+   |
+LL |         bar2(Rc::new(())).await
+   |              ----------- ^^^^^^ await occurs here, with `Rc::new(())` maybe used later
+   |              |
+   |              has type `Rc<()>` which is not `Send`
+LL |     };
+   |      - `Rc::new(())` is later dropped here
+note: required by a bound in `is_send`
+  --> $DIR/async-await-let-else.rs:16:15
+   |
+LL | fn is_send<T: Send>(_: T) {}
+   |               ^^^^ required by this bound in `is_send`
+
+error: future cannot be sent between threads safely
+  --> $DIR/async-await-let-else.rs:49:13
+   |
+LL |     is_send(foo3(Some(true)));
+   |             ^^^^^^^^^^^^^^^^ future returned by `foo3` is not `Send`
+   |
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/async-await-let-else.rs:30:28
+   |
+LL |         (Rc::new(()), bar().await);
+   |          -----------       ^^^^^^ await occurs here, with `Rc::new(())` maybe used later
+   |          |
+   |          has type `Rc<()>` which is not `Send`
+note: `Rc::new(())` is later dropped here
+  --> $DIR/async-await-let-else.rs:30:35
+   |
+LL |         (Rc::new(()), bar().await);
+   |                                   ^
+note: required by a bound in `is_send`
+  --> $DIR/async-await-let-else.rs:16:15
+   |
+LL | fn is_send<T: Send>(_: T) {}
+   |               ^^^^ required by this bound in `is_send`
+
+error: future cannot be sent between threads safely
+  --> $DIR/async-await-let-else.rs:51:13
+   |
+LL |     is_send(foo4(Some(true)));
+   |             ^^^^^^^^^^^^^^^^ future returned by `foo4` is not `Send`
+   |
+   = help: within `impl Future<Output = ()>`, the trait `Send` is not implemented for `Rc<()>`
+note: future is not `Send` as this value is used across an await
+  --> $DIR/async-await-let-else.rs:38:14
+   |
+LL |         let r = Rc::new(());
+   |             - has type `Rc<()>` which is not `Send`
+LL |         bar().await;
+   |              ^^^^^^ await occurs here, with `r` maybe used later
+...
+LL |     };
+   |     - `r` is later dropped here
+note: required by a bound in `is_send`
+  --> $DIR/async-await-let-else.rs:16:15
+   |
+LL | fn is_send<T: Send>(_: T) {}
+   |               ^^^^ required by this bound in `is_send`
+
+error: aborting due to 4 previous errors
+
diff --git a/src/test/ui/layout/unsafe-cell-hides-niche.rs b/src/test/ui/layout/unsafe-cell-hides-niche.rs
index 4ca3f7a1aad..73b32066fad 100644
--- a/src/test/ui/layout/unsafe-cell-hides-niche.rs
+++ b/src/test/ui/layout/unsafe-cell-hides-niche.rs
@@ -3,30 +3,80 @@
 // test checks that an `Option<UnsafeCell<NonZeroU32>>` has the same
 // size in memory as an `Option<UnsafeCell<u32>>` (namely, 8 bytes).
 
-// run-pass
+// check-pass
+// compile-flags: --crate-type=lib
+// only-x86
 
-#![feature(no_niche)]
+#![feature(repr_simd)]
 
-use std::cell::UnsafeCell;
+use std::cell::{UnsafeCell, RefCell, Cell};
 use std::mem::size_of;
 use std::num::NonZeroU32 as N32;
+use std::sync::{Mutex, RwLock};
 
 struct Wrapper<T>(T);
 
 #[repr(transparent)]
 struct Transparent<T>(T);
 
-#[repr(no_niche)]
-struct NoNiche<T>(T);
+struct NoNiche<T>(UnsafeCell<T>);
 
-fn main() {
-    assert_eq!(size_of::<Option<Wrapper<u32>>>(),     8);
-    assert_eq!(size_of::<Option<Wrapper<N32>>>(),     4);
-    assert_eq!(size_of::<Option<Transparent<u32>>>(), 8);
-    assert_eq!(size_of::<Option<Transparent<N32>>>(), 4);
-    assert_eq!(size_of::<Option<NoNiche<u32>>>(),     8);
-    assert_eq!(size_of::<Option<NoNiche<N32>>>(),     8);
+struct Size<const S: usize>;
 
-    assert_eq!(size_of::<Option<UnsafeCell<u32>>>(),  8);
-    assert_eq!(size_of::<Option<UnsafeCell<N32>>>(),  8);
+macro_rules! check_sizes {
+    (check_one_specific_size: $ty:ty, $size:expr) => {
+        const _: Size::<{$size}> = Size::<{size_of::<$ty>()}>;
+    };
+    // Any tests run on `UnsafeCell` must be the same for `Cell`
+    (UnsafeCell<$ty:ty>: $size:expr => $optioned_size:expr) => {
+        check_sizes!(Cell<$ty>: $size => $optioned_size);
+        check_sizes!(@actual_check: UnsafeCell<$ty>: $size => $optioned_size);
+    };
+    ($ty:ty: $size:expr => $optioned_size:expr) => {
+        check_sizes!(@actual_check: $ty: $size => $optioned_size);
+    };
+    // This branch does the actual checking logic, the `@actual_check` prefix is here to distinguish
+    // it from other branches and not accidentally match any.
+    (@actual_check: $ty:ty: $size:expr => $optioned_size:expr) => {
+        check_sizes!(check_one_specific_size: $ty, $size);
+        check_sizes!(check_one_specific_size: Option<$ty>, $optioned_size);
+        check_sizes!(check_no_niche_opt: $size != $optioned_size, $ty);
+    };
+    // only check that there is no niche (size goes up when wrapped in an option),
+    // don't check actual sizes
+    ($ty:ty) => {
+        check_sizes!(check_no_niche_opt: true, $ty);
+    };
+    (check_no_niche_opt: $no_niche_opt:expr, $ty:ty) => {
+        const _: () = if $no_niche_opt { assert!(size_of::<$ty>() < size_of::<Option<$ty>>()); };
+    };
 }
+
+const PTR_SIZE: usize = std::mem::size_of::<*const ()>();
+
+check_sizes!(Wrapper<u32>:     4 => 8);
+check_sizes!(Wrapper<N32>:     4 => 4); // (✓ niche opt)
+check_sizes!(Transparent<u32>: 4 => 8);
+check_sizes!(Transparent<N32>: 4 => 4); // (✓ niche opt)
+check_sizes!(NoNiche<u32>:     4 => 8);
+check_sizes!(NoNiche<N32>:     4 => 8);
+
+check_sizes!(UnsafeCell<u32>:  4 => 8);
+check_sizes!(UnsafeCell<N32>:  4 => 8);
+
+check_sizes!(UnsafeCell<&()>: PTR_SIZE => PTR_SIZE * 2);
+check_sizes!(   RefCell<&()>: PTR_SIZE * 2 => PTR_SIZE * 3);
+
+check_sizes!(RwLock<&()>);
+check_sizes!(Mutex<&()>);
+
+check_sizes!(UnsafeCell<&[i32]>: PTR_SIZE * 2 => PTR_SIZE * 3);
+check_sizes!(UnsafeCell<(&(), &())>: PTR_SIZE * 2 => PTR_SIZE * 3);
+
+trait Trait {}
+check_sizes!(UnsafeCell<&dyn Trait>: PTR_SIZE * 2 => PTR_SIZE * 3);
+
+#[repr(simd)]
+pub struct Vec4<T>([T; 4]);
+
+check_sizes!(UnsafeCell<Vec4<N32>>: 16 => 32);
diff --git a/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.stderr b/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.stderr
index fdec7e7f6a7..065787cab08 100644
--- a/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.stderr
+++ b/src/test/ui/let-else/let-else-binding-explicit-mut-annotated.stderr
@@ -2,7 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/let-else-binding-explicit-mut-annotated.rs:9:37
    |
 LL |     let Some(n): &mut Option<i32> = &&Some(5i32) else { return };
-   |                                     ^^^^^^^^^^^^ types differ in mutability
+   |                  ----------------   ^^^^^^^^^^^^ types differ in mutability
+   |                  |
+   |                  expected due to this
    |
    = note: expected mutable reference `&mut Option<i32>`
                       found reference `&&Option<i32>`
@@ -11,7 +13,9 @@ error[E0308]: mismatched types
   --> $DIR/let-else-binding-explicit-mut-annotated.rs:13:37
    |
 LL |     let Some(n): &mut Option<i32> = &&mut Some(5i32) else { return };
-   |                                     ^^^^^^^^^^^^^^^^ types differ in mutability
+   |                  ----------------   ^^^^^^^^^^^^^^^^ types differ in mutability
+   |                  |
+   |                  expected due to this
    |
    = note: expected mutable reference `&mut Option<i32>`
                       found reference `&&mut Option<i32>`
diff --git a/src/test/ui/let-else/let-else-check.stderr b/src/test/ui/let-else/let-else-check.stderr
index b3da412ec28..3d647a4c05d 100644
--- a/src/test/ui/let-else/let-else-check.stderr
+++ b/src/test/ui/let-else/let-else-check.stderr
@@ -1,8 +1,8 @@
 error: unused variable: `x`
-  --> $DIR/let-else-check.rs:18:9
+  --> $DIR/let-else-check.rs:14:13
    |
-LL |     let x = 1;
-   |         ^ help: if this is intentional, prefix it with an underscore: `_x`
+LL |         let x = 1;
+   |             ^ help: if this is intentional, prefix it with an underscore: `_x`
    |
 note: the lint level is defined here
   --> $DIR/let-else-check.rs:3:9
@@ -11,10 +11,10 @@ LL | #![deny(unused_variables)]
    |         ^^^^^^^^^^^^^^^^
 
 error: unused variable: `x`
-  --> $DIR/let-else-check.rs:14:13
+  --> $DIR/let-else-check.rs:18:9
    |
-LL |         let x = 1;
-   |             ^ help: if this is intentional, prefix it with an underscore: `_x`
+LL |     let x = 1;
+   |         ^ help: if this is intentional, prefix it with an underscore: `_x`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/test/ui/let-else/let-else-non-diverging.stderr b/src/test/ui/let-else/let-else-non-diverging.stderr
index b961b16b6f6..05e45f68989 100644
--- a/src/test/ui/let-else/let-else-non-diverging.stderr
+++ b/src/test/ui/let-else/let-else-non-diverging.stderr
@@ -1,8 +1,11 @@
 error[E0308]: `else` clause of `let...else` does not diverge
-  --> $DIR/let-else-non-diverging.rs:12:32
+  --> $DIR/let-else-non-diverging.rs:4:32
    |
-LL |     let Some(x) = Some(1) else { Some(2) };
-   |                                ^^^^^^^^^^^ expected `!`, found enum `Option`
+LL |       let Some(x) = Some(1) else {
+   |  ________________________________^
+LL | |         Some(2)
+LL | |     };
+   | |_____^ expected `!`, found enum `Option`
    |
    = note: expected type `!`
               found enum `Option<{integer}>`
@@ -26,13 +29,10 @@ LL | |     };
    = help: ...or use `match` instead of `let...else`
 
 error[E0308]: `else` clause of `let...else` does not diverge
-  --> $DIR/let-else-non-diverging.rs:4:32
+  --> $DIR/let-else-non-diverging.rs:12:32
    |
-LL |       let Some(x) = Some(1) else {
-   |  ________________________________^
-LL | |         Some(2)
-LL | |     };
-   | |_____^ expected `!`, found enum `Option`
+LL |     let Some(x) = Some(1) else { Some(2) };
+   |                                ^^^^^^^^^^^ expected `!`, found enum `Option`
    |
    = note: expected type `!`
               found enum `Option<{integer}>`
diff --git a/src/test/ui/let-else/let-else-ref-bindings.stderr b/src/test/ui/let-else/let-else-ref-bindings.stderr
index 650f4ec5e77..56b9e073330 100644
--- a/src/test/ui/let-else/let-else-ref-bindings.stderr
+++ b/src/test/ui/let-else/let-else-ref-bindings.stderr
@@ -20,7 +20,9 @@ error[E0308]: mismatched types
   --> $DIR/let-else-ref-bindings.rs:24:34
    |
 LL |     let Some(a): Option<&[u8]> = some else { return };
-   |                                  ^^^^ expected `&[u8]`, found struct `Vec`
+   |                  -------------   ^^^^ expected `&[u8]`, found struct `Vec`
+   |                  |
+   |                  expected due to this
    |
    = note: expected enum `Option<&[u8]>`
               found enum `Option<Vec<u8>>`
@@ -29,7 +31,9 @@ error[E0308]: mismatched types
   --> $DIR/let-else-ref-bindings.rs:27:34
    |
 LL |     let Some(a): Option<&[u8]> = &some else { return };
-   |                                  ^^^^^ expected enum `Option`, found `&Option<Vec<u8>>`
+   |                  -------------   ^^^^^ expected enum `Option`, found `&Option<Vec<u8>>`
+   |                  |
+   |                  expected due to this
    |
    = note:   expected enum `Option<&[u8]>`
            found reference `&Option<Vec<u8>>`
@@ -56,7 +60,9 @@ error[E0308]: mismatched types
   --> $DIR/let-else-ref-bindings.rs:52:38
    |
 LL |     let Some(a): Option<&mut [u8]> = some else { return };
-   |                                      ^^^^ expected `&mut [u8]`, found struct `Vec`
+   |                  -----------------   ^^^^ expected `&mut [u8]`, found struct `Vec`
+   |                  |
+   |                  expected due to this
    |
    = note: expected enum `Option<&mut [u8]>`
               found enum `Option<Vec<u8>>`
@@ -65,7 +71,9 @@ error[E0308]: mismatched types
   --> $DIR/let-else-ref-bindings.rs:55:38
    |
 LL |     let Some(a): Option<&mut [u8]> = &mut some else { return };
-   |                                      ^^^^^^^^^ expected enum `Option`, found mutable reference
+   |                  -----------------   ^^^^^^^^^ expected enum `Option`, found mutable reference
+   |                  |
+   |                  expected due to this
    |
    = note:           expected enum `Option<&mut [u8]>`
            found mutable reference `&mut Option<Vec<u8>>`
diff --git a/src/test/ui/let-else/let-else-temporary-lifetime.rs b/src/test/ui/let-else/let-else-temporary-lifetime.rs
new file mode 100644
index 00000000000..624c2ea37a7
--- /dev/null
+++ b/src/test/ui/let-else/let-else-temporary-lifetime.rs
@@ -0,0 +1,25 @@
+// run-pass
+#![feature(let_else)]
+
+use std::sync::atomic::{AtomicU8, Ordering};
+
+static TRACKER: AtomicU8 = AtomicU8::new(0);
+
+#[derive(Default)]
+struct Droppy {
+    inner: u32,
+}
+
+impl Drop for Droppy {
+    fn drop(&mut self) {
+        TRACKER.store(1, Ordering::Release);
+        println!("I've been dropped");
+    }
+}
+
+fn main() {
+    assert_eq!(TRACKER.load(Ordering::Acquire), 0);
+    let 0 = Droppy::default().inner else { return };
+    assert_eq!(TRACKER.load(Ordering::Acquire), 1);
+    println!("Should have dropped 👆");
+}
diff --git a/src/test/ui/lint/clashing-extern-fn.rs b/src/test/ui/lint/clashing-extern-fn.rs
index 2ce4dd56eab..809e0602671 100644
--- a/src/test/ui/lint/clashing-extern-fn.rs
+++ b/src/test/ui/lint/clashing-extern-fn.rs
@@ -1,7 +1,6 @@
 // check-pass
 // aux-build:external_extern_fn.rs
 #![crate_type = "lib"]
-#![feature(no_niche)]
 #![warn(clashing_extern_declarations)]
 
 mod redeclared_different_signature {
@@ -400,9 +399,8 @@ mod hidden_niche {
         #[repr(transparent)]
         struct Transparent { x: NonZeroUsize }
 
-        #[repr(no_niche)]
         #[repr(transparent)]
-        struct TransparentNoNiche { y: NonZeroUsize }
+        struct TransparentNoNiche { y: UnsafeCell<NonZeroUsize> }
 
         extern "C" {
             fn hidden_niche_transparent() -> Option<Transparent>;
diff --git a/src/test/ui/lint/clashing-extern-fn.stderr b/src/test/ui/lint/clashing-extern-fn.stderr
index a856de322c8..4607f684993 100644
--- a/src/test/ui/lint/clashing-extern-fn.stderr
+++ b/src/test/ui/lint/clashing-extern-fn.stderr
@@ -1,5 +1,5 @@
 warning: `clash` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:15:13
+  --> $DIR/clashing-extern-fn.rs:14:13
    |
 LL |             fn clash(x: u8);
    |             ---------------- `clash` previously declared here
@@ -8,7 +8,7 @@ LL |             fn clash(x: u64);
    |             ^^^^^^^^^^^^^^^^^ this signature doesn't match the previous declaration
    |
 note: the lint level is defined here
-  --> $DIR/clashing-extern-fn.rs:5:9
+  --> $DIR/clashing-extern-fn.rs:4:9
    |
 LL | #![warn(clashing_extern_declarations)]
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL | #![warn(clashing_extern_declarations)]
               found `unsafe extern "C" fn(u64)`
 
 warning: `extern_link_name` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:53:9
+  --> $DIR/clashing-extern-fn.rs:52:9
    |
 LL | /     #[link_name = "extern_link_name"]
 LL | |     fn some_new_name(x: i16);
@@ -29,7 +29,7 @@ LL |           fn extern_link_name(x: u32);
               found `unsafe extern "C" fn(u32)`
 
 warning: `some_other_extern_link_name` redeclares `some_other_new_name` with a different signature
-  --> $DIR/clashing-extern-fn.rs:56:9
+  --> $DIR/clashing-extern-fn.rs:55:9
    |
 LL |       fn some_other_new_name(x: i16);
    |       ------------------------------- `some_other_new_name` previously declared here
@@ -43,7 +43,7 @@ LL | |         fn some_other_extern_link_name(x: u32);
               found `unsafe extern "C" fn(u32)`
 
 warning: `other_both_names_different` redeclares `link_name_same` with a different signature
-  --> $DIR/clashing-extern-fn.rs:60:9
+  --> $DIR/clashing-extern-fn.rs:59:9
    |
 LL | /     #[link_name = "link_name_same"]
 LL | |     fn both_names_different(x: i16);
@@ -58,7 +58,7 @@ LL | |         fn other_both_names_different(x: u32);
               found `unsafe extern "C" fn(u32)`
 
 warning: `different_mod` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:73:9
+  --> $DIR/clashing-extern-fn.rs:72:9
    |
 LL |         fn different_mod(x: u8);
    |         ------------------------ `different_mod` previously declared here
@@ -70,7 +70,7 @@ LL |         fn different_mod(x: u64);
               found `unsafe extern "C" fn(u64)`
 
 warning: `variadic_decl` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:83:9
+  --> $DIR/clashing-extern-fn.rs:82:9
    |
 LL |     fn variadic_decl(x: u8, ...);
    |     ----------------------------- `variadic_decl` previously declared here
@@ -82,7 +82,7 @@ LL |         fn variadic_decl(x: u8);
               found `unsafe extern "C" fn(u8)`
 
 warning: `weigh_banana` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:143:13
+  --> $DIR/clashing-extern-fn.rs:142:13
    |
 LL |             fn weigh_banana(count: *const Banana) -> u64;
    |             --------------------------------------------- `weigh_banana` previously declared here
@@ -94,7 +94,7 @@ LL |             fn weigh_banana(count: *const Banana) -> u64;
               found `unsafe extern "C" fn(*const three::Banana) -> u64`
 
 warning: `draw_point` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:172:13
+  --> $DIR/clashing-extern-fn.rs:171:13
    |
 LL |             fn draw_point(p: Point);
    |             ------------------------ `draw_point` previously declared here
@@ -106,7 +106,7 @@ LL |             fn draw_point(p: Point);
               found `unsafe extern "C" fn(sameish_members::b::Point)`
 
 warning: `origin` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:198:13
+  --> $DIR/clashing-extern-fn.rs:197:13
    |
 LL |             fn origin() -> Point3;
    |             ---------------------- `origin` previously declared here
@@ -118,7 +118,7 @@ LL |             fn origin() -> Point3;
               found `unsafe extern "C" fn() -> same_sized_members_clash::b::Point3`
 
 warning: `transparent_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:221:13
+  --> $DIR/clashing-extern-fn.rs:220:13
    |
 LL |             fn transparent_incorrect() -> T;
    |             -------------------------------- `transparent_incorrect` previously declared here
@@ -130,7 +130,7 @@ LL |             fn transparent_incorrect() -> isize;
               found `unsafe extern "C" fn() -> isize`
 
 warning: `missing_return_type` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:239:13
+  --> $DIR/clashing-extern-fn.rs:238:13
    |
 LL |             fn missing_return_type() -> usize;
    |             ---------------------------------- `missing_return_type` previously declared here
@@ -142,7 +142,7 @@ LL |             fn missing_return_type();
               found `unsafe extern "C" fn()`
 
 warning: `non_zero_usize` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:257:13
+  --> $DIR/clashing-extern-fn.rs:256:13
    |
 LL |             fn non_zero_usize() -> core::num::NonZeroUsize;
    |             ----------------------------------------------- `non_zero_usize` previously declared here
@@ -154,7 +154,7 @@ LL |             fn non_zero_usize() -> usize;
               found `unsafe extern "C" fn() -> usize`
 
 warning: `non_null_ptr` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:259:13
+  --> $DIR/clashing-extern-fn.rs:258:13
    |
 LL |             fn non_null_ptr() -> core::ptr::NonNull<usize>;
    |             ----------------------------------------------- `non_null_ptr` previously declared here
@@ -166,7 +166,7 @@ LL |             fn non_null_ptr() -> *const usize;
               found `unsafe extern "C" fn() -> *const usize`
 
 warning: `option_non_zero_usize_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:357:13
+  --> $DIR/clashing-extern-fn.rs:356:13
    |
 LL |             fn option_non_zero_usize_incorrect() -> usize;
    |             ---------------------------------------------- `option_non_zero_usize_incorrect` previously declared here
@@ -178,7 +178,7 @@ LL |             fn option_non_zero_usize_incorrect() -> isize;
               found `unsafe extern "C" fn() -> isize`
 
 warning: `option_non_null_ptr_incorrect` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:359:13
+  --> $DIR/clashing-extern-fn.rs:358:13
    |
 LL |             fn option_non_null_ptr_incorrect() -> *const usize;
    |             --------------------------------------------------- `option_non_null_ptr_incorrect` previously declared here
@@ -190,7 +190,7 @@ LL |             fn option_non_null_ptr_incorrect() -> *const isize;
               found `unsafe extern "C" fn() -> *const isize`
 
 warning: `hidden_niche_transparent_no_niche` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:410:13
+  --> $DIR/clashing-extern-fn.rs:408:13
    |
 LL |             fn hidden_niche_transparent_no_niche() -> usize;
    |             ------------------------------------------------ `hidden_niche_transparent_no_niche` previously declared here
@@ -202,7 +202,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
               found `unsafe extern "C" fn() -> Option<TransparentNoNiche>`
 
 warning: `hidden_niche_unsafe_cell` redeclared with a different signature
-  --> $DIR/clashing-extern-fn.rs:414:13
+  --> $DIR/clashing-extern-fn.rs:412:13
    |
 LL |             fn hidden_niche_unsafe_cell() -> usize;
    |             --------------------------------------- `hidden_niche_unsafe_cell` previously declared here
@@ -214,7 +214,7 @@ LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize
               found `unsafe extern "C" fn() -> Option<UnsafeCell<NonZeroUsize>>`
 
 warning: `extern` block uses type `Option<TransparentNoNiche>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:410:55
+  --> $DIR/clashing-extern-fn.rs:408:55
    |
 LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoNiche>;
    |                                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
@@ -224,7 +224,7 @@ LL |             fn hidden_niche_transparent_no_niche() -> Option<TransparentNoN
    = note: enum has no representation hint
 
 warning: `extern` block uses type `Option<UnsafeCell<NonZeroUsize>>`, which is not FFI-safe
-  --> $DIR/clashing-extern-fn.rs:414:46
+  --> $DIR/clashing-extern-fn.rs:412:46
    |
 LL |             fn hidden_niche_unsafe_cell() -> Option<UnsafeCell<NonZeroUsize>>;
    |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ not FFI-safe
diff --git a/src/test/ui/parser/issues/issue-52496.stderr b/src/test/ui/parser/issues/issue-52496.stderr
index 9dbf26ef4b6..77335c64c21 100644
--- a/src/test/ui/parser/issues/issue-52496.stderr
+++ b/src/test/ui/parser/issues/issue-52496.stderr
@@ -4,12 +4,13 @@ error: float literals must have an integer part
 LL |     let _ = Foo { bar: .5, baz: 42 };
    |                        ^^ help: must have an integer part: `0.5`
 
-error: expected one of `,` or `}`, found `.`
+error: expected one of `,`, `:`, or `}`, found `.`
   --> $DIR/issue-52496.rs:8:22
    |
 LL |     let _ = Foo { bar.into(), bat: -1, . };
-   |             ---      ^ expected one of `,` or `}`
-   |             |
+   |             ---   -  ^ expected one of `,`, `:`, or `}`
+   |             |     |
+   |             |     help: try naming a field: `bar:`
    |             while parsing this struct
 
 error: expected identifier, found `.`
diff --git a/src/test/ui/parser/issues/issue-62973.stderr b/src/test/ui/parser/issues/issue-62973.stderr
index bc3358fc6ba..4737bc71860 100644
--- a/src/test/ui/parser/issues/issue-62973.stderr
+++ b/src/test/ui/parser/issues/issue-62973.stderr
@@ -20,15 +20,23 @@ LL |
 LL |
    |  ^
 
-error: expected one of `,` or `}`, found `{`
+error: expected one of `,`, `:`, or `}`, found `{`
   --> $DIR/issue-62973.rs:6:8
    |
 LL | fn p() { match s { v, E { [) {) }
-   |        ^       -       -^ expected one of `,` or `}`
-   |        |       |       |
-   |        |       |       help: `}` may belong here
+   |        ^       -        ^ expected one of `,`, `:`, or `}`
+   |        |       |
    |        |       while parsing this struct
    |        unclosed delimiter
+   |
+help: `}` may belong here
+   |
+LL | fn p() { match s { v, E} { [) {) }
+   |                        +
+help: try naming a field
+   |
+LL | fn p() { match s { v, E: E { [) {) }
+   |                       ++
 
 error: struct literals are not allowed here
   --> $DIR/issue-62973.rs:6:16
diff --git a/src/test/ui/parser/removed-syntax-with-2.rs b/src/test/ui/parser/removed-syntax-with-2.rs
index 8a489e71990..451057c66a1 100644
--- a/src/test/ui/parser/removed-syntax-with-2.rs
+++ b/src/test/ui/parser/removed-syntax-with-2.rs
@@ -6,6 +6,6 @@ fn main() {
 
     let a = S { foo: (), bar: () };
     let b = S { foo: (), with a };
-    //~^ ERROR expected one of `,` or `}`, found `a`
+    //~^ ERROR expected one of `,`, `:`, or `}`, found `a`
     //~| ERROR missing field `bar` in initializer of `S`
 }
diff --git a/src/test/ui/parser/removed-syntax-with-2.stderr b/src/test/ui/parser/removed-syntax-with-2.stderr
index 2c96dceb587..c6ae1ce674f 100644
--- a/src/test/ui/parser/removed-syntax-with-2.stderr
+++ b/src/test/ui/parser/removed-syntax-with-2.stderr
@@ -1,8 +1,8 @@
-error: expected one of `,` or `}`, found `a`
+error: expected one of `,`, `:`, or `}`, found `a`
   --> $DIR/removed-syntax-with-2.rs:8:31
    |
 LL |     let b = S { foo: (), with a };
-   |             -                 ^ expected one of `,` or `}`
+   |             -                 ^ expected one of `,`, `:`, or `}`
    |             |
    |             while parsing this struct
 
diff --git a/src/test/ui/repr/feature-gate-no-niche.rs b/src/test/ui/repr/feature-gate-no-niche.rs
deleted file mode 100644
index 8872ee7119e..00000000000
--- a/src/test/ui/repr/feature-gate-no-niche.rs
+++ /dev/null
@@ -1,20 +0,0 @@
-use std::num::NonZeroU8 as N8;
-use std::num::NonZeroU16 as N16;
-
-#[repr(no_niche)]
-pub struct Cloaked(N16);
-//~^^ ERROR the attribute `repr(no_niche)` is currently unstable [E0658]
-
-#[repr(transparent, no_niche)]
-pub struct Shadowy(N16);
-//~^^ ERROR the attribute `repr(no_niche)` is currently unstable [E0658]
-
-#[repr(no_niche)]
-pub enum Cloaked1 { _A(N16), }
-//~^^ ERROR the attribute `repr(no_niche)` is currently unstable [E0658]
-
-#[repr(no_niche)]
-pub enum Cloaked2 { _A(N16), _B(u8, N8) }
-//~^^ ERROR the attribute `repr(no_niche)` is currently unstable [E0658]
-
-fn main() { }
diff --git a/src/test/ui/repr/feature-gate-no-niche.stderr b/src/test/ui/repr/feature-gate-no-niche.stderr
deleted file mode 100644
index 34fd417cc99..00000000000
--- a/src/test/ui/repr/feature-gate-no-niche.stderr
+++ /dev/null
@@ -1,35 +0,0 @@
-error[E0658]: the attribute `repr(no_niche)` is currently unstable
-  --> $DIR/feature-gate-no-niche.rs:4:8
-   |
-LL | #[repr(no_niche)]
-   |        ^^^^^^^^
-   |
-   = help: add `#![feature(no_niche)]` to the crate attributes to enable
-
-error[E0658]: the attribute `repr(no_niche)` is currently unstable
-  --> $DIR/feature-gate-no-niche.rs:8:21
-   |
-LL | #[repr(transparent, no_niche)]
-   |                     ^^^^^^^^
-   |
-   = help: add `#![feature(no_niche)]` to the crate attributes to enable
-
-error[E0658]: the attribute `repr(no_niche)` is currently unstable
-  --> $DIR/feature-gate-no-niche.rs:12:8
-   |
-LL | #[repr(no_niche)]
-   |        ^^^^^^^^
-   |
-   = help: add `#![feature(no_niche)]` to the crate attributes to enable
-
-error[E0658]: the attribute `repr(no_niche)` is currently unstable
-  --> $DIR/feature-gate-no-niche.rs:16:8
-   |
-LL | #[repr(no_niche)]
-   |        ^^^^^^^^
-   |
-   = help: add `#![feature(no_niche)]` to the crate attributes to enable
-
-error: aborting due to 4 previous errors
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/src/test/ui/repr/repr-no-niche-inapplicable-to-unions.rs b/src/test/ui/repr/repr-no-niche-inapplicable-to-unions.rs
deleted file mode 100644
index 870eda89c20..00000000000
--- a/src/test/ui/repr/repr-no-niche-inapplicable-to-unions.rs
+++ /dev/null
@@ -1,14 +0,0 @@
-#![feature(no_niche)]
-
-use std::num::NonZeroU8 as N8;
-use std::num::NonZeroU16 as N16;
-
-#[repr(no_niche)]
-pub union Cloaked1 { _A: N16 }
-//~^^ ERROR attribute should be applied to a struct or enum [E0517]
-
-#[repr(no_niche)]
-pub union Cloaked2 { _A: N16, _B: (u8, N8) }
-//~^^ ERROR attribute should be applied to a struct or enum [E0517]
-
-fn main() { }
diff --git a/src/test/ui/repr/repr-no-niche-inapplicable-to-unions.stderr b/src/test/ui/repr/repr-no-niche-inapplicable-to-unions.stderr
deleted file mode 100644
index 9af929d4094..00000000000
--- a/src/test/ui/repr/repr-no-niche-inapplicable-to-unions.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0517]: attribute should be applied to a struct or enum
-  --> $DIR/repr-no-niche-inapplicable-to-unions.rs:6:8
-   |
-LL | #[repr(no_niche)]
-   |        ^^^^^^^^
-LL | pub union Cloaked1 { _A: N16 }
-   | ------------------------------ not a struct or enum
-
-error[E0517]: attribute should be applied to a struct or enum
-  --> $DIR/repr-no-niche-inapplicable-to-unions.rs:10:8
-   |
-LL | #[repr(no_niche)]
-   |        ^^^^^^^^
-LL | pub union Cloaked2 { _A: N16, _B: (u8, N8) }
-   | -------------------------------------------- not a struct or enum
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0517`.
diff --git a/src/test/ui/repr/repr-no-niche.rs b/src/test/ui/repr/repr-no-niche.rs
deleted file mode 100644
index 2e6064aeb00..00000000000
--- a/src/test/ui/repr/repr-no-niche.rs
+++ /dev/null
@@ -1,327 +0,0 @@
-// run-pass
-
-// This file tests repr(no_niche), which causes an struct/enum to hide
-// any niche space that may exist in its internal state from the
-// context it appears in.
-
-// Here are the axes this test is seeking to cover:
-//
-// repr annotation:
-// visible: (); cloaked: (no_niche); transparent: (transparent); shadowy: (transparent, no_niche)
-//
-// enum vs struct
-//
-// niche-type via type-parameter vs inline declaration
-
-#![feature(decl_macro)]
-#![feature(no_niche)]
-
-use std::mem::size_of;
-use std::num::{NonZeroU8, NonZeroU16};
-
-mod struct_inline {
-    use std::num::NonZeroU16 as N16;
-
-    #[derive(Debug)] pub struct Visible(N16);
-
-    #[repr(no_niche)]
-    #[derive(Debug)] pub struct Cloaked(N16);
-
-    #[repr(transparent)]
-    #[derive(Debug)] pub struct Transparent(N16);
-
-    #[repr(transparent, no_niche)]
-    #[derive(Debug)] pub struct Shadowy(N16);
-}
-
-mod struct_param {
-    #[derive(Debug)] pub struct Visible<T>(T);
-
-    #[repr(no_niche)]
-    #[derive(Debug)] pub struct Cloaked<T>(T);
-
-    #[repr(transparent)]
-    #[derive(Debug)] pub struct Transparent<T>(T);
-
-    #[repr(transparent, no_niche)]
-    #[derive(Debug)] pub struct Shadowy<T>(T);
-}
-
-mod enum_inline {
-    use crate::two_fifty_six_variant_enum;
-    use std::num::{NonZeroU8 as N8, NonZeroU16 as N16};
-
-    #[derive(Debug)] pub enum Visible1 { _A(N16), }
-
-    #[repr(no_niche)]
-    #[derive(Debug)] pub enum Cloaked1 { _A(N16), }
-
-    // (N.B.: transparent enums must be univariant)
-    #[repr(transparent)]
-    #[derive(Debug)] pub enum Transparent { _A(N16), }
-
-    #[repr(transparent, no_niche)]
-    #[derive(Debug)] pub enum Shadowy { _A(N16), }
-
-    // including multivariant enums for completeness. Payload and
-    // number of variants (i.e. discriminant size) have been chosen so
-    // that layout including discriminant is 4 bytes, with no space in
-    // padding to hide another discrimnant from the surrounding
-    // context.
-    //
-    // (Note that multivariant enums cannot usefully expose a niche in
-    // general; this test is relying on that.)
-    two_fifty_six_variant_enum!(Visible2, N8);
-
-    two_fifty_six_variant_enum!(#[repr(no_niche)] Cloaked2, N8);
-}
-
-mod enum_param {
-    use super::two_fifty_six_variant_enum;
-
-    #[derive(Debug)] pub enum Visible1<T> { _A(T), }
-
-    #[repr(no_niche)]
-    #[derive(Debug)] pub enum Cloaked1<T> { _A(T), }
-
-    // (N.B.: transparent enums must be univariant)
-    #[repr(transparent)]
-    #[derive(Debug)] pub enum Transparent<T> { _A(T), }
-
-    #[repr(transparent, no_niche)]
-    #[derive(Debug)] pub enum Shadowy<T> { _A(T), }
-
-    // including multivariant enums for completeness. Same notes apply
-    // here as above (assuming `T` is instantiated with `NonZeroU8`).
-    two_fifty_six_variant_enum!(Visible2<T>);
-
-    two_fifty_six_variant_enum!(#[repr(no_niche)] Cloaked2<T>);
-}
-
-fn main() {
-    // sanity-checks
-    assert_eq!(size_of::<struct_inline::Visible>(),               2);
-    assert_eq!(size_of::<struct_inline::Cloaked>(),               2);
-    assert_eq!(size_of::<struct_inline::Transparent>(),           2);
-    assert_eq!(size_of::<struct_inline::Shadowy>(),               2);
-
-    assert_eq!(size_of::<struct_param::Visible<NonZeroU16>>(), 2);
-    assert_eq!(size_of::<struct_param::Cloaked<NonZeroU16>>(), 2);
-    assert_eq!(size_of::<struct_param::Transparent<NonZeroU16>>(), 2);
-    assert_eq!(size_of::<struct_param::Shadowy<NonZeroU16>>(), 2);
-
-    assert_eq!(size_of::<enum_inline::Visible1>(),    2);
-    assert_eq!(size_of::<enum_inline::Cloaked1>(),    2);
-    assert_eq!(size_of::<enum_inline::Transparent>(), 2); // transparent enums are univariant
-    assert_eq!(size_of::<enum_inline::Shadowy>(),     2);
-    assert_eq!(size_of::<enum_inline::Visible2>(),    4);
-    assert_eq!(size_of::<enum_inline::Cloaked2>(),    4);
-
-    assert_eq!(size_of::<enum_param::Visible1<NonZeroU16>>(),    2);
-    assert_eq!(size_of::<enum_param::Cloaked1<NonZeroU16>>(),    2);
-    assert_eq!(size_of::<enum_param::Transparent<NonZeroU16>>(), 2);
-    assert_eq!(size_of::<enum_param::Shadowy<NonZeroU16>>(),     2);
-    assert_eq!(size_of::<enum_param::Visible2<NonZeroU8>>(),     4);
-    assert_eq!(size_of::<enum_param::Cloaked2<NonZeroU8>>(),     4);
-
-    // now the actual tests of no_niche: how do inputs above compose
-    // with `Option` type constructor. The cases with a `_+2` are the
-    // ones where no_niche fires.
-    assert_eq!(size_of::<Option<struct_inline::Visible>>(),       2);
-    assert_eq!(size_of::<Option<struct_inline::Cloaked>>(),       2+2);
-    assert_eq!(size_of::<Option<struct_inline::Transparent>>(),   2);
-    assert_eq!(size_of::<Option<struct_inline::Shadowy>>(),       2+2);
-
-    assert_eq!(size_of::<Option<struct_param::Visible<NonZeroU16>>>(),     2);
-    assert_eq!(size_of::<Option<struct_param::Cloaked<NonZeroU16>>>(),     2+2);
-    assert_eq!(size_of::<Option<struct_param::Transparent<NonZeroU16>>>(), 2);
-    assert_eq!(size_of::<Option<struct_param::Shadowy<NonZeroU16>>>(),     2+2);
-
-    assert_eq!(size_of::<Option<enum_inline::Visible1>>(),    2);
-    assert_eq!(size_of::<Option<enum_inline::Cloaked1>>(),    2+2);
-    assert_eq!(size_of::<Option<enum_inline::Transparent>>(), 2);
-    assert_eq!(size_of::<Option<enum_inline::Shadowy>>(),     2+2);
-    // cannot use niche of multivariant payload
-    assert_eq!(size_of::<Option<enum_inline::Visible2>>(),    4+2);
-    assert_eq!(size_of::<Option<enum_inline::Cloaked2>>(),    4+2);
-
-    assert_eq!(size_of::<Option<enum_param::Visible1<NonZeroU16>>>(),    2);
-    assert_eq!(size_of::<Option<enum_param::Cloaked1<NonZeroU16>>>(),    2+2);
-    assert_eq!(size_of::<Option<enum_param::Transparent<NonZeroU16>>>(), 2);
-    assert_eq!(size_of::<Option<enum_param::Shadowy<NonZeroU16>>>(),     2+2);
-    // cannot use niche of multivariant payload
-    assert_eq!(size_of::<Option<enum_param::Visible2<NonZeroU8>>>(),    4+2);
-    assert_eq!(size_of::<Option<enum_param::Cloaked2<NonZeroU8>>>(),    4+2);
-}
-
-macro two_fifty_six_variant_enum {
-    ($(#[$attr:meta])* $name:ident<$param:ident>) => {
-        #[derive(Debug)] $(#[$attr])*
-        pub enum $name<$param> {
-            _V00($param, u16), _V01(u16, $param), _V02($param, u16), _V03(u16, $param),
-            _V04($param, u16), _V05(u16, $param), _V06($param, u16), _V07(u16, $param),
-            _V08($param, u16), _V09(u16, $param), _V0a($param, u16), _V0b(u16, $param),
-            _V0c($param, u16), _V0d(u16, $param), _V0e($param, u16), _V0f(u16, $param),
-
-            _V10($param, u16), _V11(u16, $param), _V12($param, u16), _V13(u16, $param),
-            _V14($param, u16), _V15(u16, $param), _V16($param, u16), _V17(u16, $param),
-            _V18($param, u16), _V19(u16, $param), _V1a($param, u16), _V1b(u16, $param),
-            _V1c($param, u16), _V1d(u16, $param), _V1e($param, u16), _V1f(u16, $param),
-
-            _V20($param, u16), _V21(u16, $param), _V22($param, u16), _V23(u16, $param),
-            _V24($param, u16), _V25(u16, $param), _V26($param, u16), _V27(u16, $param),
-            _V28($param, u16), _V29(u16, $param), _V2a($param, u16), _V2b(u16, $param),
-            _V2c($param, u16), _V2d(u16, $param), _V2e($param, u16), _V2f(u16, $param),
-
-            _V30($param, u16), _V31(u16, $param), _V32($param, u16), _V33(u16, $param),
-            _V34($param, u16), _V35(u16, $param), _V36($param, u16), _V37(u16, $param),
-            _V38($param, u16), _V39(u16, $param), _V3a($param, u16), _V3b(u16, $param),
-            _V3c($param, u16), _V3d(u16, $param), _V3e($param, u16), _V3f(u16, $param),
-
-            _V40($param, u16), _V41(u16, $param), _V42($param, u16), _V43(u16, $param),
-            _V44($param, u16), _V45(u16, $param), _V46($param, u16), _V47(u16, $param),
-            _V48($param, u16), _V49(u16, $param), _V4a($param, u16), _V4b(u16, $param),
-            _V4c($param, u16), _V4d(u16, $param), _V4e($param, u16), _V4f(u16, $param),
-
-            _V50($param, u16), _V51(u16, $param), _V52($param, u16), _V53(u16, $param),
-            _V54($param, u16), _V55(u16, $param), _V56($param, u16), _V57(u16, $param),
-            _V58($param, u16), _V59(u16, $param), _V5a($param, u16), _V5b(u16, $param),
-            _V5c($param, u16), _V5d(u16, $param), _V5e($param, u16), _V5f(u16, $param),
-
-            _V60($param, u16), _V61(u16, $param), _V62($param, u16), _V63(u16, $param),
-            _V64($param, u16), _V65(u16, $param), _V66($param, u16), _V67(u16, $param),
-            _V68($param, u16), _V69(u16, $param), _V6a($param, u16), _V6b(u16, $param),
-            _V6c($param, u16), _V6d(u16, $param), _V6e($param, u16), _V6f(u16, $param),
-
-            _V70($param, u16), _V71(u16, $param), _V72($param, u16), _V73(u16, $param),
-            _V74($param, u16), _V75(u16, $param), _V76($param, u16), _V77(u16, $param),
-            _V78($param, u16), _V79(u16, $param), _V7a($param, u16), _V7b(u16, $param),
-            _V7c($param, u16), _V7d(u16, $param), _V7e($param, u16), _V7f(u16, $param),
-
-            _V80($param, u16), _V81(u16, $param), _V82($param, u16), _V83(u16, $param),
-            _V84($param, u16), _V85(u16, $param), _V86($param, u16), _V87(u16, $param),
-            _V88($param, u16), _V89(u16, $param), _V8a($param, u16), _V8b(u16, $param),
-            _V8c($param, u16), _V8d(u16, $param), _V8e($param, u16), _V8f(u16, $param),
-
-            _V90($param, u16), _V91(u16, $param), _V92($param, u16), _V93(u16, $param),
-            _V94($param, u16), _V95(u16, $param), _V96($param, u16), _V97(u16, $param),
-            _V98($param, u16), _V99(u16, $param), _V9a($param, u16), _V9b(u16, $param),
-            _V9c($param, u16), _V9d(u16, $param), _V9e($param, u16), _V9f(u16, $param),
-
-            _Va0($param, u16), _Va1(u16, $param), _Va2($param, u16), _Va3(u16, $param),
-            _Va4($param, u16), _Va5(u16, $param), _Va6($param, u16), _Va7(u16, $param),
-            _Va8($param, u16), _Va9(u16, $param), _Vaa($param, u16), _Vab(u16, $param),
-            _Vac($param, u16), _Vad(u16, $param), _Vae($param, u16), _Vaf(u16, $param),
-
-            _Vb0($param, u16), _Vb1(u16, $param), _Vb2($param, u16), _Vb3(u16, $param),
-            _Vb4($param, u16), _Vb5(u16, $param), _Vb6($param, u16), _Vb7(u16, $param),
-            _Vb8($param, u16), _Vb9(u16, $param), _Vba($param, u16), _Vbb(u16, $param),
-            _Vbc($param, u16), _Vbd(u16, $param), _Vbe($param, u16), _Vbf(u16, $param),
-
-            _Vc0($param, u16), _Vc1(u16, $param), _Vc2($param, u16), _Vc3(u16, $param),
-            _Vc4($param, u16), _Vc5(u16, $param), _Vc6($param, u16), _Vc7(u16, $param),
-            _Vc8($param, u16), _Vc9(u16, $param), _Vca($param, u16), _Vcb(u16, $param),
-            _Vcc($param, u16), _Vcd(u16, $param), _Vce($param, u16), _Vcf(u16, $param),
-
-            _Vd0($param, u16), _Vd1(u16, $param), _Vd2($param, u16), _Vd3(u16, $param),
-            _Vd4($param, u16), _Vd5(u16, $param), _Vd6($param, u16), _Vd7(u16, $param),
-            _Vd8($param, u16), _Vd9(u16, $param), _Vda($param, u16), _Vdb(u16, $param),
-            _Vdc($param, u16), _Vdd(u16, $param), _Vde($param, u16), _Vdf(u16, $param),
-
-            _Ve0($param, u16), _Ve1(u16, $param), _Ve2($param, u16), _Ve3(u16, $param),
-            _Ve4($param, u16), _Ve5(u16, $param), _Ve6($param, u16), _Ve7(u16, $param),
-            _Ve8($param, u16), _Ve9(u16, $param), _Vea($param, u16), _Veb(u16, $param),
-            _Vec($param, u16), _Ved(u16, $param), _Vee($param, u16), _Vef(u16, $param),
-
-            _Vf0($param, u16), _Vf1(u16, $param), _Vf2($param, u16), _Vf3(u16, $param),
-            _Vf4($param, u16), _Vf5(u16, $param), _Vf6($param, u16), _Vf7(u16, $param),
-            _Vf8($param, u16), _Vf9(u16, $param), _Vfa($param, u16), _Vfb(u16, $param),
-            _Vfc($param, u16), _Vfd(u16, $param), _Vfe($param, u16), _Vff(u16, $param),
-        }
-    },
-
-    ($(#[$attr:meta])* $name:ident, $param:ty) => {
-        #[derive(Debug)] $(#[$attr])*
-        pub enum $name {
-            _V00($param, u16), _V01(u16, $param), _V02($param, u16), _V03(u16, $param),
-            _V04($param, u16), _V05(u16, $param), _V06($param, u16), _V07(u16, $param),
-            _V08($param, u16), _V09(u16, $param), _V0a($param, u16), _V0b(u16, $param),
-            _V0c($param, u16), _V0d(u16, $param), _V0e($param, u16), _V0f(u16, $param),
-
-            _V10($param, u16), _V11(u16, $param), _V12($param, u16), _V13(u16, $param),
-            _V14($param, u16), _V15(u16, $param), _V16($param, u16), _V17(u16, $param),
-            _V18($param, u16), _V19(u16, $param), _V1a($param, u16), _V1b(u16, $param),
-            _V1c($param, u16), _V1d(u16, $param), _V1e($param, u16), _V1f(u16, $param),
-
-            _V20($param, u16), _V21(u16, $param), _V22($param, u16), _V23(u16, $param),
-            _V24($param, u16), _V25(u16, $param), _V26($param, u16), _V27(u16, $param),
-            _V28($param, u16), _V29(u16, $param), _V2a($param, u16), _V2b(u16, $param),
-            _V2c($param, u16), _V2d(u16, $param), _V2e($param, u16), _V2f(u16, $param),
-
-            _V30($param, u16), _V31(u16, $param), _V32($param, u16), _V33(u16, $param),
-            _V34($param, u16), _V35(u16, $param), _V36($param, u16), _V37(u16, $param),
-            _V38($param, u16), _V39(u16, $param), _V3a($param, u16), _V3b(u16, $param),
-            _V3c($param, u16), _V3d(u16, $param), _V3e($param, u16), _V3f(u16, $param),
-
-            _V40($param, u16), _V41(u16, $param), _V42($param, u16), _V43(u16, $param),
-            _V44($param, u16), _V45(u16, $param), _V46($param, u16), _V47(u16, $param),
-            _V48($param, u16), _V49(u16, $param), _V4a($param, u16), _V4b(u16, $param),
-            _V4c($param, u16), _V4d(u16, $param), _V4e($param, u16), _V4f(u16, $param),
-
-            _V50($param, u16), _V51(u16, $param), _V52($param, u16), _V53(u16, $param),
-            _V54($param, u16), _V55(u16, $param), _V56($param, u16), _V57(u16, $param),
-            _V58($param, u16), _V59(u16, $param), _V5a($param, u16), _V5b(u16, $param),
-            _V5c($param, u16), _V5d(u16, $param), _V5e($param, u16), _V5f(u16, $param),
-
-            _V60($param, u16), _V61(u16, $param), _V62($param, u16), _V63(u16, $param),
-            _V64($param, u16), _V65(u16, $param), _V66($param, u16), _V67(u16, $param),
-            _V68($param, u16), _V69(u16, $param), _V6a($param, u16), _V6b(u16, $param),
-            _V6c($param, u16), _V6d(u16, $param), _V6e($param, u16), _V6f(u16, $param),
-
-            _V70($param, u16), _V71(u16, $param), _V72($param, u16), _V73(u16, $param),
-            _V74($param, u16), _V75(u16, $param), _V76($param, u16), _V77(u16, $param),
-            _V78($param, u16), _V79(u16, $param), _V7a($param, u16), _V7b(u16, $param),
-            _V7c($param, u16), _V7d(u16, $param), _V7e($param, u16), _V7f(u16, $param),
-
-            _V80($param, u16), _V81(u16, $param), _V82($param, u16), _V83(u16, $param),
-            _V84($param, u16), _V85(u16, $param), _V86($param, u16), _V87(u16, $param),
-            _V88($param, u16), _V89(u16, $param), _V8a($param, u16), _V8b(u16, $param),
-            _V8c($param, u16), _V8d(u16, $param), _V8e($param, u16), _V8f(u16, $param),
-
-            _V90($param, u16), _V91(u16, $param), _V92($param, u16), _V93(u16, $param),
-            _V94($param, u16), _V95(u16, $param), _V96($param, u16), _V97(u16, $param),
-            _V98($param, u16), _V99(u16, $param), _V9a($param, u16), _V9b(u16, $param),
-            _V9c($param, u16), _V9d(u16, $param), _V9e($param, u16), _V9f(u16, $param),
-
-            _Va0($param, u16), _Va1(u16, $param), _Va2($param, u16), _Va3(u16, $param),
-            _Va4($param, u16), _Va5(u16, $param), _Va6($param, u16), _Va7(u16, $param),
-            _Va8($param, u16), _Va9(u16, $param), _Vaa($param, u16), _Vab(u16, $param),
-            _Vac($param, u16), _Vad(u16, $param), _Vae($param, u16), _Vaf(u16, $param),
-
-            _Vb0($param, u16), _Vb1(u16, $param), _Vb2($param, u16), _Vb3(u16, $param),
-            _Vb4($param, u16), _Vb5(u16, $param), _Vb6($param, u16), _Vb7(u16, $param),
-            _Vb8($param, u16), _Vb9(u16, $param), _Vba($param, u16), _Vbb(u16, $param),
-            _Vbc($param, u16), _Vbd(u16, $param), _Vbe($param, u16), _Vbf(u16, $param),
-
-            _Vc0($param, u16), _Vc1(u16, $param), _Vc2($param, u16), _Vc3(u16, $param),
-            _Vc4($param, u16), _Vc5(u16, $param), _Vc6($param, u16), _Vc7(u16, $param),
-            _Vc8($param, u16), _Vc9(u16, $param), _Vca($param, u16), _Vcb(u16, $param),
-            _Vcc($param, u16), _Vcd(u16, $param), _Vce($param, u16), _Vcf(u16, $param),
-
-            _Vd0($param, u16), _Vd1(u16, $param), _Vd2($param, u16), _Vd3(u16, $param),
-            _Vd4($param, u16), _Vd5(u16, $param), _Vd6($param, u16), _Vd7(u16, $param),
-            _Vd8($param, u16), _Vd9(u16, $param), _Vda($param, u16), _Vdb(u16, $param),
-            _Vdc($param, u16), _Vdd(u16, $param), _Vde($param, u16), _Vdf(u16, $param),
-
-            _Ve0($param, u16), _Ve1(u16, $param), _Ve2($param, u16), _Ve3(u16, $param),
-            _Ve4($param, u16), _Ve5(u16, $param), _Ve6($param, u16), _Ve7(u16, $param),
-            _Ve8($param, u16), _Ve9(u16, $param), _Vea($param, u16), _Veb(u16, $param),
-            _Vec($param, u16), _Ved(u16, $param), _Vee($param, u16), _Vef(u16, $param),
-
-            _Vf0($param, u16), _Vf1(u16, $param), _Vf2($param, u16), _Vf3(u16, $param),
-            _Vf4($param, u16), _Vf5(u16, $param), _Vf6($param, u16), _Vf7(u16, $param),
-            _Vf8($param, u16), _Vf9(u16, $param), _Vfa($param, u16), _Vfb(u16, $param),
-            _Vfc($param, u16), _Vfd(u16, $param), _Vfe($param, u16), _Vff(u16, $param),
-        }
-    }
-}
diff --git a/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs b/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs
index 45af6be2653..ca617859db4 100644
--- a/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/while_let_loop.rs
@@ -11,7 +11,7 @@ use rustc_lint::LateContext;
 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, loop_block: &'tcx Block<'_>) {
     let (init, has_trailing_exprs) = match (loop_block.stmts, loop_block.expr) {
         ([stmt, stmts @ ..], expr) => {
-            if let StmtKind::Local(&Local { init: Some(e), .. }) | StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind {
+            if let StmtKind::Local(&Local { init: Some(e), els: None, .. }) | StmtKind::Semi(e) | StmtKind::Expr(e) = stmt.kind {
                 (e, !stmts.is_empty() || expr.is_some())
             } else {
                 return;
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index b2a873ef582..3077b999f4e 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -1041,7 +1041,8 @@ impl<'tcx> LateLintPass<'tcx> for Matches {
     }
 
     fn check_local(&mut self, cx: &LateContext<'tcx>, local: &'tcx Local<'_>) {
-        self.infallible_destructuring_match_linted |= infallible_destructuring_match::check(cx, local);
+        self.infallible_destructuring_match_linted |=
+            local.els.is_none() && infallible_destructuring_match::check(cx, local);
     }
 
     fn check_pat(&mut self, cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>) {
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 6598413c77e..819646bb678 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -92,6 +92,7 @@ fn check_no_effect(cx: &LateContext<'_>, stmt: &Stmt<'_>) -> bool {
         if_chain! {
             if !is_lint_allowed(cx, NO_EFFECT_UNDERSCORE_BINDING, local.hir_id);
             if let Some(init) = local.init;
+            if local.els.is_none();
             if !local.pat.span.from_expansion();
             if has_no_effect(cx, init);
             if let PatKind::Binding(_, _, ident, _) = local.pat.kind;
diff --git a/src/tools/clippy/clippy_lints/src/non_copy_const.rs b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
index a1ef32ae608..6bce5fbd4c1 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -148,7 +148,7 @@ fn is_value_unfrozen_raw<'tcx>(
         match val.ty().kind() {
             // the fact that we have to dig into every structs to search enums
             // leads us to the point checking `UnsafeCell` directly is the only option.
-            ty::Adt(ty_def, ..) if Some(ty_def.did()) == cx.tcx.lang_items().unsafe_cell_type() => true,
+            ty::Adt(ty_def, ..) if ty_def.is_unsafe_cell() => true,
             ty::Array(..) | ty::Adt(..) | ty::Tuple(..) => {
                 let val = cx.tcx.destructure_mir_constant(cx.param_env, val);
                 val.fields.iter().any(|field| inner(cx, *field))
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 5ae04947b82..1d9a2abf706 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -10,7 +10,6 @@ use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty::subst::GenericArgKind;
 use rustc_session::{declare_lint_pass, declare_tool_lint};
-use rustc_span::hygiene::DesugaringKind;
 use rustc_span::source_map::Span;
 use rustc_span::sym;
 
@@ -203,9 +202,7 @@ fn check_final_expr<'tcx>(
                 check_block_return(cx, ifblock);
             }
             if let Some(else_clause) = else_clause_opt {
-                if expr.span.desugaring_kind() != Some(DesugaringKind::LetElse) {
-                    check_final_expr(cx, else_clause, None, RetReplacement::Empty);
-                }
+                check_final_expr(cx, else_clause, None, RetReplacement::Empty);
             }
         },
         // a match expr, check all arms
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 793e3cc58c2..942f14ddd3d 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -102,7 +102,7 @@ pub struct HirEqInterExpr<'a, 'b, 'tcx> {
 impl HirEqInterExpr<'_, '_, '_> {
     pub fn eq_stmt(&mut self, left: &Stmt<'_>, right: &Stmt<'_>) -> bool {
         match (&left.kind, &right.kind) {
-            (&StmtKind::Local(l), &StmtKind::Local(r)) => {
+            (&StmtKind::Local(l, ), &StmtKind::Local(r, )) => {
                 // This additional check ensures that the type of the locals are equivalent even if the init
                 // expression or type have some inferred parts.
                 if let Some((typeck_lhs, typeck_rhs)) = self.inner.maybe_typeck_results {
@@ -117,6 +117,7 @@ impl HirEqInterExpr<'_, '_, '_> {
                 // these only get added if the init and type is equal.
                 both(&l.init, &r.init, |l, r| self.eq_expr(l, r))
                     && both(&l.ty, &r.ty, |l, r| self.eq_ty(l, r))
+                    && both(&l.els, &r.els, |l, r| self.eq_block(l, r))
                     && self.eq_pat(l.pat, r.pat)
             },
             (&StmtKind::Expr(l), &StmtKind::Expr(r)) | (&StmtKind::Semi(l), &StmtKind::Semi(r)) => self.eq_expr(l, r),
@@ -921,11 +922,14 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
         std::mem::discriminant(&b.kind).hash(&mut self.s);
 
         match &b.kind {
-            StmtKind::Local(local) => {
+            StmtKind::Local(local, ) => {
                 self.hash_pat(local.pat);
                 if let Some(init) = local.init {
                     self.hash_expr(init);
                 }
+                if let Some(els) = local.els {
+                    self.hash_block(els);
+                }
             },
             StmtKind::Item(..) => {},
             StmtKind::Expr(expr) | StmtKind::Semi(expr) => {