diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2021-03-18 23:01:42 +0100 |
|---|---|---|
| committer | Matthias Krüger <matthias.krueger@famsik.de> | 2021-03-18 23:47:21 +0100 |
| commit | b42ec5e04d51e2fa16a689ce61128533559f09ff (patch) | |
| tree | f4559e730cf935b79cad288e44a8842139103f78 | |
| parent | 36aee1c52663472870d2fe43658b27a74e1e6f9a (diff) | |
| download | rust-b42ec5e04d51e2fa16a689ce61128533559f09ff.tar.gz rust-b42ec5e04d51e2fa16a689ce61128533559f09ff.zip | |
needless_question_mark: don't lint if Some(..) is inside a macro def and the ? is not.
The suggestion would fail to apply. Fixes #6921 changelog: needless_question_mark: don't lint if Some(..) is inside a macro def and the ? is not.
| -rw-r--r-- | clippy_lints/src/needless_question_mark.rs | 7 | ||||
| -rw-r--r-- | tests/ui/needless_question_mark.fixed | 25 | ||||
| -rw-r--r-- | tests/ui/needless_question_mark.rs | 25 | ||||
| -rw-r--r-- | tests/ui/needless_question_mark.stderr | 13 |
4 files changed, 68 insertions, 2 deletions
diff --git a/clippy_lints/src/needless_question_mark.rs b/clippy_lints/src/needless_question_mark.rs index 99e85e6683c..9852633b734 100644 --- a/clippy_lints/src/needless_question_mark.rs +++ b/clippy_lints/src/needless_question_mark.rs @@ -1,7 +1,7 @@ use clippy_utils::diagnostics::span_lint_and_sugg; use clippy_utils::source::snippet; use clippy_utils::ty::is_type_diagnostic_item; -use clippy_utils::{is_ok_ctor, is_some_ctor, meets_msrv}; +use clippy_utils::{differing_macro_contexts, is_ok_ctor, is_some_ctor, meets_msrv}; use if_chain::if_chain; use rustc_errors::Applicability; use rustc_hir::{Body, Expr, ExprKind, LangItem, MatchSource, QPath}; @@ -173,6 +173,11 @@ fn is_some_or_ok_call<'a>( // question mark operator let inner_expr = &args[0]; + // if the inner expr is inside macro but the outer one is not, do not lint (#6921) + if differing_macro_contexts(expr.span, inner_expr.span) { + return None; + } + let inner_ty = cx.typeck_results().expr_ty(inner_expr); let outer_ty = cx.typeck_results().expr_ty(expr); diff --git a/tests/ui/needless_question_mark.fixed b/tests/ui/needless_question_mark.fixed index 71fb3565224..fd8433870bb 100644 --- a/tests/ui/needless_question_mark.fixed +++ b/tests/ui/needless_question_mark.fixed @@ -167,3 +167,28 @@ mod question_mark_both { needless_question_mark_result(); } } + +// #6921 if a macro wraps an expr in Some( ) and the ? is in the macro use, +// the suggestion fails to apply; do not lint +macro_rules! some_in_macro { + ($expr:expr) => { + || -> _ { Some($expr) }() + }; +} + +pub fn test1() { + let x = Some(3); + let _x = some_in_macro!(x?); +} + +// this one is ok because both the ? and the Some are both inside the macro def +macro_rules! some_and_qmark_in_macro { + ($expr:expr) => { + || -> Option<_> { Some($expr) }() + }; +} + +pub fn test2() { + let x = Some(3); + let _x = some_and_qmark_in_macro!(x?); +} diff --git a/tests/ui/needless_question_mark.rs b/tests/ui/needless_question_mark.rs index e31f6f48fa7..36d45ac7e03 100644 --- a/tests/ui/needless_question_mark.rs +++ b/tests/ui/needless_question_mark.rs @@ -167,3 +167,28 @@ mod question_mark_both { needless_question_mark_result(); } } + +// #6921 if a macro wraps an expr in Some( ) and the ? is in the macro use, +// the suggestion fails to apply; do not lint +macro_rules! some_in_macro { + ($expr:expr) => { + || -> _ { Some($expr) }() + }; +} + +pub fn test1() { + let x = Some(3); + let _x = some_in_macro!(x?); +} + +// this one is ok because both the ? and the Some are both inside the macro def +macro_rules! some_and_qmark_in_macro { + ($expr:expr) => { + || -> Option<_> { Some(Some($expr)?) }() + }; +} + +pub fn test2() { + let x = Some(3); + let _x = some_and_qmark_in_macro!(x?); +} diff --git a/tests/ui/needless_question_mark.stderr b/tests/ui/needless_question_mark.stderr index 983c56031d8..7cbf1e505ad 100644 --- a/tests/ui/needless_question_mark.stderr +++ b/tests/ui/needless_question_mark.stderr @@ -84,5 +84,16 @@ error: question mark operator is useless here LL | Ok(to.magic?) // should be triggered | ^^^^^^^^^^^^^ help: try: `to.magic` -error: aborting due to 14 previous errors +error: question mark operator is useless here + --> $DIR/needless_question_mark.rs:187:27 + | +LL | || -> Option<_> { Some(Some($expr)?) }() + | ^^^^^^^^^^^^^^^^^^ help: try: `Some($expr)` +... +LL | let _x = some_and_qmark_in_macro!(x?); + | ---------------------------- in this macro invocation + | + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to 15 previous errors |
