Skip to content

Clippy subtree update #140540

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 36 commits into from
May 2, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
cbfe1f5
Restrict the cases where `ptr_eq` triggers
samueltardieu Apr 2, 2025
2422f0b
Restrict the cases where `ptr_eq` triggers (#14526)
Alexendoo Apr 22, 2025
ff428d9
Merge commit '0621446356e20fd2ead13a6763bb936c95eb0cfa' into clippy-s…
flip1995 Apr 22, 2025
bf713a0
style: pull one more `if` into the let-chain
ada4a Apr 22, 2025
2304a9c
remove non-existent pathspec from pre-commit hook
ada4a Apr 22, 2025
aa27ae3
remove non-existent pathspec from pre-commit hook (#14671)
Manishearth Apr 22, 2025
dd5948c
Clippy: Fix doc issue
flip1995 Apr 23, 2025
7c5312b
Reword `needless_question_mark` diagnostics and docs
Alexendoo Apr 23, 2025
dc695f5
Reword `needless_question_mark` diagnostics and docs (#14682)
Manishearth Apr 23, 2025
34f81f9
style: pull one more `if` into the let-chain (#14669)
y21 Apr 23, 2025
6e64338
Suggest {to,from}_ne_bytes for transmutations between arrays and inte…
bend-n Mar 31, 2025
6ee75c4
Remove `weak` alias terminology
BoxyUwU Apr 24, 2025
736be8b
Consistently refer to the `?` operator
Alexendoo Apr 24, 2025
fc12b5b
fix-issue-14665
Kivooeo Apr 22, 2025
91ed606
Consistently refer to the `?` operator (#14687)
y21 Apr 24, 2025
7b337f6
Replace some `Symbol::as_str` usage
Alexendoo Apr 23, 2025
8a9153d
Merge from rustc
Apr 25, 2025
148c9a1
Fix error message for static references or mutable references
yuk1ty Apr 20, 2025
3f72ffa
fix: `unnecessary_cast` suggests extra brackets when in macro
profetia Apr 17, 2025
ad69347
fix: `equatable_if_let` suggests wrongly when involving reference
profetia Mar 30, 2025
ff307ba
fix: `unnecessary_cast` suggests extra brackets when in macro (#14643)
Jarcho Apr 26, 2025
58cfdb7
fix: `equatable_if_let` suggests wrongly when involving reference (#1…
dswij Apr 26, 2025
39a4086
`manual_div_ceil`: fix suggestions when macro is involved (#14666)
dswij Apr 27, 2025
5d8fb77
fix: `unused_unit` suggests wrongly when unit never type fallback
profetia Apr 17, 2025
5123ad5
Fix `zombie_processes` FP inside closures
profetia Apr 27, 2025
0dd9722
Replace some `Symbol::as_str` usage (#14679)
y21 Apr 27, 2025
542762e
fix: `unused_unit` suggests wrongly when unit never type fallback (#1…
Jarcho Apr 27, 2025
bca637c
Add or-patterns to pattern types
oli-obk Feb 27, 2025
92ba063
Rollup merge of #140249 - BoxyUwU:remove_weak_alias_terminology, r=ol…
GuillaumeGomez Apr 28, 2025
549107d
Fix `zombie_processes` FP inside closures (#14696)
Manishearth Apr 28, 2025
d172204
Merge from rustc
Apr 29, 2025
6d58910
Rollup merge of #139909 - oli-obk:or-patterns, r=BoxyUwU
tgross35 Apr 29, 2025
4379767
Merge remote-tracking branch 'upstream/master' into rustup
flip1995 May 1, 2025
8a91bbf
Bump nightly version -> 2025-05-01
flip1995 May 1, 2025
03a5b6b
Rustup (#14721)
flip1995 May 1, 2025
c9992d6
Merge commit '03a5b6b976ac121f4233775c49a4bce026065b47' into clippy-s…
flip1995 May 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Reword needless_question_mark diagnostics and docs
  • Loading branch information
Alexendoo committed Apr 23, 2025
commit 7c5312bdab3ce012c136114559ba988bfad8ecc1
70 changes: 33 additions & 37 deletions clippy_lints/src/needless_question_mark.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::diagnostics::span_lint_hir_and_then;
use clippy_utils::path_res;
use clippy_utils::source::snippet;
use rustc_errors::Applicability;
use rustc_hir::def::{DefKind, Res};
use rustc_hir::{Block, Body, Expr, ExprKind, LangItem, MatchSource, QPath};
Expand All @@ -9,52 +8,38 @@ use rustc_session::declare_lint_pass;

declare_clippy_lint! {
/// ### What it does
/// Suggests alternatives for useless applications of `?` in terminating expressions
/// Suggests replacing `Ok(x?)` or `Some(x?)` with `x` in return positions where the `?` operator
/// is not needed to convert the type of `x`.
///
/// ### Why is this bad?
/// There's no reason to use `?` to short-circuit when execution of the body will end there anyway.
///
/// ### Example
/// ```no_run
/// struct TO {
/// magic: Option<usize>,
/// # use std::num::ParseIntError;
/// fn f(s: &str) -> Option<usize> {
/// Some(s.find('x')?)
/// }
///
/// fn f(to: TO) -> Option<usize> {
/// Some(to.magic?)
/// fn g(s: &str) -> Result<usize, ParseIntError> {
/// Ok(s.parse()?)
/// }
///
/// struct TR {
/// magic: Result<usize, bool>,
/// }
///
/// fn g(tr: Result<TR, bool>) -> Result<usize, bool> {
/// tr.and_then(|t| Ok(t.magic?))
/// }
///
/// ```
/// Use instead:
/// ```no_run
/// struct TO {
/// magic: Option<usize>,
/// # use std::num::ParseIntError;
/// fn f(s: &str) -> Option<usize> {
/// s.find('x')
/// }
///
/// fn f(to: TO) -> Option<usize> {
/// to.magic
/// }
///
/// struct TR {
/// magic: Result<usize, bool>,
/// }
///
/// fn g(tr: Result<TR, bool>) -> Result<usize, bool> {
/// tr.and_then(|t| t.magic)
/// fn g(s: &str) -> Result<usize, ParseIntError> {
/// s.parse()
/// }
/// ```
#[clippy::version = "1.51.0"]
pub NEEDLESS_QUESTION_MARK,
complexity,
"Suggest `value.inner_option` instead of `Some(value.inner_option?)`. The same goes for `Result<T, E>`."
"using `Ok(x?)` or `Some(x?)` where `x` would be equivalent"
}

declare_lint_pass!(NeedlessQuestionMark => [NEEDLESS_QUESTION_MARK]);
Expand Down Expand Up @@ -111,10 +96,10 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
if let ExprKind::Call(path, [arg]) = expr.kind
&& let Res::Def(DefKind::Ctor(..), ctor_id) = path_res(cx, path)
&& let Some(variant_id) = cx.tcx.opt_parent(ctor_id)
&& let sugg_remove = if cx.tcx.lang_items().option_some_variant() == Some(variant_id) {
"Some()"
&& let variant = if cx.tcx.lang_items().option_some_variant() == Some(variant_id) {
"Some"
} else if cx.tcx.lang_items().result_ok_variant() == Some(variant_id) {
"Ok()"
"Ok"
} else {
return;
}
Expand All @@ -126,14 +111,25 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
&& let inner_ty = cx.typeck_results().expr_ty(inner_expr)
&& expr_ty == inner_ty
{
span_lint_and_sugg(
span_lint_hir_and_then(
cx,
NEEDLESS_QUESTION_MARK,
expr.hir_id,
expr.span,
"question mark operator is useless here",
format!("try removing question mark and `{sugg_remove}`"),
format!("{}", snippet(cx, inner_expr.span, r#""...""#)),
Applicability::MachineApplicable,
format!("enclosing `{variant}` and `?` operator are unneeded"),
|diag| {
diag.multipart_suggestion(
format!("remove the enclosing `{variant}` and `?` operator"),
vec![
(expr.span.until(inner_expr.span), String::new()),
(
inner_expr.span.shrink_to_hi().to(expr.span.shrink_to_hi()),
String::new(),
),
],
Applicability::MachineApplicable,
);
},
);
}
}
148 changes: 118 additions & 30 deletions tests/ui/needless_question_mark.stderr
Original file line number Diff line number Diff line change
@@ -1,100 +1,188 @@
error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:20:12
|
LL | return Some(to.magic?);
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
| ^^^^^^^^^^^^^^^
|
= note: `-D clippy::needless-question-mark` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::needless_question_mark)]`
help: remove the enclosing `Some` and `?` operator
|
LL - return Some(to.magic?);
LL + return to.magic;
|

error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:29:12
|
LL | return Some(to.magic?)
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
| ^^^^^^^^^^^^^^^
|
help: remove the enclosing `Some` and `?` operator
|
LL - return Some(to.magic?)
LL + return to.magic
|

error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:35:5
|
LL | Some(to.magic?)
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
| ^^^^^^^^^^^^^^^
|
help: remove the enclosing `Some` and `?` operator
|
LL - Some(to.magic?)
LL + to.magic
|

error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:41:21
|
LL | to.and_then(|t| Some(t.magic?))
| ^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `t.magic`
| ^^^^^^^^^^^^^^
|
help: remove the enclosing `Some` and `?` operator
|
LL - to.and_then(|t| Some(t.magic?))
LL + to.and_then(|t| t.magic)
|

error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:51:9
|
LL | Some(t.magic?)
| ^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `t.magic`
| ^^^^^^^^^^^^^^
|
help: remove the enclosing `Some` and `?` operator
|
LL - Some(t.magic?)
LL + t.magic
|

error: question mark operator is useless here
error: enclosing `Ok` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:57:12
|
LL | return Ok(tr.magic?);
| ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic`
| ^^^^^^^^^^^^^
|
help: remove the enclosing `Ok` and `?` operator
|
LL - return Ok(tr.magic?);
LL + return tr.magic;
|

error: question mark operator is useless here
error: enclosing `Ok` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:65:12
|
LL | return Ok(tr.magic?)
| ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic`
| ^^^^^^^^^^^^^
|
help: remove the enclosing `Ok` and `?` operator
|
LL - return Ok(tr.magic?)
LL + return tr.magic
|

error: question mark operator is useless here
error: enclosing `Ok` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:70:5
|
LL | Ok(tr.magic?)
| ^^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `tr.magic`
| ^^^^^^^^^^^^^
|
help: remove the enclosing `Ok` and `?` operator
|
LL - Ok(tr.magic?)
LL + tr.magic
|

error: question mark operator is useless here
error: enclosing `Ok` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:75:21
|
LL | tr.and_then(|t| Ok(t.magic?))
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic`
| ^^^^^^^^^^^^
|
help: remove the enclosing `Ok` and `?` operator
|
LL - tr.and_then(|t| Ok(t.magic?))
LL + tr.and_then(|t| t.magic)
|

error: question mark operator is useless here
error: enclosing `Ok` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:84:9
|
LL | Ok(t.magic?)
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic`
| ^^^^^^^^^^^^
|
help: remove the enclosing `Ok` and `?` operator
|
LL - Ok(t.magic?)
LL + t.magic
|

error: question mark operator is useless here
error: enclosing `Ok` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:92:16
|
LL | return Ok(t.magic?);
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `t.magic`
| ^^^^^^^^^^^^
|
help: remove the enclosing `Ok` and `?` operator
|
LL - return Ok(t.magic?);
LL + return t.magic;
|

error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:128:27
|
LL | || -> Option<_> { Some(Some($expr)?) }()
| ^^^^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `Some($expr)`
| ^^^^^^^^^^^^^^^^^^
...
LL | let _x = some_and_qmark_in_macro!(x?);
| ---------------------------- in this macro invocation
|
= note: this error originates in the macro `some_and_qmark_in_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
help: remove the enclosing `Some` and `?` operator
|
LL - || -> Option<_> { Some(Some($expr)?) }()
LL + || -> Option<_> { Some($expr) }()
|

error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:140:5
|
LL | Some(to.magic?)
| ^^^^^^^^^^^^^^^ help: try removing question mark and `Some()`: `to.magic`
| ^^^^^^^^^^^^^^^
|
help: remove the enclosing `Some` and `?` operator
|
LL - Some(to.magic?)
LL + to.magic
|

error: question mark operator is useless here
error: enclosing `Ok` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:149:5
|
LL | Ok(s.magic?)
| ^^^^^^^^^^^^ help: try removing question mark and `Ok()`: `s.magic`
| ^^^^^^^^^^^^
|
help: remove the enclosing `Ok` and `?` operator
|
LL - Ok(s.magic?)
LL + s.magic
|

error: question mark operator is useless here
error: enclosing `Some` and `?` operator are unneeded
--> tests/ui/needless_question_mark.rs:154:7
|
LL | { Some(a?) }
| ^^^^^^^^ help: try removing question mark and `Some()`: `a`
| ^^^^^^^^
|
help: remove the enclosing `Some` and `?` operator
|
LL - { Some(a?) }
LL + { a }
|

error: aborting due to 15 previous errors

5 changes: 5 additions & 0 deletions tests/ui/question_mark.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,11 @@ fn pattern() -> Result<(), PatternedError> {
res
}

fn expect_expr(a: Option<usize>) -> Option<usize> {
#[expect(clippy::needless_question_mark)]
Some(a?)
}

fn main() {}

// `?` is not the same as `return None;` if inside of a try block
Expand Down
5 changes: 5 additions & 0 deletions tests/ui/question_mark.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,11 @@ fn pattern() -> Result<(), PatternedError> {
res
}

fn expect_expr(a: Option<usize>) -> Option<usize> {
#[expect(clippy::needless_question_mark)]
Some(a?)
}

fn main() {}

// `?` is not the same as `return None;` if inside of a try block
Expand Down
Loading