about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--clippy_lints/src/casts/ptr_cast_constness.rs3
-rw-r--r--clippy_lints/src/transmute/mod.rs2
-rw-r--r--clippy_lints/src/transmute/transmute_ptr_to_ptr.rs43
-rw-r--r--tests/ui/ptr_cast_constness.fixed4
-rw-r--r--tests/ui/ptr_cast_constness.rs4
-rw-r--r--tests/ui/ptr_cast_constness.stderr4
-rw-r--r--tests/ui/transmute_ptr_to_ptr.fixed79
-rw-r--r--tests/ui/transmute_ptr_to_ptr.rs87
-rw-r--r--tests/ui/transmute_ptr_to_ptr.stderr152
-rw-r--r--tests/ui/transmutes_expressible_as_ptr_casts.fixed2
-rw-r--r--tests/ui/transmutes_expressible_as_ptr_casts.stderr13
11 files changed, 309 insertions, 84 deletions
diff --git a/clippy_lints/src/casts/ptr_cast_constness.rs b/clippy_lints/src/casts/ptr_cast_constness.rs
index 921693567fc..7513e18d408 100644
--- a/clippy_lints/src/casts/ptr_cast_constness.rs
+++ b/clippy_lints/src/casts/ptr_cast_constness.rs
@@ -4,7 +4,7 @@ use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, Mutability};
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 
 use super::PTR_CAST_CONSTNESS;
 
@@ -24,6 +24,7 @@ pub(super) fn check<'tcx>(
             (Mutability::Not, Mutability::Mut) | (Mutability::Mut, Mutability::Not)
         )
         && from_ty == to_ty
+        && !from_ty.has_erased_regions()
     {
         let sugg = Sugg::hir(cx, cast_expr, "_");
         let constness = match *to_mutbl {
diff --git a/clippy_lints/src/transmute/mod.rs b/clippy_lints/src/transmute/mod.rs
index e556d5867bb..9c6813a54b9 100644
--- a/clippy_lints/src/transmute/mod.rs
+++ b/clippy_lints/src/transmute/mod.rs
@@ -617,7 +617,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 | missing_transmute_annotations::check(cx, path, from_ty, to_ty, e.hir_id)
                 | transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
                 | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
-                | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg)
+                | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, &self.msrv)
                 | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)
                 | transmute_int_to_float::check(cx, e, from_ty, to_ty, arg, const_context)
                 | transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg)
diff --git a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
index 1476ea8e7a4..0772b284968 100644
--- a/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
+++ b/clippy_lints/src/transmute/transmute_ptr_to_ptr.rs
@@ -1,10 +1,11 @@
 use super::TRANSMUTE_PTR_TO_PTR;
+use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::sugg;
 use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::{self, Ty, TypeVisitableExt};
 
 /// Checks for `transmute_ptr_to_ptr` lint.
 /// Returns `true` if it's triggered, otherwise returns `false`.
