about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-04-15 01:57:52 +0000
committerbors <bors@rust-lang.org>2022-04-15 01:57:52 +0000
commit0bc93b67f55ed04de7b462af69f06407844c6531 (patch)
tree1544ba68bd9a4a11f91b8a64e592ef71d09999a1
parent80bcd9bc6e91cc00fbf7c9bf7aab13c0a4ec2367 (diff)
parent70f7c624e442c3049d440cd20f8d77b66580105c (diff)
downloadrust-0bc93b67f55ed04de7b462af69f06407844c6531.tar.gz
rust-0bc93b67f55ed04de7b462af69f06407844c6531.zip
Auto merge of #8563 - Jarcho:let_unit_1502, r=Jarcho
Don't lint `let_unit_value` when needed for type inferenece

fixes: #1502

Pinging `@dtolnay.` I think this is enough to fix the issue. Do you have a good list crates to test this on?

changelog: Don't lint `let_unit_value` when needed for type inference
-rw-r--r--clippy_lints/src/lib.register_all.rs1
-rw-r--r--clippy_lints/src/lib.register_pedantic.rs1
-rw-r--r--clippy_lints/src/lib.register_style.rs1
-rw-r--r--clippy_lints/src/unit_types/let_unit_value.rs80
-rw-r--r--clippy_lints/src/unit_types/mod.rs2
-rw-r--r--clippy_utils/src/visitors.rs34
-rw-r--r--tests/ui-internal/interning_defined_symbol.fixed2
-rw-r--r--tests/ui-internal/interning_defined_symbol.rs2
-rw-r--r--tests/ui-toml/functions_maxlines/test.rs1
-rw-r--r--tests/ui-toml/functions_maxlines/test.stderr8
-rw-r--r--tests/ui/cast_alignment.rs6
-rw-r--r--tests/ui/cast_slice_different_sizes.rs2
-rw-r--r--tests/ui/cast_slice_different_sizes.stderr12
-rw-r--r--tests/ui/crashes/ice-5944.rs1
-rw-r--r--tests/ui/default_numeric_fallback_f64.fixed15
-rw-r--r--tests/ui/default_numeric_fallback_f64.rs15
-rw-r--r--tests/ui/default_numeric_fallback_f64.stderr46
-rw-r--r--tests/ui/default_numeric_fallback_i32.fixed13
-rw-r--r--tests/ui/default_numeric_fallback_i32.rs13
-rw-r--r--tests/ui/default_numeric_fallback_i32.stderr50
-rw-r--r--tests/ui/doc_unsafe.rs2
-rw-r--r--tests/ui/doc_unsafe.stderr12
-rw-r--r--tests/ui/iter_overeager_cloned.fixed2
-rw-r--r--tests/ui/iter_overeager_cloned.rs2
-rw-r--r--tests/ui/let_underscore_drop.rs1
-rw-r--r--tests/ui/let_underscore_drop.stderr6
-rw-r--r--tests/ui/let_unit.fixed52
-rw-r--r--tests/ui/let_unit.rs52
-rw-r--r--tests/ui/let_unit.stderr71
-rw-r--r--tests/ui/needless_for_each_fixable.fixed7
-rw-r--r--tests/ui/needless_for_each_fixable.rs7
-rw-r--r--tests/ui/needless_for_each_fixable.stderr16
-rw-r--r--tests/ui/needless_late_init.rs1
-rw-r--r--tests/ui/needless_late_init.stderr18
-rw-r--r--tests/ui/non_expressive_names.rs2
-rw-r--r--tests/ui/option_if_let_else.fixed7
-rw-r--r--tests/ui/option_if_let_else.rs7
-rw-r--r--tests/ui/option_if_let_else.stderr30
-rw-r--r--tests/ui/or_then_unwrap.fixed2
-rw-r--r--tests/ui/or_then_unwrap.rs2
-rw-r--r--tests/ui/panicking_macros.rs2
-rw-r--r--tests/ui/shadow.rs1
-rw-r--r--tests/ui/shadow.stderr88
-rw-r--r--tests/ui/similar_names.rs3
-rw-r--r--tests/ui/similar_names.stderr28
-rw-r--r--tests/ui/single_char_lifetime_names.rs1
-rw-r--r--tests/ui/single_char_lifetime_names.stderr10
-rw-r--r--tests/ui/suspicious_else_formatting.rs2
-rw-r--r--tests/ui/undocumented_unsafe_blocks.rs1
-rw-r--r--tests/ui/undocumented_unsafe_blocks.stderr36
-rw-r--r--tests/ui/uninit.rs1
-rw-r--r--tests/ui/uninit.stderr6
-rw-r--r--tests/ui/unit_arg.rs3
-rw-r--r--tests/ui/unit_arg.stderr20
-rw-r--r--tests/ui/unit_hash.rs1
-rw-r--r--tests/ui/unit_hash.stderr6
-rw-r--r--tests/ui/wildcard_imports.fixed3
-rw-r--r--tests/ui/wildcard_imports.rs3
-rw-r--r--tests/ui/wildcard_imports.stderr42
59 files changed, 592 insertions, 269 deletions
diff --git a/clippy_lints/src/lib.register_all.rs b/clippy_lints/src/lib.register_all.rs
index 2fa59733365..097064ae26f 100644
--- a/clippy_lints/src/lib.register_all.rs
+++ b/clippy_lints/src/lib.register_all.rs
@@ -308,6 +308,7 @@ store.register_group(true, "clippy::all", Some("clippy_all"), vec![
     LintId::of(uninit_vec::UNINIT_VEC),
     LintId::of(unit_hash::UNIT_HASH),
     LintId::of(unit_return_expecting_ord::UNIT_RETURN_EXPECTING_ORD),
+    LintId::of(unit_types::LET_UNIT_VALUE),
     LintId::of(unit_types::UNIT_ARG),
     LintId::of(unit_types::UNIT_CMP),
     LintId::of(unnamed_address::FN_ADDRESS_COMPARISONS),
diff --git a/clippy_lints/src/lib.register_pedantic.rs b/clippy_lints/src/lib.register_pedantic.rs
index eb6534cb8ca..96cdc4577d5 100644
--- a/clippy_lints/src/lib.register_pedantic.rs
+++ b/clippy_lints/src/lib.register_pedantic.rs
@@ -89,7 +89,6 @@ store.register_group(true, "clippy::pedantic", Some("clippy_pedantic"), vec![
     LintId::of(types::LINKEDLIST),
     LintId::of(types::OPTION_OPTION),
     LintId::of(unicode::UNICODE_NOT_NFC),
-    LintId::of(unit_types::LET_UNIT_VALUE),
     LintId::of(unnecessary_wraps::UNNECESSARY_WRAPS),
     LintId::of(unnested_or_patterns::UNNESTED_OR_PATTERNS),
     LintId::of(unused_async::UNUSED_ASYNC),
diff --git a/clippy_lints/src/lib.register_style.rs b/clippy_lints/src/lib.register_style.rs
index d6e4390fde1..5a85a9e209e 100644
--- a/clippy_lints/src/lib.register_style.rs
+++ b/clippy_lints/src/lib.register_style.rs
@@ -107,6 +107,7 @@ store.register_group(true, "clippy::style", Some("clippy_style"), vec![
     LintId::of(single_component_path_imports::SINGLE_COMPONENT_PATH_IMPORTS),
     LintId::of(tabs_in_doc_comments::TABS_IN_DOC_COMMENTS),
     LintId::of(to_digit_is_some::TO_DIGIT_IS_SOME),
+    LintId::of(unit_types::LET_UNIT_VALUE),
     LintId::of(unnecessary_owned_empty_strings::UNNECESSARY_OWNED_EMPTY_STRINGS),
     LintId::of(unsafe_removed_from_name::UNSAFE_REMOVED_FROM_NAME),
     LintId::of(unused_unit::UNUSED_UNIT),
diff --git a/clippy_lints/src/unit_types/let_unit_value.rs b/clippy_lints/src/unit_types/let_unit_value.rs
index b25a6e3375b..96858fc7f27 100644
--- a/clippy_lints/src/unit_types/let_unit_value.rs
+++ b/clippy_lints/src/unit_types/let_unit_value.rs
@@ -1,18 +1,46 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_macro_callsite;
+use clippy_utils::visitors::for_each_value_source;
+use core::ops::ControlFlow;
 use rustc_errors::Applicability;
-use rustc_hir::{Stmt, StmtKind};
+use rustc_hir::{Expr, ExprKind, PatKind, Stmt, StmtKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::{self, Ty, TypeFoldable, TypeVisitor};
 
 use super::LET_UNIT_VALUE;
 
 pub(super) fn check(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
-    if let StmtKind::Local(local) = stmt.kind {
-        if cx.typeck_results().pat_ty(local.pat).is_unit() {
-            if in_external_macro(cx.sess(), stmt.span) || local.pat.span.from_expansion() {
-                return;
+    if let StmtKind::Local(local) = stmt.kind
+        && let Some(init) = local.init
+        && !local.pat.span.from_expansion()
+        && !in_external_macro(cx.sess(), stmt.span)
+        && cx.typeck_results().pat_ty(local.pat).is_unit()
+    {
+        let needs_inferred = for_each_value_source(init, &mut |e| if needs_inferred_result_ty(cx, e) {
+            ControlFlow::Continue(())
+        } else {
+            ControlFlow::Break(())
+        }).is_continue();
+
+        if needs_inferred {
+            if !matches!(local.pat.kind, PatKind::Wild) {
+                span_lint_and_then(
+                    cx,
+                    LET_UNIT_VALUE,
+                    stmt.span,
+                    "this let-binding has unit value",
+                    |diag| {
+                            diag.span_suggestion(
+                                local.pat.span,
+                                "use a wild (`_`) binding",
+                                "_".into(),
+                                Applicability::MaybeIncorrect, // snippet
+                            );
+                    },
+                );
             }
+        } else {
             span_lint_and_then(
                 cx,
                 LET_UNIT_VALUE,
@@ -33,3 +61,45 @@ pub(super) fn check(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
         }
     }
 }
+
+fn needs_inferred_result_ty(cx: &LateContext<'_>, e: &Expr<'_>) -> bool {
+    let id = match e.kind {
+        ExprKind::Call(
+            Expr {
+                kind: ExprKind::Path(ref path),
+                hir_id,
+                ..
+            },
+            _,
+        ) => cx.qpath_res(path, *hir_id).opt_def_id(),
+        ExprKind::MethodCall(..) => cx.typeck_results().type_dependent_def_id(e.hir_id),
+        _ => return false,
+    };
+    if let Some(id) = id
+        && let sig = cx.tcx.fn_sig(id).skip_binder()
+        && let ty::Param(output_ty) = *sig.output().kind()
+    {
+        sig.inputs().iter().all(|&ty| !ty_contains_param(ty, output_ty.index))
+    } else {
+        false
+    }
+}
+
+fn ty_contains_param(ty: Ty<'_>, index: u32) -> bool {
+    struct Visitor(u32);
+    impl<'tcx> TypeVisitor<'tcx> for Visitor {
+        type BreakTy = ();
+        fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
+            if let ty::Param(ty) = *ty.kind() {
+                if ty.index == self.0 {
+                    ControlFlow::BREAK
+                } else {
+                    ControlFlow::CONTINUE
+                }
+            } else {
+                ty.super_visit_with(self)
+            }
+        }
+    }
+    ty.visit_with(&mut Visitor(index)).is_break()
+}
diff --git a/clippy_lints/src/unit_types/mod.rs b/clippy_lints/src/unit_types/mod.rs
index d9f5b53b413..a9e2073dec2 100644
--- a/clippy_lints/src/unit_types/mod.rs
+++ b/clippy_lints/src/unit_types/mod.rs
@@ -23,7 +23,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "pre 1.29.0"]
     pub LET_UNIT_VALUE,
-    pedantic,
+    style,
     "creating a `let` binding to a value of unit type, which usually can't be used afterwards"
 }
 
diff --git a/clippy_utils/src/visitors.rs b/clippy_utils/src/visitors.rs
index 3db64b25353..c00bc2bd213 100644
--- a/clippy_utils/src/visitors.rs
+++ b/clippy_utils/src/visitors.rs
@@ -1,4 +1,5 @@
 use crate::path_to_local_id;
+use core::ops::ControlFlow;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::intravisit::{self, walk_block, walk_expr, Visitor};
@@ -402,3 +403,36 @@ pub fn contains_unsafe_block<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'tcx>)
     v.visit_expr(e);
     v.found_unsafe
 }
+
+/// Runs the given function for each sub-expression producing the final value consumed by the parent
+/// of the give expression.
+///
+/// e.g. for the following expression
+/// ```rust,ignore
+/// if foo {
+///     f(0)
+/// } else {
+///     1 + 1
+/// }
+/// ```
+/// this will pass both `f(0)` and `1+1` to the given function.
+pub fn for_each_value_source<'tcx, B>(
+    e: &'tcx Expr<'tcx>,
+    f: &mut impl FnMut(&'tcx Expr<'tcx>) -> ControlFlow<B>,
+) -> ControlFlow<B> {
+    match e.kind {
+        ExprKind::Block(Block { expr: Some(e), .. }, _) => for_each_value_source(e, f),
+        ExprKind::Match(_, arms, _) => {
+            for arm in arms {
+                for_each_value_source(arm.body, f)?;
+            }
+            ControlFlow::Continue(())
+        },
+        ExprKind::If(_, if_expr, Some(else_expr)) => {
+            for_each_value_source(if_expr, f)?;
+            for_each_value_source(else_expr, f)
+        },
+        ExprKind::DropTemps(e) => for_each_value_source(e, f),
+        _ => f(e),
+    }
+}
diff --git a/tests/ui-internal/interning_defined_symbol.fixed b/tests/ui-internal/interning_defined_symbol.fixed
index 6b7fd6efe39..eaea218e128 100644
--- a/tests/ui-internal/interning_defined_symbol.fixed
+++ b/tests/ui-internal/interning_defined_symbol.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 #![deny(clippy::internal)]
-#![allow(clippy::missing_clippy_version_attribute)]
+#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
 #![feature(rustc_private)]
 
 extern crate rustc_span;
diff --git a/tests/ui-internal/interning_defined_symbol.rs b/tests/ui-internal/interning_defined_symbol.rs
index 98d7d7adad1..7efebb8fae4 100644
--- a/tests/ui-internal/interning_defined_symbol.rs
+++ b/tests/ui-internal/interning_defined_symbol.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 #![deny(clippy::internal)]
-#![allow(clippy::missing_clippy_version_attribute)]
+#![allow(clippy::missing_clippy_version_attribute, clippy::let_unit_value)]
 #![feature(rustc_private)]
 
 extern crate rustc_span;
diff --git a/tests/ui-toml/functions_maxlines/test.rs b/tests/ui-toml/functions_maxlines/test.rs
index e678c896fd3..4ac0378544c 100644
--- a/tests/ui-toml/functions_maxlines/test.rs
+++ b/tests/ui-toml/functions_maxlines/test.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::too_many_lines)]
+#![allow(clippy::let_unit_value)]
 
 // This function should be considered one line.
 fn many_comments_but_one_line_of_code() {
diff --git a/tests/ui-toml/functions_maxlines/test.stderr b/tests/ui-toml/functions_maxlines/test.stderr
index d736bf89973..dc255bdcaba 100644
--- a/tests/ui-toml/functions_maxlines/test.stderr
+++ b/tests/ui-toml/functions_maxlines/test.stderr
@@ -1,5 +1,5 @@
 error: this function has too many lines (2/1)
-  --> $DIR/test.rs:18:1
+  --> $DIR/test.rs:19:1
    |
 LL | / fn too_many_lines() {
 LL | |     println!("This is bad.");
@@ -10,7 +10,7 @@ LL | | }
    = note: `-D clippy::too-many-lines` implied by `-D warnings`
 
 error: this function has too many lines (4/1)
-  --> $DIR/test.rs:24:1
+  --> $DIR/test.rs:25:1
    |
 LL | / async fn async_too_many_lines() {
 LL | |     println!("This is bad.");
@@ -19,7 +19,7 @@ LL | | }
    | |_^
 
 error: this function has too many lines (4/1)
-  --> $DIR/test.rs:30:1
+  --> $DIR/test.rs:31:1
    |
 LL | / fn closure_too_many_lines() {
 LL | |     let _ = {
@@ -30,7 +30,7 @@ LL | | }
    | |_^
 
 error: this function has too many lines (2/1)
-  --> $DIR/test.rs:52:1
+  --> $DIR/test.rs:53:1
    |
 LL | / fn comment_before_code() {
 LL | |     let _ = "test";
diff --git a/tests/ui/cast_alignment.rs b/tests/ui/cast_alignment.rs
index e4e7290a30e..95bb883df1b 100644
--- a/tests/ui/cast_alignment.rs
+++ b/tests/ui/cast_alignment.rs
@@ -44,8 +44,8 @@ fn main() {
         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);
+        (ptr as *mut u16).write_unaligned(0);
+        core::ptr::write_unaligned(ptr as *mut u16, 0);
+        core::intrinsics::unaligned_volatile_store(ptr as *mut u16, 0);
     }
 }
diff --git a/tests/ui/cast_slice_different_sizes.rs b/tests/ui/cast_slice_different_sizes.rs
index cfe1cca2eba..57270fcf52b 100644
--- a/tests/ui/cast_slice_different_sizes.rs
+++ b/tests/ui/cast_slice_different_sizes.rs
@@ -1,3 +1,5 @@
+#![allow(clippy::let_unit_value)]
+
 fn main() {
     let x: [i32; 3] = [1_i32, 2, 3];
     let r_x = &x;
diff --git a/tests/ui/cast_slice_different_sizes.stderr b/tests/ui/cast_slice_different_sizes.stderr
index a37cec7cb3b..993e93c2bf3 100644
--- a/tests/ui/cast_slice_different_sizes.stderr
+++ b/tests/ui/cast_slice_different_sizes.stderr
@@ -1,5 +1,5 @@
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:7:13
+  --> $DIR/cast_slice_different_sizes.rs:9:13
    |
 LL |     let b = a as *const [u8];
    |             ^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(a as *const u8, ..)`
@@ -7,25 +7,25 @@ LL |     let b = a as *const [u8];
    = note: `#[deny(clippy::cast_slice_different_sizes)]` on by default
 
 error: casting between raw pointers to `[u8]` (element size 1) and `[u32]` (element size 4) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:8:13
+  --> $DIR/cast_slice_different_sizes.rs:10:13
    |
 LL |     let c = b as *const [u32];
    |             ^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(b as *const u32, ..)`
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:11:16
+  --> $DIR/cast_slice_different_sizes.rs:13:16
    |
 LL |     let loss = r_x as *const [i32] as *const [u8];
    |                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const u8, ..)`
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:18:24
+  --> $DIR/cast_slice_different_sizes.rs:20:24
    |
 LL |     let loss_block_1 = { r_x as *const [i32] } as *const [u8];
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts({ r_x as *const [i32] } as *const u8, ..)`
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:19:24
+  --> $DIR/cast_slice_different_sizes.rs:21:24
    |
 LL |       let loss_block_2 = {
    |  ________________________^
@@ -43,7 +43,7 @@ LL ~     } as *const u8, ..);
    |
 
 error: casting between raw pointers to `[i32]` (element size 4) and `[u8]` (element size 1) does not adjust the count
-  --> $DIR/cast_slice_different_sizes.rs:36:27
+  --> $DIR/cast_slice_different_sizes.rs:38:27
    |
 LL |     let long_chain_loss = r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const [u8];
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with `ptr::slice_from_raw_parts`: `core::ptr::slice_from_raw_parts(r_x as *const [i32] as *const [u32] as *const [u16] as *const [i8] as *const u8, ..)`
diff --git a/tests/ui/crashes/ice-5944.rs b/tests/ui/crashes/ice-5944.rs
index 5caf29c6197..ce46bc1acc1 100644
--- a/tests/ui/crashes/ice-5944.rs
+++ b/tests/ui/crashes/ice-5944.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::repeat_once)]
+#![allow(clippy::let_unit_value)]
 
 trait Repeat {
     fn repeat(&self) {}
diff --git a/tests/ui/default_numeric_fallback_f64.fixed b/tests/ui/default_numeric_fallback_f64.fixed
index e0b4a2f6942..a28bff76755 100644
--- a/tests/ui/default_numeric_fallback_f64.fixed
+++ b/tests/ui/default_numeric_fallback_f64.fixed
@@ -2,12 +2,15 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
-#![allow(clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/tests/ui/default_numeric_fallback_f64.rs b/tests/ui/default_numeric_fallback_f64.rs
index 50bbb6eec6c..b48435cc7b2 100644
--- a/tests/ui/default_numeric_fallback_f64.rs
+++ b/tests/ui/default_numeric_fallback_f64.rs
@@ -2,12 +2,15 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
-#![allow(clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/tests/ui/default_numeric_fallback_f64.stderr b/tests/ui/default_numeric_fallback_f64.stderr
index f8a2407b693..f8b6c7746ed 100644
--- a/tests/ui/default_numeric_fallback_f64.stderr
+++ b/tests/ui/default_numeric_fallback_f64.stderr
@@ -1,5 +1,5 @@
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:18:17
+  --> $DIR/default_numeric_fallback_f64.rs:21:17
    |
 LL |         let x = 0.12;
    |                 ^^^^ help: consider adding suffix: `0.12_f64`
@@ -7,133 +7,133 @@ LL |         let x = 0.12;
    = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:19:18
+  --> $DIR/default_numeric_fallback_f64.rs:22:18
    |
 LL |         let x = [1., 2., 3.];
    |                  ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:19:22
+  --> $DIR/default_numeric_fallback_f64.rs:22:22
    |
 LL |         let x = [1., 2., 3.];
    |                      ^^ help: consider adding suffix: `2.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:19:26
+  --> $DIR/default_numeric_fallback_f64.rs:22:26
    |
 LL |         let x = [1., 2., 3.];
    |                          ^^ help: consider adding suffix: `3.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:28
+  --> $DIR/default_numeric_fallback_f64.rs:23:28
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                            ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:32
+  --> $DIR/default_numeric_fallback_f64.rs:23:32
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                                ^^ help: consider adding suffix: `2.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:46
+  --> $DIR/default_numeric_fallback_f64.rs:23:46
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                                              ^^ help: consider adding suffix: `3.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:20:50
+  --> $DIR/default_numeric_fallback_f64.rs:23:50
    |
 LL |         let x = if true { (1., 2.) } else { (3., 4.) };
    |                                                  ^^ help: consider adding suffix: `4.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:21:23
+  --> $DIR/default_numeric_fallback_f64.rs:24:23
    |
 LL |         let x = match 1. {
    |                       ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:22:18
+  --> $DIR/default_numeric_fallback_f64.rs:25:18
    |
 LL |             _ => 1.,
    |                  ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:40:21
+  --> $DIR/default_numeric_fallback_f64.rs:43:21
    |
 LL |             let y = 1.;
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:48:21
+  --> $DIR/default_numeric_fallback_f64.rs:51:21
    |
 LL |             let y = 1.;
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:54:21
+  --> $DIR/default_numeric_fallback_f64.rs:57:21
    |
 LL |             let y = 1.;
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:66:9
+  --> $DIR/default_numeric_fallback_f64.rs:69:9
    |
 LL |         1.
    |         ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:72:27
+  --> $DIR/default_numeric_fallback_f64.rs:75:27
    |
 LL |         let f = || -> _ { 1. };
    |                           ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:76:29
+  --> $DIR/default_numeric_fallback_f64.rs:79:29
    |
 LL |         let f = || -> f64 { 1. };
    |                             ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:90:21
+  --> $DIR/default_numeric_fallback_f64.rs:93:21
    |
 LL |         generic_arg(1.);
    |                     ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:93:32
+  --> $DIR/default_numeric_fallback_f64.rs:96:32
    |
 LL |         let x: _ = generic_arg(1.);
    |                                ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:111:28
+  --> $DIR/default_numeric_fallback_f64.rs:114:28
    |
 LL |         GenericStruct { x: 1. };
    |                            ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:114:36
+  --> $DIR/default_numeric_fallback_f64.rs:117:36
    |
 LL |         let _ = GenericStruct { x: 1. };
    |                                    ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:132:24
+  --> $DIR/default_numeric_fallback_f64.rs:135:24
    |
 LL |         GenericEnum::X(1.);
    |                        ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:152:23
+  --> $DIR/default_numeric_fallback_f64.rs:155:23
    |
 LL |         s.generic_arg(1.);
    |                       ^^ help: consider adding suffix: `1.0_f64`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_f64.rs:159:21
+  --> $DIR/default_numeric_fallback_f64.rs:162:21
    |
 LL |             let x = 22.;
    |                     ^^^ help: consider adding suffix: `22.0_f64`
diff --git a/tests/ui/default_numeric_fallback_i32.fixed b/tests/ui/default_numeric_fallback_i32.fixed
index bded9e2c0e8..fa85d278c8f 100644
--- a/tests/ui/default_numeric_fallback_i32.fixed
+++ b/tests/ui/default_numeric_fallback_i32.fixed
@@ -2,11 +2,14 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/tests/ui/default_numeric_fallback_i32.rs b/tests/ui/default_numeric_fallback_i32.rs
index 3fceefa551c..71acccd702b 100644
--- a/tests/ui/default_numeric_fallback_i32.rs
+++ b/tests/ui/default_numeric_fallback_i32.rs
@@ -2,11 +2,14 @@
 // aux-build:macro_rules.rs
 
 #![warn(clippy::default_numeric_fallback)]
-#![allow(unused)]
-#![allow(clippy::never_loop)]
-#![allow(clippy::no_effect)]
-#![allow(clippy::unnecessary_operation)]
-#![allow(clippy::branches_sharing_code)]
+#![allow(
+    unused,
+    clippy::never_loop,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::branches_sharing_code,
+    clippy::let_unit_value
+)]
 
 #[macro_use]
 extern crate macro_rules;
diff --git a/tests/ui/default_numeric_fallback_i32.stderr b/tests/ui/default_numeric_fallback_i32.stderr
index 6f9e124704b..3cc84ff1132 100644
--- a/tests/ui/default_numeric_fallback_i32.stderr
+++ b/tests/ui/default_numeric_fallback_i32.stderr
@@ -1,5 +1,5 @@
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:17:17
+  --> $DIR/default_numeric_fallback_i32.rs:20:17
    |
 LL |         let x = 22;
    |                 ^^ help: consider adding suffix: `22_i32`
@@ -7,145 +7,145 @@ LL |         let x = 22;
    = note: `-D clippy::default-numeric-fallback` implied by `-D warnings`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:18:18
+  --> $DIR/default_numeric_fallback_i32.rs:21:18
    |
 LL |         let x = [1, 2, 3];
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:18:21
+  --> $DIR/default_numeric_fallback_i32.rs:21:21
    |
 LL |         let x = [1, 2, 3];
    |                     ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:18:24
+  --> $DIR/default_numeric_fallback_i32.rs:21:24
    |
 LL |         let x = [1, 2, 3];
    |                        ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:28
+  --> $DIR/default_numeric_fallback_i32.rs:22:28
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:31
+  --> $DIR/default_numeric_fallback_i32.rs:22:31
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                               ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:44
+  --> $DIR/default_numeric_fallback_i32.rs:22:44
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                            ^ help: consider adding suffix: `3_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:19:47
+  --> $DIR/default_numeric_fallback_i32.rs:22:47
    |
 LL |         let x = if true { (1, 2) } else { (3, 4) };
    |                                               ^ help: consider adding suffix: `4_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:20:23
+  --> $DIR/default_numeric_fallback_i32.rs:23:23
    |
 LL |         let x = match 1 {
    |                       ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:21:13
+  --> $DIR/default_numeric_fallback_i32.rs:24:13
    |
 LL |             1 => 1,
    |             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:21:18
+  --> $DIR/default_numeric_fallback_i32.rs:24:18
    |
 LL |             1 => 1,
    |                  ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:22:18
+  --> $DIR/default_numeric_fallback_i32.rs:25:18
    |
 LL |             _ => 2,
    |                  ^ help: consider adding suffix: `2_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:39:21
+  --> $DIR/default_numeric_fallback_i32.rs:42:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:47:21
+  --> $DIR/default_numeric_fallback_i32.rs:50:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:53:21
+  --> $DIR/default_numeric_fallback_i32.rs:56:21
    |
 LL |             let y = 1;
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:65:9
+  --> $DIR/default_numeric_fallback_i32.rs:68:9
    |
 LL |         1
    |         ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:71:27
+  --> $DIR/default_numeric_fallback_i32.rs:74:27
    |
 LL |         let f = || -> _ { 1 };
    |                           ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:75:29
+  --> $DIR/default_numeric_fallback_i32.rs:78:29
    |
 LL |         let f = || -> i32 { 1 };
    |                             ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:89:21
+  --> $DIR/default_numeric_fallback_i32.rs:92:21
    |
 LL |         generic_arg(1);
    |                     ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:92:32
+  --> $DIR/default_numeric_fallback_i32.rs:95:32
    |
 LL |         let x: _ = generic_arg(1);
    |                                ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:110:28
+  --> $DIR/default_numeric_fallback_i32.rs:113:28
    |
 LL |         GenericStruct { x: 1 };
    |                            ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:113:36
+  --> $DIR/default_numeric_fallback_i32.rs:116:36
    |
 LL |         let _ = GenericStruct { x: 1 };
    |                                    ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:131:24
+  --> $DIR/default_numeric_fallback_i32.rs:134:24
    |
 LL |         GenericEnum::X(1);
    |                        ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:151:23
+  --> $DIR/default_numeric_fallback_i32.rs:154:23
    |
 LL |         s.generic_arg(1);
    |                       ^ help: consider adding suffix: `1_i32`
 
 error: default numeric fallback might occur
-  --> $DIR/default_numeric_fallback_i32.rs:158:21
+  --> $DIR/default_numeric_fallback_i32.rs:161:21
    |
 LL |             let x = 22;
    |                     ^^ help: consider adding suffix: `22_i32`
diff --git a/tests/ui/doc_unsafe.rs b/tests/ui/doc_unsafe.rs
index 4464a21b3b6..b91f7aa0dd8 100644
--- a/tests/ui/doc_unsafe.rs
+++ b/tests/ui/doc_unsafe.rs
@@ -1,5 +1,7 @@
 // aux-build:doc_unsafe_macros.rs
 
+#![allow(clippy::let_unit_value)]
+
 #[macro_use]
 extern crate doc_unsafe_macros;
 
diff --git a/tests/ui/doc_unsafe.stderr b/tests/ui/doc_unsafe.stderr
index d68b8a0c67b..904b88eaef6 100644
--- a/tests/ui/doc_unsafe.stderr
+++ b/tests/ui/doc_unsafe.stderr
@@ -1,5 +1,5 @@
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:7:1
+  --> $DIR/doc_unsafe.rs:9:1
    |
 LL | / pub unsafe fn destroy_the_planet() {
 LL | |     unimplemented!();
@@ -9,7 +9,7 @@ LL | | }
    = note: `-D clippy::missing-safety-doc` implied by `-D warnings`
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:30:5
+  --> $DIR/doc_unsafe.rs:32:5
    |
 LL | /     pub unsafe fn republished() {
 LL | |         unimplemented!();
@@ -17,13 +17,13 @@ LL | |     }
    | |_____^
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:38:5
+  --> $DIR/doc_unsafe.rs:40:5
    |
 LL |     unsafe fn woefully_underdocumented(self);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: docs for unsafe trait missing `# Safety` section
-  --> $DIR/doc_unsafe.rs:44:1
+  --> $DIR/doc_unsafe.rs:46:1
    |
 LL | / pub unsafe trait UnsafeTrait {
 LL | |     fn method();
@@ -31,7 +31,7 @@ LL | | }
    | |_^
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:74:5
+  --> $DIR/doc_unsafe.rs:76:5
    |
 LL | /     pub unsafe fn more_undocumented_unsafe() -> Self {
 LL | |         unimplemented!();
@@ -39,7 +39,7 @@ LL | |     }
    | |_____^
 
 error: unsafe function's docs miss `# Safety` section
-  --> $DIR/doc_unsafe.rs:90:9
+  --> $DIR/doc_unsafe.rs:92:9
    |
 LL | /         pub unsafe fn whee() {
 LL | |             unimplemented!()
diff --git a/tests/ui/iter_overeager_cloned.fixed b/tests/ui/iter_overeager_cloned.fixed
index 56761ebbcb8..7c2b05d837b 100644
--- a/tests/ui/iter_overeager_cloned.fixed
+++ b/tests/ui/iter_overeager_cloned.fixed
@@ -1,6 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::let_unit_value)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
diff --git a/tests/ui/iter_overeager_cloned.rs b/tests/ui/iter_overeager_cloned.rs
index 98321d889b5..f2d0b155d2c 100644
--- a/tests/ui/iter_overeager_cloned.rs
+++ b/tests/ui/iter_overeager_cloned.rs
@@ -1,6 +1,6 @@
 // run-rustfix
 #![warn(clippy::iter_overeager_cloned, clippy::redundant_clone, clippy::filter_next)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::let_unit_value)]
 
 fn main() {
     let vec = vec!["1".to_string(), "2".to_string(), "3".to_string()];
diff --git a/tests/ui/let_underscore_drop.rs b/tests/ui/let_underscore_drop.rs
index 50744f81c3c..11b50492ab2 100644
--- a/tests/ui/let_underscore_drop.rs
+++ b/tests/ui/let_underscore_drop.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::let_underscore_drop)]
+#![allow(clippy::let_unit_value)]
 
 struct Droppable;
 
diff --git a/tests/ui/let_underscore_drop.stderr b/tests/ui/let_underscore_drop.stderr
index 66069e0c5e1..ee7bbe995f1 100644
--- a/tests/ui/let_underscore_drop.stderr
+++ b/tests/ui/let_underscore_drop.stderr
@@ -1,5 +1,5 @@
 error: non-binding `let` on a type that implements `Drop`
-  --> $DIR/let_underscore_drop.rs:16:5
+  --> $DIR/let_underscore_drop.rs:17:5
    |
 LL |     let _ = Box::new(());
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     let _ = Box::new(());
    = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
 
 error: non-binding `let` on a type that implements `Drop`
-  --> $DIR/let_underscore_drop.rs:17:5
+  --> $DIR/let_underscore_drop.rs:18:5
    |
 LL |     let _ = Droppable;
    |     ^^^^^^^^^^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     let _ = Droppable;
    = help: consider using an underscore-prefixed named binding or dropping explicitly with `std::mem::drop`
 
 error: non-binding `let` on a type that implements `Drop`
-  --> $DIR/let_underscore_drop.rs:18:5
+  --> $DIR/let_underscore_drop.rs:19:5
    |
 LL |     let _ = Some(Droppable);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/let_unit.fixed b/tests/ui/let_unit.fixed
index f398edc23cb..e72b7462325 100644
--- a/tests/ui/let_unit.fixed
+++ b/tests/ui/let_unit.fixed
@@ -61,3 +61,55 @@ fn multiline_sugg() {
 
 #[derive(Copy, Clone)]
 pub struct ContainsUnit(()); // should be fine
+
+fn _returns_generic() {
+    fn f<T>() -> T {
+        unimplemented!()
+    }
+    fn f2<T, U>(_: T) -> U {
+        unimplemented!()
+    }
+    fn f3<T>(x: T) -> T {
+        x
+    }
+    fn f4<T>(mut x: Vec<T>) -> T {
+        x.pop().unwrap()
+    }
+
+    let _: () = f(); // Ok
+    let _: () = f(); // Lint.
+
+    let _: () = f2(0i32); // Ok
+    let _: () = f2(0i32); // Lint.
+
+    f3(()); // Lint
+    f3(()); // Lint
+
+    f4(vec![()]); // Lint
+    f4(vec![()]); // Lint
+
+    // Ok
+    let _: () = {
+        let x = 5;
+        f2(x)
+    };
+
+    let _: () = if true { f() } else { f2(0) }; // Ok
+    let _: () = if true { f() } else { f2(0) }; // Lint
+
+    // Ok
+    let _: () = match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => f2('x'),
+    };
+
+    // Lint
+    match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => (),
+    };
+}
diff --git a/tests/ui/let_unit.rs b/tests/ui/let_unit.rs
index af5b1fb2ac7..47ee0a76724 100644
--- a/tests/ui/let_unit.rs
+++ b/tests/ui/let_unit.rs
@@ -61,3 +61,55 @@ fn multiline_sugg() {
 
 #[derive(Copy, Clone)]
 pub struct ContainsUnit(()); // should be fine
+
+fn _returns_generic() {
+    fn f<T>() -> T {
+        unimplemented!()
+    }
+    fn f2<T, U>(_: T) -> U {
+        unimplemented!()
+    }
+    fn f3<T>(x: T) -> T {
+        x
+    }
+    fn f4<T>(mut x: Vec<T>) -> T {
+        x.pop().unwrap()
+    }
+
+    let _: () = f(); // Ok
+    let x: () = f(); // Lint.
+
+    let _: () = f2(0i32); // Ok
+    let x: () = f2(0i32); // Lint.
+
+    let _: () = f3(()); // Lint
+    let x: () = f3(()); // Lint
+
+    let _: () = f4(vec![()]); // Lint
+    let x: () = f4(vec![()]); // Lint
+
+    // Ok
+    let _: () = {
+        let x = 5;
+        f2(x)
+    };
+
+    let _: () = if true { f() } else { f2(0) }; // Ok
+    let x: () = if true { f() } else { f2(0) }; // Lint
+
+    // Ok
+    let _: () = match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => f2('x'),
+    };
+
+    // Lint
+    let _: () = match Some(0) {
+        None => f2(1),
+        Some(0) => f(),
+        Some(1) => f2(3),
+        Some(_) => (),
+    };
+}
diff --git a/tests/ui/let_unit.stderr b/tests/ui/let_unit.stderr
index f2600c6c228..13ec11a6d33 100644
--- a/tests/ui/let_unit.stderr
+++ b/tests/ui/let_unit.stderr
@@ -34,5 +34,74 @@ LL +         .map(|_| ())
 LL +         .next()
  ...
 
-error: aborting due to 3 previous errors
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:80:5
+   |
+LL |     let x: () = f(); // Lint.
+   |     ^^^^-^^^^^^^^^^^
+   |         |
+   |         help: use a wild (`_`) binding: `_`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:83:5
+   |
+LL |     let x: () = f2(0i32); // Lint.
+   |     ^^^^-^^^^^^^^^^^^^^^^
+   |         |
+   |         help: use a wild (`_`) binding: `_`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:85:5
+   |
+LL |     let _: () = f3(()); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:86:5
+   |
+LL |     let x: () = f3(()); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f3(());`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:88:5
+   |
+LL |     let _: () = f4(vec![()]); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f4(vec![()]);`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:89:5
+   |
+LL |     let x: () = f4(vec![()]); // Lint
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: omit the `let` binding: `f4(vec![()]);`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:98:5
+   |
+LL |     let x: () = if true { f() } else { f2(0) }; // Lint
+   |     ^^^^-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |         |
+   |         help: use a wild (`_`) binding: `_`
+
+error: this let-binding has unit value
+  --> $DIR/let_unit.rs:109:5
+   |
+LL | /     let _: () = match Some(0) {
+LL | |         None => f2(1),
+LL | |         Some(0) => f(),
+LL | |         Some(1) => f2(3),
+LL | |         Some(_) => (),
+LL | |     };
+   | |______^
+   |
+help: omit the `let` binding
+   |
+LL ~     match Some(0) {
+LL +         None => f2(1),
+LL +         Some(0) => f(),
+LL +         Some(1) => f2(3),
+LL +         Some(_) => (),
+LL +     };
+   |
+
+error: aborting due to 11 previous errors
 
diff --git a/tests/ui/needless_for_each_fixable.fixed b/tests/ui/needless_for_each_fixable.fixed
index f00f9ee4c33..c1685f7b6d7 100644
--- a/tests/ui/needless_for_each_fixable.fixed
+++ b/tests/ui/needless_for_each_fixable.fixed
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::needless_for_each)]
-#![allow(unused, clippy::needless_return, clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::needless_return,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 use std::collections::HashMap;
 
diff --git a/tests/ui/needless_for_each_fixable.rs b/tests/ui/needless_for_each_fixable.rs
index 1bd400d348b..ad17b0956fa 100644
--- a/tests/ui/needless_for_each_fixable.rs
+++ b/tests/ui/needless_for_each_fixable.rs
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::needless_for_each)]
-#![allow(unused, clippy::needless_return, clippy::match_single_binding)]
+#![allow(
+    unused,
+    clippy::needless_return,
+    clippy::match_single_binding,
+    clippy::let_unit_value
+)]
 
 use std::collections::HashMap;
 
