mirror of
https://github.com/rust-lang/rust-clippy
synced 2024-11-10 07:04:18 +00:00
the implementation!!
This commit is contained in:
parent
590c9fc108
commit
8c191add87
7 changed files with 225 additions and 1 deletions
|
@ -4948,6 +4948,7 @@ Released 2018-09-13
|
||||||
[`println_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#println_empty_string
|
[`println_empty_string`]: https://rust-lang.github.io/rust-clippy/master/index.html#println_empty_string
|
||||||
[`ptr_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
|
[`ptr_arg`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_arg
|
||||||
[`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr
|
[`ptr_as_ptr`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_as_ptr
|
||||||
|
[`ptr_cast_constness`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_cast_constness
|
||||||
[`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq
|
[`ptr_eq`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_eq
|
||||||
[`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast
|
[`ptr_offset_with_cast`]: https://rust-lang.github.io/rust-clippy/master/index.html#ptr_offset_with_cast
|
||||||
[`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names
|
[`pub_enum_variant_names`]: https://rust-lang.github.io/rust-clippy/master/index.html#pub_enum_variant_names
|
||||||
|
|
|
@ -18,6 +18,7 @@ mod fn_to_numeric_cast;
|
||||||
mod fn_to_numeric_cast_any;
|
mod fn_to_numeric_cast_any;
|
||||||
mod fn_to_numeric_cast_with_truncation;
|
mod fn_to_numeric_cast_with_truncation;
|
||||||
mod ptr_as_ptr;
|
mod ptr_as_ptr;
|
||||||
|
mod ptr_cast_constness;
|
||||||
mod unnecessary_cast;
|
mod unnecessary_cast;
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
|
@ -399,7 +400,7 @@ declare_clippy_lint! {
|
||||||
/// namely `*const T` to `*const U` and `*mut T` to `*mut U`.
|
/// namely `*const T` to `*const U` and `*mut T` to `*mut U`.
|
||||||
///
|
///
|
||||||
/// ### Why is this bad?
|
/// ### Why is this bad?
|
||||||
/// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because
|
/// Though `as` casts between raw pointers are not terrible, `pointer::cast` is safer because
|
||||||
/// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
|
/// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
|
||||||
///
|
///
|
||||||
/// ### Example
|
/// ### Example
|
||||||
|
@ -422,6 +423,34 @@ declare_clippy_lint! {
|
||||||
"casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
|
"casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare_clippy_lint! {
|
||||||
|
/// ### What it does
|
||||||
|
/// Checks for `as` casts between raw pointers which change its constness, namely `*const T` to
|
||||||
|
/// `*mut T` and `*mut T` to `*const T`.
|
||||||
|
///
|
||||||
|
/// ### Why is this bad?
|
||||||
|
/// Though `as` casts between raw pointers are not terrible, `pointer::cast_mut` and
|
||||||
|
/// `pointer::cast_const` are safer because they cannot accidentally cast the pointer to another
|
||||||
|
/// type.
|
||||||
|
///
|
||||||
|
/// ### Example
|
||||||
|
/// ```rust
|
||||||
|
/// let ptr: *const u32 = &42_u32;
|
||||||
|
/// let mut_ptr = ptr as *mut u32;
|
||||||
|
/// let ptr = mut_ptr as *const u32;
|
||||||
|
/// ```
|
||||||
|
/// Use instead:
|
||||||
|
/// ```rust
|
||||||
|
/// let ptr: *const u32 = &42_u32;
|
||||||
|
/// let mut_ptr = ptr.cast_mut();
|
||||||
|
/// let ptr = mut_ptr.cast_const();
|
||||||
|
/// ```
|
||||||
|
#[clippy::version = "1.65.0"]
|
||||||
|
pub PTR_CAST_CONSTNESS,
|
||||||
|
pedantic,
|
||||||
|
"TODO"
|
||||||
|
}
|
||||||
|
|
||||||
declare_clippy_lint! {
|
declare_clippy_lint! {
|
||||||
/// ### What it does
|
/// ### What it does
|
||||||
/// Checks for casts from an enum type to an integral type which will definitely truncate the
|
/// Checks for casts from an enum type to an integral type which will definitely truncate the
|
||||||
|
@ -689,6 +718,7 @@ impl_lint_pass!(Casts => [
|
||||||
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
|
||||||
CHAR_LIT_AS_U8,
|
CHAR_LIT_AS_U8,
|
||||||
PTR_AS_PTR,
|
PTR_AS_PTR,
|
||||||
|
PTR_CAST_CONSTNESS,
|
||||||
CAST_ENUM_TRUNCATION,
|
CAST_ENUM_TRUNCATION,
|
||||||
CAST_ENUM_CONSTRUCTOR,
|
CAST_ENUM_CONSTRUCTOR,
|
||||||
CAST_ABS_TO_UNSIGNED,
|
CAST_ABS_TO_UNSIGNED,
|
||||||
|
@ -722,6 +752,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, &self.msrv);
|
cast_slice_from_raw_parts::check(cx, expr, cast_expr, cast_to, &self.msrv);
|
||||||
|
ptr_cast_constness::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
as_ptr_cast_mut::check(cx, expr, cast_expr, cast_to);
|
as_ptr_cast_mut::check(cx, expr, cast_expr, cast_to);
|
||||||
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
|
fn_to_numeric_cast_any::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
|
fn_to_numeric_cast::check(cx, expr, cast_expr, cast_from, cast_to);
|
||||||
|
|
35
clippy_lints/src/casts/ptr_cast_constness.rs
Normal file
35
clippy_lints/src/casts/ptr_cast_constness.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
use clippy_utils::diagnostics::span_lint_and_sugg;
|
||||||
|
use clippy_utils::sugg::Sugg;
|
||||||
|
use if_chain::if_chain;
|
||||||
|
use rustc_errors::Applicability;
|
||||||
|
use rustc_hir::{Expr, Mutability};
|
||||||
|
use rustc_lint::LateContext;
|
||||||
|
use rustc_middle::ty::{self, Ty, TypeAndMut};
|
||||||
|
|
||||||
|
use super::PTR_CAST_CONSTNESS;
|
||||||
|
|
||||||
|
pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>, cast_from: Ty<'_>, cast_to: Ty<'_>) {
|
||||||
|
if_chain! {
|
||||||
|
if let ty::RawPtr(TypeAndMut { mutbl: from_mutbl, .. }) = cast_from.kind();
|
||||||
|
if let ty::RawPtr(TypeAndMut { mutbl: to_mutbl, .. }) = cast_to.kind();
|
||||||
|
if !matches!((from_mutbl, to_mutbl),
|
||||||
|
(Mutability::Not, Mutability::Not) | (Mutability::Mut, Mutability::Mut));
|
||||||
|
then {
|
||||||
|
let sugg = Sugg::hir(cx, cast_expr, "_");
|
||||||
|
let constness = match *to_mutbl {
|
||||||
|
Mutability::Not => "const",
|
||||||
|
Mutability::Mut => "mut",
|
||||||
|
};
|
||||||
|
|
||||||
|
span_lint_and_sugg(
|
||||||
|
cx,
|
||||||
|
PTR_CAST_CONSTNESS,
|
||||||
|
expr.span,
|
||||||
|
"`as` casting between raw pointers while changing its constness",
|
||||||
|
&format!("try `pointer::cast_{constness}`, a safer alternative"),
|
||||||
|
format!("{}.cast_{constness}()", sugg.maybe_par()),
|
||||||
|
Applicability::MachineApplicable,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -89,6 +89,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
|
||||||
crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO,
|
crate::casts::FN_TO_NUMERIC_CAST_ANY_INFO,
|
||||||
crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
|
crate::casts::FN_TO_NUMERIC_CAST_WITH_TRUNCATION_INFO,
|
||||||
crate::casts::PTR_AS_PTR_INFO,
|
crate::casts::PTR_AS_PTR_INFO,
|
||||||
|
crate::casts::PTR_CAST_CONSTNESS_INFO,
|
||||||
crate::casts::UNNECESSARY_CAST_INFO,
|
crate::casts::UNNECESSARY_CAST_INFO,
|
||||||
crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
|
crate::checked_conversions::CHECKED_CONVERSIONS_INFO,
|
||||||
crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
|
crate::cognitive_complexity::COGNITIVE_COMPLEXITY_INFO,
|
||||||
|
|
55
tests/ui/ptr_cast_constness.fixed
Normal file
55
tests/ui/ptr_cast_constness.fixed
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
//@run-rustfix
|
||||||
|
//@aux-build:proc_macros.rs
|
||||||
|
|
||||||
|
#![warn(clippy::ptr_cast_constness)]
|
||||||
|
|
||||||
|
extern crate proc_macros;
|
||||||
|
use proc_macros::{external, inline_macros};
|
||||||
|
|
||||||
|
#[inline_macros]
|
||||||
|
fn main() {
|
||||||
|
let ptr: *const u32 = &42_u32;
|
||||||
|
let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
|
|
||||||
|
let _ = ptr as *const i32;
|
||||||
|
let _ = mut_ptr as *mut i32;
|
||||||
|
|
||||||
|
// Make sure the lint can handle the difference in their operator precedences.
|
||||||
|
unsafe {
|
||||||
|
let ptr_ptr: *const *const u32 = &ptr;
|
||||||
|
let _ = (*ptr_ptr).cast_mut();
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = ptr.cast_mut();
|
||||||
|
let _ = mut_ptr.cast_const();
|
||||||
|
|
||||||
|
// Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized
|
||||||
|
let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4];
|
||||||
|
let _ = ptr_of_array as *const [u32];
|
||||||
|
let _ = ptr_of_array as *const dyn std::fmt::Debug;
|
||||||
|
|
||||||
|
// Make sure the lint is triggered inside a macro
|
||||||
|
let _ = inline!($ptr as *const i32);
|
||||||
|
|
||||||
|
// Do not lint inside macros from external crates
|
||||||
|
let _ = external!($ptr as *const i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.64"]
|
||||||
|
fn _msrv_1_37() {
|
||||||
|
let ptr: *const u32 = &42_u32;
|
||||||
|
let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
|
|
||||||
|
// `pointer::cast_const` and `pointer::cast_mut` were stabilized in 1.65. Do not lint this
|
||||||
|
let _ = ptr.cast_mut();
|
||||||
|
let _ = mut_ptr.cast_const();
|
||||||
|
}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.65"]
|
||||||
|
fn _msrv_1_38() {
|
||||||
|
let ptr: *const u32 = &42_u32;
|
||||||
|
let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
|
|
||||||
|
let _ = ptr.cast_mut();
|
||||||
|
let _ = mut_ptr.cast_const();
|
||||||
|
}
|
55
tests/ui/ptr_cast_constness.rs
Normal file
55
tests/ui/ptr_cast_constness.rs
Normal file
|
@ -0,0 +1,55 @@
|
||||||
|
//@run-rustfix
|
||||||
|
//@aux-build:proc_macros.rs
|
||||||
|
|
||||||
|
#![warn(clippy::ptr_cast_constness)]
|
||||||
|
|
||||||
|
extern crate proc_macros;
|
||||||
|
use proc_macros::{external, inline_macros};
|
||||||
|
|
||||||
|
#[inline_macros]
|
||||||
|
fn main() {
|
||||||
|
let ptr: *const u32 = &42_u32;
|
||||||
|
let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
|
|
||||||
|
let _ = ptr as *const i32;
|
||||||
|
let _ = mut_ptr as *mut i32;
|
||||||
|
|
||||||
|
// Make sure the lint can handle the difference in their operator precedences.
|
||||||
|
unsafe {
|
||||||
|
let ptr_ptr: *const *const u32 = &ptr;
|
||||||
|
let _ = *ptr_ptr as *mut i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = ptr as *mut i32;
|
||||||
|
let _ = mut_ptr as *const i32;
|
||||||
|
|
||||||
|
// Lint this, since pointer::cast_mut and pointer::cast_const have ?Sized
|
||||||
|
let ptr_of_array: *const [u32; 4] = &[1, 2, 3, 4];
|
||||||
|
let _ = ptr_of_array as *const [u32];
|
||||||
|
let _ = ptr_of_array as *const dyn std::fmt::Debug;
|
||||||
|
|
||||||
|
// Make sure the lint is triggered inside a macro
|
||||||
|
let _ = inline!($ptr as *const i32);
|
||||||
|
|
||||||
|
// Do not lint inside macros from external crates
|
||||||
|
let _ = external!($ptr as *const i32);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.64"]
|
||||||
|
fn _msrv_1_37() {
|
||||||
|
let ptr: *const u32 = &42_u32;
|
||||||
|
let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
|
|
||||||
|
// `pointer::cast_const` and `pointer::cast_mut` were stabilized in 1.65. Do not lint this
|
||||||
|
let _ = ptr as *mut i32;
|
||||||
|
let _ = mut_ptr as *const i32;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[clippy::msrv = "1.65"]
|
||||||
|
fn _msrv_1_38() {
|
||||||
|
let ptr: *const u32 = &42_u32;
|
||||||
|
let mut_ptr: *mut u32 = &mut 42_u32;
|
||||||
|
|
||||||
|
let _ = ptr as *mut i32;
|
||||||
|
let _ = mut_ptr as *const i32;
|
||||||
|
}
|
46
tests/ui/ptr_cast_constness.stderr
Normal file
46
tests/ui/ptr_cast_constness.stderr
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
error: `as` casting between raw pointers while changing its constness
|
||||||
|
--> $DIR/ptr_cast_constness.rs:20:17
|
||||||
|
|
|
||||||
|
LL | let _ = *ptr_ptr as *mut i32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(*ptr_ptr).cast_mut()`
|
||||||
|
|
|
||||||
|
= note: `-D clippy::ptr-cast-constness` implied by `-D warnings`
|
||||||
|
|
||||||
|
error: `as` casting between raw pointers while changing its constness
|
||||||
|
--> $DIR/ptr_cast_constness.rs:23:13
|
||||||
|
|
|
||||||
|
LL | let _ = ptr as *mut i32;
|
||||||
|
| ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
|
||||||
|
|
||||||
|
error: `as` casting between raw pointers while changing its constness
|
||||||
|
--> $DIR/ptr_cast_constness.rs:24:13
|
||||||
|
|
|
||||||
|
LL | let _ = mut_ptr as *const i32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
|
||||||
|
|
||||||
|
error: `as` casting between raw pointers while changing its constness
|
||||||
|
--> $DIR/ptr_cast_constness.rs:44:13
|
||||||
|
|
|
||||||
|
LL | let _ = ptr as *mut i32;
|
||||||
|
| ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
|
||||||
|
|
||||||
|
error: `as` casting between raw pointers while changing its constness
|
||||||
|
--> $DIR/ptr_cast_constness.rs:45:13
|
||||||
|
|
|
||||||
|
LL | let _ = mut_ptr as *const i32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
|
||||||
|
|
||||||
|
error: `as` casting between raw pointers while changing its constness
|
||||||
|
--> $DIR/ptr_cast_constness.rs:53:13
|
||||||
|
|
|
||||||
|
LL | let _ = ptr as *mut i32;
|
||||||
|
| ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
|
||||||
|
|
||||||
|
error: `as` casting between raw pointers while changing its constness
|
||||||
|
--> $DIR/ptr_cast_constness.rs:54:13
|
||||||
|
|
|
||||||
|
LL | let _ = mut_ptr as *const i32;
|
||||||
|
| ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
|
||||||
|
|
||||||
|
error: aborting due to 7 previous errors
|
||||||
|
|
Loading…
Reference in a new issue