mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-02 07:22:42 +00:00
Remove needless_question_mark MSRV
This commit is contained in:
parent
a362a4d1d0
commit
33ed8b5b24
@ -1076,7 +1076,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||||||
store.register_late_pass(move || box from_over_into::FromOverInto::new(msrv));
|
store.register_late_pass(move || box from_over_into::FromOverInto::new(msrv));
|
||||||
store.register_late_pass(move || box use_self::UseSelf::new(msrv));
|
store.register_late_pass(move || box use_self::UseSelf::new(msrv));
|
||||||
store.register_late_pass(move || box missing_const_for_fn::MissingConstForFn::new(msrv));
|
store.register_late_pass(move || box missing_const_for_fn::MissingConstForFn::new(msrv));
|
||||||
store.register_late_pass(move || box needless_question_mark::NeedlessQuestionMark::new(msrv));
|
store.register_late_pass(move || box needless_question_mark::NeedlessQuestionMark);
|
||||||
store.register_late_pass(move || box casts::Casts::new(msrv));
|
store.register_late_pass(move || box casts::Casts::new(msrv));
|
||||||
store.register_early_pass(move || box unnested_or_patterns::UnnestedOrPatterns::new(msrv));
|
store.register_early_pass(move || box unnested_or_patterns::UnnestedOrPatterns::new(msrv));
|
||||||
|
|
||||||
|
@ -1,15 +1,13 @@
|
|||||||
use clippy_utils::diagnostics::span_lint_and_sugg;
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
use clippy_utils::is_lang_ctor;
|
|
||||||
use clippy_utils::source::snippet;
|
use clippy_utils::source::snippet;
|
||||||
use clippy_utils::ty::is_type_diagnostic_item;
|
use clippy_utils::ty::is_type_diagnostic_item;
|
||||||
use clippy_utils::{differing_macro_contexts, meets_msrv};
|
use clippy_utils::{differing_macro_contexts, is_lang_ctor};
|
||||||
use if_chain::if_chain;
|
use if_chain::if_chain;
|
||||||
use rustc_errors::Applicability;
|
use rustc_errors::Applicability;
|
||||||
use rustc_hir::LangItem::{OptionSome, ResultOk};
|
use rustc_hir::LangItem::{OptionSome, ResultOk};
|
||||||
use rustc_hir::{Body, Expr, ExprKind, LangItem, MatchSource, QPath};
|
use rustc_hir::{Body, Expr, ExprKind, LangItem, MatchSource, QPath};
|
||||||
use rustc_lint::{LateContext, LateLintPass, LintContext};
|
use rustc_lint::{LateContext, LateLintPass};
|
||||||
use rustc_semver::RustcVersion;
|
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
|
||||||
use rustc_span::sym;
|
use rustc_span::sym;
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
@ -63,21 +61,7 @@ declare_clippy_lint! {
|
|||||||
"Suggest `value.inner_option` instead of `Some(value.inner_option?)`. The same goes for `Result<T, E>`."
|
"Suggest `value.inner_option` instead of `Some(value.inner_option?)`. The same goes for `Result<T, E>`."
|
||||||
}
|
}
|
||||||
|
|
||||||
const NEEDLESS_QUESTION_MARK_RESULT_MSRV: RustcVersion = RustcVersion::new(1, 13, 0);
|
declare_lint_pass!(NeedlessQuestionMark => [NEEDLESS_QUESTION_MARK]);
|
||||||
const NEEDLESS_QUESTION_MARK_OPTION_MSRV: RustcVersion = RustcVersion::new(1, 22, 0);
|
|
||||||
|
|
||||||
pub struct NeedlessQuestionMark {
|
|
||||||
msrv: Option<RustcVersion>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl NeedlessQuestionMark {
|
|
||||||
#[must_use]
|
|
||||||
pub fn new(msrv: Option<RustcVersion>) -> Self {
|
|
||||||
Self { msrv }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl_lint_pass!(NeedlessQuestionMark => [NEEDLESS_QUESTION_MARK]);
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum SomeOkCall<'a> {
|
enum SomeOkCall<'a> {
|
||||||
@ -111,7 +95,7 @@ impl LateLintPass<'_> for NeedlessQuestionMark {
|
|||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Some(ok_some_call) = is_some_or_ok_call(self, cx, e) {
|
if let Some(ok_some_call) = is_some_or_ok_call(cx, e) {
|
||||||
emit_lint(cx, &ok_some_call);
|
emit_lint(cx, &ok_some_call);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,14 +111,12 @@ impl LateLintPass<'_> for NeedlessQuestionMark {
|
|||||||
|
|
||||||
if_chain! {
|
if_chain! {
|
||||||
if let Some(expr) = expr_opt;
|
if let Some(expr) = expr_opt;
|
||||||
if let Some(ok_some_call) = is_some_or_ok_call(self, cx, expr);
|
if let Some(ok_some_call) = is_some_or_ok_call(cx, expr);
|
||||||
then {
|
then {
|
||||||
emit_lint(cx, &ok_some_call);
|
emit_lint(cx, &ok_some_call);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
extract_msrv_attr!(LateContext);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn emit_lint(cx: &LateContext<'_>, expr: &SomeOkCall<'_>) {
|
fn emit_lint(cx: &LateContext<'_>, expr: &SomeOkCall<'_>) {
|
||||||
@ -153,11 +135,7 @@ fn emit_lint(cx: &LateContext<'_>, expr: &SomeOkCall<'_>) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn is_some_or_ok_call<'a>(
|
fn is_some_or_ok_call<'a>(cx: &'a LateContext<'_>, expr: &'a Expr<'_>) -> Option<SomeOkCall<'a>> {
|
||||||
nqml: &NeedlessQuestionMark,
|
|
||||||
cx: &'a LateContext<'_>,
|
|
||||||
expr: &'a Expr<'_>,
|
|
||||||
) -> Option<SomeOkCall<'a>> {
|
|
||||||
if_chain! {
|
if_chain! {
|
||||||
// Check outer expression matches CALL_IDENT(ARGUMENT) format
|
// Check outer expression matches CALL_IDENT(ARGUMENT) format
|
||||||
if let ExprKind::Call(path, args) = &expr.kind;
|
if let ExprKind::Call(path, args) = &expr.kind;
|
||||||
@ -188,8 +166,7 @@ fn is_some_or_ok_call<'a>(
|
|||||||
let inner_is_some = is_type_diagnostic_item(cx, inner_ty, sym::option_type);
|
let inner_is_some = is_type_diagnostic_item(cx, inner_ty, sym::option_type);
|
||||||
|
|
||||||
// Check for Option MSRV
|
// Check for Option MSRV
|
||||||
let meets_option_msrv = meets_msrv(nqml.msrv.as_ref(), &NEEDLESS_QUESTION_MARK_OPTION_MSRV);
|
if outer_is_some && inner_is_some {
|
||||||
if outer_is_some && inner_is_some && meets_option_msrv {
|
|
||||||
return Some(SomeOkCall::SomeCall(expr, inner_expr));
|
return Some(SomeOkCall::SomeCall(expr, inner_expr));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -202,8 +179,7 @@ fn is_some_or_ok_call<'a>(
|
|||||||
let does_not_call_from = !has_implicit_error_from(cx, expr, inner_expr);
|
let does_not_call_from = !has_implicit_error_from(cx, expr, inner_expr);
|
||||||
|
|
||||||
// Must meet Result MSRV
|
// Must meet Result MSRV
|
||||||
let meets_result_msrv = meets_msrv(nqml.msrv.as_ref(), &NEEDLESS_QUESTION_MARK_RESULT_MSRV);
|
if outer_is_result && inner_is_result && does_not_call_from {
|
||||||
if outer_is_result && inner_is_result && does_not_call_from && meets_result_msrv {
|
|
||||||
return Some(SomeOkCall::OkCall(expr, inner_expr));
|
return Some(SomeOkCall::OkCall(expr, inner_expr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ macro_rules! define_Conf {
|
|||||||
|
|
||||||
pub use self::helpers::Conf;
|
pub use self::helpers::Conf;
|
||||||
define_Conf! {
|
define_Conf! {
|
||||||
/// Lint: CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, NEEDLESS_QUESTION_MARK, PTR_AS_PTR. The minimum rust version that the project supports
|
/// Lint: CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR. The minimum rust version that the project supports
|
||||||
(msrv, "msrv": Option<String>, None),
|
(msrv, "msrv": Option<String>, None),
|
||||||
/// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about. NB: `bar` is not here since it has legitimate uses
|
/// Lint: BLACKLISTED_NAME. The list of blacklisted names to lint about. NB: `bar` is not here since it has legitimate uses
|
||||||
(blacklisted_names, "blacklisted_names": Vec<String>, ["foo", "baz", "quux"].iter().map(ToString::to_string).collect()),
|
(blacklisted_names, "blacklisted_names": Vec<String>, ["foo", "baz", "quux"].iter().map(ToString::to_string).collect()),
|
||||||
|
@ -96,78 +96,6 @@ where
|
|||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
mod question_mark_none {
|
|
||||||
#![clippy::msrv = "1.12.0"]
|
|
||||||
fn needless_question_mark_option() -> Option<usize> {
|
|
||||||
struct TO {
|
|
||||||
magic: Option<usize>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: None };
|
|
||||||
Some(to.magic?) // should not be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn needless_question_mark_result() -> Result<usize, bool> {
|
|
||||||
struct TO {
|
|
||||||
magic: Result<usize, bool>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: Ok(1_usize) };
|
|
||||||
Ok(to.magic?) // should not be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
needless_question_mark_option();
|
|
||||||
needless_question_mark_result();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod question_mark_result {
|
|
||||||
#![clippy::msrv = "1.21.0"]
|
|
||||||
fn needless_question_mark_option() -> Option<usize> {
|
|
||||||
struct TO {
|
|
||||||
magic: Option<usize>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: None };
|
|
||||||
Some(to.magic?) // should not be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn needless_question_mark_result() -> Result<usize, bool> {
|
|
||||||
struct TO {
|
|
||||||
magic: Result<usize, bool>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: Ok(1_usize) };
|
|
||||||
to.magic // should be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
needless_question_mark_option();
|
|
||||||
needless_question_mark_result();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod question_mark_both {
|
|
||||||
#![clippy::msrv = "1.22.0"]
|
|
||||||
fn needless_question_mark_option() -> Option<usize> {
|
|
||||||
struct TO {
|
|
||||||
magic: Option<usize>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: None };
|
|
||||||
to.magic // should be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn needless_question_mark_result() -> Result<usize, bool> {
|
|
||||||
struct TO {
|
|
||||||
magic: Result<usize, bool>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: Ok(1_usize) };
|
|
||||||
to.magic // should be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
needless_question_mark_option();
|
|
||||||
needless_question_mark_result();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// #6921 if a macro wraps an expr in Some( ) and the ? is in the macro use,
|
// #6921 if a macro wraps an expr in Some( ) and the ? is in the macro use,
|
||||||
// the suggestion fails to apply; do not lint
|
// the suggestion fails to apply; do not lint
|
||||||
macro_rules! some_in_macro {
|
macro_rules! some_in_macro {
|
||||||
|
@ -96,78 +96,6 @@ where
|
|||||||
|
|
||||||
fn main() {}
|
fn main() {}
|
||||||
|
|
||||||
mod question_mark_none {
|
|
||||||
#![clippy::msrv = "1.12.0"]
|
|
||||||
fn needless_question_mark_option() -> Option<usize> {
|
|
||||||
struct TO {
|
|
||||||
magic: Option<usize>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: None };
|
|
||||||
Some(to.magic?) // should not be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn needless_question_mark_result() -> Result<usize, bool> {
|
|
||||||
struct TO {
|
|
||||||
magic: Result<usize, bool>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: Ok(1_usize) };
|
|
||||||
Ok(to.magic?) // should not be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
needless_question_mark_option();
|
|
||||||
needless_question_mark_result();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod question_mark_result {
|
|
||||||
#![clippy::msrv = "1.21.0"]
|
|
||||||
fn needless_question_mark_option() -> Option<usize> {
|
|
||||||
struct TO {
|
|
||||||
magic: Option<usize>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: None };
|
|
||||||
Some(to.magic?) // should not be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn needless_question_mark_result() -> Result<usize, bool> {
|
|
||||||
struct TO {
|
|
||||||
magic: Result<usize, bool>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: Ok(1_usize) };
|
|
||||||
Ok(to.magic?) // should be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
needless_question_mark_option();
|
|
||||||
needless_question_mark_result();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
mod question_mark_both {
|
|
||||||
#![clippy::msrv = "1.22.0"]
|
|
||||||
fn needless_question_mark_option() -> Option<usize> {
|
|
||||||
struct TO {
|
|
||||||
magic: Option<usize>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: None };
|
|
||||||
Some(to.magic?) // should be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn needless_question_mark_result() -> Result<usize, bool> {
|
|
||||||
struct TO {
|
|
||||||
magic: Result<usize, bool>,
|
|
||||||
}
|
|
||||||
let to = TO { magic: Ok(1_usize) };
|
|
||||||
Ok(to.magic?) // should be triggered
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
needless_question_mark_option();
|
|
||||||
needless_question_mark_result();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// #6921 if a macro wraps an expr in Some( ) and the ? is in the macro use,
|
// #6921 if a macro wraps an expr in Some( ) and the ? is in the macro use,
|
||||||
// the suggestion fails to apply; do not lint
|
// the suggestion fails to apply; do not lint
|
||||||
macro_rules! some_in_macro {
|
macro_rules! some_in_macro {
|
||||||
|
@ -67,25 +67,7 @@ LL | return Ok(t.magic?);
|
|||||||
| ^^^^^^^^^^^^ help: try: `t.magic`
|
| ^^^^^^^^^^^^ help: try: `t.magic`
|
||||||
|
|
||||||
error: question mark operator is useless here
|
error: question mark operator is useless here
|
||||||
--> $DIR/needless_question_mark.rs:138:9
|
--> $DIR/needless_question_mark.rs:115:27
|
||||||
|
|
|
||||||
LL | Ok(to.magic?) // should be triggered
|
|
||||||
| ^^^^^^^^^^^^^ help: try: `to.magic`
|
|
||||||
|
|
||||||
error: question mark operator is useless here
|
|
||||||
--> $DIR/needless_question_mark.rs:154:9
|
|
||||||
|
|
|
||||||
LL | Some(to.magic?) // should be triggered
|
|
||||||
| ^^^^^^^^^^^^^^^ help: try: `to.magic`
|
|
||||||
|
|
||||||
error: question mark operator is useless here
|
|
||||||
--> $DIR/needless_question_mark.rs:162:9
|
|
||||||
|
|
|
||||||
LL | Ok(to.magic?) // should be triggered
|
|
||||||
| ^^^^^^^^^^^^^ help: try: `to.magic`
|
|
||||||
|
|
||||||
error: question mark operator is useless here
|
|
||||||
--> $DIR/needless_question_mark.rs:187:27
|
|
||||||
|
|
|
|
||||||
LL | || -> Option<_> { Some(Some($expr)?) }()
|
LL | || -> Option<_> { Some(Some($expr)?) }()
|
||||||
| ^^^^^^^^^^^^^^^^^^ help: try: `Some($expr)`
|
| ^^^^^^^^^^^^^^^^^^ help: try: `Some($expr)`
|
||||||
@ -95,5 +77,5 @@ LL | let _x = some_and_qmark_in_macro!(x?);
|
|||||||
|
|
|
|
||||||
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
|
= 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
|
error: aborting due to 12 previous errors
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user