about summary refs log tree commit diff
path: root/clippy_lints/src/casts/zero_ptr.rs
blob: 5071af5ecb986f059daeae1622b70392973ac05c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::source::snippet_opt;
use clippy_utils::{in_constant, is_integer_literal, std_or_core};
use rustc_errors::Applicability;
use rustc_hir::{Expr, Mutability, Ty, TyKind};
use rustc_lint::LateContext;

use super::ZERO_PTR;

pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {
    if let TyKind::Ptr(ref mut_ty) = to.kind
        && is_integer_literal(from, 0)
        && !in_constant(cx, from.hir_id)
        && let Some(std_or_core) = std_or_core(cx)
    {
        let (msg, sugg_fn) = match mut_ty.mutbl {
            Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
            Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
        };

        let sugg = if let TyKind::Infer = mut_ty.ty.kind {
            format!("{std_or_core}::{sugg_fn}()")
        } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
            format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()")
        } else {
            return;
        };

        span_lint_and_sugg(
            cx,
            ZERO_PTR,
            expr.span,
            msg,
            "try",
            sugg,
            Applicability::MachineApplicable,
        );
    }
}