Skip to content

Commit

Permalink
Add lint for misleading_use_of_ok
Browse files Browse the repository at this point in the history
  • Loading branch information
ithinuel committed Jan 15, 2024
1 parent a71211d commit 2893485
Show file tree
Hide file tree
Showing 8 changed files with 126 additions and 5 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5347,6 +5347,7 @@ Released 2018-09-13
[`min_ident_chars`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_ident_chars
[`min_max`]: https://rust-lang.github.io/rust-clippy/master/index.html#min_max
[`misaligned_transmute`]: https://rust-lang.github.io/rust-clippy/master/index.html#misaligned_transmute
[`misleading_use_of_ok`]: https://rust-lang.github.io/rust-clippy/master/index.html#misleading_use_of_ok
[`mismatched_target_os`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatched_target_os
[`mismatching_type_param_order`]: https://rust-lang.github.io/rust-clippy/master/index.html#mismatching_type_param_order
[`misnamed_getters`]: https://rust-lang.github.io/rust-clippy/master/index.html#misnamed_getters
Expand Down
10 changes: 5 additions & 5 deletions clippy_dev/src/update_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,14 +377,14 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io

// Some lints have their own directories, delete them
if path.is_dir() {
fs::remove_dir_all(path).ok();
let _ = fs::remove_dir_all(path);
return;
}

// Remove all related test files
fs::remove_file(path.with_extension("rs")).ok();
fs::remove_file(path.with_extension("stderr")).ok();
fs::remove_file(path.with_extension("fixed")).ok();
let _ = fs::remove_file(path.with_extension("rs"));
let _ = fs::remove_file(path.with_extension("stderr"));
let _ = fs::remove_file(path.with_extension("fixed"));
}

fn remove_impl_lint_pass(lint_name_upper: &str, content: &mut String) {
Expand Down Expand Up @@ -427,7 +427,7 @@ fn remove_lint_declaration(name: &str, path: &Path, lints: &mut Vec<Lint>) -> io
lint_mod_path.set_file_name(name);
lint_mod_path.set_extension("rs");

fs::remove_file(lint_mod_path).ok();
let _ = fs::remove_file(lint_mod_path);
}

let mut content =
Expand Down
1 change: 1 addition & 0 deletions clippy_lints/src/declared_lints.rs
Original file line number Diff line number Diff line change
Expand Up @@ -477,6 +477,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
crate::misc_early::UNNEEDED_WILDCARD_PATTERN_INFO,
crate::misc_early::UNSEPARATED_LITERAL_SUFFIX_INFO,
crate::misc_early::ZERO_PREFIXED_LITERAL_INFO,
crate::misleading_use_of_ok::MISLEADING_USE_OF_OK_INFO,
crate::mismatching_type_param_order::MISMATCHING_TYPE_PARAM_ORDER_INFO,
crate::missing_assert_message::MISSING_ASSERT_MESSAGE_INFO,
crate::missing_asserts_for_indexing::MISSING_ASSERTS_FOR_INDEXING_INFO,
Expand Down
2 changes: 2 additions & 0 deletions clippy_lints/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ mod min_ident_chars;
mod minmax;
mod misc;
mod misc_early;
mod misleading_use_of_ok;
mod mismatching_type_param_order;
mod missing_assert_message;
mod missing_asserts_for_indexing;
Expand Down Expand Up @@ -765,6 +766,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
store.register_late_pass(move |_| Box::new(missing_doc::MissingDoc::new(missing_docs_in_crate_items)));
store.register_late_pass(|_| Box::new(missing_inline::MissingInline));
store.register_late_pass(move |_| Box::new(exhaustive_items::ExhaustiveItems));
store.register_late_pass(|_| Box::new(misleading_use_of_ok::MisleadingUseOfOk));
store.register_late_pass(|_| Box::new(match_result_ok::MatchResultOk));
store.register_late_pass(|_| Box::new(partialeq_ne_impl::PartialEqNeImpl));
store.register_late_pass(|_| Box::new(unused_io_amount::UnusedIoAmount));
Expand Down
57 changes: 57 additions & 0 deletions clippy_lints/src/misleading_use_of_ok.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_with_context;
use clippy_utils::ty::is_type_diagnostic_item;
use rustc_errors::Applicability;
use rustc_hir::{ExprKind, Stmt, StmtKind};
use rustc_lint::{LateContext, LateLintPass};
use rustc_session::declare_lint_pass;
use rustc_span::sym;

declare_clippy_lint! {
/// ### What it does
/// Checks for `Result::ok();` when the result is not captured.
///
/// ### Why is this bad?
/// Using `Result::ok()` may look like the result is checked like `unwrap` or `expect` would do
/// but it only silences the warning caused by `#[must_use]` on the `Result`.
///
/// ### Example
/// ```no_run
/// # fn some_function() -> Result<(), ()> { Ok(()) }
/// some_function().ok();
/// ```
/// Use instead:
/// ```no_run
/// # fn some_function() -> Result<(), ()> { Ok(()) }
/// let _ = some_function();
/// ```
#[clippy::version = "1.70.0"]
pub MISLEADING_USE_OF_OK,
style,
"Use of `.ok()` to silence `Result`'s `#[must_use]` is misleading. Use `let _ =` instead."
}
declare_lint_pass!(MisleadingUseOfOk => [MISLEADING_USE_OF_OK]);

impl LateLintPass<'_> for MisleadingUseOfOk {
fn check_stmt(&mut self, cx: &LateContext<'_>, stmt: &Stmt<'_>) {
if let StmtKind::Semi(expr) = stmt.kind &&
let ExprKind::MethodCall(ok_path, recv, [], ..) = expr.kind //check is expr.ok() has type Result<T,E>.ok(, _)
&& ok_path.ident.as_str() == "ok"
&& is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(recv), sym::Result)
{
let ctxt = expr.span.ctxt();
let mut applicability = Applicability::MachineApplicable;
let trimmed_ok = snippet_with_context(cx, recv.span, ctxt, "", &mut applicability).0;
let sugg = format!("let _ = {}", trimmed_ok.trim().trim_end_matches('.'),);
span_lint_and_sugg(
cx,
MISLEADING_USE_OF_OK,
expr.span,
"ignoring a result with `.ok()` is misleading",
"consider using `let _ =` and removing the call to `.ok()` instead",
sugg,
applicability,
);
}
}
}
17 changes: 17 additions & 0 deletions tests/ui/misleading_use_of_ok.fixed
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![warn(clippy::misleading_use_of_ok)]
#![allow(dead_code)]

