Skip to content

Commit 48ce25e

Browse files
authored
Add MSRV check for question_mark (rust-lang#14436)
changelog: [`question_mark`]: Now respects the [`msrv`] configuration
2 parents 31497d6 + d793c0a commit 48ce25e

File tree

7 files changed

+80
-4
lines changed

7 files changed

+80
-4
lines changed

book/src/lint_configuration.md

+1
Original file line numberDiff line numberDiff line change
@@ -819,6 +819,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
819819
* [`option_as_ref_deref`](https://rust-lang.github.io/rust-clippy/master/index.html#option_as_ref_deref)
820820
* [`option_map_unwrap_or`](https://rust-lang.github.io/rust-clippy/master/index.html#option_map_unwrap_or)
821821
* [`ptr_as_ptr`](https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr)
822+
* [`question_mark`](https://rust-lang.github.io/rust-clippy/master/index.html#question_mark)
822823
* [`redundant_field_names`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_field_names)
823824
* [`redundant_static_lifetimes`](https://rust-lang.github.io/rust-clippy/master/index.html#redundant_static_lifetimes)
824825
* [`repeat_vec_with_capacity`](https://rust-lang.github.io/rust-clippy/master/index.html#repeat_vec_with_capacity)

clippy_config/src/conf.rs

+1
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,7 @@ define_Conf! {
668668
option_as_ref_deref,
669669
option_map_unwrap_or,
670670
ptr_as_ptr,
671+
question_mark,
671672
redundant_field_names,
672673
redundant_static_lifetimes,
673674
repeat_vec_with_capacity,

clippy_lints/src/question_mark.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ use crate::question_mark_used::QUESTION_MARK_USED;
33
use clippy_config::Conf;
44
use clippy_config::types::MatchLintBehaviour;
55
use clippy_utils::diagnostics::span_lint_and_sugg;
6-
use clippy_utils::msrvs::Msrv;
6+
use clippy_utils::msrvs::{self, Msrv};
77
use clippy_utils::source::snippet_with_applicability;
88
use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
99
use clippy_utils::{
@@ -524,7 +524,8 @@ fn is_inferred_ret_closure(expr: &Expr<'_>) -> bool {
524524

525525
impl<'tcx> LateLintPass<'tcx> for QuestionMark {
526526
fn check_stmt(&mut self, cx: &LateContext<'tcx>, stmt: &'tcx Stmt<'_>) {
527-
if !is_lint_allowed(cx, QUESTION_MARK_USED, stmt.hir_id) {
527+
if !is_lint_allowed(cx, QUESTION_MARK_USED, stmt.hir_id) || !self.msrv.meets(cx, msrvs::QUESTION_MARK_OPERATOR)
528+
{
528529
return;
529530
}
530531

@@ -540,7 +541,10 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
540541
return;
541542
}
542543

543-
if !self.inside_try_block() && !is_in_const_context(cx) && is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)
544+
if !self.inside_try_block()
545+
&& !is_in_const_context(cx)
546+
&& is_lint_allowed(cx, QUESTION_MARK_USED, expr.hir_id)
547+
&& self.msrv.meets(cx, msrvs::QUESTION_MARK_OPERATOR)
544548
{
545549
check_is_none_or_err_and_early_return(cx, expr);
546550
check_if_let_some_or_err_and_early_return(cx, expr);

clippy_utils/src/msrvs.rs

+1
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ msrv_aliases! {
7474
1,17,0 { FIELD_INIT_SHORTHAND, STATIC_IN_CONST, EXPECT_ERR }
7575
1,16,0 { STR_REPEAT }
7676
1,15,0 { MAYBE_BOUND_IN_WHERE }
77+
1,13,0 { QUESTION_MARK_OPERATOR }
7778
}
7879

7980
/// `#[clippy::msrv]` attributes are rarely used outside of Clippy's test suite, as a basic

tests/ui/question_mark.fixed

+21
Original file line numberDiff line numberDiff line change
@@ -409,3 +409,24 @@ fn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<Wrapper
409409
//~^^^ question_mark
410410
Some(())
411411
}
412+
413+
#[clippy::msrv = "1.12"]
414+
fn msrv_1_12(arg: Option<i32>) -> Option<i32> {
415+
if arg.is_none() {
416+
return None;
417+
}
418+
let val = match arg {
419+
Some(val) => val,
420+
None => return None,
421+
};
422+
println!("{}", val);
423+
Some(val)
424+
}
425+
426+
#[clippy::msrv = "1.13"]
427+
fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
428+
arg?;
429+
let val = arg?;
430+
println!("{}", val);
431+
Some(val)
432+
}

tests/ui/question_mark.rs

+28
Original file line numberDiff line numberDiff line change
@@ -496,3 +496,31 @@ fn issue_13417_weirder(foo: &mut StructWithOptionString, mut bar: Option<Wrapper
496496
//~^^^ question_mark
497497
Some(())
498498
}
499+
500+
#[clippy::msrv = "1.12"]
501+
fn msrv_1_12(arg: Option<i32>) -> Option<i32> {
502+
if arg.is_none() {
503+
return None;
504+
}
505+
let val = match arg {
506+
Some(val) => val,
507+
None => return None,
508+
};
509+
println!("{}", val);
510+
Some(val)
511+
}
512+
513+
#[clippy::msrv = "1.13"]
514+
fn msrv_1_13(arg: Option<i32>) -> Option<i32> {
515+
if arg.is_none() {
516+
//~^ question_mark
517+
return None;
518+
}
519+
let val = match arg {
520+
//~^ question_mark
521+
Some(val) => val,
522+
None => return None,
523+
};
524+
println!("{}", val);
525+
Some(val)
526+
}

tests/ui/question_mark.stderr

+21-1
Original file line numberDiff line numberDiff line change
@@ -255,5 +255,25 @@ LL | | return None;
255255
LL | | };
256256
| |______^ help: replace it with: `let x @ &mut WrapperStructWithString(_) = bar.as_mut()?;`
257257

258-
error: aborting due to 27 previous errors
258+
error: this block may be rewritten with the `?` operator
259+
--> tests/ui/question_mark.rs:515:5
260+
|
261+
LL | / if arg.is_none() {
262+
LL | |
263+
LL | | return None;
264+
LL | | }
265+
| |_____^ help: replace it with: `arg?;`
266+
267+
error: this `match` expression can be replaced with `?`
268+
--> tests/ui/question_mark.rs:519:15
269+
|
270+
LL | let val = match arg {
271+
| _______________^
272+
LL | |
273+
LL | | Some(val) => val,
274+
LL | | None => return None,
275+
LL | | };
276+
| |_____^ help: try instead: `arg?`
277+
278+
error: aborting due to 29 previous errors
259279

0 commit comments

Comments
 (0)