]> git.lizzy.rs Git - rust.git/blob - src/tools/clippy/clippy_lints/src/transmute/transmuting_null.rs
Rollup merge of #106260 - chenyukang:yukang/fix-106213-doc, r=GuillaumeGomez
[rust.git] / src / tools / clippy / clippy_lints / src / transmute / transmuting_null.rs
1 use clippy_utils::consts::{constant_context, Constant};
2 use clippy_utils::diagnostics::span_lint;
3 use clippy_utils::{is_integer_literal, is_path_diagnostic_item};
4 use rustc_hir::{Expr, ExprKind};
5 use rustc_lint::LateContext;
6 use rustc_middle::ty::Ty;
7 use rustc_span::symbol::sym;
8
9 use super::TRANSMUTING_NULL;
10
11 const LINT_MSG: &str = "transmuting a known null pointer into a reference";
12
13 pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, arg: &'tcx Expr<'_>, to_ty: Ty<'tcx>) -> bool {
14     if !to_ty.is_ref() {
15         return false;
16     }
17
18     // Catching transmute over constants that resolve to `null`.
19     let mut const_eval_context = constant_context(cx, cx.typeck_results());
20     if let ExprKind::Path(ref _qpath) = arg.kind &&
21         let Some(Constant::RawPtr(0)) = const_eval_context.expr(arg)
22     {
23         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
24         return true;
25     }
26
27     // Catching:
28     // `std::mem::transmute(0 as *const i32)`
29     if let ExprKind::Cast(inner_expr, _cast_ty) = arg.kind && is_integer_literal(inner_expr, 0) {
30         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
31         return true;
32     }
33
34     // Catching:
35     // `std::mem::transmute(std::ptr::null::<i32>())`
36     if let ExprKind::Call(func1, []) = arg.kind &&
37         is_path_diagnostic_item(cx, func1, sym::ptr_null)
38     {
39         span_lint(cx, TRANSMUTING_NULL, expr.span, LINT_MSG);
40         return true;
41     }
42
43     // FIXME:
44     // Also catch transmutations of variables which are known nulls.
45     // To do this, MIR const propagation seems to be the better tool.
46     // Whenever MIR const prop routines are more developed, this will
47     // become available. As of this writing (25/03/19) it is not yet.
48     false
49 }