@@ -14,9 +15,10 @@ pub(super) fn check<'tcx>(
     from_ty: Ty<'tcx>,
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
+    msrv: &Msrv,
 ) -> bool {
-    match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::RawPtr(_, _), ty::RawPtr(to_ty, to_mutbl)) => {
+    match (from_ty.kind(), to_ty.kind()) {
+        (ty::RawPtr(from_pointee_ty, from_mutbl), ty::RawPtr(to_pointee_ty, to_mutbl)) => {
             span_lint_and_then(
                 cx,
                 TRANSMUTE_PTR_TO_PTR,
@@ -24,8 +26,39 @@ pub(super) fn check<'tcx>(
                 "transmute from a pointer to a pointer",
                 |diag| {
                     if let Some(arg) = sugg::Sugg::hir_opt(cx, arg) {
-                        let sugg = arg.as_ty(Ty::new_ptr(cx.tcx, *to_ty, *to_mutbl));
-                        diag.span_suggestion(e.span, "try", sugg, Applicability::Unspecified);
+                        if from_mutbl == to_mutbl
+                            && to_pointee_ty.is_sized(cx.tcx, cx.param_env)
+                            && msrv.meets(msrvs::POINTER_CAST)
+                        {
+                            diag.span_suggestion_verbose(
+                                e.span,
+                                "use `pointer::cast` instead",
+                                format!("{}.cast::<{to_pointee_ty}>()", arg.maybe_par()),
+                                Applicability::MaybeIncorrect,
+                            );
+                        } else if from_pointee_ty == to_pointee_ty
+                            && let Some(method) = match (from_mutbl, to_mutbl) {
+                                (ty::Mutability::Not, ty::Mutability::Mut) => Some("cast_mut"),
+                                (ty::Mutability::Mut, ty::Mutability::Not) => Some("cast_const"),
+                                _ => None,
+                            }
+                            && !from_pointee_ty.has_erased_regions()
+                            && msrv.meets(msrvs::POINTER_CAST_CONSTNESS)
+                        {
+                            diag.span_suggestion_verbose(
+                                e.span,
+                                format!("use `pointer::{method}` instead"),
+                                format!("{}.{method}()", arg.maybe_par()),
+                                Applicability::MaybeIncorrect,
+                            );
+                        } else {
+                            diag.span_suggestion_verbose(
+                                e.span,
+                                "use an `as` cast instead",
+                                arg.as_ty(to_ty),
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
                     }
                 },
             );
diff --git a/tests/ui/ptr_cast_constness.fixed b/tests/ui/ptr_cast_constness.fixed
index 33c0725faad..21ac42196e1 100644
--- a/tests/ui/ptr_cast_constness.fixed
+++ b/tests/ui/ptr_cast_constness.fixed
@@ -46,6 +46,10 @@ fn main() {
     let _ = external!($ptr as *const u32);
 }
 
+fn lifetime_to_static(v: *mut &()) -> *const &'static () {
+    v as _
+}
+
 #[clippy::msrv = "1.64"]
 fn _msrv_1_64() {
     let ptr: *const u32 = &42_u32;
diff --git a/tests/ui/ptr_cast_constness.rs b/tests/ui/ptr_cast_constness.rs
index 24d959856db..5ce590b2b7e 100644
--- a/tests/ui/ptr_cast_constness.rs
+++ b/tests/ui/ptr_cast_constness.rs
@@ -46,6 +46,10 @@ fn main() {
     let _ = external!($ptr as *const u32);
 }
 
+fn lifetime_to_static(v: *mut &()) -> *const &'static () {
+    v as _
+}
+
 #[clippy::msrv = "1.64"]
 fn _msrv_1_64() {
     let ptr: *const u32 = &42_u32;
diff --git a/tests/ui/ptr_cast_constness.stderr b/tests/ui/ptr_cast_constness.stderr
index 322c3585e62..2c52ebd3464 100644
--- a/tests/ui/ptr_cast_constness.stderr
+++ b/tests/ui/ptr_cast_constness.stderr
@@ -32,13 +32,13 @@ LL |     let _ = mut_ptr as *const u32;
    |             ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:64:13
+  --> tests/ui/ptr_cast_constness.rs:68:13
    |
 LL |     let _ = ptr as *mut u32;
    |             ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:65:13
+  --> tests/ui/ptr_cast_constness.rs:69:13
    |
 LL |     let _ = mut_ptr as *const u32;
    |             ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
diff --git a/tests/ui/transmute_ptr_to_ptr.fixed b/tests/ui/transmute_ptr_to_ptr.fixed
index b696a574ae3..39e67b25052 100644
--- a/tests/ui/transmute_ptr_to_ptr.fixed
+++ b/tests/ui/transmute_ptr_to_ptr.fixed
@@ -1,17 +1,19 @@
 #![warn(clippy::transmute_ptr_to_ptr)]
 #![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
 
+use std::mem::transmute;
+
 // Make sure we can modify lifetimes, which is one of the recommended uses
 // of transmute
 
 // Make sure we can do static lifetime transmutes
 unsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {
-    std::mem::transmute::<&'a T, &'static T>(t)
+    transmute::<&'a T, &'static T>(t)
 }
 
 // Make sure we can do non-static lifetime transmutes
 unsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {
-    std::mem::transmute::<&'a T, &'b T>(t)
+    transmute::<&'a T, &'b T>(t)
 }
 
 struct LifetimeParam<'a> {
@@ -27,39 +29,40 @@ fn transmute_ptr_to_ptr() {
     let mut_ptr = &mut 1u32 as *mut u32;
     unsafe {
         // pointer-to-pointer transmutes; bad
-        let _: *const f32 = ptr as *const f32;
-        //~^ ERROR: transmute from a pointer to a pointer
-        //~| NOTE: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
-        let _: *mut f32 = mut_ptr as *mut f32;
-        //~^ ERROR: transmute from a pointer to a pointer
+        let _: *const f32 = ptr.cast::<f32>();
+        //~^ transmute_ptr_to_ptr
+        let _: *mut f32 = mut_ptr.cast::<f32>();
+        //~^ transmute_ptr_to_ptr
         // ref-ref transmutes; bad
         let _: &f32 = &*(&1u32 as *const u32 as *const f32);
-        //~^ ERROR: transmute from a reference to a reference
+        //~^ transmute_ptr_to_ptr
         let _: &f32 = &*(&1f64 as *const f64 as *const f32);
-        //~^ ERROR: transmute from a reference to a reference
+        //~^ transmute_ptr_to_ptr
         //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not
         // the same type
         let _: &mut f32 = &mut *(&mut 1u32 as *mut u32 as *mut f32);
-        //~^ ERROR: transmute from a reference to a reference
+        //~^ transmute_ptr_to_ptr
         let _: &GenericParam<f32> = &*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>);
-        //~^ ERROR: transmute from a reference to a reference
+        //~^ transmute_ptr_to_ptr
         let u64_ref: &u64 = &0u64;
-        let u8_ref: &u8 = unsafe { &*(u64_ref as *const u64 as *const u8) };
-        //~^ ERROR: transmute from a reference to a reference
+        let u8_ref: &u8 = &*(u64_ref as *const u64 as *const u8);
+        //~^ transmute_ptr_to_ptr
+        let _: *const u32 = mut_ptr.cast_const();
+        //~^ transmute_ptr_to_ptr
+        let _: *mut u32 = ptr.cast_mut();
+        //~^ transmute_ptr_to_ptr
     }
 
-    // these are recommendations for solving the above; if these lint we need to update
-    // those suggestions
-    let _ = ptr as *const f32;
-    let _ = mut_ptr as *mut f32;
-    let _ = unsafe { &*(&1u32 as *const u32 as *const f32) };
-    let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) };
-
     // transmute internal lifetimes, should not lint
     let s = "hello world".to_owned();
     let lp = LifetimeParam { s: &s };
-    let _: &LifetimeParam<'static> = unsafe { std::mem::transmute(&lp) };
-    let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
+    let _: &LifetimeParam<'static> = unsafe { transmute(&lp) };
+    let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) };
+}
+
+fn lifetime_to_static(v: *mut &()) -> *const &'static () {
+    unsafe { v as *const &() }
+    //~^ transmute_ptr_to_ptr
 }
 
 // dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
