| 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, |
| ); |
| } |
| } |