blob: f4738e7b0d51d83a7ab6021722c1d0dd310057ad [file] [log] [blame] [edit]
use clippy_utils::diagnostics::span_lint_and_sugg;
use clippy_utils::msrvs::{self, Msrv};
use clippy_utils::source::SpanRangeExt;
use clippy_utils::{is_in_const_context, 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<'_>, msrv: Msrv) {
if let TyKind::Ptr(ref mut_ty) = to.kind
&& is_integer_literal(from, 0)
&& (!is_in_const_context(cx) || msrv.meets(cx, msrvs::PTR_NULL))
&& 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) = mut_ty.ty.span.get_source_text(cx) {
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,
);
}
}