diff --git a/clippy_lints/src/let_with_type_underscore.rs b/clippy_lints/src/let_with_type_underscore.rs
index 8fcf42564d5..4f8c5ff58b5 100644
--- a/clippy_lints/src/let_with_type_underscore.rs
+++ b/clippy_lints/src/let_with_type_underscore.rs
@@ -1,4 +1,5 @@
-use clippy_utils::{diagnostics::span_lint_and_help, is_from_proc_macro};
+use clippy_utils::diagnostics::span_lint_and_help;
+use clippy_utils::source::snippet;
 use rustc_hir::{Local, TyKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::lint::in_external_macro;
@@ -32,7 +33,12 @@ impl LateLintPass<'_> for UnderscoreTyped {
             if let TyKind::Infer = &ty.kind; // that type is '_'
             if local.span.ctxt() == ty.span.ctxt();
             then {
-                if let Some(init) = local.init && is_from_proc_macro(cx, init) {
+                let underscore_span = ty.span.with_lo(local.pat.span.hi());
+                let snippet = snippet(cx, underscore_span, ": _");
+
+                // NOTE: Using `is_from_proc_macro` on `init` will require that it's initialized,
+                // this doesn't. Alternatively, `WithSearchPat` can be implemented for `Ty`
+                if !snippet.trim().starts_with(':') && !snippet.trim().ends_with('_') {
                     return;
                 }
 
@@ -41,7 +47,7 @@ impl LateLintPass<'_> for UnderscoreTyped {
                     LET_WITH_TYPE_UNDERSCORE,
                     local.span,
                     "variable declared with type underscore",
-                    Some(ty.span.with_lo(local.pat.span.hi())),
+                    Some(underscore_span),
                     "remove the explicit type `_` declaration"
                 )
             }
diff --git a/tests/ui/let_with_type_underscore.rs b/tests/ui/let_with_type_underscore.rs
index 832d0304ffa..ae1a480bcfc 100644
--- a/tests/ui/let_with_type_underscore.rs
+++ b/tests/ui/let_with_type_underscore.rs
@@ -1,7 +1,7 @@
 //@aux-build: proc_macros.rs
 #![allow(unused)]
 #![warn(clippy::let_with_type_underscore)]
-#![allow(clippy::let_unit_value)]
+#![allow(clippy::let_unit_value, clippy::needless_late_init)]
 
 extern crate proc_macros;
 
@@ -9,20 +9,34 @@ fn func() -> &'static str {
     ""
 }
 
+#[rustfmt::skip]
 fn main() {
     // Will lint
     let x: _ = 1;
     let _: _ = 2;
     let x: _ = func();
+    let x: _;
+    x = ();
 
     let x = 1; // Will not lint, Rust infers this to an integer before Clippy
     let x = func();
     let x: Vec<_> = Vec::<u32>::new();
     let x: [_; 1] = [1];
+    let x : _ = 1;
 
-    // do not lint from procedural macros
+    // Do not lint from procedural macros
     proc_macros::with_span! {
         span
         let x: _ = ();
+        // Late initialization
+        let x: _;
+        x = ();
+        // Ensure weird formatting will not break it (hopefully)
+        let x : _ = 1;
+        let x
+: _ = 1;
+        let                   x :              
+        _;
+        x = ();
     };
 }
diff --git a/tests/ui/let_with_type_underscore.stderr b/tests/ui/let_with_type_underscore.stderr
index 26400363f5d..a749552c7fa 100644
--- a/tests/ui/let_with_type_underscore.stderr
+++ b/tests/ui/let_with_type_underscore.stderr
@@ -1,39 +1,63 @@
 error: variable declared with type underscore
-  --> $DIR/let_with_type_underscore.rs:14:5
+  --> $DIR/let_with_type_underscore.rs:15:5
    |
 LL |     let x: _ = 1;
    |     ^^^^^^^^^^^^^
    |
 help: remove the explicit type `_` declaration
-  --> $DIR/let_with_type_underscore.rs:14:10
+  --> $DIR/let_with_type_underscore.rs:15:10
    |
 LL |     let x: _ = 1;
    |          ^^^
    = note: `-D clippy::let-with-type-underscore` implied by `-D warnings`
 
 error: variable declared with type underscore
-  --> $DIR/let_with_type_underscore.rs:15:5
+  --> $DIR/let_with_type_underscore.rs:16:5
    |
 LL |     let _: _ = 2;
    |     ^^^^^^^^^^^^^
    |
 help: remove the explicit type `_` declaration
-  --> $DIR/let_with_type_underscore.rs:15:10
+  --> $DIR/let_with_type_underscore.rs:16:10
    |
 LL |     let _: _ = 2;
    |          ^^^
 
 error: variable declared with type underscore
-  --> $DIR/let_with_type_underscore.rs:16:5
+  --> $DIR/let_with_type_underscore.rs:17:5
    |
 LL |     let x: _ = func();
    |     ^^^^^^^^^^^^^^^^^^
    |
 help: remove the explicit type `_` declaration
-  --> $DIR/let_with_type_underscore.rs:16:10
+  --> $DIR/let_with_type_underscore.rs:17:10
    |
 LL |     let x: _ = func();
    |          ^^^
 
-error: aborting due to 3 previous errors
+error: variable declared with type underscore
+  --> $DIR/let_with_type_underscore.rs:18:5
+   |
+LL |     let x: _;
+   |     ^^^^^^^^^
+   |
+help: remove the explicit type `_` declaration
+  --> $DIR/let_with_type_underscore.rs:18:10
+   |
+LL |     let x: _;
+   |          ^^^
+
+error: variable declared with type underscore
+  --> $DIR/let_with_type_underscore.rs:25:5
+   |
+LL |     let x : _ = 1;
+   |     ^^^^^^^^^^^^^^
+   |
+help: remove the explicit type `_` declaration
+  --> $DIR/let_with_type_underscore.rs:25:10
+   |
+LL |     let x : _ = 1;
+   |          ^^^^
+
+error: aborting due to 5 previous errors