Skip to content

Commit 889e1b9

Browse files
committed
Auto merge of rust-lang#11530 - Alexendoo:zero-ptr-file-location, r=blyxyas
Move zero_ptr to the casts module Also a bit of a touch up to the code while I was there changelog: none
2 parents 5cba09c + b06b915 commit 889e1b9

File tree

5 files changed

+75
-78
lines changed

5 files changed

+75
-78
lines changed

clippy_lints/src/casts/mod.rs

+26
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ mod ptr_as_ptr;
2020
mod ptr_cast_constness;
2121
mod unnecessary_cast;
2222
mod utils;
23+
mod zero_ptr;
2324

2425
use clippy_utils::is_hir_ty_cfg_dependant;
2526
use clippy_utils::msrvs::{self, Msrv};
@@ -665,6 +666,29 @@ declare_clippy_lint! {
665666
"casting a known floating-point NaN into an integer"
666667
}
667668

669+
declare_clippy_lint! {
670+
/// ### What it does
671+
/// Catch casts from `0` to some pointer type
672+
///
673+
/// ### Why is this bad?
674+
/// This generally means `null` and is better expressed as
675+
/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
676+
///
677+
/// ### Example
678+
/// ```rust
679+
/// let a = 0 as *const u32;
680+
/// ```
681+
///
682+
/// Use instead:
683+
/// ```rust
684+
/// let a = std::ptr::null::<u32>();
685+
/// ```
686+
#[clippy::version = "pre 1.29.0"]
687+
pub ZERO_PTR,
688+
style,
689+
"using `0 as *{const, mut} T`"
690+
}
691+
668692
pub struct Casts {
669693
msrv: Msrv,
670694
}
@@ -699,6 +723,7 @@ impl_lint_pass!(Casts => [
699723
CAST_SLICE_FROM_RAW_PARTS,
700724
AS_PTR_CAST_MUT,
701725
CAST_NAN_TO_INT,
726+
ZERO_PTR,
702727
]);
703728

704729
impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -729,6 +754,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
729754
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
730755
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
731756
fn_to_numeric_cast_with_truncation::check(cx, expr, cast_expr, cast_from, cast_to);
757+
zero_ptr::check(cx, expr, cast_expr, cast_to_hir);
732758

733759
if cast_to.is_numeric() && !in_external_macro(cx.sess(), expr.span) {
734760
cast_possible_truncation::check(cx, expr, cast_expr, cast_from, cast_to, cast_to_hir.span);

clippy_lints/src/casts/zero_ptr.rs

+39
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
use clippy_utils::diagnostics::span_lint_and_sugg;
2+
use clippy_utils::source::snippet_opt;
3+
use clippy_utils::{in_constant, is_integer_literal, std_or_core};
4+
use rustc_errors::Applicability;
5+
use rustc_hir::{Expr, Mutability, Ty, TyKind};
6+
use rustc_lint::LateContext;
7+
8+
use super::ZERO_PTR;
9+
10+
pub fn check(cx: &LateContext<'_>, expr: &Expr<'_>, from: &Expr<'_>, to: &Ty<'_>) {
11+
if let TyKind::Ptr(ref mut_ty) = to.kind
12+
&& is_integer_literal(from, 0)
13+
&& !in_constant(cx, from.hir_id)
14+
&& let Some(std_or_core) = std_or_core(cx)
15+
{
16+
let (msg, sugg_fn) = match mut_ty.mutbl {
17+
Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
18+
Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
19+
};
20+
21+
let sugg = if let TyKind::Infer = mut_ty.ty.kind {
22+
format!("{std_or_core}::{sugg_fn}()")
23+
} else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
24+
format!("{std_or_core}::{sugg_fn}::<{mut_ty_snip}>()")
25+
} else {
26+
return;
27+
};
28+
29+
span_lint_and_sugg(
30+
cx,
31+
ZERO_PTR,
32+
expr.span,
33+
msg,
34+
"try",
35+
sugg,
36+
Applicability::MachineApplicable,
37+
);
38+
}
39+
}

clippy_lints/src/declared_lints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
9797
crate::casts::PTR_AS_PTR_INFO,
9898
crate::casts::PTR_CAST_CONSTNESS_INFO,
9999
crate::casts::UNNECESSARY_CAST_INFO,
100+
crate::casts::ZERO_PTR_INFO,
100101
crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
101102
crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
102103
crate::collapsible_if::COLLAPSIBLE_ELSE_IF_INFO,
@@ -443,7 +444,6 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
443444
crate::misc::SHORT_CIRCUIT_STATEMENT_INFO,
444445
crate::misc::TOPLEVEL_REF_ARG_INFO,
445446
crate::misc::USED_UNDERSCORE_BINDING_INFO,
446-
crate::misc::ZERO_PTR_INFO,
447447
crate::misc_early::BUILTIN_TYPE_SHADOW_INFO,
448448
crate::misc_early::DOUBLE_NEG_INFO,
449449
crate::misc_early::DUPLICATE_UNDERSCORE_ARGUMENT_INFO,

clippy_lints/src/lib.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -637,7 +637,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
637637
store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
638638
store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
639639
store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
640-
store.register_late_pass(|_| Box::<misc::LintPass>::default());
640+
store.register_late_pass(|_| Box::new(misc::LintPass));
641641
store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
642642
store.register_late_pass(|_| Box::new(mut_mut::MutMut));
643643
store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));

clippy_lints/src/misc.rs

