Skip to content

Commit 3c5e403

Browse files
authored
char::is_digit() is const-stable only since Rust 1.87 (#14771)
The `to_digit_is_some()` lint suggests using `char::is_digit()`. It should not trigger in const contexts before Rust 1.87. changelog: [`to_digit_is_some`]: Do not lint in const contexts when MSRV is below 1.87
2 parents 16fd2a8 + bde9390 commit 3c5e403

File tree

8 files changed

+69
-7
lines changed

8 files changed

+69
-7
lines changed

book/src/lint_configuration.md

+1
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
849849
* [`same_item_push`](https://rust-lang.github.io/rust-clippy/master/index.html#same_item_push)
850850
* [`seek_from_current`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_from_current)
851851
* [`seek_rewind`](https://rust-lang.github.io/rust-clippy/master/index.html#seek_rewind)
852+
* [`to_digit_is_some`](https://rust-lang.github.io/rust-clippy/master/index.html#to_digit_is_some)
852853
* [`transmute_ptr_to_ref`](https://rust-lang.github.io/rust-clippy/master/index.html#transmute_ptr_to_ref)
853854
* [`tuple_array_conversions`](https://rust-lang.github.io/rust-clippy/master/index.html#tuple_array_conversions)
854855
* [`type_repetition_in_bounds`](https://rust-lang.github.io/rust-clippy/master/index.html#type_repetition_in_bounds)

clippy_config/src/conf.rs

+1
Original file line numberDiff line numberDiff line change
@@ -759,6 +759,7 @@ define_Conf! {
759759
same_item_push,
760760
seek_from_current,
761761
seek_rewind,
762+
to_digit_is_some,
762763
transmute_ptr_to_ref,
763764
tuple_array_conversions,
764765
type_repetition_in_bounds,

clippy_lints/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -746,7 +746,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
746746
store.register_late_pass(move |_| Box::new(unused_self::UnusedSelf::new(conf)));
747747
store.register_late_pass(|_| Box::new(mutable_debug_assertion::DebugAssertWithMutCall));
748748
store.register_late_pass(|_| Box::new(exit::Exit));
749-
store.register_late_pass(|_| Box::new(to_digit_is_some::ToDigitIsSome));
749+
store.register_late_pass(move |_| Box::new(to_digit_is_some::ToDigitIsSome::new(conf)));
750750
store.register_late_pass(move |_| Box::new(large_stack_arrays::LargeStackArrays::new(conf)));
751751
store.register_late_pass(move |_| Box::new(large_const_arrays::LargeConstArrays::new(conf)));
752752
store.register_late_pass(|_| Box::new(floating_point_arithmetic::FloatingPointArithmetic));

clippy_lints/src/to_digit_is_some.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
1+
use clippy_config::Conf;
12
use clippy_utils::diagnostics::span_lint_and_sugg;
3+
use clippy_utils::msrvs::{self, Msrv};
24
use clippy_utils::source::snippet_with_applicability;
3-
use clippy_utils::{paths, sym};
5+
use clippy_utils::{is_in_const_context, paths, sym};
46
use rustc_errors::Applicability;
57
use rustc_hir as hir;
68
use rustc_lint::{LateContext, LateLintPass};
7-
use rustc_session::declare_lint_pass;
9+
use rustc_session::impl_lint_pass;
810

911
declare_clippy_lint! {
1012
/// ### What it does
@@ -32,7 +34,17 @@ declare_clippy_lint! {
3234
"`char.is_digit()` is clearer"
3335
}
3436

35-
declare_lint_pass!(ToDigitIsSome => [TO_DIGIT_IS_SOME]);
37+
impl_lint_pass!(ToDigitIsSome => [TO_DIGIT_IS_SOME]);
38+
39+
pub(crate) struct ToDigitIsSome {
40+
msrv: Msrv,
41+
}
42+
43+
impl ToDigitIsSome {
44+
pub(crate) fn new(conf: &'static Conf) -> Self {
45+
Self { msrv: conf.msrv }
46+
}
47+
}
3648

3749
impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
3850
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
@@ -59,7 +71,9 @@ impl<'tcx> LateLintPass<'tcx> for ToDigitIsSome {
5971
_ => None,
6072
};
6173

62-
if let Some((is_method_call, char_arg, radix_arg)) = match_result {
74+
if let Some((is_method_call, char_arg, radix_arg)) = match_result
75+
&& (!is_in_const_context(cx) || self.msrv.meets(cx, msrvs::CONST_CHAR_IS_DIGIT))
76+
{
6377
let mut applicability = Applicability::MachineApplicable;
6478
let char_arg_snip = snippet_with_applicability(cx, char_arg.span, "_", &mut applicability);
6579
let radix_snip = snippet_with_applicability(cx, radix_arg.span, "_", &mut applicability);

clippy_utils/src/msrvs.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ macro_rules! msrv_aliases {
2323
// names may refer to stabilized feature flags or library items
2424
msrv_aliases! {
2525
1,88,0 { LET_CHAINS }
26-
1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT }
26+
1,87,0 { OS_STR_DISPLAY, INT_MIDPOINT, CONST_CHAR_IS_DIGIT }
2727
1,85,0 { UINT_FLOAT_MIDPOINT }
2828
1,84,0 { CONST_OPTION_AS_SLICE, MANUAL_DANGLING_PTR }
2929
1,83,0 { CONST_EXTERN_FN, CONST_FLOAT_BITS_CONV, CONST_FLOAT_CLASSIFY, CONST_MUT_REFS, CONST_UNWRAP }

tests/ui/to_digit_is_some.fixed

+17
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,20 @@ fn main() {
99
let _ = char::is_digit(c, 8);
1010
//~^ to_digit_is_some
1111
}
12+
13+
#[clippy::msrv = "1.86"]
14+
mod cannot_lint_in_const_context {
15+
fn without_const(c: char) -> bool {
16+
c.is_digit(8)
17+
//~^ to_digit_is_some
18+
}
19+
const fn with_const(c: char) -> bool {
20+
c.to_digit(8).is_some()
21+
}
22+
}
23+
24+
#[clippy::msrv = "1.87"]
25+
const fn with_const(c: char) -> bool {
26+
c.is_digit(8)
27+
//~^ to_digit_is_some
28+
}

tests/ui/to_digit_is_some.rs

+17
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,20 @@ fn main() {
99
let _ = char::to_digit(c, 8).is_some();
1010
//~^ to_digit_is_some
1111
}
12+
13+
#[clippy::msrv = "1.86"]
14+
mod cannot_lint_in_const_context {
15+
fn without_const(c: char) -> bool {
16+
c.to_digit(8).is_some()
17+
//~^ to_digit_is_some
18+
}
19+
const fn with_const(c: char) -> bool {
20+
c.to_digit(8).is_some()
21+
}
22+
}
23+
24+
#[clippy::msrv = "1.87"]
25+
const fn with_const(c: char) -> bool {
26+
c.to_digit(8).is_some()
27+
//~^ to_digit_is_some
28+
}

tests/ui/to_digit_is_some.stderr

+13-1
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,17 @@ error: use of `.to_digit(..).is_some()`
1313
LL | let _ = char::to_digit(c, 8).is_some();
1414
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `char::is_digit(c, 8)`
1515

16-
error: aborting due to 2 previous errors
16+
error: use of `.to_digit(..).is_some()`
17+
--> tests/ui/to_digit_is_some.rs:16:9
18+
|
19+
LL | c.to_digit(8).is_some()
20+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_digit(8)`
21+
22+
error: use of `.to_digit(..).is_some()`
23+
--> tests/ui/to_digit_is_some.rs:26:5
24+
|
25+
LL | c.to_digit(8).is_some()
26+
| ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `c.is_digit(8)`
27+
28+
error: aborting due to 4 previous errors
1729

0 commit comments

Comments
 (0)