diff --git a/tests/ui/needless_for_each_fixable.stderr b/tests/ui/needless_for_each_fixable.stderr
index 6487e57266c..08e995851d7 100644
--- a/tests/ui/needless_for_each_fixable.stderr
+++ b/tests/ui/needless_for_each_fixable.stderr
@@ -1,5 +1,5 @@
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:10:5
+  --> $DIR/needless_for_each_fixable.rs:15:5
    |
 LL | /     v.iter().for_each(|elem| {
 LL | |         acc += elem;
@@ -15,7 +15,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:13:5
+  --> $DIR/needless_for_each_fixable.rs:18:5
    |
 LL | /     v.into_iter().for_each(|elem| {
 LL | |         acc += elem;
@@ -30,7 +30,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:17:5
+  --> $DIR/needless_for_each_fixable.rs:22:5
    |
 LL | /     [1, 2, 3].iter().for_each(|elem| {
 LL | |         acc += elem;
@@ -45,7 +45,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:22:5
+  --> $DIR/needless_for_each_fixable.rs:27:5
    |
 LL | /     hash_map.iter().for_each(|(k, v)| {
 LL | |         acc += k + v;
@@ -60,7 +60,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:25:5
+  --> $DIR/needless_for_each_fixable.rs:30:5
    |
 LL | /     hash_map.iter_mut().for_each(|(k, v)| {
 LL | |         acc += *k + *v;
@@ -75,7 +75,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:28:5
+  --> $DIR/needless_for_each_fixable.rs:33:5
    |
 LL | /     hash_map.keys().for_each(|k| {
 LL | |         acc += k;
@@ -90,7 +90,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:31:5
+  --> $DIR/needless_for_each_fixable.rs:36:5
    |
 LL | /     hash_map.values().for_each(|v| {
 LL | |         acc += v;
@@ -105,7 +105,7 @@ LL +     }
    |
 
 error: needless use of `for_each`
-  --> $DIR/needless_for_each_fixable.rs:38:5
+  --> $DIR/needless_for_each_fixable.rs:43:5
    |
 LL | /     my_vec().iter().for_each(|elem| {
 LL | |         acc += elem;
diff --git a/tests/ui/needless_late_init.rs b/tests/ui/needless_late_init.rs
index 89e012c066f..3cfbfb6033b 100644
--- a/tests/ui/needless_late_init.rs
+++ b/tests/ui/needless_late_init.rs
@@ -1,4 +1,5 @@
 #![allow(unused)]
+#![allow(clippy::let_unit_value)]
 
 fn main() {
     let a;
diff --git a/tests/ui/needless_late_init.stderr b/tests/ui/needless_late_init.stderr
index ef79e635d2a..9ef8bb23df6 100644
--- a/tests/ui/needless_late_init.stderr
+++ b/tests/ui/needless_late_init.stderr
@@ -1,5 +1,5 @@
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:4:5
+  --> $DIR/needless_late_init.rs:5:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -21,7 +21,7 @@ LL |     };
    |      +
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:13:5
+  --> $DIR/needless_late_init.rs:14:5
    |
 LL |     let b;
    |     ^^^^^^
@@ -42,7 +42,7 @@ LL |     };
    |      +
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:20:5
+  --> $DIR/needless_late_init.rs:21:5
    |
 LL |     let c;
    |     ^^^^^^
@@ -63,7 +63,7 @@ LL |     };
    |      +
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:27:5
+  --> $DIR/needless_late_init.rs:28:5
    |
 LL |     let d;
    |     ^^^^^^
@@ -84,7 +84,7 @@ LL |     };
    |      +
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:35:5
+  --> $DIR/needless_late_init.rs:36:5
    |
 LL |     let e;
    |     ^^^^^^
@@ -105,7 +105,7 @@ LL |     };
    |      +
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:42:5
+  --> $DIR/needless_late_init.rs:43:5
    |
 LL |     let f;
    |     ^^^^^^
@@ -121,7 +121,7 @@ LL +         1 => "three",
    | 
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:48:5
+  --> $DIR/needless_late_init.rs:49:5
    |
 LL |     let g: usize;
    |     ^^^^^^^^^^^^^
@@ -141,7 +141,7 @@ LL |     };
    |      +
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:63:5
+  --> $DIR/needless_late_init.rs:64:5
    |
 LL |     let a;
    |     ^^^^^^
@@ -162,7 +162,7 @@ LL |     };
    |      +
 
 error: unneeded late initalization
-  --> $DIR/needless_late_init.rs:80:5
+  --> $DIR/needless_late_init.rs:81:5
    |
 LL |     let a;
    |     ^^^^^^
diff --git a/tests/ui/non_expressive_names.rs b/tests/ui/non_expressive_names.rs
index 9937005d68d..583096ac054 100644
--- a/tests/ui/non_expressive_names.rs
+++ b/tests/ui/non_expressive_names.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::all)]
-#![allow(unused, clippy::println_empty_string, non_snake_case)]
+#![allow(unused, clippy::println_empty_string, non_snake_case, clippy::let_unit_value)]
 
 #[derive(Clone, Debug)]
 enum MaybeInst {
diff --git a/tests/ui/option_if_let_else.fixed b/tests/ui/option_if_let_else.fixed
index 7790c816481..e12e13a57f1 100644
--- a/tests/ui/option_if_let_else.fixed
+++ b/tests/ui/option_if_let_else.fixed
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
-#![allow(clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let)]
+#![allow(
+    clippy::redundant_closure,
+    clippy::ref_option_ref,
+    clippy::equatable_if_let,
+    clippy::let_unit_value
+)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     string.map_or((false, "hello"), |x| (true, x))
diff --git a/tests/ui/option_if_let_else.rs b/tests/ui/option_if_let_else.rs
index 3d9f76ee4a6..b5206fc26a9 100644
--- a/tests/ui/option_if_let_else.rs
+++ b/tests/ui/option_if_let_else.rs
@@ -1,6 +1,11 @@
 // run-rustfix
 #![warn(clippy::option_if_let_else)]
-#![allow(clippy::redundant_closure, clippy::ref_option_ref, clippy::equatable_if_let)]
+#![allow(
+    clippy::redundant_closure,
+    clippy::ref_option_ref,
+    clippy::equatable_if_let,
+    clippy::let_unit_value
+)]
 
 fn bad1(string: Option<&str>) -> (bool, &str) {
     if let Some(x) = string {
diff --git a/tests/ui/option_if_let_else.stderr b/tests/ui/option_if_let_else.stderr
index 546131ceb5b..40aef977b98 100644
--- a/tests/ui/option_if_let_else.stderr
+++ b/tests/ui/option_if_let_else.stderr
@@ -1,5 +1,5 @@
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:6:5
+  --> $DIR/option_if_let_else.rs:11:5
    |
 LL | /     if let Some(x) = string {
 LL | |         (true, x)
@@ -11,19 +11,19 @@ LL | |     }
    = note: `-D clippy::option-if-let-else` implied by `-D warnings`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:24:13
+  --> $DIR/option_if_let_else.rs:29:13
    |
 LL |     let _ = if let Some(s) = *string { s.len() } else { 0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `string.map_or(0, |s| s.len())`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:25:13
+  --> $DIR/option_if_let_else.rs:30:13
    |
 LL |     let _ = if let Some(s) = &num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:26:13
+  --> $DIR/option_if_let_else.rs:31:13
    |
 LL |       let _ = if let Some(s) = &mut num {
    |  _____________^
@@ -43,13 +43,13 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:32:13
+  --> $DIR/option_if_let_else.rs:37:13
    |
 LL |     let _ = if let Some(ref s) = num { s } else { &0 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `num.as_ref().map_or(&0, |s| s)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:33:13
+  --> $DIR/option_if_let_else.rs:38:13
    |
 LL |       let _ = if let Some(mut s) = num {
    |  _____________^
@@ -69,7 +69,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:39:13
+  --> $DIR/option_if_let_else.rs:44:13
    |
 LL |       let _ = if let Some(ref mut s) = num {
    |  _____________^
@@ -89,7 +89,7 @@ LL ~     });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:48:5
+  --> $DIR/option_if_let_else.rs:53:5
    |
 LL | /     if let Some(x) = arg {
 LL | |         let y = x * x;
@@ -108,7 +108,7 @@ LL +     })
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:61:13
+  --> $DIR/option_if_let_else.rs:66:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -120,7 +120,7 @@ LL | |     };
    | |_____^ help: try: `arg.map_or_else(|| side_effect(), |x| x)`
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:70:13
+  --> $DIR/option_if_let_else.rs:75:13
    |
 LL |       let _ = if let Some(x) = arg {
    |  _____________^
@@ -143,7 +143,7 @@ LL ~     }, |x| x * x * x * x);
    |
 
 error: use Option::map_or_else instead of an if let/else
-  --> $DIR/option_if_let_else.rs:103:13
+  --> $DIR/option_if_let_else.rs:108:13
    |
 LL | /             if let Some(idx) = s.find('.') {
 LL | |                 vec![s[..idx].to_string(), s[idx..].to_string()]
@@ -153,13 +153,13 @@ LL | |             }
    | |_____________^ help: try: `s.find('.').map_or_else(|| vec![s.to_string()], |idx| vec![s[..idx].to_string(), s[idx..].to_string()])`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:127:13
+  --> $DIR/option_if_let_else.rs:132:13
    |
 LL |     let _ = if let Some(x) = optional { x + 2 } else { 5 };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `optional.map_or(5, |x| x + 2)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:136:13
+  --> $DIR/option_if_let_else.rs:141:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
@@ -181,13 +181,13 @@ LL ~         });
    |
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:164:13
+  --> $DIR/option_if_let_else.rs:169:13
    |
 LL |     let _ = if let Some(x) = Some(0) { s.len() + x } else { s.len() };
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(0).map_or(s.len(), |x| s.len() + x)`
 
 error: use Option::map_or instead of an if let/else
-  --> $DIR/option_if_let_else.rs:168:13
+  --> $DIR/option_if_let_else.rs:173:13
    |
 LL |       let _ = if let Some(x) = Some(0) {
    |  _____________^
diff --git a/tests/ui/or_then_unwrap.fixed b/tests/ui/or_then_unwrap.fixed
index 6e0d5a87f68..844cc4b7a09 100644
--- a/tests/ui/or_then_unwrap.fixed
+++ b/tests/ui/or_then_unwrap.fixed
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::or_then_unwrap)]
-#![allow(clippy::map_identity)]
+#![allow(clippy::map_identity, clippy::let_unit_value)]
 
 struct SomeStruct;
 impl SomeStruct {
diff --git a/tests/ui/or_then_unwrap.rs b/tests/ui/or_then_unwrap.rs
index e406a71d46d..1528ef9be96 100644
--- a/tests/ui/or_then_unwrap.rs
+++ b/tests/ui/or_then_unwrap.rs
@@ -1,7 +1,7 @@
 // run-rustfix
 
 #![warn(clippy::or_then_unwrap)]
-#![allow(clippy::map_identity)]
+#![allow(clippy::map_identity, clippy::let_unit_value)]
 
 struct SomeStruct;
 impl SomeStruct {
diff --git a/tests/ui/panicking_macros.rs b/tests/ui/panicking_macros.rs
index 12a0c776ae2..041ef17fa68 100644
--- a/tests/ui/panicking_macros.rs
+++ b/tests/ui/panicking_macros.rs
@@ -1,4 +1,4 @@
-#![allow(clippy::assertions_on_constants, clippy::eq_op)]
+#![allow(clippy::assertions_on_constants, clippy::eq_op, clippy::let_unit_value)]
 #![feature(inline_const)]
 #![warn(clippy::unimplemented, clippy::unreachable, clippy::todo, clippy::panic)]
 
diff --git a/tests/ui/shadow.rs b/tests/ui/shadow.rs
index 0321f8c4cdf..a394ef8f25c 100644
--- a/tests/ui/shadow.rs
+++ b/tests/ui/shadow.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::shadow_same, clippy::shadow_reuse, clippy::shadow_unrelated)]
+#![allow(clippy::let_unit_value)]
 
 fn shadow_same() {
     let x = 1;
diff --git a/tests/ui/shadow.stderr b/tests/ui/shadow.stderr
index f8b9221d555..3bd41d06260 100644
--- a/tests/ui/shadow.stderr
+++ b/tests/ui/shadow.stderr
@@ -1,266 +1,266 @@
 error: `x` is shadowed by itself in `x`
-  --> $DIR/shadow.rs:5:9
+  --> $DIR/shadow.rs:6:9
    |
 LL |     let x = x;
    |         ^
    |
    = note: `-D clippy::shadow-same` implied by `-D warnings`
 note: previous binding is here
-  --> $DIR/shadow.rs:4:9
+  --> $DIR/shadow.rs:5:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `mut x` is shadowed by itself in `&x`
-  --> $DIR/shadow.rs:6:13
+  --> $DIR/shadow.rs:7:13
    |
 LL |     let mut x = &x;
    |             ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:5:9
+  --> $DIR/shadow.rs:6:9
    |
 LL |     let x = x;
    |         ^
 
 error: `x` is shadowed by itself in `&mut x`
-  --> $DIR/shadow.rs:7:9
+  --> $DIR/shadow.rs:8:9
    |
 LL |     let x = &mut x;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:6:9
+  --> $DIR/shadow.rs:7:9
    |
 LL |     let mut x = &x;
    |         ^^^^^
 
 error: `x` is shadowed by itself in `*x`
-  --> $DIR/shadow.rs:8:9
+  --> $DIR/shadow.rs:9:9
    |
 LL |     let x = *x;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:7:9
+  --> $DIR/shadow.rs:8:9
    |
 LL |     let x = &mut x;
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:13:9
+  --> $DIR/shadow.rs:14:9
    |
 LL |     let x = x.0;
    |         ^
    |
    = note: `-D clippy::shadow-reuse` implied by `-D warnings`
 note: previous binding is here
-  --> $DIR/shadow.rs:12:9
+  --> $DIR/shadow.rs:13:9
    |
 LL |     let x = ([[0]], ());
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:14:9
+  --> $DIR/shadow.rs:15:9
    |
 LL |     let x = x[0];
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:13:9
+  --> $DIR/shadow.rs:14:9
    |
 LL |     let x = x.0;
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:15:10
+  --> $DIR/shadow.rs:16:10
    |
 LL |     let [x] = x;
    |          ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:14:9
+  --> $DIR/shadow.rs:15:9
    |
 LL |     let x = x[0];
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:16:9
+  --> $DIR/shadow.rs:17:9
    |
 LL |     let x = Some(x);
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:15:10
+  --> $DIR/shadow.rs:16:10
    |
 LL |     let [x] = x;
    |          ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:17:9
+  --> $DIR/shadow.rs:18:9
    |
 LL |     let x = foo(x);
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:16:9
+  --> $DIR/shadow.rs:17:9
    |
 LL |     let x = Some(x);
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:18:9
+  --> $DIR/shadow.rs:19:9
    |
 LL |     let x = || x;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:17:9
+  --> $DIR/shadow.rs:18:9
    |
 LL |     let x = foo(x);
    |         ^
 
 error: `x` is shadowed
-  --> $DIR/shadow.rs:19:9
+  --> $DIR/shadow.rs:20:9
    |
 LL |     let x = Some(1).map(|_| x)?;
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:18:9
+  --> $DIR/shadow.rs:19:9
    |
 LL |     let x = || x;
    |         ^
 
 error: `y` is shadowed
-  --> $DIR/shadow.rs:21:9
+  --> $DIR/shadow.rs:22:9
    |
 LL |     let y = match y {
    |         ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:20:9
+  --> $DIR/shadow.rs:21:9
    |
 LL |     let y = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:30:9
+  --> $DIR/shadow.rs:31:9
    |
 LL |     let x = 2;
    |         ^
    |
    = note: `-D clippy::shadow-unrelated` implied by `-D warnings`
 note: previous binding is here
-  --> $DIR/shadow.rs:29:9
+  --> $DIR/shadow.rs:30:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:35:13
+  --> $DIR/shadow.rs:36:13
    |
 LL |         let x = 1;
    |             ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:34:10
+  --> $DIR/shadow.rs:35:10
    |
 LL |     fn f(x: u32) {
    |          ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:40:14
+  --> $DIR/shadow.rs:41:14
    |
 LL |         Some(x) => {
    |              ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:41:17
+  --> $DIR/shadow.rs:42:17
    |
 LL |             let x = 1;
    |                 ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:40:14
+  --> $DIR/shadow.rs:41:14
    |
 LL |         Some(x) => {
    |              ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:45:17
+  --> $DIR/shadow.rs:46:17
    |
 LL |     if let Some(x) = Some(1) {}
    |                 ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:46:20
+  --> $DIR/shadow.rs:47:20
    |
 LL |     while let Some(x) = Some(1) {}
    |                    ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:47:15
+  --> $DIR/shadow.rs:48:15
    |
 LL |     let _ = |[x]: [u32; 1]| {
    |               ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:37:9
+  --> $DIR/shadow.rs:38:9
    |
 LL |     let x = 1;
    |         ^
 
 error: `x` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:48:13
+  --> $DIR/shadow.rs:49:13
    |
 LL |         let x = 1;
    |             ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:47:15
+  --> $DIR/shadow.rs:48:15
    |
 LL |     let _ = |[x]: [u32; 1]| {
    |               ^
 
 error: `y` is shadowed
-  --> $DIR/shadow.rs:51:17
+  --> $DIR/shadow.rs:52:17
    |
 LL |     if let Some(y) = y {}
    |                 ^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:50:9
+  --> $DIR/shadow.rs:51:9
    |
 LL |     let y = Some(1);
    |         ^
 
 error: `_b` shadows a previous, unrelated binding
-  --> $DIR/shadow.rs:87:9
+  --> $DIR/shadow.rs:88:9
    |
 LL |     let _b = _a;
    |         ^^
    |
 note: previous binding is here
-  --> $DIR/shadow.rs:86:28
+  --> $DIR/shadow.rs:87:28
    |
 LL | pub async fn foo2(_a: i32, _b: i64) {
    |                            ^^
diff --git a/tests/ui/similar_names.rs b/tests/ui/similar_names.rs
index 76f6ce9ee6b..c21225d153b 100644
--- a/tests/ui/similar_names.rs
+++ b/tests/ui/similar_names.rs
@@ -3,7 +3,8 @@
     unused,
     clippy::println_empty_string,
     clippy::empty_loop,
-    clippy::diverging_sub_expression
+    clippy::diverging_sub_expression,
+    clippy::let_unit_value
 )]
 
 struct Foo {
diff --git a/tests/ui/similar_names.stderr b/tests/ui/similar_names.stderr
index faf572b0c6b..6e772693897 100644
--- a/tests/ui/similar_names.stderr
+++ b/tests/ui/similar_names.stderr
@@ -1,84 +1,84 @@
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:20:9
+  --> $DIR/similar_names.rs:21:9
    |
 LL |     let bpple: i32;
    |         ^^^^^
    |
    = note: `-D clippy::similar-names` implied by `-D warnings`
 note: existing binding defined here
-  --> $DIR/similar_names.rs:18:9
+  --> $DIR/similar_names.rs:19:9
    |
 LL |     let apple: i32;
    |         ^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:22:9
+  --> $DIR/similar_names.rs:23:9
    |
 LL |     let cpple: i32;
    |         ^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:18:9
+  --> $DIR/similar_names.rs:19:9
    |
 LL |     let apple: i32;
    |         ^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:46:9
+  --> $DIR/similar_names.rs:47:9
    |
 LL |     let bluby: i32;
    |         ^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:45:9
+  --> $DIR/similar_names.rs:46:9
    |
 LL |     let blubx: i32;
    |         ^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:50:9
+  --> $DIR/similar_names.rs:51:9
    |
 LL |     let coke: i32;
    |         ^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:48:9
+  --> $DIR/similar_names.rs:49:9
    |
 LL |     let cake: i32;
    |         ^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:68:9
+  --> $DIR/similar_names.rs:69:9
    |
 LL |     let xyzeabc: i32;
    |         ^^^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:66:9
+  --> $DIR/similar_names.rs:67:9
    |
 LL |     let xyz1abc: i32;
    |         ^^^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:72:9
+  --> $DIR/similar_names.rs:73:9
    |
 LL |     let parsee: i32;
    |         ^^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:70:9
+  --> $DIR/similar_names.rs:71:9
    |
 LL |     let parser: i32;
    |         ^^^^^^
 
 error: binding's name is too similar to existing binding
-  --> $DIR/similar_names.rs:93:16
+  --> $DIR/similar_names.rs:94:16
    |
 LL |         bpple: sprang,
    |                ^^^^^^
    |
 note: existing binding defined here
-  --> $DIR/similar_names.rs:92:16
+  --> $DIR/similar_names.rs:93:16
    |
 LL |         apple: spring,
    |                ^^^^^^
diff --git a/tests/ui/single_char_lifetime_names.rs b/tests/ui/single_char_lifetime_names.rs
index 261d8bc7260..69c5b236f7c 100644
--- a/tests/ui/single_char_lifetime_names.rs
+++ b/tests/ui/single_char_lifetime_names.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::single_char_lifetime_names)]
+#![allow(clippy::let_unit_value)]
 
 // Lifetimes should only be linted when they're introduced
 struct DiagnosticCtx<'a, 'b>
diff --git a/tests/ui/single_char_lifetime_names.stderr b/tests/ui/single_char_lifetime_names.stderr
index 013b64f46a8..1438b3999db 100644
--- a/tests/ui/single_char_lifetime_names.stderr
+++ b/tests/ui/single_char_lifetime_names.stderr
@@ -1,5 +1,5 @@
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:4:22
+  --> $DIR/single_char_lifetime_names.rs:5:22
    |
 LL | struct DiagnosticCtx<'a, 'b>
    |                      ^^
@@ -8,7 +8,7 @@ LL | struct DiagnosticCtx<'a, 'b>
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:4:26
+  --> $DIR/single_char_lifetime_names.rs:5:26
    |
 LL | struct DiagnosticCtx<'a, 'b>
    |                          ^^
@@ -16,7 +16,7 @@ LL | struct DiagnosticCtx<'a, 'b>
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:13:6
+  --> $DIR/single_char_lifetime_names.rs:14:6
    |
 LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    |      ^^
@@ -24,7 +24,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:13:10
+  --> $DIR/single_char_lifetime_names.rs:14:10
    |
 LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    |          ^^
@@ -32,7 +32,7 @@ LL | impl<'a, 'b> DiagnosticCtx<'a, 'b> {
    = help: use a more informative name
 
 error: single-character lifetime names are likely uninformative
-  --> $DIR/single_char_lifetime_names.rs:33:15
+  --> $DIR/single_char_lifetime_names.rs:34:15
    |
 LL | fn split_once<'a>(base: &'a str, other: &'_ str) -> (&'a str, Option<&'a str>) {
    |               ^^
diff --git a/tests/ui/suspicious_else_formatting.rs b/tests/ui/suspicious_else_formatting.rs
index fcd827a91c7..21753e5dc6a 100644
--- a/tests/ui/suspicious_else_formatting.rs
+++ b/tests/ui/suspicious_else_formatting.rs
@@ -1,7 +1,7 @@
 // aux-build:proc_macro_suspicious_else_formatting.rs
 
 #![warn(clippy::suspicious_else_formatting)]
-#![allow(clippy::if_same_then_else)]
+#![allow(clippy::if_same_then_else, clippy::let_unit_value)]
 
 extern crate proc_macro_suspicious_else_formatting;
 use proc_macro_suspicious_else_formatting::DeriveBadSpan;
diff --git a/tests/ui/undocumented_unsafe_blocks.rs b/tests/ui/undocumented_unsafe_blocks.rs
index afa337c45f4..7be15b0b2dd 100644
--- a/tests/ui/undocumented_unsafe_blocks.rs
+++ b/tests/ui/undocumented_unsafe_blocks.rs
@@ -1,6 +1,7 @@
 // aux-build:proc_macro_unsafe.rs
 
 #![warn(clippy::undocumented_unsafe_blocks)]
+#![allow(clippy::let_unit_value)]
 
 extern crate proc_macro_unsafe;
 
diff --git a/tests/ui/undocumented_unsafe_blocks.stderr b/tests/ui/undocumented_unsafe_blocks.stderr
index 856a07fd316..87d445bd7b8 100644
--- a/tests/ui/undocumented_unsafe_blocks.stderr
+++ b/tests/ui/undocumented_unsafe_blocks.stderr
@@ -1,5 +1,5 @@
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:256:19
+  --> $DIR/undocumented_unsafe_blocks.rs:257:19
    |
 LL |     /* Safety: */ unsafe {}
    |                   ^^^^^^^^^
@@ -8,7 +8,7 @@ LL |     /* Safety: */ unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:260:5
+  --> $DIR/undocumented_unsafe_blocks.rs:261:5
    |
 LL |     unsafe {}
    |     ^^^^^^^^^
@@ -16,7 +16,7 @@ LL |     unsafe {}
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:264:14
+  --> $DIR/undocumented_unsafe_blocks.rs:265:14
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |              ^^^^^^^^^^^^^
@@ -24,7 +24,7 @@ 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:264:29
+  --> $DIR/undocumented_unsafe_blocks.rs:265:29
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                             ^^^^^^^^^^^^^
@@ -32,7 +32,7 @@ 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:264:48
+  --> $DIR/undocumented_unsafe_blocks.rs:265:48
    |
 LL |     let _ = [unsafe { 14 }, unsafe { 15 }, 42, unsafe { 16 }];
    |                                                ^^^^^^^^^^^^^
@@ -40,7 +40,7 @@ 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:268:18
+  --> $DIR/undocumented_unsafe_blocks.rs:269:18
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                  ^^^^^^^^^
@@ -48,7 +48,7 @@ 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:268:37
+  --> $DIR/undocumented_unsafe_blocks.rs:269:37
    |
 LL |     let _ = (42, unsafe {}, "test", unsafe {});
    |                                     ^^^^^^^^^
@@ -56,7 +56,7 @@ 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:272:14
+  --> $DIR/undocumented_unsafe_blocks.rs:273:14
    |
 LL |     let _ = *unsafe { &42 };
    |              ^^^^^^^^^^^^^^
@@ -64,7 +64,7 @@ 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:277:19
+  --> $DIR/undocumented_unsafe_blocks.rs:278:19
    |
 LL |     let _ = match unsafe {} {
    |                   ^^^^^^^^^
@@ -72,7 +72,7 @@ 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:283:14
+  --> $DIR/undocumented_unsafe_blocks.rs:284:14
    |
 LL |     let _ = &unsafe {};
    |              ^^^^^^^^^
@@ -80,7 +80,7 @@ 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:287:14
+  --> $DIR/undocumented_unsafe_blocks.rs:288:14
    |
 LL |     let _ = [unsafe {}; 5];
    |              ^^^^^^^^^
@@ -88,7 +88,7 @@ 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:291:13
+  --> $DIR/undocumented_unsafe_blocks.rs:292:13
    |
 LL |     let _ = unsafe {};
    |             ^^^^^^^^^
@@ -96,7 +96,7 @@ 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:301:8
+  --> $DIR/undocumented_unsafe_blocks.rs:302:8
    |
 LL |     t!(unsafe {});
    |        ^^^^^^^^^
@@ -104,7 +104,7 @@ LL |     t!(unsafe {});
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:307:13
+  --> $DIR/undocumented_unsafe_blocks.rs:308:13
    |
 LL |             unsafe {}
    |             ^^^^^^^^^
@@ -116,7 +116,7 @@ LL |     t!();
    = 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:315:5
+  --> $DIR/undocumented_unsafe_blocks.rs:316:5
    |
 LL |     unsafe {} // SAFETY:
    |     ^^^^^^^^^
@@ -124,7 +124,7 @@ 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:319:5
+  --> $DIR/undocumented_unsafe_blocks.rs:320:5
    |
 LL |     unsafe {
    |     ^^^^^^^^
@@ -132,7 +132,7 @@ LL |     unsafe {
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:329:5
+  --> $DIR/undocumented_unsafe_blocks.rs:330:5
    |
 LL |     unsafe {};
    |     ^^^^^^^^^
@@ -140,7 +140,7 @@ LL |     unsafe {};
    = help: consider adding a safety comment on the preceding line
 
 error: unsafe block missing a safety comment
-  --> $DIR/undocumented_unsafe_blocks.rs:333:20
+  --> $DIR/undocumented_unsafe_blocks.rs:334:20
    |
 LL |     println!("{}", unsafe { String::from_utf8_unchecked(vec![]) });
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/uninit.rs b/tests/ui/uninit.rs
index 1ed3883c1f0..dac5ce272c0 100644
--- a/tests/ui/uninit.rs
+++ b/tests/ui/uninit.rs
@@ -1,4 +1,5 @@
 #![feature(stmt_expr_attributes)]
+#![allow(clippy::let_unit_value)]
 
 use std::mem::{self, MaybeUninit};
 
diff --git a/tests/ui/uninit.stderr b/tests/ui/uninit.stderr
index 85b64a8419a..15ef2349489 100644
--- a/tests/ui/uninit.stderr
+++ b/tests/ui/uninit.stderr
@@ -1,5 +1,5 @@
 error: this call for this type may be undefined behavior
-  --> $DIR/uninit.rs:6:29
+  --> $DIR/uninit.rs:7:29
    |
 LL |     let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -7,13 +7,13 @@ LL |     let _: usize = unsafe { MaybeUninit::uninit().assume_init() };
    = note: `#[deny(clippy::uninit_assumed_init)]` on by default
 
 error: this call for this type may be undefined behavior
-  --> $DIR/uninit.rs:9:31
+  --> $DIR/uninit.rs:10:31
    |
 LL |     let _: [u8; 0] = unsafe { MaybeUninit::uninit().assume_init() };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: this call for this type may be undefined behavior
-  --> $DIR/uninit.rs:24:29
+  --> $DIR/uninit.rs:25:29
    |
 LL |     let _: usize = unsafe { mem::MaybeUninit::uninit().assume_init() };
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/unit_arg.rs b/tests/ui/unit_arg.rs
index 535683729f6..38be87bddf1 100644
--- a/tests/ui/unit_arg.rs
+++ b/tests/ui/unit_arg.rs
@@ -7,7 +7,8 @@
     clippy::unnecessary_wraps,
     clippy::or_fun_call,
     clippy::needless_question_mark,
-    clippy::self_named_constructors
+    clippy::self_named_constructors,
+    clippy::let_unit_value
 )]
 
 use std::fmt::Debug;
diff --git a/tests/ui/unit_arg.stderr b/tests/ui/unit_arg.stderr
index 5cfb367a7be..394dee29dc9 100644
--- a/tests/ui/unit_arg.stderr
+++ b/tests/ui/unit_arg.stderr
@@ -1,5 +1,5 @@
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:56:5
+  --> $DIR/unit_arg.rs:57:5
    |
 LL | /     foo({
 LL | |         1;
@@ -20,7 +20,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:59:5
+  --> $DIR/unit_arg.rs:60:5
    |
 LL |     foo(foo(1));
    |     ^^^^^^^^^^^
@@ -32,7 +32,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:60:5
+  --> $DIR/unit_arg.rs:61:5
    |
 LL | /     foo({
 LL | |         foo(1);
@@ -54,7 +54,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:65:5
+  --> $DIR/unit_arg.rs:66:5
    |
 LL | /     b.bar({
 LL | |         1;
@@ -74,7 +74,7 @@ LL ~     b.bar(());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:68:5
+  --> $DIR/unit_arg.rs:69:5
    |
 LL |     taking_multiple_units(foo(0), foo(1));
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -87,7 +87,7 @@ LL ~     taking_multiple_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:69:5
+  --> $DIR/unit_arg.rs:70:5
    |
 LL | /     taking_multiple_units(foo(0), {
 LL | |         foo(1);
@@ -110,7 +110,7 @@ LL ~     taking_multiple_units((), ());
    |
 
 error: passing unit values to a function
-  --> $DIR/unit_arg.rs:73:5
+  --> $DIR/unit_arg.rs:74:5
    |
 LL | /     taking_multiple_units(
 LL | |         {
@@ -140,7 +140,7 @@ LL +         foo(2);
  ...
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:84:13
+  --> $DIR/unit_arg.rs:85:13
    |
 LL |     None.or(Some(foo(2)));
    |             ^^^^^^^^^^^^
@@ -154,7 +154,7 @@ LL ~     });
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:87:5
+  --> $DIR/unit_arg.rs:88:5
    |
 LL |     foo(foo(()));
    |     ^^^^^^^^^^^^
@@ -166,7 +166,7 @@ LL ~     foo(());
    |
 
 error: passing a unit value to a function
-  --> $DIR/unit_arg.rs:124:5
+  --> $DIR/unit_arg.rs:125:5
    |
 LL |     Some(foo(1))
    |     ^^^^^^^^^^^^
diff --git a/tests/ui/unit_hash.rs b/tests/ui/unit_hash.rs
index 989916c239b..43eb54eff47 100644
--- a/tests/ui/unit_hash.rs
+++ b/tests/ui/unit_hash.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::unit_hash)]
+#![allow(clippy::let_unit_value)]
 
 use std::collections::hash_map::DefaultHasher;
 use std::hash::Hash;
diff --git a/tests/ui/unit_hash.stderr b/tests/ui/unit_hash.stderr
index da276296e02..050fa55a12b 100644
--- a/tests/ui/unit_hash.stderr
+++ b/tests/ui/unit_hash.stderr
@@ -1,5 +1,5 @@
 error: this call to `hash` on the unit type will do nothing
-  --> $DIR/unit_hash.rs:18:23
+  --> $DIR/unit_hash.rs:19:23
    |
 LL |         Foo::Empty => ().hash(&mut state),
    |                       ^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
@@ -8,7 +8,7 @@ LL |         Foo::Empty => ().hash(&mut state),
    = note: the implementation of `Hash` for `()` is a no-op
 
 error: this call to `hash` on the unit type will do nothing
-  --> $DIR/unit_hash.rs:23:5
+  --> $DIR/unit_hash.rs:24:5
    |
 LL |     res.hash(&mut state);
    |     ^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
@@ -16,7 +16,7 @@ LL |     res.hash(&mut state);
    = note: the implementation of `Hash` for `()` is a no-op
 
 error: this call to `hash` on the unit type will do nothing
-  --> $DIR/unit_hash.rs:26:5
+  --> $DIR/unit_hash.rs:27:5
    |
 LL |     do_nothing().hash(&mut state);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: remove the call to `hash` or consider using: `0_u8.hash(&mut state)`
diff --git a/tests/ui/wildcard_imports.fixed b/tests/ui/wildcard_imports.fixed
index 8402c33a4cd..b6f47ae906b 100644
--- a/tests/ui/wildcard_imports.fixed
+++ b/tests/ui/wildcard_imports.fixed
@@ -8,8 +8,7 @@
 // FIXME: We should likely add another edition 2021 test case for this lint
 
 #![warn(clippy::wildcard_imports)]
-#![allow(unused)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]
 #![warn(unused_imports)]
 
 extern crate wildcard_imports_helper;
diff --git a/tests/ui/wildcard_imports.rs b/tests/ui/wildcard_imports.rs
index faaeaade9b0..eb404b7a3de 100644
--- a/tests/ui/wildcard_imports.rs
+++ b/tests/ui/wildcard_imports.rs
@@ -8,8 +8,7 @@
 // FIXME: We should likely add another edition 2021 test case for this lint
 
 #![warn(clippy::wildcard_imports)]
-#![allow(unused)]
-#![allow(clippy::unnecessary_wraps)]
+#![allow(unused, clippy::unnecessary_wraps, clippy::let_unit_value)]
 #![warn(unused_imports)]
 
 extern crate wildcard_imports_helper;
diff --git a/tests/ui/wildcard_imports.stderr b/tests/ui/wildcard_imports.stderr
index 7534a65ec9b..626c1754fc8 100644
--- a/tests/ui/wildcard_imports.stderr
+++ b/tests/ui/wildcard_imports.stderr
@@ -1,5 +1,5 @@
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:17:5
+  --> $DIR/wildcard_imports.rs:16:5
    |
 LL | use crate::fn_mod::*;
    |     ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
@@ -7,85 +7,85 @@ LL | use crate::fn_mod::*;
    = note: `-D clippy::wildcard-imports` implied by `-D warnings`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:18:5
+  --> $DIR/wildcard_imports.rs:17:5
    |
 LL | use crate::mod_mod::*;
    |     ^^^^^^^^^^^^^^^^^ help: try: `crate::mod_mod::inner_mod`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:19:5
+  --> $DIR/wildcard_imports.rs:18:5
    |
 LL | use crate::multi_fn_mod::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate::multi_fn_mod::{multi_bar, multi_foo, multi_inner_mod}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:21:5
+  --> $DIR/wildcard_imports.rs:20:5
    |
 LL | use crate::struct_mod::*;
    |     ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::struct_mod::{A, inner_struct_mod}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:25:5
+  --> $DIR/wildcard_imports.rs:24:5
    |
 LL | use wildcard_imports_helper::inner::inner_for_self_import::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::inner::inner_for_self_import::inner_extern_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:26:5
+  --> $DIR/wildcard_imports.rs:25:5
    |
 LL | use wildcard_imports_helper::*;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:97:13
+  --> $DIR/wildcard_imports.rs:96:13
    |
 LL |         use crate::fn_mod::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `crate::fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:103:75
+  --> $DIR/wildcard_imports.rs:102:75
    |
 LL |         use wildcard_imports_helper::inner::inner_for_self_import::{self, *};
    |                                                                           ^ help: try: `inner_extern_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:104:13
+  --> $DIR/wildcard_imports.rs:103:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternA, extern_foo}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:115:20
+  --> $DIR/wildcard_imports.rs:114:20
    |
 LL |         use self::{inner::*, inner2::*};
    |                    ^^^^^^^^ help: try: `inner::inner_foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:115:30
+  --> $DIR/wildcard_imports.rs:114:30
    |
 LL |         use self::{inner::*, inner2::*};
    |                              ^^^^^^^^^ help: try: `inner2::inner_bar`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:122:13
+  --> $DIR/wildcard_imports.rs:121:13
    |
 LL |         use wildcard_imports_helper::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `wildcard_imports_helper::{ExternExportedEnum, ExternExportedStruct, extern_exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:151:9
+  --> $DIR/wildcard_imports.rs:150:9
    |
 LL |     use crate::in_fn_test::*;
    |         ^^^^^^^^^^^^^^^^^^^^ help: try: `crate::in_fn_test::{ExportedEnum, ExportedStruct, exported}`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:160:9
+  --> $DIR/wildcard_imports.rs:159:9
    |
 LL |     use crate:: in_fn_test::  * ;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `crate:: in_fn_test::exported`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:161:9
+  --> $DIR/wildcard_imports.rs:160:9
    |
 LL |       use crate:: fn_mod::
    |  _________^
@@ -93,37 +93,37 @@ LL | |         *;
    | |_________^ help: try: `crate:: fn_mod::foo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:172:13
+  --> $DIR/wildcard_imports.rs:171:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:207:17
+  --> $DIR/wildcard_imports.rs:206:17
    |
 LL |             use super::*;
    |                 ^^^^^^^^ help: try: `super::insidefoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:215:13
+  --> $DIR/wildcard_imports.rs:214:13
    |
 LL |         use super_imports::*;
    |             ^^^^^^^^^^^^^^^^ help: try: `super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:224:17
+  --> $DIR/wildcard_imports.rs:223:17
    |
 LL |             use super::super::*;
    |                 ^^^^^^^^^^^^^^^ help: try: `super::super::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:233:13
+  --> $DIR/wildcard_imports.rs:232:13
    |
 LL |         use super::super::super_imports::*;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `super::super::super_imports::foofoo`
 
 error: usage of wildcard import
-  --> $DIR/wildcard_imports.rs:241:13
+  --> $DIR/wildcard_imports.rs:240:13
    |
 LL |         use super::*;
    |             ^^^^^^^^ help: try: `super::foofoo`