Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

Commit 9a24877

Browse files
committed
Move fn_to_numeric_cast_with_truncation to its own module
1 parent 458f6d1 commit 9a24877

File tree

2 files changed

+41
-38
lines changed

2 files changed

+41
-38
lines changed
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use rustc_errors::Applicability;
2+
use rustc_hir::Expr;
3+
use rustc_lint::LateContext;
4+
use rustc_middle::ty::{self, Ty};
5+
6+
use crate::utils::{snippet_with_applicability, span_lint_and_sugg};
7+
8+
use super::{utils, FN_TO_NUMERIC_CAST_WITH_TRUNCATION};
9+
10+
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
11+
// We only want to check casts to `ty::Uint` or `ty::Int`
12+
match cast_to.kind() {
13+
ty::Uint(_) | ty::Int(..) => { /* continue on */ },
14+
_ => return,
15+
}
16+
match cast_from.kind() {
17+
ty::FnDef(..) | ty::FnPtr(_) => {
18+
let mut applicability = Applicability::MaybeIncorrect;
19+
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
20+
21+
let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx);
22+
if to_nbits < cx.tcx.data_layout.pointer_size.bits() {
23+
span_lint_and_sugg(
24+
cx,
25+
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
26+
expr.span,
27+
&format!(
28+
"casting function pointer `{}` to `{}`, which truncates the value",
29+
from_snippet, cast_to
30+
),
31+
"try",
32+
format!("{} as usize", from_snippet),
33+
applicability,
34+
);
35+
}
36+
},
37+
_ => {},
38+
}
39+
}

clippy_lints/src/casts/mod.rs

Lines changed: 2 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ mod cast_possible_wrap;
44
mod cast_precision_loss;
55
mod cast_sign_loss;
66
mod fn_to_numeric_cast;
7+
mod fn_to_numeric_cast_with_truncation;
78
mod unnecessary_cast;
89
mod utils;
910

@@ -304,7 +305,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
304305
}
305306

306307
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
307-
lint_fn_to_numeric_cast(cx, expr, cast_expr, cast_from, cast_to);
308+
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
308309
lint_cast_ptr_alignment(cx, expr, cast_from, cast_to);
309310
if cast_from.is_numeric() && cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
310311
cast_possible_truncation::check(cx, expr, cast_from, cast_to);
@@ -358,43 +359,6 @@ fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_f
358359
}
359360
}
360361

361-
fn lint_fn_to_numeric_cast(
362-
cx: &LateContext<'_>,
363-
expr: &Expr<'_>,
364-
cast_expr: &Expr<'_>,
365-
cast_from: Ty<'_>,
366-
cast_to: Ty<'_>,
367-
) {
368-
// We only want to check casts to `ty::Uint` or `ty::Int`
369-
match cast_to.kind() {
370-
ty::Uint(_) | ty::Int(..) => { /* continue on */ },
371-
_ => return,
372-
}
373-
match cast_from.kind() {
374-
ty::FnDef(..) | ty::FnPtr(_) => {
375-
let mut applicability = Applicability::MaybeIncorrect;
376-
let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability);
377-
378-
let to_nbits = int_ty_to_nbits(cast_to, cx.tcx);
379-
if to_nbits < cx.tcx.data_layout.pointer_size.bits() {
380-
span_lint_and_sugg(
381-
cx,
382-
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
383-
expr.span,
384-
&format!(
385-
"casting function pointer `{}` to `{}`, which truncates the value",
386-
from_snippet, cast_to
387-
),
388-
"try",
389-
format!("{} as usize", from_snippet),
390-
applicability,
391-
);
392-
}
393-
},
394-
_ => {},
395-
}
396-
}
397-
398362
declare_clippy_lint! {
399363
/// **What it does:** Checks for casts of `&T` to `&mut T` anywhere in the code.
400364
///

0 commit comments

Comments
 (0)