mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-23 21:23:56 +00:00
Fix zero_ptr
suggestion for no_std
crates
This commit is contained in:
parent
d822110d3b
commit
6ba2cda79a
5 changed files with 111 additions and 25 deletions
|
@ -538,7 +538,7 @@ pub fn register_plugins(store: &mut rustc_lint::LintStore, sess: &Session, conf:
|
|||
store.register_late_pass(|_| Box::new(needless_bool::NeedlessBool));
|
||||
store.register_late_pass(|_| Box::new(needless_bool::BoolComparison));
|
||||
store.register_late_pass(|_| Box::new(needless_for_each::NeedlessForEach));
|
||||
store.register_late_pass(|_| Box::new(misc::MiscLints));
|
||||
store.register_late_pass(|_| Box::<misc::LintPass>::default());
|
||||
store.register_late_pass(|_| Box::new(eta_reduction::EtaReduction));
|
||||
store.register_late_pass(|_| Box::new(mut_mut::MutMut));
|
||||
store.register_late_pass(|_| Box::new(mut_reference::UnnecessaryMutPassed));
|
||||
|
|
|
@ -9,12 +9,14 @@ use rustc_hir::{
|
|||
};
|
||||
use rustc_lint::{LateContext, LateLintPass};
|
||||
use rustc_middle::lint::in_external_macro;
|
||||
use rustc_session::{declare_lint_pass, declare_tool_lint};
|
||||
use rustc_session::{declare_tool_lint, impl_lint_pass};
|
||||
use rustc_span::hygiene::DesugaringKind;
|
||||
use rustc_span::source_map::{ExpnKind, Span};
|
||||
|
||||
use clippy_utils::sugg::Sugg;
|
||||
use clippy_utils::{get_parent_expr, in_constant, is_integer_literal, iter_input_pats, last_path_segment, SpanlessEq};
|
||||
use clippy_utils::{
|
||||
get_parent_expr, in_constant, is_integer_literal, is_no_std_crate, iter_input_pats, last_path_segment, SpanlessEq,
|
||||
};
|
||||
|
||||
declare_clippy_lint! {
|
||||
/// ### What it does
|
||||
|
@ -120,14 +122,28 @@ declare_clippy_lint! {
|
|||
"using `0 as *{const, mut} T`"
|
||||
}
|
||||
|
||||
declare_lint_pass!(MiscLints => [
|
||||
pub struct LintPass {
|
||||
std_or_core: &'static str,
|
||||
}
|
||||
impl Default for LintPass {
|
||||
fn default() -> Self {
|
||||
Self { std_or_core: "std" }
|
||||
}
|
||||
}
|
||||
impl_lint_pass!(LintPass => [
|
||||
TOPLEVEL_REF_ARG,
|
||||
USED_UNDERSCORE_BINDING,
|
||||
SHORT_CIRCUIT_STATEMENT,
|
||||
ZERO_PTR,
|
||||
]);
|
||||
|
||||
impl<'tcx> LateLintPass<'tcx> for MiscLints {
|
||||
impl<'tcx> LateLintPass<'tcx> for LintPass {
|
||||
fn check_crate(&mut self, cx: &LateContext<'_>) {
|
||||
if is_no_std_crate(cx) {
|
||||
self.std_or_core = "core";
|
||||
}
|
||||
}
|
||||
|
||||
fn check_fn(
|
||||
&mut self,
|
||||
cx: &LateContext<'tcx>,
|
||||
|
@ -231,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for MiscLints {
|
|||
|
||||
fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
|
||||
if let ExprKind::Cast(e, ty) = expr.kind {
|
||||
check_cast(cx, expr.span, e, ty);
|
||||
self.check_cast(cx, expr.span, e, ty);
|
||||
return;
|
||||
}
|
||||
if in_attributes_expansion(expr) || expr.span.is_desugaring(DesugaringKind::Await) {
|
||||
|
@ -310,26 +326,28 @@ fn non_macro_local(cx: &LateContext<'_>, res: def::Res) -> bool {
|
|||
}
|
||||
}
|
||||
|
||||
fn check_cast(cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
|
||||
if_chain! {
|
||||
if let TyKind::Ptr(ref mut_ty) = ty.kind;
|
||||
if is_integer_literal(e, 0);
|
||||
if !in_constant(cx, e.hir_id);
|
||||
then {
|
||||
let (msg, sugg_fn) = match mut_ty.mutbl {
|
||||
Mutability::Mut => ("`0 as *mut _` detected", "std::ptr::null_mut"),
|
||||
Mutability::Not => ("`0 as *const _` detected", "std::ptr::null"),
|
||||
};
|
||||
impl LintPass {
|
||||
fn check_cast(&self, cx: &LateContext<'_>, span: Span, e: &Expr<'_>, ty: &hir::Ty<'_>) {
|
||||
if_chain! {
|
||||
if let TyKind::Ptr(ref mut_ty) = ty.kind;
|
||||
if is_integer_literal(e, 0);
|
||||
if !in_constant(cx, e.hir_id);
|
||||
then {
|
||||
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, 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);
|
||||
let (sugg, appl) = if let TyKind::Infer = mut_ty.ty.kind {
|
||||
(format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MachineApplicable)
|
||||
} else if let Some(mut_ty_snip) = snippet_opt(cx, mut_ty.ty.span) {
|
||||
(format!("{}::{sugg_fn}::<{mut_ty_snip}>()", self.std_or_core), Applicability::MachineApplicable)
|
||||
} else {
|
||||
// `MaybeIncorrect` as type inference may not work with the suggested code
|
||||
(format!("{}::{sugg_fn}()", self.std_or_core), Applicability::MaybeIncorrect)
|
||||
};
|
||||
span_lint_and_sugg(cx, ZERO_PTR, span, msg, "try", sugg, appl);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
21
tests/ui/zero_ptr_no_std.fixed
Normal file
21
tests/ui/zero_ptr_no_std.fixed
Normal file
|
@ -0,0 +1,21 @@
|
|||
// run-rustfix
|
||||
|
||||
#![feature(lang_items, start, libc)]
|
||||
#![no_std]
|
||||
#![deny(clippy::zero_ptr)]
|
||||
|
||||
#[start]
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
let _ = core::ptr::null::<usize>();
|
||||
let _ = core::ptr::null_mut::<f64>();
|
||||
let _: *const u8 = core::ptr::null();
|
||||
0
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
extern "C" fn eh_personality() {}
|
21
tests/ui/zero_ptr_no_std.rs
Normal file
21
tests/ui/zero_ptr_no_std.rs
Normal file
|
@ -0,0 +1,21 @@
|
|||
// run-rustfix
|
||||
|
||||
#![feature(lang_items, start, libc)]
|
||||
#![no_std]
|
||||
#![deny(clippy::zero_ptr)]
|
||||
|
||||
#[start]
|
||||
fn main(_argc: isize, _argv: *const *const u8) -> isize {
|
||||
let _ = 0 as *const usize;
|
||||
let _ = 0 as *mut f64;
|
||||
let _: *const u8 = 0 as *const _;
|
||||
0
|
||||
}
|
||||
|
||||
#[panic_handler]
|
||||
fn panic(_info: &core::panic::PanicInfo) -> ! {
|
||||
loop {}
|
||||
}
|
||||
|
||||
#[lang = "eh_personality"]
|
||||
extern "C" fn eh_personality() {}
|
26
tests/ui/zero_ptr_no_std.stderr
Normal file
26
tests/ui/zero_ptr_no_std.stderr
Normal file
|
@ -0,0 +1,26 @@
|
|||
error: `0 as *const _` detected
|
||||
--> $DIR/zero_ptr_no_std.rs:9:13
|
||||
|
|
||||
LL | let _ = 0 as *const usize;
|
||||
| ^^^^^^^^^^^^^^^^^ help: try: `core::ptr::null::<usize>()`
|
||||
|
|
||||
note: the lint level is defined here
|
||||
--> $DIR/zero_ptr_no_std.rs:5:9
|
||||
|
|
||||
LL | #![deny(clippy::zero_ptr)]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `0 as *mut _` detected
|
||||
--> $DIR/zero_ptr_no_std.rs:10:13
|
||||
|
|
||||
LL | let _ = 0 as *mut f64;
|
||||
| ^^^^^^^^^^^^^ help: try: `core::ptr::null_mut::<f64>()`
|
||||
|
||||
error: `0 as *const _` detected
|
||||
--> $DIR/zero_ptr_no_std.rs:11:24
|
||||
|
|
||||
LL | let _: *const u8 = 0 as *const _;
|
||||
| ^^^^^^^^^^^^^ help: try: `core::ptr::null()`
|
||||
|
||||
error: aborting due to 3 previous errors
|
||||
|
Loading…
Reference in a new issue