1+ mod as_ptr_cast_mut;
12mod as_underscore;
23mod borrow_as_ptr;
34mod cast_abs_to_unsigned;
@@ -596,6 +597,32 @@ declare_clippy_lint! {
596597 "casting a slice created from a pointer and length to a slice pointer"
597598}
598599
600+ declare_clippy_lint ! {
601+ /// ### What it does
602+ /// Checks for the result of a `&self`-taking `as_ptr` being cast to a mutable pointer
603+ ///
604+ /// ### Why is this bad?
605+ /// Since `as_ptr` takes a `&self`, the pointer won't have write permissions unless interior
606+ /// mutability is used, making it unlikely that having it as a mutable pointer is correct.
607+ ///
608+ /// ### Example
609+ /// ```rust
610+ /// let string = String::with_capacity(1);
611+ /// let ptr = string.as_ptr() as *mut u8;
612+ /// unsafe { ptr.write(4) }; // UNDEFINED BEHAVIOUR
613+ /// ```
614+ /// Use instead:
615+ /// ```rust
616+ /// let mut string = String::with_capacity(1);
617+ /// let ptr = string.as_mut_ptr();
618+ /// unsafe { ptr.write(4) };
619+ /// ```
620+ #[ clippy:: version = "1.66.0" ]
621+ pub AS_PTR_CAST_MUT ,
622+ nursery,
623+ "casting the result of the `&self`-taking `as_ptr` to a mutabe pointer"
624+ }
625+
599626pub struct Casts {
600627 msrv : Option < RustcVersion > ,
601628}
@@ -627,7 +654,8 @@ impl_lint_pass!(Casts => [
627654 CAST_ABS_TO_UNSIGNED ,
628655 AS_UNDERSCORE ,
629656 BORROW_AS_PTR ,
630- CAST_SLICE_FROM_RAW_PARTS
657+ CAST_SLICE_FROM_RAW_PARTS ,
658+ AS_PTR_CAST_MUT ,
631659] ) ;
632660
633661impl < ' tcx > LateLintPass < ' tcx > for Casts {
@@ -653,6 +681,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
653681 return ;
654682 }
655683 cast_slice_from_raw_parts:: check ( cx, expr, cast_expr, cast_to, self . msrv ) ;
684+ as_ptr_cast_mut:: check ( cx, expr, cast_expr, cast_to) ;
656685 fn_to_numeric_cast_any:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
657686 fn_to_numeric_cast:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
658687 fn_to_numeric_cast_with_truncation:: check ( cx, expr, cast_expr, cast_from, cast_to) ;
0 commit comments