about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJason Newcomb <jsnewcomb@pm.me>2024-12-06 20:50:33 +0000
committerGitHub <noreply@github.com>2024-12-06 20:50:33 +0000
commit7f866c7cc66693ffd9bf082726e6354ec3d09369 (patch)
tree5c7a187053efd24341a8a61b20734471b2c064e7
parent5198941bb793d1e5ce001bfde5c6c74ac299b87d (diff)
parent149671192dcbdab92772a37f23cf9166c51be124 (diff)
New lint for `as *const _` and `as *mut _` pointer casts (#13251)
changelog: New lint for as *const _ and as *mut _ pointer casts

EDIT: lets go with the simpler version
-rw-r--r--CHANGELOG.md1
-rw-r--r--clippy_lints/src/casts/as_pointer_underscore.rs19
-rw-r--r--clippy_lints/src/casts/mod.rs30
-rw-r--r--clippy_lints/src/declared_lints.rs1
-rw-r--r--tests/ui/as_pointer_underscore.fixed15
-rw-r--r--tests/ui/as_pointer_underscore.rs15
-rw-r--r--tests/ui/as_pointer_underscore.stderr17
7 files changed, 98 insertions, 0 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md
index bf49ddfbd74..cc966972939 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -5380,6 +5380,7 @@ Released 2018-09-13
 [`arc_with_non_send_sync`]: https://rust-lang.github.io/rust-clippy/master/index.html#arc_with_non_send_sync
 [`arithmetic_side_effects`]: https://rust-lang.github.io/rust-clippy/master/index.html#arithmetic_side_effects
 [`as_conversions`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_conversions
+[`as_pointer_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_pointer_underscore
 [`as_ptr_cast_mut`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_ptr_cast_mut
 [`as_underscore`]: https://rust-lang.github.io/rust-clippy/master/index.html#as_underscore
 [`assertions_on_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#assertions_on_constants
diff --git a/clippy_lints/src/casts/as_pointer_underscore.rs b/clippy_lints/src/casts/as_pointer_underscore.rs
new file mode 100644
index 00000000000..536126fd02b
--- /dev/null
+++ b/clippy_lints/src/casts/as_pointer_underscore.rs
@@ -0,0 +1,19 @@
+use rustc_errors::Applicability;
+use rustc_lint::LateContext;
+use rustc_middle::ty::Ty;
+
+pub fn check<'tcx>(cx: &LateContext<'tcx>, ty_into: Ty<'_>, cast_to_hir: &'tcx rustc_hir::Ty<'tcx>) {
+    if let rustc_hir::TyKind::Ptr(rustc_hir::MutTy { ty, .. }) = cast_to_hir.kind
+        && matches!(ty.kind, rustc_hir::TyKind::Infer)
+    {
+        clippy_utils::diagnostics::span_lint_and_sugg(
+            cx,
+            super::AS_POINTER_UNDERSCORE,
+            cast_to_hir.span,
+            "using inferred pointer cast",
+            "use explicit type",
+            ty_into.to_string(),
+            Applicability::MachineApplicable,
+        );
+    }
+}
diff --git a/clippy_lints/src/casts/mod.rs b/clippy_lints/src/casts/mod.rs
index 84fab9cb75f..c64c0e15144 100644
--- a/clippy_lints/src/casts/mod.rs
+++ b/clippy_lints/src/casts/mod.rs
@@ -1,3 +1,4 @@
+mod as_pointer_underscore;
 mod as_ptr_cast_mut;
 mod as_underscore;
 mod borrow_as_ptr;
@@ -726,6 +727,33 @@ declare_clippy_lint! {
     "using `as` to cast a reference to pointer"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for the usage of `as *const _` or `as *mut _` conversion using inferred type.
+    ///
+    /// ### Why restrict this?
+    /// The conversion might include a dangerous cast that might go undetected due to the type being inferred.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// fn as_usize<T>(t: &T) -> usize {
+    ///     // BUG: `t` is already a reference, so we will here
+    ///     // return a dangling pointer to a temporary value instead
+    ///     &t as *const _ as usize
+    /// }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// fn as_usize<T>(t: &T) -> usize {
+    ///     t as *const T as usize
+    /// }
+    /// ```
+    #[clippy::version = "1.81.0"]
+    pub AS_POINTER_UNDERSCORE,
+    restriction,
+    "detects `as *mut _` and `as *const _` conversion"
+}
+
 pub struct Casts {
     msrv: Msrv,
 }
@@ -763,6 +791,7 @@ impl_lint_pass!(Casts => [
     CAST_NAN_TO_INT,
     ZERO_PTR,
     REF_AS_PTR,
+    AS_POINTER_UNDERSCORE,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Casts {
@@ -805,6 +834,7 @@ impl<'tcx> LateLintPass<'tcx> for Casts {
             }
 
             as_underscore::check(cx, expr, cast_to_hir);
+            as_pointer_underscore::check(cx, cast_to, cast_to_hir);
 
             let was_borrow_as_ptr_emitted = if self.msrv.meets(msrvs::BORROW_AS_PTR) {
                 borrow_as_ptr::check(cx, expr, cast_from_expr, cast_to_hir, &self.msrv)
diff --git a/clippy_lints/src/declared_lints.rs b/clippy_lints/src/declared_lints.rs
index 1dcf3a87449..304622afe53 100644
--- a/clippy_lints/src/declared_lints.rs
+++ b/clippy_lints/src/declared_lints.rs
@@ -75,6 +75,7 @@ pub static LINTS: &[&crate::LintInfo] = &[
     crate::cargo::NEGATIVE_FEATURE_NAMES_INFO,
     crate::cargo::REDUNDANT_FEATURE_NAMES_INFO,
     crate::cargo::WILDCARD_DEPENDENCIES_INFO,
+    crate::casts::AS_POINTER_UNDERSCORE_INFO,
     crate::casts::AS_PTR_CAST_MUT_INFO,
     crate::casts::AS_UNDERSCORE_INFO,
     crate::casts::BORROW_AS_PTR_INFO,
diff --git a/tests/ui/as_pointer_underscore.fixed b/tests/ui/as_pointer_underscore.fixed
new file mode 100644
index 00000000000..db06486ecb0
--- /dev/null
+++ b/tests/ui/as_pointer_underscore.fixed
@@ -0,0 +1,15 @@
+#![warn(clippy::as_pointer_underscore)]
+#![crate_type = "lib"]
+#![no_std]
+
+struct S;
+
+fn f(s: &S) -> usize {
+    &s as *const &S as usize
+    //~^ ERROR: using inferred pointer cast
+}
+
+fn g(s: &mut S) -> usize {
+    s as *mut S as usize
+    //~^ ERROR: using inferred pointer cast
+}
diff --git a/tests/ui/as_pointer_underscore.rs b/tests/ui/as_pointer_underscore.rs
new file mode 100644
index 00000000000..955c702ccc9
--- /dev/null
+++ b/tests/ui/as_pointer_underscore.rs
@@ -0,0 +1,15 @@
+#![warn(clippy::as_pointer_underscore)]
+#![crate_type = "lib"]
+#![no_std]
+
+struct S;
+
+fn f(s: &S) -> usize {
+    &s as *const _ as usize
+    //~^ ERROR: using inferred pointer cast
+}
+
+fn g(s: &mut S) -> usize {
+    s as *mut _ as usize
+    //~^ ERROR: using inferred pointer cast
+}
diff --git a/tests/ui/as_pointer_underscore.stderr b/tests/ui/as_pointer_underscore.stderr
new file mode 100644
index 00000000000..270056f3645
--- /dev/null
+++ b/tests/ui/as_pointer_underscore.stderr
@@ -0,0 +1,17 @@
+error: using inferred pointer cast
+  --> tests/ui/as_pointer_underscore.rs:8:11
+   |
+LL |     &s as *const _ as usize
+   |           ^^^^^^^^ help: use explicit type: `*const &S`
+   |
+   = note: `-D clippy::as-pointer-underscore` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::as_pointer_underscore)]`
+
+error: using inferred pointer cast
+  --> tests/ui/as_pointer_underscore.rs:13:10
+   |
+LL |     s as *mut _ as usize
+   |          ^^^^^^ help: use explicit type: `*mut S`
+
+error: aborting due to 2 previous errors
+