@@ -67,7 +70,37 @@ const _: &() = {
     struct Zst;
     let zst = &Zst;
 
-    unsafe { std::mem::transmute::<&'static Zst, &'static ()>(zst) }
+    unsafe { transmute::<&'static Zst, &'static ()>(zst) }
 };
 
+#[clippy::msrv = "1.37"]
+fn msrv_1_37(ptr: *const u8) {
+    unsafe {
+        let _: *const i8 = ptr as *const i8;
+    }
+}
+
+#[clippy::msrv = "1.38"]
+fn msrv_1_38(ptr: *const u8) {
+    unsafe {
+        let _: *const i8 = ptr.cast::<i8>();
+    }
+}
+
+#[clippy::msrv = "1.64"]
+fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) {
+    unsafe {
+        let _: *mut u8 = ptr as *mut u8;
+        let _: *const u8 = mut_ptr as *const u8;
+    }
+}
+
+#[clippy::msrv = "1.65"]
+fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {
+    unsafe {
+        let _: *mut u8 = ptr.cast_mut();
+        let _: *const u8 = mut_ptr.cast_const();
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs
index 85cc1d7802c..580b2855173 100644
--- a/tests/ui/transmute_ptr_to_ptr.rs
+++ b/tests/ui/transmute_ptr_to_ptr.rs
@@ -1,17 +1,19 @@
 #![warn(clippy::transmute_ptr_to_ptr)]
 #![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
 
+use std::mem::transmute;
+
 // Make sure we can modify lifetimes, which is one of the recommended uses
 // of transmute
 
 // Make sure we can do static lifetime transmutes
 unsafe fn transmute_lifetime_to_static<'a, T>(t: &'a T) -> &'static T {
-    std::mem::transmute::<&'a T, &'static T>(t)
+    transmute::<&'a T, &'static T>(t)
 }
 
 // Make sure we can do non-static lifetime transmutes
 unsafe fn transmute_lifetime<'a, 'b, T>(t: &'a T, u: &'b T) -> &'b T {