fn bad_style(x: &str) {
let _ = x.parse::<u32>();
}

fn good_style(x: &str) -> Option<u32> {
x.parse::<u32>().ok()
}

#[rustfmt::skip]
fn strange_parse(x: &str) {
let _ = x . parse::<i32>();
}

fn main() {}
17 changes: 17 additions & 0 deletions tests/ui/misleading_use_of_ok.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#![warn(clippy::misleading_use_of_ok)]
#![allow(dead_code)]

fn bad_style(x: &str) {
x.parse::<u32>().ok();
}

fn good_style(x: &str) -> Option<u32> {
x.parse::<u32>().ok()
}

#[rustfmt::skip]
fn strange_parse(x: &str) {
x . parse::<i32>() . ok ();
}

fn main() {}
26 changes: 26 additions & 0 deletions tests/ui/misleading_use_of_ok.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: ignoring a result with `.ok()` is misleading
--> $DIR/misleading_use_of_ok.rs:5:5
|
LL | x.parse::<u32>().ok();
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D clippy::misleading-use-of-ok` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::misleading_use_of_ok)]`
help: consider using `let _ =` and removing the call to `.ok()` instead
|
LL | let _ = x.parse::<u32>();
| ~~~~~~~~~~~~~~~~~~~~~~~~

error: ignoring a result with `.ok()` is misleading
--> $DIR/misleading_use_of_ok.rs:14:5
|
LL | x . parse::<i32>() . ok ();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
help: consider using `let _ =` and removing the call to `.ok()` instead
|
LL | let _ = x . parse::<i32>();
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

error: aborting due to 2 previous errors

0 comments on commit 2893485

Please sign in to comment.