1 use clippy_utils
::diagnostics
::span_lint_and_sugg
;
2 use clippy_utils
::match_def_path
;
3 use clippy_utils
::source
::snippet_with_applicability
;
4 use if_chain
::if_chain
;
5 use rustc_errors
::Applicability
;
7 use rustc_lint
::{LateContext, LateLintPass}
;
9 use rustc_session
::{declare_lint_pass, declare_tool_lint}
;
11 declare_clippy_lint
! {
13 /// Checks for `.to_digit(..).is_some()` on `char`s.
15 /// ### Why is this bad?
16 /// This is a convoluted way of checking if a `char` is a digit. It's
17 /// more straight forward to use the dedicated `is_digit` method.
23 /// let is_digit = c.to_digit(radix).is_some();
25 /// can be written as:
29 /// let is_digit = c.is_digit(radix);
31 #[clippy::version = "1.41.0"]
34 "`char.is_digit()` is clearer"
37 declare_lint_pass
!(ToDigitIsSome
=> [TO_DIGIT_IS_SOME
]);
39 impl<'tcx
> LateLintPass
<'tcx
> for ToDigitIsSome
{
40 fn check_expr(&mut self, cx
: &LateContext
<'tcx
>, expr
: &'tcx hir
::Expr
<'_
>) {
42 if let hir
::ExprKind
::MethodCall(is_some_path
, to_digit_expr
, [], _
) = &expr
.kind
;
43 if is_some_path
.ident
.name
.as_str() == "is_some";
45 let match_result
= match &to_digit_expr
.kind
{
46 hir
::ExprKind
::MethodCall(to_digits_path
, char_arg
, [radix_arg
], _
) => {
48 if to_digits_path
.ident
.name
.as_str() == "to_digit";
49 let char_arg_ty
= cx
.typeck_results().expr_ty_adjusted(char_arg
);
50 if *char_arg_ty
.kind() == ty
::Char
;
52 Some((true, *char_arg
, radix_arg
))
58 hir
::ExprKind
::Call(to_digits_call
, to_digit_args
) => {
60 if let [char_arg
, radix_arg
] = *to_digit_args
;
61 if let hir
::ExprKind
::Path(to_digits_path
) = &to_digits_call
.kind
;
62 if let to_digits_call_res
= cx
.qpath_res(to_digits_path
, to_digits_call
.hir_id
);
63 if let Some(to_digits_def_id
) = to_digits_call_res
.opt_def_id();
64 if match_def_path(cx
, to_digits_def_id
, &["core", "char", "methods", "<impl char>", "to_digit"]);
66 Some((false, char_arg
, radix_arg
))
75 if let Some((is_method_call
, char_arg
, radix_arg
)) = match_result
{
76 let mut applicability
= Applicability
::MachineApplicable
;
77 let char_arg_snip
= snippet_with_applicability(cx
, char_arg
.span
, "_", &mut applicability
);
78 let radix_snip
= snippet_with_applicability(cx
, radix_arg
.span
, "_", &mut applicability
);
84 "use of `.to_digit(..).is_some()`",
87 format
!("{char_arg_snip}.is_digit({radix_snip})")
89 format
!("char::is_digit({char_arg_snip}, {radix_snip})")