-    std::mem::transmute::<&'a T, &'b T>(t)
+    transmute::<&'a T, &'b T>(t)
 }
 
 struct LifetimeParam<'a> {
@@ -27,39 +29,40 @@ fn transmute_ptr_to_ptr() {
     let mut_ptr = &mut 1u32 as *mut u32;
     unsafe {
         // pointer-to-pointer transmutes; bad
-        let _: *const f32 = std::mem::transmute(ptr);
-        //~^ ERROR: transmute from a pointer to a pointer
-        //~| NOTE: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
-        let _: *mut f32 = std::mem::transmute(mut_ptr);
-        //~^ ERROR: transmute from a pointer to a pointer
+        let _: *const f32 = transmute(ptr);
+        //~^ transmute_ptr_to_ptr
+        let _: *mut f32 = transmute(mut_ptr);
+        //~^ transmute_ptr_to_ptr
         // ref-ref transmutes; bad
-        let _: &f32 = std::mem::transmute(&1u32);
-        //~^ ERROR: transmute from a reference to a reference
-        let _: &f32 = std::mem::transmute(&1f64);
-        //~^ ERROR: transmute from a reference to a reference
+        let _: &f32 = transmute(&1u32);
+        //~^ transmute_ptr_to_ptr
+        let _: &f32 = transmute(&1f64);
+        //~^ transmute_ptr_to_ptr
         //:^ this test is here because both f32 and f64 are the same TypeVariant, but they are not
         // the same type
-        let _: &mut f32 = std::mem::transmute(&mut 1u32);
-        //~^ ERROR: transmute from a reference to a reference
-        let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 });
-        //~^ ERROR: transmute from a reference to a reference
+        let _: &mut f32 = transmute(&mut 1u32);
+        //~^ transmute_ptr_to_ptr
+        let _: &GenericParam<f32> = transmute(&GenericParam { t: 1u32 });
+        //~^ transmute_ptr_to_ptr
         let u64_ref: &u64 = &0u64;
-        let u8_ref: &u8 = unsafe { std::mem::transmute(u64_ref) };
-        //~^ ERROR: transmute from a reference to a reference
+        let u8_ref: &u8 = transmute(u64_ref);
+        //~^ transmute_ptr_to_ptr
+        let _: *const u32 = transmute(mut_ptr);
+        //~^ transmute_ptr_to_ptr
+        let _: *mut u32 = transmute(ptr);
+        //~^ transmute_ptr_to_ptr
     }
 
