@@ -18,6 +18,7 @@ mod fn_to_numeric_cast;
1818mod fn_to_numeric_cast_any;
1919mod fn_to_numeric_cast_with_truncation;
2020mod ptr_as_ptr;
21+ mod ptr_cast_constness;
2122mod unnecessary_cast;
2223mod utils;
2324
@@ -399,7 +400,7 @@ declare_clippy_lint! {
399400 /// namely `*const T` to `*const U` and `*mut T` to `*mut U`.
400401 ///
401402 /// ### Why is this bad?
402- /// Though `as` casts between raw pointers is not terrible, `pointer::cast` is safer because
403+ /// Though `as` casts between raw pointers are not terrible, `pointer::cast` is safer because
403404 /// it cannot accidentally change the pointer's mutability nor cast the pointer to other types like `usize`.
404405 ///
405406 /// ### Example
@@ -422,6 +423,34 @@ declare_clippy_lint! {
422423 "casting using `as` from and to raw pointers that doesn't change its mutability, where `pointer::cast` could take the place of `as`"
423424}
424425
426+ declare_clippy_lint ! {
427+ /// ### What it does
428+ /// Checks for `as` casts between raw pointers which change its constness, namely `*const T` to
429+ /// `*mut T` and `*mut T` to `*const T`.
430+ ///
431+ /// ### Why is this bad?
432+ /// Though `as` casts between raw pointers are not terrible, `pointer::cast_mut` and
433+ /// `pointer::cast_const` are safer because they cannot accidentally cast the pointer to another
434+ /// type.
435+ ///
436+ /// ### Example
437+ /// ```rust
438+ /// let ptr: *const u32 = &42_u32;
439+ /// let mut_ptr = ptr as *mut u32;
440+ /// let ptr = mut_ptr as *const u32;
441+ /// ```
442+ /// Use instead:
443+ /// ```rust
444+ /// let ptr: *const u32 = &42_u32;
445+ /// let mut_ptr = ptr.cast_mut();
446+ /// let ptr = mut_ptr.cast_const();
447+ /// ```
448+ #[ clippy:: version = "1.71.0" ]
449+ pub PTR_CAST_CONSTNESS ,
450+ pedantic,
451+ "casting using `as` from and to raw pointers to change constness when specialized methods apply"
452+ }
453+
425454declare_clippy_lint ! {
426455 /// ### What it does
427456 /// Checks for casts from an enum type to an integral type which will definitely truncate the
@@ -689,6 +718,7 @@ impl_lint_pass!(Casts => [
689718 FN_TO_NUMERIC_CAST_WITH_TRUNCATION ,
690719 CHAR_LIT_AS_U8 ,
691720 PTR_AS_PTR ,
721+ PTR_CAST_CONSTNESS ,
692722 CAST_ENUM_TRUNCATION ,
693723 CAST_ENUM_CONSTRUCTOR ,
694724 CAST_ABS_TO_UNSIGNED ,
@@ -722,6 +752,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
722752 return ;
723753 }
724754 cast_slice_from_raw_parts:: check ( cx, expr, cast_expr, cast_to, & self . msrv ) ;
755+ ptr_cast_constness:: check ( cx, expr, cast_expr, cast_from, cast_to, & self . msrv ) ;
725756 as_ptr_cast_mut:: check ( cx, expr, cast_expr, cast_to) ;
726757 fn_to_numeric_cast_any:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
727758 fn_to_numeric_cast:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
0 commit comments