rustc_lint/
function_cast_as_integer.rs1use rustc_hir as hir;
2use rustc_middle::ty;
3use rustc_session::{declare_lint, declare_lint_pass};
4use rustc_span::BytePos;
5
6use crate::lints::{FunctionCastsAsIntegerDiag, FunctionCastsAsIntegerSugg};
7use crate::{LateContext, LateLintPass};
8
9declare_lint! {
10 pub FUNCTION_CASTS_AS_INTEGER,
28 Warn,
29 "casting a function into an integer",
30}
31
32declare_lint_pass!(
33 FunctionCastsAsInteger => [FUNCTION_CASTS_AS_INTEGER]
35);
36
37impl<'tcx> LateLintPass<'tcx> for FunctionCastsAsInteger {
38 fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
39 let hir::ExprKind::Cast(cast_from_expr, cast_to_expr) = expr.kind else { return };
40 let cast_to_ty = cx.typeck_results().expr_ty(expr);
41 if matches!(cast_to_ty.kind(), ty::FnDef(..) | ty::FnPtr(..) | ty::RawPtr(..)) {
46 return;
47 }
48 let cast_from_ty = cx.typeck_results().expr_ty(cast_from_expr);
49 if matches!(cast_from_ty.kind(), ty::FnDef(..)) {
50 cx.tcx.emit_node_span_lint(
51 FUNCTION_CASTS_AS_INTEGER,
52 expr.hir_id,
53 cast_to_expr.span.with_lo(cast_from_expr.span.hi() + BytePos(1)),
54 FunctionCastsAsIntegerDiag {
55 sugg: FunctionCastsAsIntegerSugg {
56 suggestion: cast_from_expr.span.shrink_to_hi(),
57 cast_to_ty,
58 },
59 },
60 );
61 }
62 }
63}