-    // these are recommendations for solving the above; if these lint we need to update
-    // those suggestions
-    let _ = ptr as *const f32;
-    let _ = mut_ptr as *mut f32;
-    let _ = unsafe { &*(&1u32 as *const u32 as *const f32) };
-    let _ = unsafe { &mut *(&mut 1u32 as *mut u32 as *mut f32) };
-
     // transmute internal lifetimes, should not lint
     let s = "hello world".to_owned();
     let lp = LifetimeParam { s: &s };
-    let _: &LifetimeParam<'static> = unsafe { std::mem::transmute(&lp) };
-    let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
+    let _: &LifetimeParam<'static> = unsafe { transmute(&lp) };
+    let _: &GenericParam<&LifetimeParam<'static>> = unsafe { transmute(&GenericParam { t: &lp }) };
+}
+
+fn lifetime_to_static(v: *mut &()) -> *const &'static () {
+    unsafe { transmute(v) }
+    //~^ transmute_ptr_to_ptr
 }
 
 // dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
@@ -67,7 +70,37 @@ const _: &() = {
     struct Zst;
     let zst = &Zst;
 
-    unsafe { std::mem::transmute::<&'static Zst, &'static ()>(zst) }
+    unsafe { transmute::<&'static Zst, &'static ()>(zst) }
 };
 
+#[clippy::msrv = "1.37"]
+fn msrv_1_37(ptr: *const u8) {
+    unsafe {
+        let _: *const i8 = transmute(ptr);
+    }
+}
+
+#[clippy::msrv = "1.38"]
+fn msrv_1_38(ptr: *const u8) {
+    unsafe {
+        let _: *const i8 = transmute(ptr);
+    }
+}
+
+#[clippy::msrv = "1.64"]
+fn msrv_1_64(ptr: *const u8, mut_ptr: *mut u8) {
+    unsafe {
+        let _: *mut u8 = transmute(ptr);
+        let _: *const u8 = transmute(mut_ptr);
+    }
+}
+
+#[clippy::msrv = "1.65"]
+fn msrv_1_65(ptr: *const u8, mut_ptr: *mut u8) {
+    unsafe {
+        let _: *mut u8 = transmute(ptr);
+        let _: *const u8 = transmute(mut_ptr);
+    }
+}
+
 fn main() {}
diff --git a/tests/ui/transmute_ptr_to_ptr.stderr b/tests/ui/transmute_ptr_to_ptr.stderr
index cd1f1f398dc..8801eb943ce 100644
--- a/tests/ui/transmute_ptr_to_ptr.stderr
+++ b/tests/ui/transmute_ptr_to_ptr.stderr
@@ -1,47 +1,155 @@
 error: transmute from a pointer to a pointer
-  --> tests/ui/transmute_ptr_to_ptr.rs:30:29
+  --> tests/ui/transmute_ptr_to_ptr.rs:32:29
    |
-LL |         let _: *const f32 = std::mem::transmute(ptr);
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr as *const f32`
+LL |         let _: *const f32 = transmute(ptr);
+   |                             ^^^^^^^^^^^^^^
    |
    = note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
+help: use `pointer::cast` instead
+   |
+LL |         let _: *const f32 = ptr.cast::<f32>();
+   |                             ~~~~~~~~~~~~~~~~~
 
 error: transmute from a pointer to a pointer
-  --> tests/ui/transmute_ptr_to_ptr.rs:33:27
+  --> tests/ui/transmute_ptr_to_ptr.rs:34:27
+   |
+LL |         let _: *mut f32 = transmute(mut_ptr);
+   |                           ^^^^^^^^^^^^^^^^^^
+   |
+help: use `pointer::cast` instead
    |
-LL |         let _: *mut f32 = std::mem::transmute(mut_ptr);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `mut_ptr as *mut f32`
+LL |         let _: *mut f32 = mut_ptr.cast::<f32>();
+   |                           ~~~~~~~~~~~~~~~~~~~~~
 
 error: transmute from a reference to a reference
-  --> tests/ui/transmute_ptr_to_ptr.rs:36:23
+  --> tests/ui/transmute_ptr_to_ptr.rs:37:23
    |
-LL |         let _: &f32 = std::mem::transmute(&1u32);
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)`
+LL |         let _: &f32 = transmute(&1u32);
+   |                       ^^^^^^^^^^^^^^^^ help: try: `&*(&1u32 as *const u32 as *const f32)`
 
 error: transmute from a reference to a reference
