From 6e0e09c8f7622caa6ea6536f2bbc5c033a9cffa2 Mon Sep 17 00:00:00 2001 From: rsdy
Date: Thu, 16 Feb 2023 15:30:09 +0000 Subject: [PATCH] Track init and unwrap of expr --- .../src/methods/unnecessary_literal_unwrap.rs | 22 ++++++++++++++++--- .../unnecessary_literal_unwrap_unfixable.rs | 6 +++++ ...nnecessary_literal_unwrap_unfixable.stderr | 15 +++++++++++++ 3 files changed, 40 insertions(+), 3 deletions(-) create mode 100644 tests/ui/unnecessary_literal_unwrap_unfixable.rs create mode 100644 tests/ui/unnecessary_literal_unwrap_unfixable.stderr diff --git a/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/clippy_lints/src/methods/unnecessary_literal_unwrap.rs index 9a9c659b2..54160a27c 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 000000000..ac3a84934 --- /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 000000000..abc789ccd --- /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 +