From 458f6d19d0c51ee97b7ac90ce60994f627983824 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 9 Mar 2021 17:03:07 +0900 Subject: [PATCH] Move fn_to_numeric_cast to its own module --- clippy_lints/src/casts/fn_to_numeric_cast.rs | 37 ++++++++++++++++++++ clippy_lints/src/casts/mod.rs | 13 ++----- 2 files changed, 40 insertions(+), 10 deletions(-) create mode 100644 clippy_lints/src/casts/fn_to_numeric_cast.rs diff --git a/clippy_lints/src/casts/fn_to_numeric_cast.rs b/clippy_lints/src/casts/fn_to_numeric_cast.rs new file mode 100644 index 00000000000..a8d508585b5 --- /dev/null +++ b/clippy_lints/src/casts/fn_to_numeric_cast.rs @@ -0,0 +1,37 @@ +use rustc_errors::Applicability; +use rustc_hir::Expr; +use rustc_lint::LateContext; +use rustc_middle::ty::{self, Ty, UintTy}; + +use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; + +use super::{utils, FN_TO_NUMERIC_CAST}; + +pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) { + // We only want to check casts to `ty::Uint` or `ty::Int` + match cast_to.kind() { + ty::Uint(_) | ty::Int(..) => { /* continue on */ }, + _ => return, + } + + match cast_from.kind() { + ty::FnDef(..) | ty::FnPtr(_) => { + let mut applicability = Applicability::MaybeIncorrect; + let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability); + let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); + + if (to_nbits >= cx.tcx.data_layout.pointer_size.bits()) && (*cast_to.kind() != ty::Uint(UintTy::Usize)) { + span_lint_and_sugg( + cx, + FN_TO_NUMERIC_CAST, + expr.span, + &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), + "try", + format!("{} as usize", from_snippet), + applicability, + ); + } + }, + _ => {}, + } +} diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs index c7e9066f3ea..bbe492be72e 100644 --- a/clippy_lints/src/casts/mod.rs +++ b/clippy_lints/src/casts/mod.rs @@ -3,6 +3,7 @@ mod cast_possible_truncation; mod cast_possible_wrap; mod cast_precision_loss; mod cast_sign_loss; +mod fn_to_numeric_cast; mod unnecessary_cast; mod utils; @@ -301,6 +302,8 @@ impl<'tcx> LateLintPass<'tcx> for Casts { if unnecessary_cast::check(cx, expr, cast_expr, cast_from, cast_to) { return; } + + fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to); lint_fn_to_numeric_cast(cx, expr, cast_expr, cast_from, cast_to); lint_cast_ptr_alignment(cx, expr, cast_from, cast_to); if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) { @@ -386,16 +389,6 @@ fn lint_fn_to_numeric_cast( format!("{} as usize", from_snippet), applicability, ); - } else if *cast_to.kind() != ty::Uint(UintTy::Usize) { - span_lint_and_sugg( - cx, - FN_TO_NUMERIC_CAST, - expr.span, - &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), - "try", - format!("{} as usize", from_snippet), - applicability, - ); } }, _ => {},