about summary refs log tree commit diff
path: root/src/tools/clippy/tests
diff options
context:
space:
mode:
authorflip1995 <philipp.krones@embecosm.com>2022-04-07 18:39:59 +0100
committerflip1995 <philipp.krones@embecosm.com>2022-04-08 10:06:10 +0100
commit515e2a2cda88e0213ab24dc97e75794eac42ebfe (patch)
tree1aa1645cba6c9a9bbd014f03f1d0e60552074cc8 /src/tools/clippy/tests
parentfa723160318fac5f3fa6f4141cfc41c0606a3008 (diff)
parent984330a6ee3c4d15626685d6dc8b7b759ff630bd (diff)
downloadrust-515e2a2cda88e0213ab24dc97e75794eac42ebfe.tar.gz
rust-515e2a2cda88e0213ab24dc97e75794eac42ebfe.zip
Merge commit '984330a6ee3c4d15626685d6dc8b7b759ff630bd' into clippyup
Diffstat (limited to 'src/tools/clippy/tests')
-rw-r--r--src/tools/clippy/tests/check-fmt.rs (renamed from src/tools/clippy/tests/fmt.rs)0
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr8
-rw-r--r--src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr4
-rw-r--r--src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr5
-rw-r--r--src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs2
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs18
-rw-r--r--src/tools/clippy/tests/ui/bytes_nth.stderr6
-rw-r--r--src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast.rs2
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed8
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs8
-rw-r--r--src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr10
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.rs14
-rw-r--r--src/tools/clippy/tests/ui/cast_alignment.stderr8
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-2774.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6179.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-6792.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-7868.stderr6
-rw-r--r--src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs2
-rw-r--r--src/tools/clippy/tests/ui/crashes/regressions.rs2
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.fixed56
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.rs56
-rw-r--r--src/tools/clippy/tests/ui/crate_in_macro_def.stderr10
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed2
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs2
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed2
-rw-r--r--src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs2
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.rs2
-rw-r--r--src/tools/clippy/tests/ui/drop_forget_copy.stderr12
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.rs40
-rw-r--r--src/tools/clippy/tests/ui/drop_non_drop.stderr27
-rw-r--r--src/tools/clippy/tests/ui/drop_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed25
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.rs25
-rw-r--r--src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr19
-rw-r--r--src/tools/clippy/tests/ui/err_expect.fixed14
-rw-r--r--src/tools/clippy/tests/ui/err_expect.rs14
-rw-r--r--src/tools/clippy/tests/ui/err_expect.stderr10
-rw-r--r--src/tools/clippy/tests/ui/fn_params_excessive_bools.rs2
-rw-r--r--src/tools/clippy/tests/ui/forget_non_drop.rs27
-rw-r--r--src/tools/clippy/tests/ui/forget_non_drop.stderr27
-rw-r--r--src/tools/clippy/tests/ui/forget_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/identity_op.rs9
-rw-r--r--src/tools/clippy/tests/ui/identity_op.stderr32
-rw-r--r--src/tools/clippy/tests/ui/implicit_clone.rs4
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.rs24
-rw-r--r--src/tools/clippy/tests/ui/indexing_slicing_index.stderr27
-rw-r--r--src/tools/clippy/tests/ui/iter_nth_zero.fixed2
-rw-r--r--src/tools/clippy/tests/ui/iter_nth_zero.rs2
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.fixed6
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.rs6
-rw-r--r--src/tools/clippy/tests/ui/iter_overeager_cloned.stderr14
-rw-r--r--src/tools/clippy/tests/ui/large_types_passed_by_value.rs2
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.rs2
-rw-r--r--src/tools/clippy/tests/ui/let_underscore_must_use.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_async_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_identity.fixed2
-rw-r--r--src/tools/clippy/tests/ui/map_identity.rs2
-rw-r--r--src/tools/clippy/tests/ui/map_identity.stderr8
-rw-r--r--src/tools/clippy/tests/ui/map_unit_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.rs14
-rw-r--r--src/tools/clippy/tests/ui/min_rust_version_attr.stderr8
-rw-r--r--src/tools/clippy/tests/ui/missing_inline.rs6
-rw-r--r--src/tools/clippy/tests/ui/module_name_repetitions.rs2
-rw-r--r--src/tools/clippy/tests/ui/module_name_repetitions.stderr4
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs7
-rw-r--r--src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr34
-rw-r--r--src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs4
-rw-r--r--src/tools/clippy/tests/ui/needless_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/needless_match.fixed170
-rw-r--r--src/tools/clippy/tests/ui/needless_match.rs202
-rw-r--r--src/tools/clippy/tests/ui/needless_match.stderr87
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.fixed30
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.rs30
-rw-r--r--src/tools/clippy/tests/ui/needless_option_as_deref.stderr12
-rw-r--r--src/tools/clippy/tests/ui/no_effect.rs2
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed5
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr12
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.fixed4
-rw-r--r--src/tools/clippy/tests/ui/or_then_unwrap.rs4
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.rs17
-rw-r--r--src/tools/clippy/tests/ui/panicking_macros.stderr32
-rw-r--r--src/tools/clippy/tests/ui/ptr_arg.rs2
-rw-r--r--src/tools/clippy/tests/ui/recursive_format_impl.rs24
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_allocation_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_clone.rs2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed2
-rw-r--r--src/tools/clippy/tests/ui/redundant_static_lifetimes.rs2
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs2
-rw-r--r--src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr10
-rw-r--r--src/tools/clippy/tests/ui/same_item_push.rs2
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.fixed24
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.rs20
-rw-r--r--src/tools/clippy/tests/ui/single_element_loop.stderr74
-rw-r--r--src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs4
-rw-r--r--src/tools/clippy/tests/ui/transmute.rs11
-rw-r--r--src/tools/clippy/tests/ui/transmute.stderr54
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs55
-rw-r--r--src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr148
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast.rs6
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed5
-rw-r--r--src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs5
-rw-r--r--src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs14
-rw-r--r--src/tools/clippy/tests/ui/unsafe_removed_from_name.rs4
-rw-r--r--src/tools/clippy/tests/ui/unused_self.rs10
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed22
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs22
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.fixed2
-rw-r--r--src/tools/clippy/tests/ui/useless_attribute.rs2
-rw-r--r--src/tools/clippy/tests/versioncheck.rs34
118 files changed, 1443 insertions, 465 deletions
diff --git a/src/tools/clippy/tests/fmt.rs b/src/tools/clippy/tests/check-fmt.rs
index 0defd45b68b..0defd45b68b 100644
--- a/src/tools/clippy/tests/fmt.rs
+++ b/src/tools/clippy/tests/check-fmt.rs
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr
index af4c298b310..e2010e99813 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_mod/src/main.stderr
@@ -1,19 +1,19 @@
-error: `mod.rs` files are required, found `/bad/inner.rs`
+error: `mod.rs` files are required, found `bad/inner.rs`
   --> $DIR/bad/inner.rs:1:1
    |
 LL | pub mod stuff;
    | ^
    |
    = note: `-D clippy::self-named-module-files` implied by `-D warnings`
-   = help: move `/bad/inner.rs` to `/bad/inner/mod.rs`
+   = help: move `bad/inner.rs` to `bad/inner/mod.rs`
 
-error: `mod.rs` files are required, found `/bad/inner/stuff.rs`
+error: `mod.rs` files are required, found `bad/inner/stuff.rs`
   --> $DIR/bad/inner/stuff.rs:1:1
    |
 LL | pub mod most;
    | ^
    |
-   = help: move `/bad/inner/stuff.rs` to `/bad/inner/stuff/mod.rs`
+   = help: move `bad/inner/stuff.rs` to `bad/inner/stuff/mod.rs`
 
 error: aborting due to 2 previous errors
 
diff --git a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr
index 11e15db7fb9..f9194020938 100644
--- a/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr
+++ b/src/tools/clippy/tests/ui-cargo/module_style/fail_no_mod/src/main.stderr
@@ -1,11 +1,11 @@
-error: `mod.rs` files are not allowed, found `/bad/mod.rs`
+error: `mod.rs` files are not allowed, found `bad/mod.rs`
   --> $DIR/bad/mod.rs:1:1
    |
 LL | pub struct Thing;
    | ^
    |
    = note: `-D clippy::mod-module-files` implied by `-D warnings`
-   = help: move `/bad/mod.rs` to `/bad.rs`
+   = help: move `bad/mod.rs` to `bad.rs`
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
index 9302e02ccb9..67e1a07b7f5 100644
--- a/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
+++ b/src/tools/clippy/tests/ui-internal/check_clippy_version_attribute.stderr
@@ -46,11 +46,6 @@ LL | |     report_in_external_macro: true
 LL | | }
    | |_^
    |
-note: the lint level is defined here
-  --> $DIR/check_clippy_version_attribute.rs:1:9
-   |
-LL | #![deny(clippy::internal)]
-   |         ^^^^^^^^^^^^^^^^
    = note: `#[deny(clippy::missing_clippy_version_attribute)]` implied by `#[deny(clippy::internal)]`
    = help: please use a `clippy::version` attribute, see `doc/adding_lints.md`
    = note: this error originates in the macro `$crate::declare_tool_lint` (in Nightly builds, run with -Z macro-backtrace for more info)
diff --git a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs
index 242984680e1..32dd80246fa 100644
--- a/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs
+++ b/src/tools/clippy/tests/ui-toml/struct_excessive_bools/test.rs
@@ -4,6 +4,6 @@ struct S {
     a: bool,
 }
 
-struct Foo {}
+struct Foo;
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs b/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs
new file mode 100644
index 00000000000..3c40f77469b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/auxiliary/proc_macro_unsafe.rs
@@ -0,0 +1,18 @@
+// compile-flags: --emit=link
+// no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::{Delimiter, Group, Ident, TokenStream, TokenTree};
+
+#[proc_macro]
+pub fn unsafe_block(input: TokenStream) -> TokenStream {
+    let span = input.into_iter().next().unwrap().span();
+    TokenStream::from_iter([TokenTree::Ident(Ident::new("unsafe", span)), {
+        let mut group = Group::new(Delimiter::Brace, TokenStream::new());
+        group.set_span(span);
+        TokenTree::Group(group)
+    }])
+}
diff --git a/src/tools/clippy/tests/ui/bytes_nth.stderr b/src/tools/clippy/tests/ui/bytes_nth.stderr
index 8a7afa93450..9851d4791d8 100644
--- a/src/tools/clippy/tests/ui/bytes_nth.stderr
+++ b/src/tools/clippy/tests/ui/bytes_nth.stderr
@@ -1,4 +1,4 @@
-error: called `.byte().nth()` on a `String`
+error: called `.bytes().nth()` on a `String`
   --> $DIR/bytes_nth.rs:8:13
    |
 LL |     let _ = s.bytes().nth(3);
@@ -6,13 +6,13 @@ LL |     let _ = s.bytes().nth(3);
    |
    = note: `-D clippy::bytes-nth` implied by `-D warnings`
 
-error: called `.byte().nth()` on a `String`
+error: called `.bytes().nth()` on a `String`
   --> $DIR/bytes_nth.rs:9:14
    |
 LL |     let _ = &s.bytes().nth(3);
    |              ^^^^^^^^^^^^^^^^ help: try: `s.as_bytes().get(3)`
 
-error: called `.byte().nth()` on a `str`
+error: called `.bytes().nth()` on a `str`
   --> $DIR/bytes_nth.rs:10:13
    |
 LL |     let _ = s[..].bytes().nth(3);
diff --git a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
index 68719c2bc6d..0d65071af15 100644
--- a/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
+++ b/src/tools/clippy/tests/ui/case_sensitive_file_extension_comparisons.rs
@@ -2,7 +2,7 @@
 
 use std::string::String;
 
-struct TestStruct {}
+struct TestStruct;
 
 impl TestStruct {
     fn ends_with(self, arg: &str) {}
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index 2e31ad3172e..cf85a5ca931 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -7,7 +7,7 @@
     clippy::cast_sign_loss,
     clippy::cast_possible_wrap
 )]
