From afeb917fca7eaa5b44acd29a60f687024c0ebeac Mon Sep 17 00:00:00 2001
From: rail <12975677+rail-rain@users.noreply.github.com>
Date: Tue, 1 Sep 2020 11:21:48 +1200
Subject: [PATCH] Fix a fp in `transmute_ptr_to_ptr`

Avoid firing the lint when `transmute` in const contexts
as dereferencing raw pointers in consts is unstable. cc #5959
---
 clippy_lints/src/transmute.rs    | 6 ++++--
 tests/ui/transmute_ptr_to_ptr.rs | 8 ++++++++
 2 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/clippy_lints/src/transmute.rs b/clippy_lints/src/transmute.rs
index 50d9c93f9d4..789d124eae2 100644
--- a/clippy_lints/src/transmute.rs
+++ b/clippy_lints/src/transmute.rs
@@ -331,8 +331,9 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
             if let Some(def_id) = cx.qpath_res(qpath, path_expr.hir_id).opt_def_id();
             if match_def_path(cx, def_id, &paths::TRANSMUTE);
             then {
-                // Avoid suggesting from/to bits in const contexts.
+                // Avoid suggesting from/to bits and dereferencing raw pointers in const contexts.
                 // See https://github.com/rust-lang/rust/issues/73736 for progress on making them `const fn`.
+                // And see https://github.com/rust-lang/rust/issues/51911 for dereferencing raw pointers.
                 let const_context = in_constant(cx, e.hir_id);
 
                 let from_ty = cx.typeck_results().expr_ty(&args[0]);
@@ -486,7 +487,8 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                                     Applicability::Unspecified,
                                 );
                             } else {
-                                if cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty) {
+                                if (cx.tcx.erase_regions(&from_ty) != cx.tcx.erase_regions(&to_ty))
+                                    && !const_context {
                                     span_lint_and_then(
                                         cx,
                                         TRANSMUTE_PTR_TO_PTR,
diff --git a/tests/ui/transmute_ptr_to_ptr.rs b/tests/ui/transmute_ptr_to_ptr.rs
index 0d8a322f2b2..26b03bdc740 100644
--- a/tests/ui/transmute_ptr_to_ptr.rs
+++ b/tests/ui/transmute_ptr_to_ptr.rs
@@ -51,4 +51,12 @@ fn transmute_ptr_to_ptr() {
     let _: &GenericParam<&LifetimeParam<'static>> = unsafe { std::mem::transmute(&GenericParam { t: &lp }) };
 }
 
+// dereferencing raw pointers in const contexts, should not lint as it's unstable (issue 5959)
+const _: &() = {
+    struct ZST;
+    let zst = &ZST;
+
+    unsafe { std::mem::transmute::<&'static ZST, &'static ()>(zst) }
+};
+
 fn main() {}