+8-76
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,20 @@
1-
use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then, span_lint_hir_and_then};
2-
use clippy_utils::source::{snippet, snippet_opt, snippet_with_context};
1+
use clippy_utils::diagnostics::{span_lint, span_lint_and_then, span_lint_hir_and_then};
2+
use clippy_utils::source::{snippet, snippet_with_context};
33
use clippy_utils::sugg::Sugg;
44
use clippy_utils::{
5-
any_parent_is_automatically_derived, fulfill_or_allowed, get_parent_expr, in_constant, is_integer_literal,
6-
is_lint_allowed, is_no_std_crate, iter_input_pats, last_path_segment, SpanlessEq,
5+
any_parent_is_automatically_derived, fulfill_or_allowed, get_parent_expr, is_lint_allowed, iter_input_pats,
6+
last_path_segment, SpanlessEq,
77
};
88
use if_chain::if_chain;
99
use rustc_errors::Applicability;
1010
use rustc_hir::def::Res;
1111
use rustc_hir::intravisit::FnKind;
1212
use rustc_hir::{
13-
BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind, Ty,
14-
TyKind,
13+
BinOpKind, BindingAnnotation, Body, ByRef, Expr, ExprKind, FnDecl, Mutability, PatKind, QPath, Stmt, StmtKind,
1514
};
1615
use rustc_lint::{LateContext, LateLintPass, LintContext};
1716
use rustc_middle::lint::in_external_macro;
18-
use rustc_session::{declare_tool_lint, impl_lint_pass};
17+
use rustc_session::{declare_lint_pass, declare_tool_lint};
1918
use rustc_span::def_id::LocalDefId;
2019
use rustc_span::source_map::Span;
2120

@@ -55,6 +54,7 @@ declare_clippy_lint! {
5554
style,
5655
"an entire binding declared as `ref`, in a function argument or a `let` statement"
5756
}
57+
5858
declare_clippy_lint! {
5959
/// ### What it does
6060
/// Checks for the use of bindings with a single leading
@@ -102,51 +102,13 @@ declare_clippy_lint! {
102102
"using a short circuit boolean condition as a statement"
103103
}
104104

105-
declare_clippy_lint! {
106-
/// ### What it does
107-
/// Catch casts from `0` to some pointer type
108-
///
109-
/// ### Why is this bad?
110-
/// This generally means `null` and is better expressed as
111-
/// {`std`, `core`}`::ptr::`{`null`, `null_mut`}.
112-
///
113-
/// ### Example
114-
/// ```rust
115-
/// let a = 0 as *const u32;
116-
/// ```
117-
///
118-
/// Use instead:
119-
/// ```rust
120-
/// let a = std::ptr::null::<u32>();
121-
/// ```
122-
#[clippy::version = "pre 1.29.0"]
123-
pub ZERO_PTR,
124-
style,
125-
"using `0 as *{const, mut} T`"
126-
}
127-
128-
pub struct LintPass {
129-
std_or_core: &'static str,
130-
}
131-
impl Default for LintPass {
132-
fn default() -> Self {
133-
Self { std_or_core: "std" }
134-
}
135-
}
136-
impl_lint_pass!(LintPass => [
105+
declare_lint_pass!(LintPass => [
137106
TOPLEVEL_REF_ARG,
138107
USED_UNDERSCORE_BINDING,
139108
SHORT_CIRCUIT_STATEMENT,
140-
ZERO_PTR,
141109
]);
142110

143111
impl<'tcx> LateLintPass<'tcx> for LintPass {
144-
fn check_crate(&mut self, cx: &LateContext<'_>) {
145-
if is_no_std_crate(cx) {
146-
self.std_or_core = "core";
147-
}
148-
}
149-
150112
fn check_fn(
151113
&mut self,
152114
cx: &LateContext<'tcx>,
@@ -252,10 +214,6 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
252214
}
253215

254216
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
255-
if let ExprKind::Cast(e, ty) = expr.kind {
256-
self.check_cast(cx, expr.span, e, ty);
257-
return;
258-
}
259217
if in_external_macro(cx.sess(), expr.span)
260218
|| expr.span.desugaring_kind().is_some()
261219
|| any_parent_is_automatically_derived(cx.tcx, expr.hir_id)
@@ -320,29 +278,3 @@ fn is_used(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
320278
_ => is_used(cx, parent),
321279
})
322280
}
323-
324-
impl LintPass {
325-
fn check_cast(&self, cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &Ty<'_>) {
326-
if_chain! {
327-
if let TyKind::Ptr(ref mut_ty) = ty.kind;
328-
if is_integer_literal(e, 0);
329-
if !in_constant(cx, e.hir_id);
330-
then {
331-
let (msg, sugg_fn) = match mut_ty.mutbl {
332-
Mutability::Mut => ("`0 as *mut _` detected", "ptr::null_mut"),
333-
Mutability::Not => ("`0 as *const _` detected", "ptr::null"),
334-
};
335-
336-
let (sugg, appl) = if let TyKind::Infer = mut_ty.ty.kind {
337-
(format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MachineApplicable)
338-
} else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
339-
(format!("{}::{sugg_fn}::<{mut_ty_snip}>()", self.std_or_core), Applicability::MachineApplicable)
340-
} else {
341-
// `MaybeIncorrect` as type inference may not work with the suggested code
342-
(format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MaybeIncorrect)
343-
};
344-
span_lint_and_sugg(cx, ZERO_PTR, span, msg, "try", sugg, appl);
345-
}
346-
}
347-
}
348-
}

0 commit comments

Comments
 (0)