about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/methods/unnecessary_literal_unwrap.rs22
-rw-r--r--tests/ui/unnecessary_literal_unwrap_unfixable.rs6
-rw-r--r--tests/ui/unnecessary_literal_unwrap_unfixable.stderr15
3 files changed, 40 insertions, 3 deletions
diff --git a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
index 9a9c659b232..54160a27cb2 100644
--- a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
+++ b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
@@ -6,7 +6,9 @@ use rustc_lint::LateContext;
 use super::UNNECESSARY_LITERAL_UNWRAP;
 
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>, name: &str) {
-    if let hir::ExprKind::Call(call, [arg]) = recv.kind {
+    let init = clippy_utils::expr_or_init(cx, recv);
+
+    if let hir::ExprKind::Call(call, [arg]) = init.kind {
         let mess = if is_res_lang_ctor(cx, path_res(cx, call), hir::LangItem::OptionSome) {
             Some("Some")
         } else if is_res_lang_ctor(cx, path_res(cx, call), hir::LangItem::ResultOk) {
@@ -15,7 +17,11 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
             None
         };
 
-        if let Some(constructor) = mess {
+        let Some(constructor) = mess else {
+	    return;
+	};
+
+        if init.span == recv.span {
             span_lint_and_then(
                 cx,
                 UNNECESSARY_LITERAL_UNWRAP,
@@ -23,7 +29,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
                 &format!("used `{name}()` on `{constructor}` value"),
                 |diag| {
                     let suggestions = vec![
-                        (call.span.with_hi(arg.span.lo()), String::new()),
+                        (recv.span.with_hi(arg.span.lo()), String::new()),
                         (expr.span.with_lo(arg.span.hi()), String::new()),
                     ];
 
@@ -34,6 +40,16 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
                     );
                 },
             );
+        } else {
+            span_lint_and_then(
+                cx,
+                UNNECESSARY_LITERAL_UNWRAP,
+                expr.span,
+                &format!("used `{name}()` on `{constructor}` value"),
+                |diag| {
+                    diag.span_help(init.span, format!("remove the `{constructor}` and `{name}()`"));
+                },
+            );
         }
     }
 }
diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.rs b/tests/ui/unnecessary_literal_unwrap_unfixable.rs
new file mode 100644
index 00000000000..ac3a84934af
--- /dev/null
+++ b/tests/ui/unnecessary_literal_unwrap_unfixable.rs
@@ -0,0 +1,6 @@
+#![warn(clippy::unnecessary_literal_unwrap)]
+
+fn main() {
+    let val = Some(1);
+    let _val2 = val.unwrap();
+}
diff --git a/tests/ui/unnecessary_literal_unwrap_unfixable.stderr b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr
new file mode 100644
index 00000000000..abc789ccda4
--- /dev/null
+++ b/tests/ui/unnecessary_literal_unwrap_unfixable.stderr
@@ -0,0 +1,15 @@
+error: used `unwrap()` on `Some` value
+  --> $DIR/unnecessary_literal_unwrap_unfixable.rs:5:17
+   |
+LL |     let _val2 = val.unwrap();
+   |                 ^^^^^^^^^^^^
+   |
+help: remove the `Some` and `unwrap()`
+  --> $DIR/unnecessary_literal_unwrap_unfixable.rs:4:15
+   |
+LL |     let val = Some(1);
+   |               ^^^^^^^
+   = note: `-D clippy::unnecessary-literal-unwrap` implied by `-D warnings`
+
+error: aborting due to previous error
+