-  --> tests/ui/transmute_ptr_to_ptr.rs:38:23
+  --> tests/ui/transmute_ptr_to_ptr.rs:39:23
    |
-LL |         let _: &f32 = std::mem::transmute(&1f64);
-   |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)`
+LL |         let _: &f32 = transmute(&1f64);
+   |                       ^^^^^^^^^^^^^^^^ help: try: `&*(&1f64 as *const f64 as *const f32)`
 
 error: transmute from a reference to a reference
-  --> tests/ui/transmute_ptr_to_ptr.rs:42:27
+  --> tests/ui/transmute_ptr_to_ptr.rs:43:27
    |
-LL |         let _: &mut f32 = std::mem::transmute(&mut 1u32);
-   |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)`
+LL |         let _: &mut f32 = transmute(&mut 1u32);
+   |                           ^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(&mut 1u32 as *mut u32 as *mut f32)`
 
 error: transmute from a reference to a reference
-  --> tests/ui/transmute_ptr_to_ptr.rs:44:37
+  --> tests/ui/transmute_ptr_to_ptr.rs:45:37
    |
-LL |         let _: &GenericParam<f32> = std::mem::transmute(&GenericParam { t: 1u32 });
-   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)`
+LL |         let _: &GenericParam<f32> = transmute(&GenericParam { t: 1u32 });
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(&GenericParam { t: 1u32 } as *const GenericParam<u32> as *const GenericParam<f32>)`
 
 error: transmute from a reference to a reference
-  --> tests/ui/transmute_ptr_to_ptr.rs:47:36
+  --> tests/ui/transmute_ptr_to_ptr.rs:48:27
+   |
+LL |         let u8_ref: &u8 = transmute(u64_ref);
+   |                           ^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)`
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:50:29
+   |
+LL |         let _: *const u32 = transmute(mut_ptr);
+   |                             ^^^^^^^^^^^^^^^^^^
+   |
+help: use `pointer::cast_const` instead
+   |
+LL |         let _: *const u32 = mut_ptr.cast_const();
+   |                             ~~~~~~~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:52:27
+   |
+LL |         let _: *mut u32 = transmute(ptr);
+   |                           ^^^^^^^^^^^^^^
+   |
+help: use `pointer::cast_mut` instead
+   |
+LL |         let _: *mut u32 = ptr.cast_mut();
+   |                           ~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:64:14
+   |
+LL |     unsafe { transmute(v) }
+   |              ^^^^^^^^^^^^
+   |
+help: use an `as` cast instead
+   |
+LL |     unsafe { v as *const &() }
+   |              ~~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:79:28
+   |
+LL |         let _: *const i8 = transmute(ptr);
+   |                            ^^^^^^^^^^^^^^
+   |
+help: use an `as` cast instead
+   |
+LL |         let _: *const i8 = ptr as *const i8;
+   |                            ~~~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:86:28
+   |
+LL |         let _: *const i8 = transmute(ptr);
+   |                            ^^^^^^^^^^^^^^
+   |
+help: use `pointer::cast` instead
+   |
+LL |         let _: *const i8 = ptr.cast::<i8>();
+   |                            ~~~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:93:26
+   |
+LL |         let _: *mut u8 = transmute(ptr);
+   |                          ^^^^^^^^^^^^^^
+   |
+help: use an `as` cast instead
+   |
+LL |         let _: *mut u8 = ptr as *mut u8;
+   |                          ~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:94:28
+   |
+LL |         let _: *const u8 = transmute(mut_ptr);
+   |                            ^^^^^^^^^^^^^^^^^^
+   |
+help: use an `as` cast instead
+   |
+LL |         let _: *const u8 = mut_ptr as *const u8;
+   |                            ~~~~~~~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:101:26
+   |
+LL |         let _: *mut u8 = transmute(ptr);
+   |                          ^^^^^^^^^^^^^^
+   |
+help: use `pointer::cast_mut` instead
+   |
+LL |         let _: *mut u8 = ptr.cast_mut();
+   |                          ~~~~~~~~~~~~~~
+
+error: transmute from a pointer to a pointer
+  --> tests/ui/transmute_ptr_to_ptr.rs:102:28
+   |
+LL |         let _: *const u8 = transmute(mut_ptr);
+   |                            ^^^^^^^^^^^^^^^^^^
+   |
+help: use `pointer::cast_const` instead
    |
