From 6b1a8683f46248ac0724543e89ed01a2c900f847 Mon Sep 17 00:00:00 2001 From: Lzu Tao Date: Wed, 2 Oct 2019 22:38:00 +0700 Subject: [PATCH] Add suggestion for zero-ptr lint --- clippy_lints/src/misc.rs | 26 ++++++++++++++++--------- clippy_lints/src/utils/mod.rs | 2 +- tests/ui/zero_ptr.fixed | 14 ++++++++++++++ tests/ui/zero_ptr.rs | 14 ++++++++++---- tests/ui/zero_ptr.stderr | 36 ++++++++++++++++++++++++++--------- 5 files changed, 69 insertions(+), 23 deletions(-) create mode 100644 tests/ui/zero_ptr.fixed diff --git a/clippy_lints/src/misc.rs b/clippy_lints/src/misc.rs index 437114066cdf..54962833b58f 100644 --- a/clippy_lints/src/misc.rs +++ b/clippy_lints/src/misc.rs @@ -13,8 +13,8 @@ use crate::consts::{constant, Constant}; use crate::utils::sugg::Sugg; use crate::utils::{ get_item_name, get_parent_expr, implements_trait, in_constant, is_integer_const, iter_input_pats, - last_path_segment, match_qpath, match_trait_method, paths, snippet, span_lint, span_lint_and_then, - span_lint_hir_and_then, walk_ptrs_ty, SpanlessEq, + last_path_segment, match_qpath, match_trait_method, paths, snippet, snippet_opt, span_lint, span_lint_and_sugg, + span_lint_and_then, span_lint_hir_and_then, walk_ptrs_ty, SpanlessEq, }; declare_clippy_lint! { @@ -621,17 +621,25 @@ fn non_macro_local(cx: &LateContext<'_, '_>, res: def::Res) -> bool { fn check_cast(cx: &LateContext<'_, '_>, span: Span, e: &Expr, ty: &Ty) { if_chain! { - if let TyKind::Ptr(MutTy { mutbl, .. }) = ty.kind; + if let TyKind::Ptr(ref mut_ty) = ty.kind; if let ExprKind::Lit(ref lit) = e.kind; - if let LitKind::Int(value, ..) = lit.node; - if value == 0; + if let LitKind::Int(0, _) = lit.node; if !in_constant(cx, e.hir_id); then { - let msg = match mutbl { - Mutability::MutMutable => "`0 as *mut _` detected. Consider using `ptr::null_mut()`", - Mutability::MutImmutable => "`0 as *const _` detected. Consider using `ptr::null()`", + let (msg, sugg_fn) = match mut_ty.mutbl { + Mutability::MutMutable => ("`0 as *mut _` detected", "std::ptr::null_mut"), + Mutability::MutImmutable => ("`0 as *const _` detected", "std::ptr::null"), }; - span_lint(cx, ZERO_PTR, span, msg); + + let (sugg, appl) = if let TyKind::Infer = mut_ty.ty.kind { + (format!("{}()", sugg_fn), Applicability::MachineApplicable) + } else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) { + (format!("{}::<{}>()", sugg_fn, mut_ty_snip), Applicability::MachineApplicable) + } else { + // `MaybeIncorrect` as type inference may not work with the suggested code + (format!("{}()", sugg_fn), Applicability::MaybeIncorrect) + }; + span_lint_and_sugg(cx, ZERO_PTR, span, msg, "try", sugg, appl); } } } diff --git a/clippy_lints/src/utils/mod.rs b/clippy_lints/src/utils/mod.rs index 8fd84c07a7d2..27dad6322d88 100644 --- a/clippy_lints/src/utils/mod.rs +++ b/clippy_lints/src/utils/mod.rs @@ -61,7 +61,7 @@ pub fn differing_macro_contexts(lhs: Span, rhs: Span) -> bool { /// # Example /// /// ```rust,ignore -/// if in_constant(cx, expr.id) { +/// if in_constant(cx, expr.hir_id) { /// // Do something /// } /// ``` diff --git a/tests/ui/zero_ptr.fixed b/tests/ui/zero_ptr.fixed new file mode 100644 index 000000000000..489aa4121a3a --- /dev/null +++ b/tests/ui/zero_ptr.fixed @@ -0,0 +1,14 @@ +// run-rustfix +pub fn foo(_const: *const f32, _mut: *mut i64) {} + +fn main() { + let _ = std::ptr::null::(); + let _ = std::ptr::null_mut::(); + let _: *const u8 = std::ptr::null(); + + foo(0 as _, 0 as _); + foo(std::ptr::null(), std::ptr::null_mut()); + + let z = 0; + let _ = z as *const usize; // this is currently not caught +} diff --git a/tests/ui/zero_ptr.rs b/tests/ui/zero_ptr.rs index 2291c77d56e6..c3b55ef9ebd9 100644 --- a/tests/ui/zero_ptr.rs +++ b/tests/ui/zero_ptr.rs @@ -1,8 +1,14 @@ -#[allow(unused_variables)] +// run-rustfix +pub fn foo(_const: *const f32, _mut: *mut i64) {} + fn main() { - let x = 0 as *const usize; - let y = 0 as *mut f64; + let _ = 0 as *const usize; + let _ = 0 as *mut f64; + let _: *const u8 = 0 as *const _; + + foo(0 as _, 0 as _); + foo(0 as *const _, 0 as *mut _); let z = 0; - let z = z as *const usize; // this is currently not caught + let _ = z as *const usize; // this is currently not caught } diff --git a/tests/ui/zero_ptr.stderr b/tests/ui/zero_ptr.stderr index b79c3457b9b3..4ee5e9a26168 100644 --- a/tests/ui/zero_ptr.stderr +++ b/tests/ui/zero_ptr.stderr @@ -1,16 +1,34 @@ -error: `0 as *const _` detected. Consider using `ptr::null()` - --> $DIR/zero_ptr.rs:3:13 +error: `0 as *const _` detected + --> $DIR/zero_ptr.rs:5:13 | -LL | let x = 0 as *const usize; - | ^^^^^^^^^^^^^^^^^ +LL | let _ = 0 as *const usize; + | ^^^^^^^^^^^^^^^^^ help: try: `std::ptr::null::()` | = note: `-D clippy::zero-ptr` implied by `-D warnings` -error: `0 as *mut _` detected. Consider using `ptr::null_mut()` - --> $DIR/zero_ptr.rs:4:13 +error: `0 as *mut _` detected + --> $DIR/zero_ptr.rs:6:13 | -LL | let y = 0 as *mut f64; - | ^^^^^^^^^^^^^ +LL | let _ = 0 as *mut f64; + | ^^^^^^^^^^^^^ help: try: `std::ptr::null_mut::()` -error: aborting due to 2 previous errors +error: `0 as *const _` detected + --> $DIR/zero_ptr.rs:7:24 + | +LL | let _: *const u8 = 0 as *const _; + | ^^^^^^^^^^^^^ help: try: `std::ptr::null()` + +error: `0 as *const _` detected + --> $DIR/zero_ptr.rs:10:9 + | +LL | foo(0 as *const _, 0 as *mut _); + | ^^^^^^^^^^^^^ help: try: `std::ptr::null()` + +error: `0 as *mut _` detected + --> $DIR/zero_ptr.rs:10:24 + | +LL | foo(0 as *const _, 0 as *mut _); + | ^^^^^^^^^^^ help: try: `std::ptr::null_mut()` + +error: aborting due to 5 previous errors