]>
Commit | Line | Data |
---|---|---|
f20569fa XL |
1 | use rustc_errors::Applicability; |
2 | use rustc_hir::Expr; | |
3 | use rustc_lint::LateContext; | |
4 | use rustc_middle::ty::{self, Ty, UintTy}; | |
5 | ||
6 | use crate::utils::{snippet_with_applicability, span_lint_and_sugg}; | |
7 | ||
8 | use super::{utils, FN_TO_NUMERIC_CAST}; | |
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 | ||
17 | match cast_from.kind() { | |
18 | ty::FnDef(..) | ty::FnPtr(_) => { | |
19 | let mut applicability = Applicability::MaybeIncorrect; | |
20 | let from_snippet = snippet_with_applicability(cx, cast_expr.span, "x", &mut applicability); | |
21 | let to_nbits = utils::int_ty_to_nbits(cast_to, cx.tcx); | |
22 | ||
23 | if (to_nbits >= cx.tcx.data_layout.pointer_size.bits()) && (*cast_to.kind() != ty::Uint(UintTy::Usize)) { | |
24 | span_lint_and_sugg( | |
25 | cx, | |
26 | FN_TO_NUMERIC_CAST, | |
27 | expr.span, | |
28 | &format!("casting function pointer `{}` to `{}`", from_snippet, cast_to), | |
29 | "try", | |
30 | format!("{} as usize", from_snippet), | |
31 | applicability, | |
32 | ); | |
33 | } | |
34 | }, | |
35 | _ => {}, | |
36 | } | |
37 | } |