-LL |         let u8_ref: &u8 = unsafe { std::mem::transmute(u64_ref) };
-   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(u64_ref as *const u64 as *const u8)`
+LL |         let _: *const u8 = mut_ptr.cast_const();
+   |                            ~~~~~~~~~~~~~~~~~~~~
 
-error: aborting due to 7 previous errors
+error: aborting due to 16 previous errors
 
diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/tests/ui/transmutes_expressible_as_ptr_casts.fixed
index 51682da4a98..e95054a7ccb 100644
--- a/tests/ui/transmutes_expressible_as_ptr_casts.fixed
+++ b/tests/ui/transmutes_expressible_as_ptr_casts.fixed
@@ -18,7 +18,7 @@ fn main() {
     let ptr_i32 = usize::MAX as *const i32;
 
     // e has type *T, U is *U_0, and either U_0: Sized ...
-    let _ptr_i8_transmute = unsafe { ptr_i32 as *const i8 };
+    let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };
     let _ptr_i8 = ptr_i32 as *const i8;
 
     let slice_ptr = &[0, 1, 2, 3] as *const [i32];
diff --git a/tests/ui/transmutes_expressible_as_ptr_casts.stderr b/tests/ui/transmutes_expressible_as_ptr_casts.stderr
index 2ca44485826..2d74967ede5 100644
--- a/tests/ui/transmutes_expressible_as_ptr_casts.stderr
+++ b/tests/ui/transmutes_expressible_as_ptr_casts.stderr
@@ -11,16 +11,25 @@ error: transmute from a pointer to a pointer
   --> tests/ui/transmutes_expressible_as_ptr_casts.rs:21:38
    |
 LL |     let _ptr_i8_transmute = unsafe { transmute::<*const i32, *const i8>(ptr_i32) };
-   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `ptr_i32 as *const i8`
+   |                                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = note: `-D clippy::transmute-ptr-to-ptr` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ptr)]`
+help: use `pointer::cast` instead
+   |
+LL |     let _ptr_i8_transmute = unsafe { ptr_i32.cast::<i8>() };
+   |                                      ~~~~~~~~~~~~~~~~~~~~
 
 error: transmute from a pointer to a pointer
   --> tests/ui/transmutes_expressible_as_ptr_casts.rs:27:46
    |
 LL |     let _ptr_to_unsized_transmute = unsafe { transmute::<*const [i32], *const [u32]>(slice_ptr) };
-   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `slice_ptr as *const [u32]`
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use an `as` cast instead
+   |
+LL |     let _ptr_to_unsized_transmute = unsafe { slice_ptr as *const [u32] };
+   |                                              ~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: transmute from `*const i32` to `usize` which could be expressed as a pointer cast instead
   --> tests/ui/transmutes_expressible_as_ptr_casts.rs:33:50