-#[allow(clippy::no_effect, clippy::unnecessary_operation)]
+#[allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
 fn main() {
     // Test clippy::cast_precision_loss
     let x0 = 1i32;
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
new file mode 100644
index 00000000000..4ec2465be06
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.fixed
@@ -0,0 +1,8 @@
+// run-rustfix
+#![warn(clippy::cast_abs_to_unsigned)]
+
+fn main() {
+    let x: i32 = -42;
+    let y: u32 = x.unsigned_abs();
+    println!("The absolute value of {} is {}", x, y);
+}
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
new file mode 100644
index 00000000000..59b9c8c3678
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.rs
@@ -0,0 +1,8 @@
+// run-rustfix
+#![warn(clippy::cast_abs_to_unsigned)]
+
+fn main() {
+    let x: i32 = -42;
+    let y: u32 = x.abs() as u32;
+    println!("The absolute value of {} is {}", x, y);
+}
diff --git a/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
new file mode 100644
index 00000000000..eb12857357a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/cast_abs_to_unsigned.stderr
@@ -0,0 +1,10 @@
+error: casting the result of `i32::abs()` to u32
+  --> $DIR/cast_abs_to_unsigned.rs:6:18
+   |
+LL |     let y: u32 = x.abs() as u32;
+   |                  ^^^^^^^^^^^^^^ help: replace with: `x.unsigned_abs()`
+   |
+   = note: `-D clippy::cast-abs-to-unsigned` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/cast_alignment.rs b/src/tools/clippy/tests/ui/cast_alignment.rs
index 659591fffbe..e4e7290a30e 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.rs
+++ b/src/tools/clippy/tests/ui/cast_alignment.rs
@@ -1,6 +1,7 @@
 //! Test casts for alignment issues
 
 #![feature(rustc_private)]
+#![feature(core_intrinsics)]
 extern crate libc;
 
 #[warn(clippy::cast_ptr_alignment)]
@@ -34,4 +35,17 @@ fn main() {
     (&1u32 as *const u32 as *const libc::c_void) as *const u32;
     // For ZST, we should trust the user. See #4256
     (&1u32 as *const u32 as *const ()) as *const u32;
+
+    // Issue #2881
+    let mut data = [0u8, 0u8];
+    unsafe {
+        let ptr = &data as *const [u8; 2] as *const u8;
+        let _ = (ptr as *const u16).read_unaligned();
+        let _ = core::ptr::read_unaligned(ptr as *const u16);
+        let _ = core::intrinsics::unaligned_volatile_load(ptr as *const u16);
+        let ptr = &mut data as *mut [u8; 2] as *mut u8;
+        let _ = (ptr as *mut u16).write_unaligned(0);
+        let _ = core::ptr::write_unaligned(ptr as *mut u16, 0);
+        let _ = core::intrinsics::unaligned_volatile_store(ptr as *mut u16, 0);
+    }
 }
diff --git a/src/tools/clippy/tests/ui/cast_alignment.stderr b/src/tools/clippy/tests/ui/cast_alignment.stderr
index aedd3684455..5df2b5b1094 100644
--- a/src/tools/clippy/tests/ui/cast_alignment.stderr
+++ b/src/tools/clippy/tests/ui/cast_alignment.stderr
@@ -1,5 +1,5 @@
 error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:18:5
+  --> $DIR/cast_alignment.rs:19:5
    |
 LL |     (&1u8 as *const u8) as *const u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,19 +7,19 @@ LL |     (&1u8 as *const u8) as *const u16;
    = note: `-D clippy::cast-ptr-alignment` implied by `-D warnings`
 
 error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:19:5
+  --> $DIR/cast_alignment.rs:20:5
    |
 LL |     (&mut 1u8 as *mut u8) as *mut u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting from `*const u8` to a more-strictly-aligned pointer (`*const u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:22:5
+  --> $DIR/cast_alignment.rs:23:5
    |
 LL |     (&1u8 as *const u8).cast::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting from `*mut u8` to a more-strictly-aligned pointer (`*mut u16`) (1 < 2 bytes)
-  --> $DIR/cast_alignment.rs:23:5
+  --> $DIR/cast_alignment.rs:24:5
    |
 LL |     (&mut 1u8 as *mut u8).cast::<u16>();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/crashes/ice-2774.rs b/src/tools/clippy/tests/ui/crashes/ice-2774.rs
index d44b0fae820..88cfa1f923c 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-2774.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-2774.rs
@@ -8,7 +8,7 @@ pub struct Bar {
 }
 
 #[derive(Eq, PartialEq, Debug, Hash)]
-pub struct Foo {}
+pub struct Foo;
 
 #[allow(clippy::implicit_hasher)]
 // This should not cause a "cannot relate bound region" ICE.
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6179.rs b/src/tools/clippy/tests/ui/crashes/ice-6179.rs
index 8d9a1af8ff1..4fe92d356c4 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6179.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6179.rs
@@ -4,7 +4,7 @@
 #![warn(clippy::use_self)]
 #![allow(dead_code)]
 
-struct Foo {}
+struct Foo;
 
 impl Foo {
     fn new() -> Self {
diff --git a/src/tools/clippy/tests/ui/crashes/ice-6792.rs b/src/tools/clippy/tests/ui/crashes/ice-6792.rs
index 0e2ab1a39b8..9cbafc716b5 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-6792.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-6792.rs
@@ -7,7 +7,7 @@ trait Trait {
     fn broken() -> Self::Ty;
 }
 
-struct Foo {}
+struct Foo;
 
 impl Trait for Foo {
     type Ty = Foo;
diff --git a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
index 111350a6280..1a33e647588 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
+++ b/src/tools/clippy/tests/ui/crashes/ice-7868.stderr
@@ -5,11 +5,7 @@ LL |     unsafe { 0 };
    |     ^^^^^^^^^^^^
    |
    = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL ~     unsafe { 0 };
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: aborting due to previous error
 
diff --git a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
index 676564b2445..376ff97ba60 100644
--- a/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
+++ b/src/tools/clippy/tests/ui/crashes/needless_lifetimes_impl_trait.rs
@@ -3,7 +3,7 @@
 
 trait Foo {}
 
-struct Bar {}
+struct Bar;
 
 struct Baz<'a> {
     bar: &'a Bar,
diff --git a/src/tools/clippy/tests/ui/crashes/regressions.rs b/src/tools/clippy/tests/ui/crashes/regressions.rs
index a41bcb33b44..6f9d98bbfe7 100644
--- a/src/tools/clippy/tests/ui/crashes/regressions.rs
+++ b/src/tools/clippy/tests/ui/crashes/regressions.rs
@@ -6,6 +6,6 @@ pub fn foo(bar: *const u8) {
 
 // Regression test for https://github.com/rust-lang/rust-clippy/issues/4917
 /// <foo
-struct A {}
+struct A;
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.fixed b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed
new file mode 100644
index 00000000000..9fc594be311
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.fixed
@@ -0,0 +1,56 @@
+// run-rustfix
+#![warn(clippy::crate_in_macro_def)]
+
+mod hygienic {
+    #[macro_export]
+    macro_rules! print_message_hygienic {
+        () => {
+            println!("{}", $crate::hygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic {
+    #[macro_export]
+    macro_rules! print_message_unhygienic {
+        () => {
+            println!("{}", $crate::unhygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic_intentionally {
+    // For cases where the use of `crate` is intentional, applying `allow` to the macro definition
+    // should suppress the lint.
+    #[allow(clippy::crate_in_macro_def)]
+    #[macro_export]
+    macro_rules! print_message_unhygienic_intentionally {
+        () => {
+            println!("{}", crate::CALLER_PROVIDED_MESSAGE);
+        };
+    }
+}
+
+#[macro_use]
+mod not_exported {
+    macro_rules! print_message_not_exported {
+        () => {
+            println!("{}", crate::not_exported::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+fn main() {
+    print_message_hygienic!();
+    print_message_unhygienic!();
+    print_message_unhygienic_intentionally!();
+    print_message_not_exported!();
+}
+
+pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!";
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.rs b/src/tools/clippy/tests/ui/crate_in_macro_def.rs
new file mode 100644
index 00000000000..ac456108e4a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.rs
@@ -0,0 +1,56 @@
+// run-rustfix
+#![warn(clippy::crate_in_macro_def)]
+
+mod hygienic {
+    #[macro_export]
+    macro_rules! print_message_hygienic {
+        () => {
+            println!("{}", $crate::hygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic {
+    #[macro_export]
+    macro_rules! print_message_unhygienic {
+        () => {
+            println!("{}", crate::unhygienic::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+mod unhygienic_intentionally {
+    // For cases where the use of `crate` is intentional, applying `allow` to the macro definition
+    // should suppress the lint.
+    #[allow(clippy::crate_in_macro_def)]
+    #[macro_export]
+    macro_rules! print_message_unhygienic_intentionally {
+        () => {
+            println!("{}", crate::CALLER_PROVIDED_MESSAGE);
+        };
+    }
+}
+
+#[macro_use]
+mod not_exported {
+    macro_rules! print_message_not_exported {
+        () => {
+            println!("{}", crate::not_exported::MESSAGE);
+        };
+    }
+
+    pub const MESSAGE: &str = "Hello!";
+}
+
+fn main() {
+    print_message_hygienic!();
+    print_message_unhygienic!();
+    print_message_unhygienic_intentionally!();
+    print_message_not_exported!();
+}
+
+pub const CALLER_PROVIDED_MESSAGE: &str = "Hello!";
diff --git a/src/tools/clippy/tests/ui/crate_in_macro_def.stderr b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr
new file mode 100644
index 00000000000..9ac5937dcc0
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crate_in_macro_def.stderr
@@ -0,0 +1,10 @@
+error: `crate` references the macro call's crate
+  --> $DIR/crate_in_macro_def.rs:19:28
+   |
+LL |             println!("{}", crate::unhygienic::MESSAGE);
+   |                            ^^^^^ help: to reference the macro definition's crate, use: `$crate`
+   |
+   = note: `-D clippy::crate-in-macro-def` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
index 1b0e7544e79..e0b4a2f6942 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.fixed
@@ -134,7 +134,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, f: f64) {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
index e9687777bbd..50bbb6eec6c 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_f64.rs
@@ -134,7 +134,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, f: f64) {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
index 55c082fcb19..bded9e2c0e8 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.fixed
@@ -133,7 +133,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, x: i32) {}
diff --git a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
index e0a4828ce9f..3fceefa551c 100644
--- a/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
+++ b/src/tools/clippy/tests/ui/default_numeric_fallback_i32.rs
@@ -133,7 +133,7 @@ mod enum_ctor {
 }
 
 mod method_calls {
-    struct StructForMethodCallTest {}
+    struct StructForMethodCallTest;
 
     impl StructForMethodCallTest {
         fn concrete_arg(&self, x: i32) {}
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.rs b/src/tools/clippy/tests/ui/drop_forget_copy.rs
index 9ddd6d64701..7c7a9ecff67 100644
--- a/src/tools/clippy/tests/ui/drop_forget_copy.rs
+++ b/src/tools/clippy/tests/ui/drop_forget_copy.rs
@@ -5,7 +5,7 @@ use std::mem::{drop, forget};
 use std::vec::Vec;
 
 #[derive(Copy, Clone)]
-struct SomeStruct {}
+struct SomeStruct;
 
 struct AnotherStruct {
     x: u8,
diff --git a/src/tools/clippy/tests/ui/drop_forget_copy.stderr b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
index 01de0be7cae..88228afae89 100644
--- a/src/tools/clippy/tests/ui/drop_forget_copy.stderr
+++ b/src/tools/clippy/tests/ui/drop_forget_copy.stderr
@@ -5,7 +5,7 @@ LL |     drop(s1);
    |     ^^^^^^^^
    |
    = note: `-D clippy::drop-copy` implied by `-D warnings`
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:33:10
    |
 LL |     drop(s1);
@@ -17,7 +17,7 @@ error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a
 LL |     drop(s2);
    |     ^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:34:10
    |
 LL |     drop(s2);
@@ -29,7 +29,7 @@ error: calls to `std::mem::drop` with a value that implements `Copy`. Dropping a
 LL |     drop(s4);
    |     ^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:36:10
    |
 LL |     drop(s4);
@@ -42,7 +42,7 @@ LL |     forget(s1);
    |     ^^^^^^^^^^
    |
    = note: `-D clippy::forget-copy` implied by `-D warnings`
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:39:12
    |
 LL |     forget(s1);
@@ -54,7 +54,7 @@ error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetti
 LL |     forget(s2);
    |     ^^^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:40:12
    |
 LL |     forget(s2);
@@ -66,7 +66,7 @@ error: calls to `std::mem::forget` with a value that implements `Copy`. Forgetti
 LL |     forget(s4);
    |     ^^^^^^^^^^
    |
-note: argument has type SomeStruct
+note: argument has type `SomeStruct`
   --> $DIR/drop_forget_copy.rs:42:12
    |
 LL |     forget(s4);
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.rs b/src/tools/clippy/tests/ui/drop_non_drop.rs
new file mode 100644
index 00000000000..5a0ebde82c5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/drop_non_drop.rs
@@ -0,0 +1,40 @@
+#![warn(clippy::drop_non_drop)]
+
+use core::mem::drop;
+
+fn make_result<T>(t: T) -> Result<T, ()> {
+    Ok(t)
+}
+
+#[must_use]
+fn must_use<T>(t: T) -> T {
+    t
+}
+
+fn drop_generic<T>(t: T) {
+    // Don't lint
+    drop(t)
+}
+
+fn main() {
+    struct Foo;
+    // Lint
+    drop(Foo);
+    // Don't lint
+    drop(make_result(Foo));
+    // Don't lint
+    drop(must_use(Foo));
+
+    struct Bar;
+    impl Drop for Bar {
+        fn drop(&mut self) {}
+    }
+    // Don't lint
+    drop(Bar);
+
+    struct Baz<T>(T);
+    // Lint
+    drop(Baz(Foo));
+    // Don't lint
+    drop(Baz(Bar));
+}
diff --git a/src/tools/clippy/tests/ui/drop_non_drop.stderr b/src/tools/clippy/tests/ui/drop_non_drop.stderr
new file mode 100644
index 00000000000..f73068901c5
--- /dev/null
+++ b/src/tools/clippy/tests/ui/drop_non_drop.stderr
@@ -0,0 +1,27 @@
+error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends it's contained lifetimes
+  --> $DIR/drop_non_drop.rs:22:5
+   |
+LL |     drop(Foo);
+   |     ^^^^^^^^^
+   |
+   = note: `-D clippy::drop-non-drop` implied by `-D warnings`
+note: argument has type `main::Foo`
+  --> $DIR/drop_non_drop.rs:22:10
+   |
+LL |     drop(Foo);
+   |          ^^^
+
+error: call to `std::mem::drop` with a value that does not implement `Drop`. Dropping such a type only extends it's contained lifetimes
+  --> $DIR/drop_non_drop.rs:37:5
+   |
+LL |     drop(Baz(Foo));
+   |     ^^^^^^^^^^^^^^
+   |
+note: argument has type `main::Baz<main::Foo>`
+  --> $DIR/drop_non_drop.rs:37:10
+   |
+LL |     drop(Baz(Foo));
+   |          ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/drop_ref.rs b/src/tools/clippy/tests/ui/drop_ref.rs
index e1a15c609fd..7de0b0bbdf9 100644
--- a/src/tools/clippy/tests/ui/drop_ref.rs
+++ b/src/tools/clippy/tests/ui/drop_ref.rs
@@ -1,7 +1,7 @@
 #![warn(clippy::drop_ref)]
 #![allow(clippy::toplevel_ref_arg)]
 #![allow(clippy::map_err_ignore)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(clippy::unnecessary_wraps, clippy::drop_non_drop)]
 
 use std::mem::drop;
 
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
new file mode 100644
index 00000000000..80f07603b8d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.fixed
@@ -0,0 +1,25 @@
+// run-rustfix
+#![warn(clippy::empty_structs_with_brackets)]
+#![allow(dead_code)]
+
+pub struct MyEmptyStruct; // should trigger lint
+struct MyEmptyTupleStruct; // should trigger lint
+
+// should not trigger lint
+struct MyCfgStruct {
+    #[cfg(feature = "thisisneverenabled")]
+    field: u8,
+}
+
+// should not trigger lint
+struct MyCfgTupleStruct(#[cfg(feature = "thisisneverenabled")] u8);
+
+// should not trigger lint
+struct MyStruct {
+    field: u8,
+}
+struct MyTupleStruct(usize, String); // should not trigger lint
+struct MySingleTupleStruct(usize); // should not trigger lint
+struct MyUnitLikeStruct; // should not trigger lint
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
new file mode 100644
index 00000000000..1d1ed4c7690
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.rs
@@ -0,0 +1,25 @@
+// run-rustfix
+#![warn(clippy::empty_structs_with_brackets)]
+#![allow(dead_code)]
+
+pub struct MyEmptyStruct {} // should trigger lint
+struct MyEmptyTupleStruct(); // should trigger lint
+
+// should not trigger lint
+struct MyCfgStruct {
+    #[cfg(feature = "thisisneverenabled")]
+    field: u8,
+}
+
+// should not trigger lint
+struct MyCfgTupleStruct(#[cfg(feature = "thisisneverenabled")] u8);
+
+// should not trigger lint
+struct MyStruct {
+    field: u8,
+}
+struct MyTupleStruct(usize, String); // should not trigger lint
+struct MySingleTupleStruct(usize); // should not trigger lint
+struct MyUnitLikeStruct; // should not trigger lint
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
new file mode 100644
index 00000000000..0308cb5571a
--- /dev/null
+++ b/src/tools/clippy/tests/ui/empty_structs_with_brackets.stderr
@@ -0,0 +1,19 @@
+error: found empty brackets on struct declaration
+  --> $DIR/empty_structs_with_brackets.rs:5:25
+   |
+LL | pub struct MyEmptyStruct {} // should trigger lint
+   |                         ^^^
+   |
+   = note: `-D clippy::empty-structs-with-brackets` implied by `-D warnings`
+   = help: remove the brackets
+
+error: found empty brackets on struct declaration
+  --> $DIR/empty_structs_with_brackets.rs:6:26
+   |
+LL | struct MyEmptyTupleStruct(); // should trigger lint
+   |                          ^^^
+   |
+   = help: remove the brackets
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/err_expect.fixed b/src/tools/clippy/tests/ui/err_expect.fixed
new file mode 100644
index 00000000000..7e18d70bae4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/err_expect.fixed
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct MyTypeNonDebug;
+
+#[derive(Debug)]
+struct MyTypeDebug;
+
+fn main() {
+    let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug);
+    test_debug.expect_err("Testing debug type");
+
+    let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug);
+    test_non_debug.err().expect("Testing non debug type");
+}
diff --git a/src/tools/clippy/tests/ui/err_expect.rs b/src/tools/clippy/tests/ui/err_expect.rs
new file mode 100644
index 00000000000..bf8c3c9fb8c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/err_expect.rs
@@ -0,0 +1,14 @@
+// run-rustfix
+
+struct MyTypeNonDebug;
+
+#[derive(Debug)]
+struct MyTypeDebug;
+
+fn main() {
+    let test_debug: Result<MyTypeDebug, u32> = Ok(MyTypeDebug);
+    test_debug.err().expect("Testing debug type");
+
+    let test_non_debug: Result<MyTypeNonDebug, u32> = Ok(MyTypeNonDebug);
+    test_non_debug.err().expect("Testing non debug type");
+}
diff --git a/src/tools/clippy/tests/ui/err_expect.stderr b/src/tools/clippy/tests/ui/err_expect.stderr
new file mode 100644
index 00000000000..ffd97e00a5c
--- /dev/null
+++ b/src/tools/clippy/tests/ui/err_expect.stderr
@@ -0,0 +1,10 @@
+error: called `.err().expect()` on a `Result` value
+  --> $DIR/err_expect.rs:10:16
+   |
+LL |     test_debug.err().expect("Testing debug type");
+   |                ^^^^^^^^^^^^ help: try: `expect_err`
+   |
+   = note: `-D clippy::err-expect` implied by `-D warnings`
+
+error: aborting due to previous error
+
diff --git a/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs b/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
index 1442ee08e75..f805bcc9ba8 100644
--- a/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
+++ b/src/tools/clippy/tests/ui/fn_params_excessive_bools.rs
@@ -20,7 +20,7 @@ fn h(_: bool, _: bool, _: bool) {}
 fn e(_: S, _: S, _: Box<S>, _: Vec<u32>) {}
 fn t(_: S, _: S, _: Box<S>, _: Vec<u32>, _: bool, _: bool, _: bool, _: bool) {}
 
-struct S {}
+struct S;
 trait Trait {
     fn f(_: bool, _: bool, _: bool, _: bool);
     fn g(_: bool, _: bool, _: bool, _: Vec<u32>);
diff --git a/src/tools/clippy/tests/ui/forget_non_drop.rs b/src/tools/clippy/tests/ui/forget_non_drop.rs
new file mode 100644
index 00000000000..7580cf95ebf
--- /dev/null
+++ b/src/tools/clippy/tests/ui/forget_non_drop.rs
@@ -0,0 +1,27 @@
+#![warn(clippy::forget_non_drop)]
+
+use core::mem::forget;
+
+fn forget_generic<T>(t: T) {
+    // Don't lint
+    forget(t)
+}
+
+fn main() {
+    struct Foo;
+    // Lint
+    forget(Foo);
+
+    struct Bar;
+    impl Drop for Bar {
+        fn drop(&mut self) {}
+    }
+    // Don't lint
+    forget(Bar);
+
+    struct Baz<T>(T);
+    // Lint
+    forget(Baz(Foo));
+    // Don't lint
+    forget(Baz(Bar));
+}
diff --git a/src/tools/clippy/tests/ui/forget_non_drop.stderr b/src/tools/clippy/tests/ui/forget_non_drop.stderr
new file mode 100644
index 00000000000..03fb00960a4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/forget_non_drop.stderr
@@ -0,0 +1,27 @@
+error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it
+  --> $DIR/forget_non_drop.rs:13:5
+   |
+LL |     forget(Foo);
+   |     ^^^^^^^^^^^
+   |
+   = note: `-D clippy::forget-non-drop` implied by `-D warnings`
+note: argument has type `main::Foo`
+  --> $DIR/forget_non_drop.rs:13:12
+   |
+LL |     forget(Foo);
+   |            ^^^
+
+error: call to `std::mem::forget` with a value that does not implement `Drop`. Forgetting such a type is the same as dropping it
+  --> $DIR/forget_non_drop.rs:24:5
+   |
+LL |     forget(Baz(Foo));
+   |     ^^^^^^^^^^^^^^^^
+   |
+note: argument has type `main::Baz<main::Foo>`
+  --> $DIR/forget_non_drop.rs:24:12
+   |
+LL |     forget(Baz(Foo));
+   |            ^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/forget_ref.rs b/src/tools/clippy/tests/ui/forget_ref.rs
index c49e6756a6c..6c8c4c9c0ed 100644
--- a/src/tools/clippy/tests/ui/forget_ref.rs
+++ b/src/tools/clippy/tests/ui/forget_ref.rs
@@ -1,6 +1,6 @@
 #![warn(clippy::forget_ref)]
 #![allow(clippy::toplevel_ref_arg)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(clippy::unnecessary_wraps, clippy::forget_non_drop)]
 
 use std::mem::forget;
 
diff --git a/src/tools/clippy/tests/ui/identity_op.rs b/src/tools/clippy/tests/ui/identity_op.rs
index 12bbda71f43..edc3fe1aec1 100644
--- a/src/tools/clippy/tests/ui/identity_op.rs
+++ b/src/tools/clippy/tests/ui/identity_op.rs
@@ -66,4 +66,13 @@ fn main() {
     let b = a << 0; // no error: non-integer
 
     1 * Meter; // no error: non-integer
+
+    2 % 3;
+    -2 % 3;
+    2 % -3 + x;
+    -2 % -3 + x;
+    x + 1 % 3;
+    (x + 1) % 3; // no error
+    4 % 3; // no error
+    4 % -3; // no error
 }
diff --git a/src/tools/clippy/tests/ui/identity_op.stderr b/src/tools/clippy/tests/ui/identity_op.stderr
index 0103cf5457e..706f01a3dd6 100644
--- a/src/tools/clippy/tests/ui/identity_op.stderr
+++ b/src/tools/clippy/tests/ui/identity_op.stderr
@@ -78,5 +78,35 @@ error: the operation is ineffective. Consider reducing it to `x`
 LL |     x >> &0;
    |     ^^^^^^^
 
-error: aborting due to 13 previous errors
+error: the operation is ineffective. Consider reducing it to `2`
+  --> $DIR/identity_op.rs:70:5
+   |
+LL |     2 % 3;
+   |     ^^^^^
+
+error: the operation is ineffective. Consider reducing it to `-2`
+  --> $DIR/identity_op.rs:71:5
+   |
+LL |     -2 % 3;
+   |     ^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `2`
+  --> $DIR/identity_op.rs:72:5
+   |
+LL |     2 % -3 + x;
+   |     ^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `-2`
+  --> $DIR/identity_op.rs:73:5
+   |
+LL |     -2 % -3 + x;
+   |     ^^^^^^^
+
+error: the operation is ineffective. Consider reducing it to `1`
+  --> $DIR/identity_op.rs:74:9
+   |
+LL |     x + 1 % 3;
+   |         ^^^^^
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/implicit_clone.rs b/src/tools/clippy/tests/ui/implicit_clone.rs
index 639fecb8927..2549c9f32f9 100644
--- a/src/tools/clippy/tests/ui/implicit_clone.rs
+++ b/src/tools/clippy/tests/ui/implicit_clone.rs
@@ -30,7 +30,7 @@ where
 }
 
 #[derive(Copy, Clone)]
-struct Kitten {}
+struct Kitten;
 impl Kitten {
     // badly named method
     fn to_vec(self) -> Kitten {
@@ -44,7 +44,7 @@ impl Borrow<BorrowedKitten> for Kitten {
     }
 }
 
-struct BorrowedKitten {}
+struct BorrowedKitten;
 impl ToOwned for BorrowedKitten {
     type Owned = Kitten;
     fn to_owned(&self) -> Kitten {
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.rs b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
index ca8ca53c80c..45a430edcb5 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.rs
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.rs
@@ -1,18 +1,34 @@
+#![feature(inline_const)]
 #![warn(clippy::indexing_slicing)]
 // We also check the out_of_bounds_indexing lint here, because it lints similar things and
 // we want to avoid false positives.
 #![warn(clippy::out_of_bounds_indexing)]
-#![allow(clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(const_err, clippy::no_effect, clippy::unnecessary_operation)]
+
+const ARR: [i32; 2] = [1, 2];
+const REF: &i32 = &ARR[idx()]; // Ok, should not produce stderr.
+const REF_ERR: &i32 = &ARR[idx4()]; // Ok, let rustc handle const contexts.
+
+const fn idx() -> usize {
+    1
+}
+const fn idx4() -> usize {
+    4
+}
 
 fn main() {
     let x = [1, 2, 3, 4];
     let index: usize = 1;
     x[index];
-    x[4]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
-    x[1 << 3]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
+    x[4]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+    x[1 << 3]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
 
     x[0]; // Ok, should not produce stderr.
     x[3]; // Ok, should not produce stderr.
+    x[const { idx() }]; // Ok, should not produce stderr.
+    x[const { idx4() }]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
+    const { &ARR[idx()] }; // Ok, should not produce stderr.
+    const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
 
     let y = &x;
     y[0]; // Ok, referencing shouldn't affect this lint. See the issue 6021
@@ -25,7 +41,7 @@ fn main() {
 
     const N: usize = 15; // Out of bounds
     const M: usize = 3; // In bounds
-    x[N]; // Ok, let rustc's `const_err` lint handle `usize` indexing on arrays.
+    x[N]; // Ok, let rustc's `unconditional_panic` lint handle `usize` indexing on arrays.
     x[M]; // Ok, should not produce stderr.
     v[N];
     v[M];
diff --git a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
index 76ecec33484..83a36f407d5 100644
--- a/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
+++ b/src/tools/clippy/tests/ui/indexing_slicing_index.stderr
@@ -1,5 +1,17 @@
+error[E0080]: evaluation of `main::{constant#3}::<&i32>` failed
+  --> $DIR/indexing_slicing_index.rs:31:14
+   |
+LL |     const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
+   |              ^^^^^^^^^^^ index out of bounds: the length is 2 but the index is 4
+
+error[E0080]: erroneous constant used
+  --> $DIR/indexing_slicing_index.rs:31:5
+   |
+LL |     const { &ARR[idx4()] }; // Ok, let rustc handle const contexts.
+   |     ^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors
+
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:10:5
+  --> $DIR/indexing_slicing_index.rs:22:5
    |
 LL |     x[index];
    |     ^^^^^^^^
@@ -8,7 +20,7 @@ LL |     x[index];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:22:5
+  --> $DIR/indexing_slicing_index.rs:38:5
    |
 LL |     v[0];
    |     ^^^^
@@ -16,7 +28,7 @@ LL |     v[0];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:23:5
+  --> $DIR/indexing_slicing_index.rs:39:5
    |
 LL |     v[10];
    |     ^^^^^
@@ -24,7 +36,7 @@ LL |     v[10];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:24:5
+  --> $DIR/indexing_slicing_index.rs:40:5
    |
 LL |     v[1 << 3];
    |     ^^^^^^^^^
@@ -32,7 +44,7 @@ LL |     v[1 << 3];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:30:5
+  --> $DIR/indexing_slicing_index.rs:46:5
    |
 LL |     v[N];
    |     ^^^^
@@ -40,12 +52,13 @@ LL |     v[N];
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
 error: indexing may panic
-  --> $DIR/indexing_slicing_index.rs:31:5
+  --> $DIR/indexing_slicing_index.rs:47:5
    |
 LL |     v[M];
    |     ^^^^
    |
    = help: consider using `.get(n)` or `.get_mut(n)` instead
 
-error: aborting due to 6 previous errors
+error: aborting due to 8 previous errors
 
+For more information about this error, try `rustc --explain E0080`.
diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.fixed b/src/tools/clippy/tests/ui/iter_nth_zero.fixed
index b54147c94d1..f23671c26e4 100644
--- a/src/tools/clippy/tests/ui/iter_nth_zero.fixed
+++ b/src/tools/clippy/tests/ui/iter_nth_zero.fixed
@@ -3,7 +3,7 @@
 #![warn(clippy::iter_nth_zero)]
 use std::collections::HashSet;
 
-struct Foo {}
+struct Foo;
 
 impl Foo {
     fn nth(&self, index: usize) -> usize {
diff --git a/src/tools/clippy/tests/ui/iter_nth_zero.rs b/src/tools/clippy/tests/ui/iter_nth_zero.rs
index b92c7d18adb..7c968d49845 100644
--- a/src/tools/clippy/tests/ui/iter_nth_zero.rs
+++ b/src/tools/clippy/tests/ui/iter_nth_zero.rs
@@ -3,7 +3,7 @@
 #![warn(clippy::iter_nth_zero)]
 use std::collections::HashSet;
 
-struct Foo {}
+struct Foo;
 
 impl Foo {
     fn nth(&self, index: usize) -> usize {
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
index a9041671101..56761ebbcb8 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.fixed
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
+#![allow(dead_code)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@@ -43,3 +44,8 @@ fn main() {
     // Should probably stay as it is.
     let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
 }
+
+// #8527
+fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
+    x.cloned().flatten()
+}
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
index dd04e33a4b3..98321d889b5 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.rs
@@ -1,5 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
+#![allow(dead_code)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
@@ -45,3 +46,8 @@ fn main() {
     // Should probably stay as it is.
     let _ = [0, 1, 2, 3, 4].iter().cloned().take(10);
 }
+
+// #8527
+fn cloned_flatten(x: Option<&Option<String>>) -> Option<String> {
+    x.cloned().flatten()
+}
diff --git a/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr b/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
index e36b0e36fbd..0582700fd16 100644
--- a/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
+++ b/src/tools/clippy/tests/ui/iter_overeager_cloned.stderr
@@ -1,5 +1,5 @@
 error: called `cloned().last()` on an `Iterator`. It may be more efficient to call `last().cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:7:29
+  --> $DIR/iter_overeager_cloned.rs:8:29
    |
 LL |     let _: Option<String> = vec.iter().cloned().last();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().last().cloned()`
@@ -7,13 +7,13 @@ LL |     let _: Option<String> = vec.iter().cloned().last();
    = note: `-D clippy::iter-overeager-cloned` implied by `-D warnings`
 
 error: called `cloned().next()` on an `Iterator`. It may be more efficient to call `next().cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:9:29
+  --> $DIR/iter_overeager_cloned.rs:10:29
    |
 LL |     let _: Option<String> = vec.iter().chain(vec.iter()).cloned().next();
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().chain(vec.iter()).next().cloned()`
 
 error: called `cloned().count()` on an `Iterator`. It may be more efficient to call `count()` instead
-  --> $DIR/iter_overeager_cloned.rs:11:20
+  --> $DIR/iter_overeager_cloned.rs:12:20
    |
 LL |     let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").count()`
@@ -21,25 +21,25 @@ LL |     let _: usize = vec.iter().filter(|x| x == &"2").cloned().count();
    = note: `-D clippy::redundant-clone` implied by `-D warnings`
 
 error: called `cloned().take(...)` on an `Iterator`. It may be more efficient to call `take(...).cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:13:21
+  --> $DIR/iter_overeager_cloned.rs:14:21
    |
 LL |     let _: Vec<_> = vec.iter().cloned().take(2).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().take(2).cloned()`
 
 error: called `cloned().skip(...)` on an `Iterator`. It may be more efficient to call `skip(...).cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:15:21
+  --> $DIR/iter_overeager_cloned.rs:16:21
    |
 LL |     let _: Vec<_> = vec.iter().cloned().skip(2).collect();
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().skip(2).cloned()`
 
 error: called `cloned().nth(...)` on an `Iterator`. It may be more efficient to call `nth(...).cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:17:13
+  --> $DIR/iter_overeager_cloned.rs:18:13
    |
 LL |     let _ = vec.iter().filter(|x| x == &"2").cloned().nth(2);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `vec.iter().filter(|x| x == &"2").nth(2).cloned()`
 
 error: called `cloned().flatten()` on an `Iterator`. It may be more efficient to call `flatten().cloned()` instead
-  --> $DIR/iter_overeager_cloned.rs:19:13
+  --> $DIR/iter_overeager_cloned.rs:20:13
    |
 LL |       let _ = [Some(Some("str".to_string())), Some(Some("str".to_string()))]
    |  _____________^
diff --git a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
index e4a2e9df4d7..7601b5c66fa 100644
--- a/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
+++ b/src/tools/clippy/tests/ui/large_types_passed_by_value.rs
@@ -37,7 +37,7 @@ pub trait PubLargeTypeDevourer {
     fn devoure_array_in_public(&self, array: [u8; 6666]);
 }
 
-struct S {}
+struct S;
 impl LargeTypeDevourer for S {
     fn devoure_array(&self, array: [u8; 6666]) {
         todo!();
diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs
index e3561863c1e..bb162adc9ad 100644
--- a/src/tools/clippy/tests/ui/let_and_return.rs
+++ b/src/tools/clippy/tests/ui/let_and_return.rs
@@ -88,7 +88,7 @@ mod no_lint_if_stmt_borrows {
             ret
         }
 
-        struct Bar {}
+        struct Bar;
 
         impl Bar {
             fn new() -> Self {
diff --git a/src/tools/clippy/tests/ui/let_underscore_must_use.rs b/src/tools/clippy/tests/ui/let_underscore_must_use.rs
index a842e872a37..1edb77c748b 100644
--- a/src/tools/clippy/tests/ui/let_underscore_must_use.rs
+++ b/src/tools/clippy/tests/ui/let_underscore_must_use.rs
@@ -26,7 +26,7 @@ fn h() -> u32 {
     0
 }
 
-struct S {}
+struct S;
 
 impl S {
     #[must_use]
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.fixed b/src/tools/clippy/tests/ui/manual_async_fn.fixed
index 136cc96be70..b7e46a4a8cc 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.fixed
+++ b/src/tools/clippy/tests/ui/manual_async_fn.fixed
@@ -38,7 +38,7 @@ async fn already_async() -> impl Future<Output = i32> {
     async { 42 }
 }
 
-struct S {}
+struct S;
 impl S {
     async fn inh_fut() -> i32 {
         // NOTE: this code is here just to check that the indentation is correct in the suggested fix
diff --git a/src/tools/clippy/tests/ui/manual_async_fn.rs b/src/tools/clippy/tests/ui/manual_async_fn.rs
index ddc453ffdb7..b05429da662 100644
--- a/src/tools/clippy/tests/ui/manual_async_fn.rs
+++ b/src/tools/clippy/tests/ui/manual_async_fn.rs
@@ -52,7 +52,7 @@ async fn already_async() -> impl Future<Output = i32> {
     async { 42 }
 }
 
-struct S {}
+struct S;
 impl S {
     fn inh_fut() -> impl Future<Output = i32> {
         async {
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
index 05d6c56f2ac..7d68978216c 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.fixed
@@ -78,7 +78,7 @@ fn result_unwrap_or() {
     (Ok(1) as Result<i32, &str>).unwrap_or(42);
 
     // method call case, suggestion must not surround Result expr `s.method()` with parentheses
-    struct S {}
+    struct S;
     impl S {
         fn method(self) -> Option<i32> {
             Some(42)
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or.rs b/src/tools/clippy/tests/ui/manual_unwrap_or.rs
index 09f62c69b71..b937fe6f977 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or.rs
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or.rs
@@ -102,7 +102,7 @@ fn result_unwrap_or() {
     };
 
     // method call case, suggestion must not surround Result expr `s.method()` with parentheses
-    struct S {}
+    struct S;
     impl S {
         fn method(self) -> Option<i32> {
             Some(42)
diff --git a/src/tools/clippy/tests/ui/map_identity.fixed b/src/tools/clippy/tests/ui/map_identity.fixed
index 4a1452b25f3..2256e51f2d0 100644
--- a/src/tools/clippy/tests/ui/map_identity.fixed
+++ b/src/tools/clippy/tests/ui/map_identity.fixed
@@ -16,6 +16,8 @@ fn main() {
     let _: Result<i8, f32> = Err(2.3).map(|x: i8| {
         return x + 3;
     });
+    let _: Result<u32, u32> = Ok(1);
+    let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42);
 }
 
 fn not_identity(x: &u16) -> u16 {
diff --git a/src/tools/clippy/tests/ui/map_identity.rs b/src/tools/clippy/tests/ui/map_identity.rs
index 65c7e6e1ea5..ccfdc9ea76d 100644
--- a/src/tools/clippy/tests/ui/map_identity.rs
+++ b/src/tools/clippy/tests/ui/map_identity.rs
@@ -18,6 +18,8 @@ fn main() {
     let _: Result<i8, f32> = Err(2.3).map(|x: i8| {
         return x + 3;
     });
+    let _: Result<u32, u32> = Ok(1).map_err(|a| a);
+    let _: Result<u32, u32> = Ok(1).map_err(|a: u32| a * 42);
 }
 
 fn not_identity(x: &u16) -> u16 {
diff --git a/src/tools/clippy/tests/ui/map_identity.stderr b/src/tools/clippy/tests/ui/map_identity.stderr
index e4a0320cbda..b6a77281f6d 100644
--- a/src/tools/clippy/tests/ui/map_identity.stderr
+++ b/src/tools/clippy/tests/ui/map_identity.stderr
@@ -33,5 +33,11 @@ LL | |         return x;
 LL | |     });
    | |______^ help: remove the call to `map`
 
-error: aborting due to 5 previous errors
+error: unnecessary map of the identity function
+  --> $DIR/map_identity.rs:21:36
+   |
+LL |     let _: Result<u32, u32> = Ok(1).map_err(|a| a);
+   |                                    ^^^^^^^^^^^^^^^ help: remove the call to `map_err`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/map_unit_fn.rs b/src/tools/clippy/tests/ui/map_unit_fn.rs
index 9a74da4e3b8..e7f07b50f3a 100644
--- a/src/tools/clippy/tests/ui/map_unit_fn.rs
+++ b/src/tools/clippy/tests/ui/map_unit_fn.rs
@@ -1,5 +1,5 @@
 #![allow(unused)]
-struct Mappable {}
+struct Mappable;
 
 impl Mappable {
     pub fn map(&self) {}
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.rs b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
index c5f221220ec..f83c3e0e281 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.rs
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.rs
@@ -99,7 +99,7 @@ pub fn manual_range_contains() {
 }
 
 pub fn use_self() {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Foo {
@@ -145,6 +145,16 @@ fn int_from_bool() -> u8 {
     true as u8
 }
 
+fn err_expect() {
+    let x: Result<u32, &str> = Ok(10);
+    x.err().expect("Testing expect_err");
+}
+
+fn cast_abs_to_unsigned() {
+    let x: i32 = 10;
+    assert_eq!(10u32, x.abs() as u32);
+}
+
 fn main() {
     filter_map_next();
     checked_conversion();
@@ -162,6 +172,8 @@ fn main() {
     missing_const_for_fn();
     unnest_or_patterns();
     int_from_bool();
+    err_expect();
+    cast_abs_to_unsigned();
 }
 
 mod just_under_msrv {
diff --git a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
index 6b3fdb0844b..de225eb740d 100644
--- a/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
+++ b/src/tools/clippy/tests/ui/min_rust_version_attr.stderr
@@ -1,12 +1,12 @@
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:186:24
+  --> $DIR/min_rust_version_attr.rs:198:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::manual-strip` implied by `-D warnings`
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:185:9
+  --> $DIR/min_rust_version_attr.rs:197:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -17,13 +17,13 @@ LL ~             assert_eq!(<stripped>.to_uppercase(), "WORLD!");
    |
 
 error: stripping a prefix manually
-  --> $DIR/min_rust_version_attr.rs:198:24
+  --> $DIR/min_rust_version_attr.rs:210:24
    |
 LL |             assert_eq!(s["hello, ".len()..].to_uppercase(), "WORLD!");
    |                        ^^^^^^^^^^^^^^^^^^^^
    |
 note: the prefix was tested here
-  --> $DIR/min_rust_version_attr.rs:197:9
+  --> $DIR/min_rust_version_attr.rs:209:9
    |
 LL |         if s.starts_with("hello, ") {
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/missing_inline.rs b/src/tools/clippy/tests/ui/missing_inline.rs
index b73b24b8e0a..07f8e3888c9 100644
--- a/src/tools/clippy/tests/ui/missing_inline.rs
+++ b/src/tools/clippy/tests/ui/missing_inline.rs
@@ -7,8 +7,8 @@
 type Typedef = String;
 pub type PubTypedef = String;
 
-struct Foo {} // ok
-pub struct PubFoo {} // ok
+struct Foo; // ok
+pub struct PubFoo; // ok
 enum FooE {} // ok
 pub enum PubFooE {} // ok
 
@@ -63,4 +63,4 @@ impl PubFoo {
 
 // do not lint this since users cannot control the external code
 #[derive(Debug)]
-pub struct S {}
+pub struct S;
diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.rs b/src/tools/clippy/tests/ui/module_name_repetitions.rs
index f5908cb5701..ebaa77cc283 100644
--- a/src/tools/clippy/tests/ui/module_name_repetitions.rs
+++ b/src/tools/clippy/tests/ui/module_name_repetitions.rs
@@ -7,7 +7,7 @@ mod foo {
     pub fn foo() {}
     pub fn foo_bar() {}
     pub fn bar_foo() {}
-    pub struct FooCake {}
+    pub struct FooCake;
     pub enum CakeFoo {}
     pub struct Foo7Bar;
 
diff --git a/src/tools/clippy/tests/ui/module_name_repetitions.stderr b/src/tools/clippy/tests/ui/module_name_repetitions.stderr
index bdd217a969c..3f343a3e430 100644
--- a/src/tools/clippy/tests/ui/module_name_repetitions.stderr
+++ b/src/tools/clippy/tests/ui/module_name_repetitions.stderr
@@ -15,8 +15,8 @@ LL |     pub fn bar_foo() {}
 error: item name starts with its containing module's name
   --> $DIR/module_name_repetitions.rs:10:5
    |
-LL |     pub struct FooCake {}
-   |     ^^^^^^^^^^^^^^^^^^^^^
+LL |     pub struct FooCake;
+   |     ^^^^^^^^^^^^^^^^^^^
 
 error: item name ends with its containing module's name
   --> $DIR/module_name_repetitions.rs:11:5
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
index 047a29fa1e3..3ebe46bc5be 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.rs
@@ -1,5 +1,10 @@
 #![warn(clippy::modulo_arithmetic)]
-#![allow(clippy::no_effect, clippy::unnecessary_operation, clippy::modulo_one)]
+#![allow(
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::modulo_one,
+    clippy::identity_op
+)]
 
 fn main() {
     // Lint when both sides are const and of the opposite sign
diff --git a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
index 64335f35f0f..11b5f77461b 100644
--- a/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
+++ b/src/tools/clippy/tests/ui/modulo_arithmetic_integral_const.stderr
@@ -1,5 +1,5 @@
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:6:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:11:5
    |
 LL |     -1 % 2;
    |     ^^^^^^
@@ -9,7 +9,7 @@ LL |     -1 % 2;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:7:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:12:5
    |
 LL |     1 % -2;
    |     ^^^^^^
@@ -18,7 +18,7 @@ LL |     1 % -2;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 3`
-  --> $DIR/modulo_arithmetic_integral_const.rs:8:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:13:5
    |
 LL |     (1 - 2) % (1 + 2);
    |     ^^^^^^^^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     (1 - 2) % (1 + 2);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `3 % -1`
-  --> $DIR/modulo_arithmetic_integral_const.rs:9:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:14:5
    |
 LL |     (1 + 2) % (1 - 2);
    |     ^^^^^^^^^^^^^^^^^
@@ -36,7 +36,7 @@ LL |     (1 + 2) % (1 - 2);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-35 % 300000`
-  --> $DIR/modulo_arithmetic_integral_const.rs:10:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:15:5
    |
 LL |     35 * (7 - 4 * 2) % (-500 * -600);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -45,7 +45,7 @@ LL |     35 * (7 - 4 * 2) % (-500 * -600);
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:12:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:17:5
    |
 LL |     -1i8 % 2i8;
    |     ^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |     -1i8 % 2i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:13:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:18:5
    |
 LL |     1i8 % -2i8;
    |     ^^^^^^^^^^
@@ -63,7 +63,7 @@ LL |     1i8 % -2i8;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:14:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:19:5
    |
 LL |     -1i16 % 2i16;
    |     ^^^^^^^^^^^^
@@ -72,7 +72,7 @@ LL |     -1i16 % 2i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:15:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:20:5
    |
 LL |     1i16 % -2i16;
    |     ^^^^^^^^^^^^
@@ -81,7 +81,7 @@ LL |     1i16 % -2i16;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:16:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:21:5
    |
 LL |     -1i32 % 2i32;
    |     ^^^^^^^^^^^^
@@ -90,7 +90,7 @@ LL |     -1i32 % 2i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:17:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:22:5
    |
 LL |     1i32 % -2i32;
    |     ^^^^^^^^^^^^
@@ -99,7 +99,7 @@ LL |     1i32 % -2i32;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:18:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:23:5
    |
 LL |     -1i64 % 2i64;
    |     ^^^^^^^^^^^^
@@ -108,7 +108,7 @@ LL |     -1i64 % 2i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:19:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:24:5
    |
 LL |     1i64 % -2i64;
    |     ^^^^^^^^^^^^
@@ -117,7 +117,7 @@ LL |     1i64 % -2i64;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:20:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:25:5
    |
 LL |     -1i128 % 2i128;
    |     ^^^^^^^^^^^^^^
@@ -126,7 +126,7 @@ LL |     -1i128 % 2i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:21:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:26:5
    |
 LL |     1i128 % -2i128;
    |     ^^^^^^^^^^^^^^
@@ -135,7 +135,7 @@ LL |     1i128 % -2i128;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `-1 % 2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:22:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:27:5
    |
 LL |     -1isize % 2isize;
    |     ^^^^^^^^^^^^^^^^
@@ -144,7 +144,7 @@ LL |     -1isize % 2isize;
    = note: or consider using `rem_euclid` or similar function
 
 error: you are using modulo operator on constants with different signs: `1 % -2`
-  --> $DIR/modulo_arithmetic_integral_const.rs:23:5
+  --> $DIR/modulo_arithmetic_integral_const.rs:28:5
    |
 LL |     1isize % -2isize;
    |     ^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
index ad0d694a217..02b43cce2bd 100644
--- a/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
+++ b/src/tools/clippy/tests/ui/needless_arbitrary_self_type_unfixable.rs
@@ -14,7 +14,7 @@ mod issue_6089 {
                 fn test(self: &Self);
             }
 
-            struct S1 {}
+            struct S1;
 
             impl T1 for S1 {
                 fn test(self: &Self) {}
@@ -32,7 +32,7 @@ mod issue_6089 {
         fn call_with_mut_self(&mut self);
     }
 
-    struct S2 {}
+    struct S2;
 
     // The method's signature will be expanded to:
     //  fn call_with_mut_self<'life0>(self: &'life0 mut Self) {}
diff --git a/src/tools/clippy/tests/ui/needless_lifetimes.rs b/src/tools/clippy/tests/ui/needless_lifetimes.rs
index f3eafe8e927..1456204ca86 100644
--- a/src/tools/clippy/tests/ui/needless_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/needless_lifetimes.rs
@@ -268,7 +268,7 @@ mod issue4291 {
 
 mod issue2944 {
     trait Foo {}
-    struct Bar {}
+    struct Bar;
     struct Baz<'a> {
         bar: &'a Bar,
     }
diff --git a/src/tools/clippy/tests/ui/needless_match.fixed b/src/tools/clippy/tests/ui/needless_match.fixed
index ece18ad737f..9ccccaa1725 100644
--- a/src/tools/clippy/tests/ui/needless_match.fixed
+++ b/src/tools/clippy/tests/ui/needless_match.fixed
@@ -4,38 +4,35 @@
 #![allow(dead_code)]
 
 #[derive(Clone, Copy)]
-enum Choice {
+enum Simple {
     A,
     B,
     C,
     D,
 }
 
-#[allow(unused_mut)]
 fn useless_match() {
-    let mut i = 10;
+    let i = 10;
     let _: i32 = i;
-    let _: i32 = i;
-    let mut _i_mut = i;
-
     let s = "test";
     let _: &str = s;
 }
 
-fn custom_type_match(se: Choice) {
-    let _: Choice = se;
+fn custom_type_match() {
+    let se = Simple::A;
+    let _: Simple = se;
     // Don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::A,
-        Choice::B => Choice::B,
-        _ => Choice::C,
+    let _: Simple = match se {
+        Simple::A => Simple::A,
+        Simple::B => Simple::B,
+        _ => Simple::C,
     };
     // Mingled, don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::B,
-        Choice::B => Choice::C,
-        Choice::C => Choice::D,
-        Choice::D => Choice::A,
+    let _: Simple = match se {
+        Simple::A => Simple::B,
+        Simple::B => Simple::C,
+        Simple::C => Simple::D,
+        Simple::D => Simple::A,
     };
 }
 
@@ -55,29 +52,146 @@ fn func_ret_err<T>(err: T) -> Result<i32, T> {
 fn result_match() {
     let _: Result<i32, i32> = Ok(1);
     let _: Result<i32, i32> = func_ret_err(0_i32);
+    // as ref, don't trigger
+    let res = &func_ret_err(0_i32);
+    let _: Result<&i32, &i32> = match *res {
+        Ok(ref x) => Ok(x),
+        Err(ref x) => Err(x),
+    };
 }
 
-fn if_let_option() -> Option<i32> {
-    Some(1)
+fn if_let_option() {
+    let _ = Some(1);
+
+    fn do_something() {}
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        Some(a)
+    } else {
+        do_something();
+        None
+    };
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        do_something();
+        Some(a)
+    } else {
+        None
+    };
 }
 
-fn if_let_result(x: Result<(), i32>) {
-    let _: Result<(), i32> = x;
-    let _: Result<(), i32> = x;
+fn if_let_result() {
+    let x: Result<i32, i32> = Ok(1);
+    let _: Result<i32, i32> = x;
+    let _: Result<i32, i32> = x;
     // Input type mismatch, don't trigger
-    let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
+    let _: Result<i32, i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
 }
 
-fn if_let_custom_enum(x: Choice) {
-    let _: Choice = x;
+fn if_let_custom_enum(x: Simple) {
+    let _: Simple = x;
+
     // Don't trigger
-    let _: Choice = if let Choice::A = x {
-        Choice::A
+    let _: Simple = if let Simple::A = x {
+        Simple::A
     } else if true {
-        Choice::B
+        Simple::B
     } else {
         x
     };
 }
 
+mod issue8542 {
+    #[derive(Clone, Copy)]
+    enum E {
+        VariantA(u8, u8),
+        VariantB(u8, bool),
+    }
+
+    enum Complex {
+        A(u8),
+        B(u8, bool),
+        C(u8, i32, f64),
+        D(E, bool),
+    }
+
+    fn match_test() {
+        let ce = Complex::B(8, false);
+        let aa = 0_u8;
+        let bb = false;
+
+        let _: Complex = ce;
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(_) => Complex::A(aa),
+            Complex::B(_, b) => Complex::B(aa, b),
+            Complex::C(_, b, _) => Complex::C(aa, b, 64_f64),
+            Complex::D(e, b) => Complex::D(e, b),
+        };
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(a) => Complex::A(a),
+            Complex::B(a, _) => Complex::B(a, bb),
+            Complex::C(a, _, _) => Complex::C(a, 32_i32, 64_f64),
+            _ => ce,
+        };
+    }
+}
+
+/// Lint triggered when type coercions happen.
+/// Do NOT trigger on any of these.
+mod issue8551 {
+    trait Trait {}
+    struct Struct;
+    impl Trait for Struct {}
+
+    fn optmap(s: Option<&Struct>) -> Option<&dyn Trait> {
+        match s {
+            Some(s) => Some(s),
+            None => None,
+        }
+    }
+
+    fn lint_tests() {
+        let option: Option<&Struct> = None;
+        let _: Option<&dyn Trait> = match option {
+            Some(s) => Some(s),
+            None => None,
+        };
+
+        let _: Option<&dyn Trait> = if true {
+            match option {
+                Some(s) => Some(s),
+                None => None,
+            }
+        } else {
+            None
+        };
+
+        let result: Result<&Struct, i32> = Err(0);
+        let _: Result<&dyn Trait, i32> = match result {
+            Ok(s) => Ok(s),
+            Err(e) => Err(e),
+        };
+
+        let _: Option<&dyn Trait> = if let Some(s) = option { Some(s) } else { None };
+    }
+}
+
+trait Tr {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32>;
+}
+impl Tr for Result<i32, i32> {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32> {
+        match self {
+            Ok(x) => Ok(x),
+            Err(e) => Err(e),
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_match.rs b/src/tools/clippy/tests/ui/needless_match.rs
index 36649de35a6..d210ecff7f1 100644
--- a/src/tools/clippy/tests/ui/needless_match.rs
+++ b/src/tools/clippy/tests/ui/needless_match.rs
@@ -4,33 +4,21 @@
 #![allow(dead_code)]
 
 #[derive(Clone, Copy)]
-enum Choice {
+enum Simple {
     A,
     B,
     C,
     D,
 }
 
-#[allow(unused_mut)]
 fn useless_match() {
-    let mut i = 10;
+    let i = 10;
     let _: i32 = match i {
         0 => 0,
         1 => 1,
         2 => 2,
         _ => i,
     };
-    let _: i32 = match i {
-        0 => 0,
-        1 => 1,
-        ref i => *i,
-    };
-    let mut _i_mut = match i {
-        0 => 0,
-        1 => 1,
-        ref mut i => *i,
-    };
-
     let s = "test";
     let _: &str = match s {
         "a" => "a",
@@ -39,25 +27,26 @@ fn useless_match() {
     };
 }
 
-fn custom_type_match(se: Choice) {
-    let _: Choice = match se {
-        Choice::A => Choice::A,
-        Choice::B => Choice::B,
-        Choice::C => Choice::C,
-        Choice::D => Choice::D,
+fn custom_type_match() {
+    let se = Simple::A;
+    let _: Simple = match se {
+        Simple::A => Simple::A,
+        Simple::B => Simple::B,
+        Simple::C => Simple::C,
+        Simple::D => Simple::D,
     };
     // Don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::A,
-        Choice::B => Choice::B,
-        _ => Choice::C,
+    let _: Simple = match se {
+        Simple::A => Simple::A,
+        Simple::B => Simple::B,
+        _ => Simple::C,
     };
     // Mingled, don't trigger
-    let _: Choice = match se {
-        Choice::A => Choice::B,
-        Choice::B => Choice::C,
-        Choice::C => Choice::D,
-        Choice::D => Choice::A,
+    let _: Simple = match se {
+        Simple::A => Simple::B,
+        Simple::B => Simple::C,
+        Simple::C => Simple::D,
+        Simple::D => Simple::A,
     };
 }
 
@@ -86,37 +75,160 @@ fn result_match() {
         Err(err) => Err(err),
         Ok(a) => Ok(a),
     };
+    // as ref, don't trigger
+    let res = &func_ret_err(0_i32);
+    let _: Result<&i32, &i32> = match *res {
+        Ok(ref x) => Ok(x),
+        Err(ref x) => Err(x),
+    };
 }
 
-fn if_let_option() -> Option<i32> {
-    if let Some(a) = Some(1) { Some(a) } else { None }
+fn if_let_option() {
+    let _ = if let Some(a) = Some(1) { Some(a) } else { None };
+
+    fn do_something() {}
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        Some(a)
+    } else {
+        do_something();
+        None
+    };
+
+    // Don't trigger
+    let _ = if let Some(a) = Some(1) {
+        do_something();
+        Some(a)
+    } else {
+        None
+    };
 }
 
-fn if_let_result(x: Result<(), i32>) {
-    let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x };
-    let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x };
+fn if_let_result() {
+    let x: Result<i32, i32> = Ok(1);
+    let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };
+    let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };
     // Input type mismatch, don't trigger
-    let _: Result<(), i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
+    let _: Result<i32, i32> = if let Err(e) = Ok(1) { Err(e) } else { x };
 }
 
-fn if_let_custom_enum(x: Choice) {
-    let _: Choice = if let Choice::A = x {
-        Choice::A
-    } else if let Choice::B = x {
-        Choice::B
-    } else if let Choice::C = x {
-        Choice::C
+fn if_let_custom_enum(x: Simple) {
+    let _: Simple = if let Simple::A = x {
+        Simple::A
+    } else if let Simple::B = x {
+        Simple::B
+    } else if let Simple::C = x {
+        Simple::C
     } else {
         x
     };
+
     // Don't trigger
-    let _: Choice = if let Choice::A = x {
-        Choice::A
+    let _: Simple = if let Simple::A = x {
+        Simple::A
     } else if true {
-        Choice::B
+        Simple::B
     } else {
         x
     };
 }
 
+mod issue8542 {
+    #[derive(Clone, Copy)]
+    enum E {
+        VariantA(u8, u8),
+        VariantB(u8, bool),
+    }
+
+    enum Complex {
+        A(u8),
+        B(u8, bool),
+        C(u8, i32, f64),
+        D(E, bool),
+    }
+
+    fn match_test() {
+        let ce = Complex::B(8, false);
+        let aa = 0_u8;
+        let bb = false;
+
+        let _: Complex = match ce {
+            Complex::A(a) => Complex::A(a),
+            Complex::B(a, b) => Complex::B(a, b),
+            Complex::C(a, b, c) => Complex::C(a, b, c),
+            Complex::D(E::VariantA(ea, eb), b) => Complex::D(E::VariantA(ea, eb), b),
+            Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b),
+        };
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(_) => Complex::A(aa),
+            Complex::B(_, b) => Complex::B(aa, b),
+            Complex::C(_, b, _) => Complex::C(aa, b, 64_f64),
+            Complex::D(e, b) => Complex::D(e, b),
+        };
+
+        // Don't trigger
+        let _: Complex = match ce {
+            Complex::A(a) => Complex::A(a),
+            Complex::B(a, _) => Complex::B(a, bb),
+            Complex::C(a, _, _) => Complex::C(a, 32_i32, 64_f64),
+            _ => ce,
+        };
+    }
+}
+
+/// Lint triggered when type coercions happen.
+/// Do NOT trigger on any of these.
+mod issue8551 {
+    trait Trait {}
+    struct Struct;
+    impl Trait for Struct {}
+
+    fn optmap(s: Option<&Struct>) -> Option<&dyn Trait> {
+        match s {
+            Some(s) => Some(s),
+            None => None,
+        }
+    }
+
+    fn lint_tests() {
+        let option: Option<&Struct> = None;
+        let _: Option<&dyn Trait> = match option {
+            Some(s) => Some(s),
+            None => None,
+        };
+
+        let _: Option<&dyn Trait> = if true {
+            match option {
+                Some(s) => Some(s),
+                None => None,
+            }
+        } else {
+            None
+        };
+
+        let result: Result<&Struct, i32> = Err(0);
+        let _: Result<&dyn Trait, i32> = match result {
+            Ok(s) => Ok(s),
+            Err(e) => Err(e),
+        };
+
+        let _: Option<&dyn Trait> = if let Some(s) = option { Some(s) } else { None };
+    }
+}
+
+trait Tr {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32>;
+}
+impl Tr for Result<i32, i32> {
+    fn as_mut(&mut self) -> Result<&mut i32, &mut i32> {
+        match self {
+            Ok(x) => Ok(x),
+            Err(e) => Err(e),
+        }
+    }
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/needless_match.stderr b/src/tools/clippy/tests/ui/needless_match.stderr
index ad1525406ad..34c5226f060 100644
--- a/src/tools/clippy/tests/ui/needless_match.stderr
+++ b/src/tools/clippy/tests/ui/needless_match.stderr
@@ -1,5 +1,5 @@
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:17:18
+  --> $DIR/needless_match.rs:16:18
    |
 LL |       let _: i32 = match i {
    |  __________________^
@@ -13,29 +13,7 @@ LL | |     };
    = note: `-D clippy::needless-match` implied by `-D warnings`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:23:18
-   |
-LL |       let _: i32 = match i {
-   |  __________________^
-LL | |         0 => 0,
-LL | |         1 => 1,
-LL | |         ref i => *i,
-LL | |     };
-   | |_____^ help: replace it with: `i`
-
-error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:28:22
-   |
-LL |       let mut _i_mut = match i {
-   |  ______________________^
-LL | |         0 => 0,
-LL | |         1 => 1,
-LL | |         ref mut i => *i,
-LL | |     };
-   | |_____^ help: replace it with: `i`
-
-error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:35:19
+  --> $DIR/needless_match.rs:23:19
    |
 LL |       let _: &str = match s {
    |  ___________________^
@@ -46,19 +24,19 @@ LL | |     };
    | |_____^ help: replace it with: `s`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:43:21
+  --> $DIR/needless_match.rs:32:21
    |
-LL |       let _: Choice = match se {
+LL |       let _: Simple = match se {
    |  _____________________^
-LL | |         Choice::A => Choice::A,
-LL | |         Choice::B => Choice::B,
-LL | |         Choice::C => Choice::C,
-LL | |         Choice::D => Choice::D,
+LL | |         Simple::A => Simple::A,
+LL | |         Simple::B => Simple::B,
+LL | |         Simple::C => Simple::C,
+LL | |         Simple::D => Simple::D,
 LL | |     };
    | |_____^ help: replace it with: `se`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:65:26
+  --> $DIR/needless_match.rs:54:26
    |
 LL |       let _: Option<i32> = match x {
    |  __________________________^
@@ -68,7 +46,7 @@ LL | |     };
    | |_____^ help: replace it with: `x`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:81:31
+  --> $DIR/needless_match.rs:70:31
    |
 LL |       let _: Result<i32, i32> = match Ok(1) {
    |  _______________________________^
@@ -78,7 +56,7 @@ LL | |     };
    | |_____^ help: replace it with: `Ok(1)`
 
 error: this match expression is unnecessary
-  --> $DIR/needless_match.rs:85:31
+  --> $DIR/needless_match.rs:74:31
    |
 LL |       let _: Result<i32, i32> = match func_ret_err(0_i32) {
    |  _______________________________^
@@ -88,35 +66,48 @@ LL | |     };
    | |_____^ help: replace it with: `func_ret_err(0_i32)`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:92:5
+  --> $DIR/needless_match.rs:87:13
    |
-LL |     if let Some(a) = Some(1) { Some(a) } else { None }
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
+LL |     let _ = if let Some(a) = Some(1) { Some(a) } else { None };
+   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `Some(1)`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:96:30
+  --> $DIR/needless_match.rs:110:31
    |
-LL |     let _: Result<(), i32> = if let Err(e) = x { Err(e) } else { x };
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
+LL |     let _: Result<i32, i32> = if let Err(e) = x { Err(e) } else { x };
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:97:30
+  --> $DIR/needless_match.rs:111:31
    |
-LL |     let _: Result<(), i32> = if let Ok(val) = x { Ok(val) } else { x };
-   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
+LL |     let _: Result<i32, i32> = if let Ok(val) = x { Ok(val) } else { x };
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace it with: `x`
 
 error: this if-let expression is unnecessary
-  --> $DIR/needless_match.rs:103:21
+  --> $DIR/needless_match.rs:117:21
    |
-LL |       let _: Choice = if let Choice::A = x {
+LL |       let _: Simple = if let Simple::A = x {
    |  _____________________^
-LL | |         Choice::A
-LL | |     } else if let Choice::B = x {
-LL | |         Choice::B
+LL | |         Simple::A
+LL | |     } else if let Simple::B = x {
+LL | |         Simple::B
 ...  |
 LL | |         x
 LL | |     };
    | |_____^ help: replace it with: `x`
 
-error: aborting due to 12 previous errors
+error: this match expression is unnecessary
+  --> $DIR/needless_match.rs:156:26
+   |
+LL |           let _: Complex = match ce {
+   |  __________________________^
+LL | |             Complex::A(a) => Complex::A(a),
+LL | |             Complex::B(a, b) => Complex::B(a, b),
+LL | |             Complex::C(a, b, c) => Complex::C(a, b, c),
+LL | |             Complex::D(E::VariantA(ea, eb), b) => Complex::D(E::VariantA(ea, eb), b),
+LL | |             Complex::D(E::VariantB(ea, eb), b) => Complex::D(E::VariantB(ea, eb), b),
+LL | |         };
+   | |_________^ help: replace it with: `ce`
+
+error: aborting due to 11 previous errors
 
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
index d721452ae88..c09b07db3dc 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.fixed
@@ -1,13 +1,41 @@
 // run-rustfix
 
-#[warn(clippy::needless_option_as_deref)]
+#![allow(unused)]
+#![warn(clippy::needless_option_as_deref)]
 
 fn main() {
     // should lint
     let _: Option<&usize> = Some(&1);
     let _: Option<&mut usize> = Some(&mut 1);
 
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    let _ = x;
+
     // should not lint
     let _ = Some(Box::new(1)).as_deref();
     let _ = Some(Box::new(1)).as_deref_mut();
+
+    // #7846
+    let mut i = 0;
+    let mut opt_vec = vec![Some(&mut i)];
+    opt_vec[0].as_deref_mut().unwrap();
+
+    let mut i = 0;
+    let x = &mut Some(&mut i);
+    (*x).as_deref_mut();
+
+    // #8047
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    x.as_deref_mut();
+    dbg!(x);
+}
+
+struct S<'a> {
+    opt: Option<&'a mut usize>,
+}
+
+fn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {
+    s.opt.as_deref_mut()
 }
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.rs b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
index bb15512adf6..c3ba27ecccf 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.rs
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.rs
@@ -1,13 +1,41 @@
 // run-rustfix
 
-#[warn(clippy::needless_option_as_deref)]
+#![allow(unused)]
+#![warn(clippy::needless_option_as_deref)]
 
 fn main() {
     // should lint
     let _: Option<&usize> = Some(&1).as_deref();
     let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();
 
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    let _ = x.as_deref_mut();
+
     // should not lint
     let _ = Some(Box::new(1)).as_deref();
     let _ = Some(Box::new(1)).as_deref_mut();
+
+    // #7846
+    let mut i = 0;
+    let mut opt_vec = vec![Some(&mut i)];
+    opt_vec[0].as_deref_mut().unwrap();
+
+    let mut i = 0;
+    let x = &mut Some(&mut i);
+    (*x).as_deref_mut();
+
+    // #8047
+    let mut y = 0;
+    let mut x = Some(&mut y);
+    x.as_deref_mut();
+    dbg!(x);
+}
+
+struct S<'a> {
+    opt: Option<&'a mut usize>,
+}
+
+fn from_field<'a>(s: &'a mut S<'a>) -> Option<&'a mut usize> {
+    s.opt.as_deref_mut()
 }
diff --git a/src/tools/clippy/tests/ui/needless_option_as_deref.stderr b/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
index 5dd507b4a71..bc07db5b38e 100644
--- a/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
+++ b/src/tools/clippy/tests/ui/needless_option_as_deref.stderr
@@ -1,5 +1,5 @@
 error: derefed type is same as origin
-  --> $DIR/needless_option_as_deref.rs:7:29
+  --> $DIR/needless_option_as_deref.rs:8:29
    |
 LL |     let _: Option<&usize> = Some(&1).as_deref();
    |                             ^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&1)`
@@ -7,10 +7,16 @@ LL |     let _: Option<&usize> = Some(&1).as_deref();
    = note: `-D clippy::needless-option-as-deref` implied by `-D warnings`
 
 error: derefed type is same as origin
-  --> $DIR/needless_option_as_deref.rs:8:33
+  --> $DIR/needless_option_as_deref.rs:9:33
    |
 LL |     let _: Option<&mut usize> = Some(&mut 1).as_deref_mut();
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try this: `Some(&mut 1)`
 
-error: aborting due to 2 previous errors
+error: derefed type is same as origin
+  --> $DIR/needless_option_as_deref.rs:13:13
+   |
+LL |     let _ = x.as_deref_mut();
+   |             ^^^^^^^^^^^^^^^^ help: try this: `x`
+
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/no_effect.rs b/src/tools/clippy/tests/ui/no_effect.rs
index 5427c88faf3..7ece66a1ccb 100644
--- a/src/tools/clippy/tests/ui/no_effect.rs
+++ b/src/tools/clippy/tests/ui/no_effect.rs
@@ -78,7 +78,7 @@ impl FnOnce<(&str,)> for GreetStruct2 {
     }
 }
 
-struct GreetStruct3 {}
+struct GreetStruct3;
 
 impl FnOnce<(&str,)> for GreetStruct3 {
     type Output = ();
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
index 7d29445e66c..1290bd8efeb 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.fixed
@@ -80,6 +80,9 @@ fn option_map_unit_fn() {
 
     if let Some(ref value) = x.field { do_nothing(value + captured) }
 
-    if let Some(a) = option() { do_nothing(a) }}
+    if let Some(a) = option() { do_nothing(a) }
+
+    if let Some(value) = option() { println!("{:?}", value) }
+}
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
index b6f834f686f..f3e5b62c65b 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.rs
@@ -80,6 +80,9 @@ fn option_map_unit_fn() {
 
     x.field.map(|ref value| { do_nothing(value + captured) });
 
-    option().map(do_nothing);}
+    option().map(do_nothing);
+
+    option().map(|value| println!("{:?}", value));
+}
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
index 8abdbcafb6e..ab2a294a060 100644
--- a/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/option_map_unit_fn_fixable.stderr
@@ -139,10 +139,18 @@ LL |     x.field.map(|ref value| { do_nothing(value + captured) });
 error: called `map(f)` on an `Option` value where `f` is a function that returns the unit type `()`
   --> $DIR/option_map_unit_fn_fixable.rs:83:5
    |
-LL |     option().map(do_nothing);}
+LL |     option().map(do_nothing);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^-
    |     |
    |     help: try this: `if let Some(a) = option() { do_nothing(a) }`
 
-error: aborting due to 18 previous errors
+error: called `map(f)` on an `Option` value where `f` is a closure that returns the unit type `()`
+  --> $DIR/option_map_unit_fn_fixable.rs:85:5
+   |
+LL |     option().map(|value| println!("{:?}", value));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |     |
+   |     help: try this: `if let Some(value) = option() { println!("{:?}", value) }`
+
+error: aborting due to 19 previous errors
 
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.fixed b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
index 27d4b795a5e..6e0d5a87f68 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.fixed
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.fixed
@@ -3,7 +3,7 @@
 #![warn(clippy::or_then_unwrap)]
 #![allow(clippy::map_identity)]
 
-struct SomeStruct {}
+struct SomeStruct;
 impl SomeStruct {
     fn or(self, _: Option<Self>) -> Self {
         self
@@ -11,7 +11,7 @@ impl SomeStruct {
     fn unwrap(&self) {}
 }
 
-struct SomeOtherStruct {}
+struct SomeOtherStruct;
 impl SomeOtherStruct {
     fn or(self) -> Self {
         self
diff --git a/src/tools/clippy/tests/ui/or_then_unwrap.rs b/src/tools/clippy/tests/ui/or_then_unwrap.rs
index 0dab5ae2f1c..e406a71d46d 100644
--- a/src/tools/clippy/tests/ui/or_then_unwrap.rs
+++ b/src/tools/clippy/tests/ui/or_then_unwrap.rs
@@ -3,7 +3,7 @@
 #![warn(clippy::or_then_unwrap)]
 #![allow(clippy::map_identity)]
 
-struct SomeStruct {}
+struct SomeStruct;
 impl SomeStruct {
     fn or(self, _: Option<Self>) -> Self {
         self
@@ -11,7 +11,7 @@ impl SomeStruct {
     fn unwrap(&self) {}
 }
 
-struct SomeOtherStruct {}
+struct SomeOtherStruct;
 impl SomeOtherStruct {
     fn or(self) -> Self {
         self
diff --git a/src/tools/clippy/tests/ui/panicking_macros.rs b/src/tools/clippy/tests/ui/panicking_macros.rs
index 73380646462..12a0c776ae2 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.rs
+++ b/src/tools/clippy/tests/ui/panicking_macros.rs
@@ -1,8 +1,23 @@
-#![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 #![allow(clippy::assertions_on_constants, clippy::eq_op)]
+#![feature(inline_const)]
+#![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 
 extern crate core;
 
+const _: () = {
+    if 1 == 0 {
+        panic!("A balanced diet means a cupcake in each hand");
+    }
+};
+
+fn inline_const() {
+    let _ = const {
+        if 1 == 0 {
+            panic!("When nothing goes right, go left")
+        }
+    };
+}
+
 fn panic() {
     let a = 2;
     panic!();
diff --git a/src/tools/clippy/tests/ui/panicking_macros.stderr b/src/tools/clippy/tests/ui/panicking_macros.stderr
index bfd1c7a3801..4ceb6d1440f 100644
--- a/src/tools/clippy/tests/ui/panicking_macros.stderr
+++ b/src/tools/clippy/tests/ui/panicking_macros.stderr
@@ -1,5 +1,5 @@
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:8:5
+  --> $DIR/panicking_macros.rs:23:5
    |
 LL |     panic!();
    |     ^^^^^^^^
@@ -7,19 +7,19 @@ LL |     panic!();
    = note: `-D clippy::panic` implied by `-D warnings`
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:9:5
+  --> $DIR/panicking_macros.rs:24:5
    |
 LL |     panic!("message");
    |     ^^^^^^^^^^^^^^^^^
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:10:5
+  --> $DIR/panicking_macros.rs:25:5
    |
 LL |     panic!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:16:5
+  --> $DIR/panicking_macros.rs:31:5
    |
 LL |     todo!();
    |     ^^^^^^^
@@ -27,19 +27,19 @@ LL |     todo!();
    = note: `-D clippy::todo` implied by `-D warnings`
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:17:5
+  --> $DIR/panicking_macros.rs:32:5
    |
 LL |     todo!("message");
    |     ^^^^^^^^^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:18:5
+  --> $DIR/panicking_macros.rs:33:5
    |
 LL |     todo!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:24:5
+  --> $DIR/panicking_macros.rs:39:5
    |
 LL |     unimplemented!();
    |     ^^^^^^^^^^^^^^^^
@@ -47,19 +47,19 @@ LL |     unimplemented!();
    = note: `-D clippy::unimplemented` implied by `-D warnings`
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:25:5
+  --> $DIR/panicking_macros.rs:40:5
    |
 LL |     unimplemented!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:26:5
+  --> $DIR/panicking_macros.rs:41:5
    |
 LL |     unimplemented!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:32:5
+  --> $DIR/panicking_macros.rs:47:5
    |
 LL |     unreachable!();
    |     ^^^^^^^^^^^^^^
@@ -67,37 +67,37 @@ LL |     unreachable!();
    = note: `-D clippy::unreachable` implied by `-D warnings`
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:33:5
+  --> $DIR/panicking_macros.rs:48:5
    |
 LL |     unreachable!("message");
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:34:5
+  --> $DIR/panicking_macros.rs:49:5
    |
 LL |     unreachable!("{} {}", "panic with", "multiple arguments");
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: `panic` should not be present in production code
-  --> $DIR/panicking_macros.rs:40:5
+  --> $DIR/panicking_macros.rs:55:5
    |
 LL |     panic!();
    |     ^^^^^^^^
 
 error: `todo` should not be present in production code
-  --> $DIR/panicking_macros.rs:41:5
+  --> $DIR/panicking_macros.rs:56:5
    |
 LL |     todo!();
    |     ^^^^^^^
 
 error: `unimplemented` should not be present in production code
-  --> $DIR/panicking_macros.rs:42:5
+  --> $DIR/panicking_macros.rs:57:5
    |
 LL |     unimplemented!();
    |     ^^^^^^^^^^^^^^^^
 
 error: usage of the `unreachable!` macro
-  --> $DIR/panicking_macros.rs:43:5
+  --> $DIR/panicking_macros.rs:58:5
    |
 LL |     unreachable!();
    |     ^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/ptr_arg.rs b/src/tools/clippy/tests/ui/ptr_arg.rs
index 03dd938a233..814bbc7af71 100644
--- a/src/tools/clippy/tests/ui/ptr_arg.rs
+++ b/src/tools/clippy/tests/ui/ptr_arg.rs
@@ -112,7 +112,7 @@ mod issue_5644 {
     ) {
     }
 
-    struct S {}
+    struct S;
     impl S {
         fn allowed(
             #[allow(clippy::ptr_arg)] _v: &Vec<u32>,
diff --git a/src/tools/clippy/tests/ui/recursive_format_impl.rs b/src/tools/clippy/tests/ui/recursive_format_impl.rs
index 9241bf7ed74..f72fc77ab99 100644
--- a/src/tools/clippy/tests/ui/recursive_format_impl.rs
+++ b/src/tools/clippy/tests/ui/recursive_format_impl.rs
@@ -66,7 +66,7 @@ impl std::fmt::Display for D {
 
 // Check for use of self as Display, in Display impl
 // Triggers on direct use of self
-struct G {}
+struct G;
 
 impl std::fmt::Display for G {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -75,7 +75,7 @@ impl std::fmt::Display for G {
 }
 
 // Triggers on reference to self
-struct H {}
+struct H;
 
 impl std::fmt::Display for H {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -90,7 +90,7 @@ impl std::fmt::Debug for H {
 }
 
 // Triggers on multiple reference to self
-struct H2 {}
+struct H2;
 
 impl std::fmt::Display for H2 {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
@@ -99,7 +99,7 @@ impl std::fmt::Display for H2 {
 }
 
 // Doesn't trigger on correct deref
-struct I {}
+struct I;
 
 impl std::ops::Deref for I {
     type Target = str;
@@ -122,7 +122,7 @@ impl std::fmt::Debug for I {
 }
 
 // Doesn't trigger on multiple correct deref
-struct I2 {}
+struct I2;
 
 impl std::ops::Deref for I2 {
     type Target = str;
@@ -139,7 +139,7 @@ impl std::fmt::Display for I2 {
 }
 
 // Doesn't trigger on multiple correct deref
-struct I3 {}
+struct I3;
 
 impl std::ops::Deref for I3 {
     type Target = str;
@@ -156,7 +156,7 @@ impl std::fmt::Display for I3 {
 }
 
 // Does trigger when deref resolves to self
-struct J {}
+struct J;
 
 impl std::ops::Deref for J {
     type Target = str;
@@ -178,7 +178,7 @@ impl std::fmt::Debug for J {
     }
 }
 
-struct J2 {}
+struct J2;
 
 impl std::ops::Deref for J2 {
     type Target = str;
@@ -194,7 +194,7 @@ impl std::fmt::Display for J2 {
     }
 }
 
-struct J3 {}
+struct J3;
 
 impl std::ops::Deref for J3 {
     type Target = str;
@@ -210,7 +210,7 @@ impl std::fmt::Display for J3 {
     }
 }
 
-struct J4 {}
+struct J4;
 
 impl std::ops::Deref for J4 {
     type Target = str;
@@ -227,7 +227,7 @@ impl std::fmt::Display for J4 {
 }
 
 // Doesn't trigger on Debug from Display
-struct K {}
+struct K;
 
 impl std::fmt::Debug for K {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
@@ -242,7 +242,7 @@ impl std::fmt::Display for K {
 }
 
 // Doesn't trigger on Display from Debug
-struct K2 {}
+struct K2;
 
 impl std::fmt::Debug for K2 {
     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
diff --git a/src/tools/clippy/tests/ui/redundant_allocation.rs b/src/tools/clippy/tests/ui/redundant_allocation.rs
index 52fbc91e325..80f94e5f3cb 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation.rs
@@ -3,7 +3,7 @@
 #![allow(clippy::blacklisted_name, unused_variables, dead_code)]
 #![allow(unused_imports)]
 
-pub struct MyStruct {}
+pub struct MyStruct;
 
 pub struct SubT<T> {
     foo: T,
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
index ef089b25f47..e7ed84731c0 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.fixed
@@ -4,7 +4,7 @@
 #![allow(clippy::blacklisted_name, unused_variables, dead_code)]
 #![allow(unused_imports)]
 
-pub struct MyStruct {}
+pub struct MyStruct;
 
 pub struct SubT<T> {
     foo: T,
diff --git a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
index fefa87721d7..de763f98b5c 100644
--- a/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
+++ b/src/tools/clippy/tests/ui/redundant_allocation_fixable.rs
@@ -4,7 +4,7 @@
 #![allow(clippy::blacklisted_name, unused_variables, dead_code)]
 #![allow(unused_imports)]
 
-pub struct MyStruct {}
+pub struct MyStruct;
 
 pub struct SubT<T> {
     foo: T,
diff --git a/src/tools/clippy/tests/ui/redundant_clone.fixed b/src/tools/clippy/tests/ui/redundant_clone.fixed
index 16b40dcd902..1525f6a93df 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.fixed
+++ b/src/tools/clippy/tests/ui/redundant_clone.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 // rustfix-only-machine-applicable
 
-#![allow(clippy::implicit_clone)]
+#![allow(clippy::implicit_clone, clippy::drop_non_drop)]
 use std::ffi::OsString;
 use std::path::Path;
 
diff --git a/src/tools/clippy/tests/ui/redundant_clone.rs b/src/tools/clippy/tests/ui/redundant_clone.rs
index bd3d7365229..2f82aefd928 100644
--- a/src/tools/clippy/tests/ui/redundant_clone.rs
+++ b/src/tools/clippy/tests/ui/redundant_clone.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 // rustfix-only-machine-applicable
 
-#![allow(clippy::implicit_clone)]
+#![allow(clippy::implicit_clone, clippy::drop_non_drop)]
 use std::ffi::OsString;
 use std::path::Path;
 
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
index 921249606ad..acc8f1e25b6 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.fixed
@@ -3,7 +3,7 @@
 #![allow(unused)]
 
 #[derive(Debug)]
-struct Foo {}
+struct Foo;
 
 const VAR_ONE: &str = "Test constant #1"; // ERROR Consider removing 'static.
 
diff --git a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
index 4d4b249d076..f2f0f78659c 100644
--- a/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/tests/ui/redundant_static_lifetimes.rs
@@ -3,7 +3,7 @@
 #![allow(unused)]
 
 #[derive(Debug)]
-struct Foo {}
+struct Foo;
 
 const VAR_ONE: &'static str = "Test constant #1"; // ERROR Consider removing 'static.
 
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
index 631042c616b..14c331f67e7 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.fixed
@@ -75,6 +75,8 @@ fn result_map_unit_fn() {
 
 
     if let Ok(ref value) = x.field { do_nothing(value + captured) }
+
+    if let Ok(value) = x.field { println!("{:?}", value) }
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
index 679eb232626..8b0fca9ece1 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.rs
@@ -75,6 +75,8 @@ fn result_map_unit_fn() {
 
 
     x.field.map(|ref value| { do_nothing(value + captured) });
+
+    x.field.map(|value| println!("{:?}", value));
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
index 4f3a8c6b792..782febd5264 100644
--- a/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
+++ b/src/tools/clippy/tests/ui/result_map_unit_fn_fixable.stderr
@@ -136,5 +136,13 @@ LL |     x.field.map(|ref value| { do_nothing(value + captured) });
    |     |
    |     help: try this: `if let Ok(ref value) = x.field { do_nothing(value + captured) }`
 
-error: aborting due to 17 previous errors
+error: called `map(f)` on an `Result` value where `f` is a closure that returns the unit type `()`
+  --> $DIR/result_map_unit_fn_fixable.rs:79:5
+   |
+LL |     x.field.map(|value| println!("{:?}", value));
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
+   |     |
+   |     help: try this: `if let Ok(value) = x.field { println!("{:?}", value) }`
+
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/same_item_push.rs b/src/tools/clippy/tests/ui/same_item_push.rs
index 9d420ec672a..99964f0de07 100644
--- a/src/tools/clippy/tests/ui/same_item_push.rs
+++ b/src/tools/clippy/tests/ui/same_item_push.rs
@@ -120,7 +120,7 @@ fn main() {
     }
     // Fix #5979
     #[derive(Clone)]
-    struct S {}
+    struct S;
 
     trait T {}
     impl T for S {}
diff --git a/src/tools/clippy/tests/ui/single_element_loop.fixed b/src/tools/clippy/tests/ui/single_element_loop.fixed
index c307afffcb8..63d31ff83f9 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.fixed
+++ b/src/tools/clippy/tests/ui/single_element_loop.fixed
@@ -6,11 +6,31 @@ fn main() {
     let item1 = 2;
     {
         let item = &item1;
-        println!("{}", item);
+        dbg!(item);
     }
 
     {
         let item = &item1;
-        println!("{:?}", item);
+        dbg!(item);
+    }
+
+    {
+        let item = &(0..5);
+        dbg!(item);
+    }
+
+    {
+        let item = &mut (0..5);
+        dbg!(item);
+    }
+
+    {
+        let item = 0..5;
+        dbg!(item);
+    }
+
+    {
+        let item = 0..5;
+        dbg!(item);
     }
 }
diff --git a/src/tools/clippy/tests/ui/single_element_loop.rs b/src/tools/clippy/tests/ui/single_element_loop.rs
index 2c0c03b7211..2cda5a329d2 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.rs
+++ b/src/tools/clippy/tests/ui/single_element_loop.rs
@@ -5,10 +5,26 @@
 fn main() {
     let item1 = 2;
     for item in &[item1] {
-        println!("{}", item);
+        dbg!(item);
     }
 
     for item in [item1].iter() {
-        println!("{:?}", item);
+        dbg!(item);
+    }
+
+    for item in &[0..5] {
+        dbg!(item);
+    }
+
+    for item in [0..5].iter_mut() {
+        dbg!(item);
+    }
+
+    for item in [0..5] {
+        dbg!(item);
+    }
+
+    for item in [0..5].into_iter() {
+        dbg!(item);
     }
 }
diff --git a/src/tools/clippy/tests/ui/single_element_loop.stderr b/src/tools/clippy/tests/ui/single_element_loop.stderr
index f52ca8c5a9b..0aeb8da1a2e 100644
--- a/src/tools/clippy/tests/ui/single_element_loop.stderr
+++ b/src/tools/clippy/tests/ui/single_element_loop.stderr
@@ -2,7 +2,7 @@ error: for loop over a single element
   --> $DIR/single_element_loop.rs:7:5
    |
 LL | /     for item in &[item1] {
-LL | |         println!("{}", item);
+LL | |         dbg!(item);
 LL | |     }
    | |_____^
    |
@@ -11,7 +11,7 @@ help: try
    |
 LL ~     {
 LL +         let item = &item1;
-LL +         println!("{}", item);
+LL +         dbg!(item);
 LL +     }
    |
 
@@ -19,7 +19,7 @@ error: for loop over a single element
   --> $DIR/single_element_loop.rs:11:5
    |
 LL | /     for item in [item1].iter() {
-LL | |         println!("{:?}", item);
+LL | |         dbg!(item);
 LL | |     }
    | |_____^
    |
@@ -27,9 +27,73 @@ help: try
    |
 LL ~     {
 LL +         let item = &item1;
-LL +         println!("{:?}", item);
+LL +         dbg!(item);
 LL +     }
    |
 
-error: aborting due to 2 previous errors
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:15:5
+   |
+LL | /     for item in &[0..5] {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = &(0..5);
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:19:5
+   |
+LL | /     for item in [0..5].iter_mut() {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = &mut (0..5);
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:23:5
+   |
+LL | /     for item in [0..5] {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = 0..5;
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: for loop over a single element
+  --> $DIR/single_element_loop.rs:27:5
+   |
+LL | /     for item in [0..5].into_iter() {
+LL | |         dbg!(item);
+LL | |     }
+   | |_____^
+   |
+help: try
+   |
+LL ~     {
+LL +         let item = 0..5;
+LL +         dbg!(item);
+LL +     }
+   |
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
index 21de19a2601..f5ca91143af 100644
--- a/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
+++ b/src/tools/clippy/tests/ui/trait_duplication_in_bounds.rs
@@ -62,7 +62,7 @@ trait BadTrait: Default + Clone {
 }
 
 #[derive(Default, Clone)]
-struct Life {}
+struct Life;
 
 impl T for Life {
     // this should not warn
@@ -85,7 +85,7 @@ trait Iter: Iterator {
     }
 }
 
-struct Foo {}
+struct Foo;
 
 trait FooIter: Iterator<Item = Foo> {
     fn bar()
diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs
index 9b681a79aae..5b688ce4d64 100644
--- a/src/tools/clippy/tests/ui/transmute.rs
+++ b/src/tools/clippy/tests/ui/transmute.rs
@@ -73,6 +73,10 @@ fn crosspointer() {
 fn int_to_char() {
     let _: char = unsafe { std::mem::transmute(0_u32) };
     let _: char = unsafe { std::mem::transmute(0_i32) };
+
+    // These shouldn't warn
+    const _: char = unsafe { std::mem::transmute(0_u32) };
+    const _: char = unsafe { std::mem::transmute(0_i32) };
 }
 
 #[warn(clippy::transmute_int_to_bool)]
@@ -130,9 +134,12 @@ mod num_to_bytes {
     }
 }
 
-fn bytes_to_str(b: &[u8], mb: &mut [u8]) {
-    let _: &str = unsafe { std::mem::transmute(b) };
+fn bytes_to_str(mb: &mut [u8]) {
+    const B: &[u8] = b"";
+
+    let _: &str = unsafe { std::mem::transmute(B) };
     let _: &mut str = unsafe { std::mem::transmute(mb) };
+    const _: &str = unsafe { std::mem::transmute(B) };
 }
 
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/transmute.stderr b/src/tools/clippy/tests/ui/transmute.stderr
index 86537153e32..72a386e8fa6 100644
--- a/src/tools/clippy/tests/ui/transmute.stderr
+++ b/src/tools/clippy/tests/ui/transmute.stderr
@@ -107,7 +107,7 @@ LL |     let _: char = unsafe { std::mem::transmute(0_i32) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
 
 error: transmute from a `u8` to a `bool`
-  --> $DIR/transmute.rs:80:28
+  --> $DIR/transmute.rs:84:28
    |
 LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
@@ -115,7 +115,7 @@ LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    = note: `-D clippy::transmute-int-to-bool` implied by `-D warnings`
 
 error: transmute from a `u32` to a `f32`
-  --> $DIR/transmute.rs:86:31
+  --> $DIR/transmute.rs:90:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
@@ -123,25 +123,25 @@ LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    = note: `-D clippy::transmute-int-to-float` implied by `-D warnings`
 
 error: transmute from a `i32` to a `f32`
-  --> $DIR/transmute.rs:87:31
+  --> $DIR/transmute.rs:91:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_i32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
 
 error: transmute from a `u64` to a `f64`
-  --> $DIR/transmute.rs:88:31
+  --> $DIR/transmute.rs:92:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_u64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
 
 error: transmute from a `i64` to a `f64`
-  --> $DIR/transmute.rs:89:31
+  --> $DIR/transmute.rs:93:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_i64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:109:30
+  --> $DIR/transmute.rs:113:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@@ -149,96 +149,102 @@ LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    = note: `-D clippy::transmute-num-to-bytes` implied by `-D warnings`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:110:30
+  --> $DIR/transmute.rs:114:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:111:31
+  --> $DIR/transmute.rs:115:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:112:30
+  --> $DIR/transmute.rs:116:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:113:30
+  --> $DIR/transmute.rs:117:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:114:31
+  --> $DIR/transmute.rs:118:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `f32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:115:30
+  --> $DIR/transmute.rs:119:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0.0f32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
 
 error: transmute from a `f64` to a `[u8; 8]`
-  --> $DIR/transmute.rs:116:30
+  --> $DIR/transmute.rs:120:30
    |
 LL |             let _: [u8; 8] = std::mem::transmute(0.0f64);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:121:30
+  --> $DIR/transmute.rs:125:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:122:30
+  --> $DIR/transmute.rs:126:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:123:31
+  --> $DIR/transmute.rs:127:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> $DIR/transmute.rs:124:30
+  --> $DIR/transmute.rs:128:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> $DIR/transmute.rs:125:30
+  --> $DIR/transmute.rs:129:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> $DIR/transmute.rs:126:31
+  --> $DIR/transmute.rs:130:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> $DIR/transmute.rs:134:28
+  --> $DIR/transmute.rs:140:28
    |
-LL |     let _: &str = unsafe { std::mem::transmute(b) };
-   |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(b).unwrap()`
+LL |     let _: &str = unsafe { std::mem::transmute(B) };
+   |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
    |
    = note: `-D clippy::transmute-bytes-to-str` implied by `-D warnings`
 
 error: transmute from a `&mut [u8]` to a `&mut str`
-  --> $DIR/transmute.rs:135:32
+  --> $DIR/transmute.rs:141:32
    |
 LL |     let _: &mut str = unsafe { std::mem::transmute(mb) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
 
-error: aborting due to 38 previous errors
+error: transmute from a `&[u8]` to a `&str`
+  --> $DIR/transmute.rs:142:30
+   |
+LL |     const _: &str = unsafe { std::mem::transmute(B) };
+   |                              ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
+
+error: aborting due to 39 previous errors
 
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
index 380303d8152..afa337c45f4 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.rs
@@ -1,5 +1,9 @@
+// aux-build:proc_macro_unsafe.rs
+
 #![warn(clippy::undocumented_unsafe_blocks)]
 
+extern crate proc_macro_unsafe;
+
 // Valid comments
 
 fn nested_local() {
@@ -89,11 +93,6 @@ fn block_comment_newlines() {
     unsafe {}
 }
 
-#[rustfmt::skip]
-fn inline_block_comment() {
-    /* Safety: */unsafe {}
-}
-
 fn block_comment_with_extras() {
     /* This is a description
      * SAFETY:
@@ -209,8 +208,54 @@ fn local_nest() {
     let _ = [(42, unsafe {}, unsafe {}), (52, unsafe {}, unsafe {})];
 }
 
+fn in_fn_call(x: *const u32) {
+    fn f(x: u32) {}
+
+    // Safety: reason
+    f(unsafe { *x });
+}
+
+fn multi_in_fn_call(x: *const u32) {
+    fn f(x: u32, y: u32) {}
+
+    // Safety: reason
+    f(unsafe { *x }, unsafe { *x });
+}
+
+fn in_multiline_fn_call(x: *const u32) {
+    fn f(x: u32, y: u32) {}
+
+    f(
+        // Safety: reason
+        unsafe { *x },
+        0,
+    );
+}
+
+fn in_macro_call(x: *const u32) {
+    // Safety: reason
+    println!("{}", unsafe { *x });
+}
+
+fn in_multiline_macro_call(x: *const u32) {
+    println!(
+        "{}",
+        // Safety: reason
+        unsafe { *x },
+    );
+}
+
+fn from_proc_macro() {
+    proc_macro_unsafe::unsafe_block!(token);
+}
+
 // Invalid comments
 
+#[rustfmt::skip]
+fn inline_block_comment() {
+    /* Safety: */ unsafe {}
+}
+
 fn no_comment() {
     unsafe {}
 }
diff --git a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
index f69d0da54e0..856a07fd316 100644
--- a/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/src/tools/clippy/tests/ui/undocumented_unsafe_blocks.stderr
@@ -1,114 +1,110 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:215:5
+  --> $DIR/undocumented_unsafe_blocks.rs:256:19
+   |
+LL |     /* Safety: */ unsafe {}
+   |                   ^^^^^^^^^
+   |
+   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:260:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
    |
-   = note: `-D clippy::undocumented-unsafe-blocks` implied by `-D warnings`
-help: consider adding a safety comment
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:264:14
    |
-LL ~     // SAFETY: ...
-LL +     unsafe {}
+LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
+   |              ^^^^^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:219:5
+  --> $DIR/undocumented_unsafe_blocks.rs:264:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                             ^^^^^^^^^^^^^
    |
-help: consider adding a safety comment
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:264:48
    |
-LL ~     // SAFETY: ...
-LL +     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
+LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
+   |                                                ^^^^^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:223:5
+  --> $DIR/undocumented_unsafe_blocks.rs:268:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |                  ^^^^^^^^^
    |
-help: consider adding a safety comment
+   = help: consider adding a safety comment on the preceding line
+
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:268:37
    |
-LL ~     // SAFETY: ...
-LL +     let _ = (42, unsafe {}, "test", unsafe {});
+LL |     let _ = (42, unsafe {}, "test", unsafe {});
+   |                                     ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:227:5
+  --> $DIR/undocumented_unsafe_blocks.rs:272:14
    |
 LL |     let _ = *unsafe { &42 };
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = *unsafe { &42 };
+   |              ^^^^^^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:232:5
+  --> $DIR/undocumented_unsafe_blocks.rs:277:19
    |
 LL |     let _ = match unsafe {} {
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = match unsafe {} {
+   |                   ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:238:5
+  --> $DIR/undocumented_unsafe_blocks.rs:283:14
    |
 LL |     let _ = &unsafe {};
-   |     ^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = &unsafe {};
+   |              ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:242:5
+  --> $DIR/undocumented_unsafe_blocks.rs:287:14
    |
 LL |     let _ = [unsafe {}; 5];
-   |     ^^^^^^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = [unsafe {}; 5];
+   |              ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:246:5
+  --> $DIR/undocumented_unsafe_blocks.rs:291:13
    |
 LL |     let _ = unsafe {};
-   |     ^^^^^^^^^^^^^^^^^^
-   |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     let _ = unsafe {};
+   |             ^^^^^^^^^
    |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:256:8
+  --> $DIR/undocumented_unsafe_blocks.rs:301:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     t!(// SAFETY: ...
-LL ~     unsafe {});
-   |
+   = help: consider adding a safety comment on the preceding line
 
-error: unsafe block in macro expansion missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:262:13
+error: unsafe block missing a safety comment
+  --> $DIR/undocumented_unsafe_blocks.rs:307:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -116,56 +112,40 @@ LL |             unsafe {}
 LL |     t!();
    |     ---- in this macro invocation
    |
-   = help: consider adding a safety comment in the macro definition
+   = help: consider adding a safety comment on the preceding line
    = note: this error originates in the macro `t` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:270:5
+  --> $DIR/undocumented_unsafe_blocks.rs:315:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL ~     unsafe {} // SAFETY:
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:274:5
+  --> $DIR/undocumented_unsafe_blocks.rs:319:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL +     unsafe {
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:284:5
+  --> $DIR/undocumented_unsafe_blocks.rs:329:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     // SAFETY: ...
-LL ~     unsafe {};
-   |
+   = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:288:20
+  --> $DIR/undocumented_unsafe_blocks.rs:333:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-help: consider adding a safety comment
-   |
-LL ~     println!("{}", // SAFETY: ...
-LL ~     unsafe { String::from_utf8_unchecked(vec![]) });
-   |
+   = help: consider adding a safety comment on the preceding line
 
-error: aborting due to 14 previous errors
+error: aborting due to 18 previous errors
 
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast.rs b/src/tools/clippy/tests/ui/unnecessary_cast.rs
index b77c19f2ba5..62c3e963686 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast.rs
@@ -30,4 +30,10 @@ fn main() {
 
     // do not lint cast to cfg-dependant type
     1 as std::os::raw::c_char;
+
+    // do not lint cast to alias type
+    1 as I32Alias;
+    &1 as &I32Alias;
 }
+
+type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
index 3332f49c80c..36800c5340d 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.fixed
@@ -42,4 +42,9 @@ fn main() {
 
     let _ = -1_i32;
     let _ = -1.0_f32;
+
+    let _ = 1 as I32Alias;
+    let _ = &1 as &I32Alias;
 }
+
+type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
index ec01e938779..d4b6bb952ab 100644
--- a/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
+++ b/src/tools/clippy/tests/ui/unnecessary_cast_fixable.rs
@@ -42,4 +42,9 @@ fn main() {
 
     let _ = -1 as i32;
     let _ = -1.0 as f32;
+
+    let _ = 1 as I32Alias;
+    let _ = &1 as &I32Alias;
 }
+
+type I32Alias = i32;
diff --git a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
index 690d705573d..bafca91917a 100644
--- a/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
+++ b/src/tools/clippy/tests/ui/unsafe_derive_deserialize.rs
@@ -6,7 +6,7 @@ extern crate serde;
 use serde::Deserialize;
 
 #[derive(Deserialize)]
-pub struct A {}
+pub struct A;
 impl A {
     pub unsafe fn new(_a: i32, _b: i32) -> Self {
         Self {}
@@ -14,13 +14,13 @@ impl A {
 }
 
 #[derive(Deserialize)]
-pub struct B {}
+pub struct B;
 impl B {
     pub unsafe fn unsafe_method(&self) {}
 }
 
 #[derive(Deserialize)]
-pub struct C {}
+pub struct C;
 impl C {
     pub fn unsafe_block(&self) {
         unsafe {}
@@ -28,7 +28,7 @@ impl C {
 }
 
 #[derive(Deserialize)]
-pub struct D {}
+pub struct D;
 impl D {
     pub fn inner_unsafe_fn(&self) {
         unsafe fn inner() {}
@@ -36,7 +36,7 @@ impl D {
 }
 
 // Does not derive `Deserialize`, should be ignored
-pub struct E {}
+pub struct E;
 impl E {
     pub unsafe fn new(_a: i32, _b: i32) -> Self {
         Self {}
@@ -55,12 +55,12 @@ impl E {
 
 // Does not have methods using `unsafe`, should be ignored
 #[derive(Deserialize)]
-pub struct F {}
+pub struct F;
 
 // Check that we honor the `allow` attribute on the ADT
 #[allow(clippy::unsafe_derive_deserialize)]
 #[derive(Deserialize)]
-pub struct G {}
+pub struct G;
 impl G {
     pub fn unsafe_block(&self) {
         unsafe {}
diff --git a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
index a1f616733bd..cde4e96d668 100644
--- a/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/tests/ui/unsafe_removed_from_name.rs
@@ -14,8 +14,8 @@ use std::cell::UnsafeCell as Dangerunsafe;
 use std::cell::UnsafeCell as Bombsawayunsafe;
 
 mod mod_with_some_unsafe_things {
-    pub struct Safe {}
-    pub struct Unsafe {}
+    pub struct Safe;
+    pub struct Unsafe;
 }
 
 use mod_with_some_unsafe_things::Unsafe as LieAboutModSafety;
diff --git a/src/tools/clippy/tests/ui/unused_self.rs b/src/tools/clippy/tests/ui/unused_self.rs
index 7a4bbdda1ab..08bf58fec7c 100644
--- a/src/tools/clippy/tests/ui/unused_self.rs
+++ b/src/tools/clippy/tests/ui/unused_self.rs
@@ -5,7 +5,7 @@ mod unused_self {
     use std::pin::Pin;
     use std::sync::{Arc, Mutex};
 
-    struct A {}
+    struct A;
 
     impl A {
         fn unused_self_move(self) {}
@@ -27,7 +27,7 @@ mod unused_self {
 }
 
 mod unused_self_allow {
-    struct A {}
+    struct A;
 
     impl A {
         // shouldn't trigger
@@ -35,7 +35,7 @@ mod unused_self_allow {
         fn unused_self_move(self) {}
     }
 
-    struct B {}
+    struct B;
 
     // shouldn't trigger
     #[allow(clippy::unused_self)]
@@ -43,7 +43,7 @@ mod unused_self_allow {
         fn unused_self_move(self) {}
     }
 
-    struct C {}
+    struct C;
 
     #[allow(clippy::unused_self)]
     impl C {
@@ -120,7 +120,7 @@ mod used_self {
 mod not_applicable {
     use std::fmt;
 
-    struct A {}
+    struct A;
 
     impl fmt::Debug for A {
         fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index 9d216f56ae6..3e62ffe74fe 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -16,7 +16,7 @@ extern crate proc_macro_derive;
 fn main() {}
 
 mod use_self {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Self {
@@ -35,7 +35,7 @@ mod use_self {
 }
 
 mod better {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Self {
@@ -123,7 +123,7 @@ mod macros {
         };
     }
 
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         use_self_expand!(); // Should not lint in local macros
@@ -134,7 +134,7 @@ mod macros {
 }
 
 mod nesting {
-    struct Foo {}
+    struct Foo;
     impl Foo {
         fn foo() {
             #[allow(unused_imports)]
@@ -209,7 +209,7 @@ mod issue3410 {
 #[allow(clippy::no_effect, path_statements)]
 mod rustfix {
     mod nested {
-        pub struct A {}
+        pub struct A;
     }
 
     impl nested::A {
@@ -227,7 +227,7 @@ mod rustfix {
 }
 
 mod issue3567 {
-    struct TestStruct {}
+    struct TestStruct;
     impl TestStruct {
         fn from_something() -> Self {
             Self {}
@@ -248,7 +248,7 @@ mod issue3567 {
 mod paths_created_by_lowering {
     use std::ops::Range;
 
-    struct S {}
+    struct S;
 
     impl S {
         const A: usize = 0;
@@ -382,7 +382,7 @@ mod issue4305 {
 }
 
 mod lint_at_item_level {
-    struct Foo {}
+    struct Foo;
 
     #[allow(clippy::use_self)]
     impl Foo {
@@ -400,7 +400,7 @@ mod lint_at_item_level {
 }
 
 mod lint_at_impl_item_level {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         #[allow(clippy::use_self)]
@@ -433,8 +433,8 @@ mod issue4734 {
 mod nested_paths {
     use std::convert::Into;
     mod submod {
-        pub struct B {}
-        pub struct C {}
+        pub struct B;
+        pub struct C;
 
         impl Into<C> for B {
             fn into(self) -> C {
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index 5f604fe25e4..da2faddee12 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -16,7 +16,7 @@ extern crate proc_macro_derive;
 fn main() {}
 
 mod use_self {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Foo {
@@ -35,7 +35,7 @@ mod use_self {
 }
 
 mod better {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         fn new() -> Self {
@@ -123,7 +123,7 @@ mod macros {
         };
     }
 
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         use_self_expand!(); // Should not lint in local macros
@@ -134,7 +134,7 @@ mod macros {
 }
 
 mod nesting {
-    struct Foo {}
+    struct Foo;
     impl Foo {
         fn foo() {
             #[allow(unused_imports)]
@@ -209,7 +209,7 @@ mod issue3410 {
 #[allow(clippy::no_effect, path_statements)]
 mod rustfix {
     mod nested {
-        pub struct A {}
+        pub struct A;
     }
 
     impl nested::A {
@@ -227,7 +227,7 @@ mod rustfix {
 }
 
 mod issue3567 {
-    struct TestStruct {}
+    struct TestStruct;
     impl TestStruct {
         fn from_something() -> Self {
             Self {}
@@ -248,7 +248,7 @@ mod issue3567 {
 mod paths_created_by_lowering {
     use std::ops::Range;
 
-    struct S {}
+    struct S;
 
     impl S {
         const A: usize = 0;
@@ -382,7 +382,7 @@ mod issue4305 {
 }
 
 mod lint_at_item_level {
-    struct Foo {}
+    struct Foo;
 
     #[allow(clippy::use_self)]
     impl Foo {
@@ -400,7 +400,7 @@ mod lint_at_item_level {
 }
 
 mod lint_at_impl_item_level {
-    struct Foo {}
+    struct Foo;
 
     impl Foo {
         #[allow(clippy::use_self)]
@@ -433,8 +433,8 @@ mod issue4734 {
 mod nested_paths {
     use std::convert::Into;
     mod submod {
-        pub struct B {}
-        pub struct C {}
+        pub struct B;
+        pub struct C;
 
         impl Into<C> for B {
             fn into(self) -> C {
diff --git a/src/tools/clippy/tests/ui/useless_attribute.fixed b/src/tools/clippy/tests/ui/useless_attribute.fixed
index a5fcde768f1..ce58a80347b 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.fixed
+++ b/src/tools/clippy/tests/ui/useless_attribute.fixed
@@ -42,7 +42,7 @@ mod a {
     mod b {
         #[allow(dead_code)]
         #[allow(unreachable_pub)]
-        pub struct C {}
+        pub struct C;
     }
 
     #[allow(unreachable_pub)]
diff --git a/src/tools/clippy/tests/ui/useless_attribute.rs b/src/tools/clippy/tests/ui/useless_attribute.rs
index 0396d39e3d5..c82bb9ba07f 100644
--- a/src/tools/clippy/tests/ui/useless_attribute.rs
+++ b/src/tools/clippy/tests/ui/useless_attribute.rs
@@ -42,7 +42,7 @@ mod a {
     mod b {
         #[allow(dead_code)]
         #[allow(unreachable_pub)]
-        pub struct C {}
+        pub struct C;
     }
 
     #[allow(unreachable_pub)]
diff --git a/src/tools/clippy/tests/versioncheck.rs b/src/tools/clippy/tests/versioncheck.rs
index 77102b8cac0..38498ebdcf2 100644
--- a/src/tools/clippy/tests/versioncheck.rs
+++ b/src/tools/clippy/tests/versioncheck.rs
@@ -3,34 +3,32 @@
 #![allow(clippy::single_match_else)]
 
 use rustc_tools_util::VersionInfo;
+use std::fs;
 
 #[test]
 fn check_that_clippy_lints_and_clippy_utils_have_the_same_version_as_clippy() {
+    fn read_version(path: &str) -> String {
+        let contents = fs::read_to_string(path).unwrap_or_else(|e| panic!("error reading `{}`: {:?}", path, e));
+        contents
+            .lines()
+            .filter_map(|l| l.split_once('='))
+            .find_map(|(k, v)| (k.trim() == "version").then(|| v.trim()))
+            .unwrap_or_else(|| panic!("error finding version in `{}`", path))
+            .to_string()
+    }
+
     // do not run this test inside the upstream rustc repo:
     // https://github.com/rust-lang/rust-clippy/issues/6683
     if option_env!("RUSTC_TEST_SUITE").is_some() {
         return;
     }
 
-    let clippy_meta = cargo_metadata::MetadataCommand::new()
-        .no_deps()
-        .exec()
-        .expect("could not obtain cargo metadata");
+    let clippy_version = read_version("Cargo.toml");
+    let clippy_lints_version = read_version("clippy_lints/Cargo.toml");
+    let clippy_utils_version = read_version("clippy_utils/Cargo.toml");
 
-    for krate in &["clippy_lints", "clippy_utils"] {
-        let krate_meta = cargo_metadata::MetadataCommand::new()
-            .current_dir(std::env::current_dir().unwrap().join(krate))
-            .no_deps()
-            .exec()
-            .expect("could not obtain cargo metadata");
-        assert_eq!(krate_meta.packages[0].version, clippy_meta.packages[0].version);
-        for package in &clippy_meta.packages[0].dependencies {
-            if package.name == *krate {
-                assert!(package.req.matches(&krate_meta.packages[0].version));
-                break;
-            }
-        }
-    }
+    assert_eq!(clippy_version, clippy_lints_version);
+    assert_eq!(clippy_version, clippy_utils_version);
 }
 
 #[test]