about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-05-31 21:06:11 +0000
committerbors <bors@rust-lang.org>2022-05-31 21:06:11 +0000
commite0944922007e1bb4fe59809293acf4364410cccc (patch)
treece23d3b4d851362df6a0ab4f0637de8ea605aa7f
parent0595ea1d12cf745e0a672d05341429ecb0917e66 (diff)
parentdff602fc18be295d1b87196a6eee1c72673e6bb8 (diff)
downloadrust-e0944922007e1bb4fe59809293acf4364410cccc.tar.gz
rust-e0944922007e1bb4fe59809293acf4364410cccc.zip
Auto merge of #97582 - tmiasko:pointer-address-cast, r=oli-obk
Add a pointer to address cast kind

A pointer to address cast are often special-cased. Introduce a dedicated cast kind to make them easy distinguishable.
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs20
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs37
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs13
-rw-r--r--compiler/rustc_const_eval/src/transform/promote_consts.rs16
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs10
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs17
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs15
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs23
-rw-r--r--compiler/rustc_mir_transform/src/dead_store_elimination.rs4
-rw-r--r--src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff2
-rw-r--r--src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff4
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs15
15 files changed, 96 insertions, 94 deletions
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 4a2b2942008..d9d31ab2c89 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2147,6 +2147,18 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         }
                     }
 
+                    CastKind::PointerAddress => {
+                        let ty_from = op.ty(body, tcx);
+                        let cast_ty_from = CastTy::from_ty(ty_from);
+                        let cast_ty_to = CastTy::from_ty(*ty);
+                        match (cast_ty_from, cast_ty_to) {
+                            (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => (),
+                            _ => {
+                                span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty)
+                            }
+                        }
+                    }
+
                     CastKind::Misc => {
                         let ty_from = op.ty(body, tcx);
                         let cast_ty_from = CastTy::from_ty(ty_from);
@@ -2155,7 +2167,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                             (None, _)
                             | (_, None | Some(CastTy::FnPtr))
                             | (Some(CastTy::Float), Some(CastTy::Ptr(_)))
-                            | (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Float)) => {
+                            | (
+                                Some(CastTy::Ptr(_) | CastTy::FnPtr),
+                                Some(CastTy::Float | CastTy::Int(_)),
+                            ) => {
                                 span_mirbug!(self, rvalue, "Invalid cast {:?} -> {:?}", ty_from, ty,)
                             }
                             (
@@ -2163,8 +2178,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 Some(CastTy::Int(_) | CastTy::Float | CastTy::Ptr(_)),
                             )
                             | (Some(CastTy::Float), Some(CastTy::Int(_) | CastTy::Float))
-                            | (Some(CastTy::Ptr(_)), Some(CastTy::Int(_) | CastTy::Ptr(_)))
-                            | (Some(CastTy::FnPtr), Some(CastTy::Int(_) | CastTy::Ptr(_))) => (),
+                            | (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Ptr(_))) => (),
                         }
                     }
                 }
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 3fe112d794b..7c59ce354c0 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -607,7 +607,7 @@ fn codegen_stmt<'tcx>(
                     let operand = codegen_operand(fx, operand);
                     lval.write_cvalue(fx, operand.cast_pointer_to(to_layout));
                 }
-                Rvalue::Cast(CastKind::Misc, ref operand, to_ty) => {
+                Rvalue::Cast(CastKind::Misc | CastKind::PointerAddress, ref operand, to_ty) => {
                     let operand = codegen_operand(fx, operand);
                     let from_ty = operand.layout().ty;
                     let to_ty = fx.monomorphize(to_ty);
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index fd29c9e281b..bd88aa33372 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -181,6 +181,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let cast = bx.cx().layout_of(self.monomorphize(mir_cast_ty));
 
                 let val = match *kind {
+                    mir::CastKind::PointerAddress => {
+                        assert!(bx.cx().is_backend_immediate(cast));
+                        let llptr = operand.immediate();
+                        let llcast_ty = bx.cx().immediate_backend_type(cast);
+                        let lladdr = bx.ptrtoint(llptr, llcast_ty);
+                        OperandValue::Immediate(lladdr)
+                    }
                     mir::CastKind::Pointer(PointerCast::ReifyFnPointer) => {
                         match *operand.layout.ty.kind() {
                             ty::FnDef(def_id, substs) => {
@@ -362,9 +369,6 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                             (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Ptr(_)) => {
                                 bx.pointercast(llval, ll_t_out)
                             }
-                            (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
-                                bx.ptrtoint(llval, ll_t_out)
-                            }
                             (CastTy::Int(_), CastTy::Ptr(_)) => {
                                 let usize_llval = bx.intcast(llval, bx.cx().type_isize(), signed);
                                 bx.inttoptr(usize_llval, ll_t_out)
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index be34a77bdba..af563c1450e 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -1,3 +1,4 @@
+use std::assert_matches::assert_matches;
 use std::convert::TryFrom;
 
 use rustc_apfloat::ieee::{Double, Single};
@@ -30,6 +31,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.unsize_into(src, cast_ty, dest)?;
             }
 
+            PointerAddress => {
+                let src = self.read_immediate(src)?;
+                let res = self.pointer_address_cast(&src, cast_ty)?;
+                self.write_immediate(res, dest)?;
+            }
+
             Misc => {
                 let src = self.read_immediate(src)?;
                 let res = self.misc_cast(&src, cast_ty)?;
@@ -174,23 +181,23 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 
         // # The remaining source values are scalar and "int-like".
         let scalar = src.to_scalar()?;
+        Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
+    }
 
-        // If we are casting from a pointer to something
-        // that is not a pointer, mark the pointer as exposed
-        if src.layout.ty.is_any_ptr() && !cast_ty.is_any_ptr() {
-            let ptr = self.scalar_to_ptr(scalar)?;
-
-            match ptr.into_pointer_or_addr() {
-                Ok(ptr) => {
-                    M::expose_ptr(self, ptr)?;
-                }
-                Err(_) => {
-                    // do nothing, exposing an invalid pointer
-                    // has no meaning
-                }
-            };
-        }
+    pub fn pointer_address_cast(
+        &mut self,
+        src: &ImmTy<'tcx, M::PointerTag>,
+        cast_ty: Ty<'tcx>,
+    ) -> InterpResult<'tcx, Immediate<M::PointerTag>> {
+        assert_matches!(src.layout.ty.kind(), ty::RawPtr(_) | ty::FnPtr(_));
+        assert!(cast_ty.is_integral());
 
+        let scalar = src.to_scalar()?;
+        let ptr = self.scalar_to_ptr(scalar)?;
+        match ptr.into_pointer_or_addr() {
+            Ok(ptr) => M::expose_ptr(self, ptr)?,
+            Err(_) => {} // do nothing, exposing an invalid pointer has no meaning
+        };
         Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
     }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index eea6e2a47a9..4ef33d62a6b 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -8,7 +8,6 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{ImplSource, Obligation, ObligationCause};
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
-use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::subst::{GenericArgKind, InternalSubsts};
 use rustc_middle::ty::{self, adjustment::PointerCast, Instance, InstanceDef, Ty, TyCtxt};
 use rustc_middle::ty::{Binder, TraitPredicate, TraitRef, TypeFoldable};
@@ -543,16 +542,12 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 // in the type of any local, which also excludes casts).
             }
 
-            Rvalue::Cast(CastKind::Misc, ref operand, cast_ty) => {
-                let operand_ty = operand.ty(self.body, self.tcx);
-                let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
-                let cast_out = CastTy::from_ty(cast_ty).expect("bad output type for cast");
-
-                if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
-                    self.check_op(ops::RawPtrToIntCast);
-                }
+            Rvalue::Cast(CastKind::PointerAddress, _, _) => {
+                self.check_op(ops::RawPtrToIntCast);
             }
 
+            Rvalue::Cast(CastKind::Misc, _, _) => {}
+
             Rvalue::NullaryOp(NullOp::SizeOf | NullOp::AlignOf, _) => {}
             Rvalue::ShallowInitBox(_, _) => {}
 
diff --git a/compiler/rustc_const_eval/src/transform/promote_consts.rs b/compiler/rustc_const_eval/src/transform/promote_consts.rs
index fc6b8a1a723..ea23bd14d25 100644
--- a/compiler/rustc_const_eval/src/transform/promote_consts.rs
+++ b/compiler/rustc_const_eval/src/transform/promote_consts.rs
@@ -16,7 +16,6 @@ use rustc_hir as hir;
 use rustc_middle::mir::traversal::ReversePostorderIter;
 use rustc_middle::mir::visit::{MutVisitor, MutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
-use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::subst::InternalSubsts;
 use rustc_middle::ty::{self, List, TyCtxt, TypeFoldable};
 use rustc_span::Span;
@@ -502,18 +501,11 @@ impl<'tcx> Validator<'_, 'tcx> {
 
             Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
 
-            Rvalue::Cast(kind, operand, cast_ty) => {
-                if matches!(kind, CastKind::Misc) {
-                    let operand_ty = operand.ty(self.body, self.tcx);
-                    let cast_in = CastTy::from_ty(operand_ty).expect("bad input type for cast");
-                    let cast_out = CastTy::from_ty(*cast_ty).expect("bad output type for cast");
-                    if let (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) = (cast_in, cast_out) {
-                        // ptr-to-int casts are not possible in consts and thus not promotable
-                        return Err(Unpromotable);
-                    }
-                    // int-to-ptr casts are fine, they just use the integer value at pointer type.
-                }
+            // ptr-to-int casts are not possible in consts and thus not promotable
+            Rvalue::Cast(CastKind::PointerAddress, _, _) => return Err(Unpromotable),
 
+            // int-to-ptr casts are fine, they just use the integer value at pointer type.
+            Rvalue::Cast(_, operand, _) => {
                 self.validate_operand(operand)?;
             }
 
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index b09d39996f4..1b63c8d67ca 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2604,9 +2604,19 @@ pub enum Rvalue<'tcx> {
 #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
 static_assert_size!(Rvalue<'_>, 40);
 
+impl<'tcx> Rvalue<'tcx> {
+    #[inline]
+    pub fn is_pointer_int_cast(&self) -> bool {
+        matches!(self, Rvalue::Cast(CastKind::PointerAddress, _, _))
+    }
+}
+
 #[derive(Clone, Copy, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
 pub enum CastKind {
     Misc,
+    /// A pointer to address cast. A cast between a pointer and an integer type,
+    /// or between a function pointer and an integer type.
+    PointerAddress,
     Pointer(PointerCast),
 }
 
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index f1fb484a801..c93b7a95502 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -4,7 +4,6 @@
  */
 
 use crate::mir::*;
-use crate::ty::cast::CastTy;
 use crate::ty::subst::Subst;
 use crate::ty::{self, Ty, TyCtxt};
 use rustc_hir as hir;
@@ -224,22 +223,6 @@ impl<'tcx> Rvalue<'tcx> {
             _ => RvalueInitializationState::Deep,
         }
     }
-
-    pub fn is_pointer_int_cast<D>(&self, local_decls: &D, tcx: TyCtxt<'tcx>) -> bool
-    where
-        D: HasLocalDecls<'tcx>,
-    {
-        if let Rvalue::Cast(CastKind::Misc, src_op, dest_ty) = self {
-            if let Some(CastTy::Int(_)) = CastTy::from_ty(*dest_ty) {
-                let src_ty = src_op.ty(local_decls, tcx);
-                if let Some(CastTy::FnPtr | CastTy::Ptr(_)) = CastTy::from_ty(src_ty) {
-                    return true;
-                }
-            }
-        }
-
-        false
-    }
 }
 
 impl<'tcx> Operand<'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index 0a0c7659b08..2b137046c7f 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -11,6 +11,7 @@ use rustc_middle::mir::AssertKind;
 use rustc_middle::mir::Place;
 use rustc_middle::mir::*;
 use rustc_middle::thir::*;
+use rustc_middle::ty::cast::CastTy;
 use rustc_middle::ty::{self, Ty, UpvarSubsts};
 use rustc_span::Span;
 
@@ -188,11 +189,19 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 block.and(Rvalue::Use(Operand::Move(Place::from(result))))
             }
             ExprKind::Cast { source } => {
+                let source = &this.thir[source];
+                let from_ty = CastTy::from_ty(source.ty);
+                let cast_ty = CastTy::from_ty(expr.ty);
+                let cast_kind = match (from_ty, cast_ty) {
+                    (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
+                        CastKind::PointerAddress
+                    }
+                    (_, _) => CastKind::Misc,
+                };
                 let source = unpack!(
-                    block =
-                        this.as_operand(block, scope, &this.thir[source], None, NeedsTemporary::No)
+                    block = this.as_operand(block, scope, source, None, NeedsTemporary::No)
                 );
-                block.and(Rvalue::Cast(CastKind::Misc, source, expr.ty))
+                block.and(Rvalue::Cast(cast_kind, source, expr.ty))
             }
             ExprKind::Pointer { cast, source } => {
                 let source = unpack!(
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
index 4350eb6cdd3..7076fbe1bdb 100644
--- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs
+++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs
@@ -1,7 +1,6 @@
 use rustc_index::bit_set::{BitSet, ChunkedBitSet};
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
-use rustc_middle::mir::{self, Local, LocalDecls, Location, Place, StatementKind};
-use rustc_middle::ty::TyCtxt;
+use rustc_middle::mir::{self, Local, Location, Place, StatementKind};
 
 use crate::{Analysis, AnalysisDomain, Backward, CallReturnPlaces, GenKill, GenKillAnalysis};
 
@@ -193,27 +192,21 @@ impl DefUse {
 /// This is basically written for dead store elimination and nothing else.
 ///
 /// All of the caveats of `MaybeLiveLocals` apply.
-pub struct MaybeTransitiveLiveLocals<'a, 'tcx> {
+pub struct MaybeTransitiveLiveLocals<'a> {
     always_live: &'a BitSet<Local>,
-    local_decls: &'a LocalDecls<'tcx>,
-    tcx: TyCtxt<'tcx>,
 }
 
-impl<'a, 'tcx> MaybeTransitiveLiveLocals<'a, 'tcx> {
+impl<'a> MaybeTransitiveLiveLocals<'a> {
     /// The `always_alive` set is the set of locals to which all stores should unconditionally be
     /// considered live.
     ///
     /// This should include at least all locals that are ever borrowed.
-    pub fn new(
-        always_live: &'a BitSet<Local>,
-        local_decls: &'a LocalDecls<'tcx>,
-        tcx: TyCtxt<'tcx>,
-    ) -> Self {
-        MaybeTransitiveLiveLocals { always_live, local_decls, tcx }
+    pub fn new(always_live: &'a BitSet<Local>) -> Self {
+        MaybeTransitiveLiveLocals { always_live }
     }
 }
 
-impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a, 'tcx> {
+impl<'a, 'tcx> AnalysisDomain<'tcx> for MaybeTransitiveLiveLocals<'a> {
     type Domain = ChunkedBitSet<Local>;
     type Direction = Backward;
 
@@ -241,7 +234,7 @@ impl<'a> GenKill<Local> for TransferWrapper<'a> {
     }
 }
 
-impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a, 'tcx> {
+impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
     fn apply_statement_effect(
         &self,
         trans: &mut Self::Domain,
@@ -251,7 +244,7 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a, 'tcx> {
         // Compute the place that we are storing to, if any
         let destination = match &statement.kind {
             StatementKind::Assign(assign) => {
-                if assign.1.is_pointer_int_cast(self.local_decls, self.tcx) {
+                if assign.1.is_pointer_int_cast() {
                     // Pointer to int casts may be side-effects due to exposing the provenance.
                     // While the model is undecided, we should be conservative. See
                     // <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
diff --git a/compiler/rustc_mir_transform/src/dead_store_elimination.rs b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
index 84f2ee639e4..8becac34ed7 100644
--- a/compiler/rustc_mir_transform/src/dead_store_elimination.rs
+++ b/compiler/rustc_mir_transform/src/dead_store_elimination.rs
@@ -24,7 +24,7 @@ use rustc_mir_dataflow::{impls::MaybeTransitiveLiveLocals, Analysis};
 /// The `borrowed` set must be a `BitSet` of all the locals that are ever borrowed in this body. It
 /// can be generated via the [`get_borrowed_locals`] function.
 pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitSet<Local>) {
-    let mut live = MaybeTransitiveLiveLocals::new(borrowed, &body.local_decls, tcx)
+    let mut live = MaybeTransitiveLiveLocals::new(borrowed)
         .into_engine(tcx, body)
         .iterate_to_fixpoint()
         .into_results_cursor(body);
@@ -34,7 +34,7 @@ pub fn eliminate<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>, borrowed: &BitS
         for (statement_index, statement) in bb_data.statements.iter().enumerate().rev() {
             let loc = Location { block: bb, statement_index };
             if let StatementKind::Assign(assign) = &statement.kind {
-                if assign.1.is_pointer_int_cast(&body.local_decls, tcx) {
+                if assign.1.is_pointer_int_cast() {
                     continue;
                 }
             }
diff --git a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
index 466c286c9d7..4fdd4b2b4bb 100644
--- a/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/const_prop_fails_gracefully.main.ConstProp.diff
@@ -21,7 +21,7 @@
                                            // + span: $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
                                            // + literal: Const { ty: &i32, val: Unevaluated(FOO, [], None) }
           _2 = &raw const (*_3);           // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:16
-          _1 = move _2 as usize (Misc);    // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39
+          _1 = move _2 as usize (PointerAddress); // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:13: 7:39
           StorageDead(_2);                 // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:38: 7:39
           StorageDead(_3);                 // scope 0 at $DIR/const_prop_fails_gracefully.rs:7:39: 7:40
           StorageLive(_4);                 // scope 1 at $DIR/const_prop_fails_gracefully.rs:8:5: 8:12
diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
index 1aeeae91d20..7eb34ed5469 100644
--- a/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
+++ b/src/test/mir-opt/const_prop/reify_fn_ptr.main.ConstProp.diff
@@ -17,7 +17,7 @@
                                            // mir::Constant
                                            // + span: $DIR/reify_fn_ptr.rs:4:13: 4:17
                                            // + literal: Const { ty: fn() {main}, val: Value(Scalar(<ZST>)) }
-          _2 = move _3 as usize (Misc);    // scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:26
+          _2 = move _3 as usize (PointerAddress); // scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:26
           StorageDead(_3);                 // scope 0 at $DIR/reify_fn_ptr.rs:4:25: 4:26
           _1 = move _2 as *const fn() (Misc); // scope 0 at $DIR/reify_fn_ptr.rs:4:13: 4:41
           StorageDead(_2);                 // scope 0 at $DIR/reify_fn_ptr.rs:4:40: 4:41
diff --git a/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
index 2250159c816..bf32245e300 100644
--- a/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
+++ b/src/test/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination.diff
@@ -19,12 +19,12 @@
           StorageLive(_2);                 // scope 0 at $DIR/provenance_soundness.rs:8:9: 8:11
           StorageLive(_3);                 // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:15
           _3 = _1;                         // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:15
-          _2 = move _3 as usize (Misc);    // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:24
+          _2 = move _3 as usize (PointerAddress); // scope 0 at $DIR/provenance_soundness.rs:8:14: 8:24
           StorageDead(_3);                 // scope 0 at $DIR/provenance_soundness.rs:8:23: 8:24
           StorageLive(_4);                 // scope 1 at $DIR/provenance_soundness.rs:9:9: 9:11
           StorageLive(_5);                 // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:15
           _5 = _1;                         // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:15
-          _4 = move _5 as isize (Misc);    // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:24
+          _4 = move _5 as isize (PointerAddress); // scope 1 at $DIR/provenance_soundness.rs:9:14: 9:24
           StorageDead(_5);                 // scope 1 at $DIR/provenance_soundness.rs:9:23: 9:24
           _0 = const ();                   // scope 0 at $DIR/provenance_soundness.rs:7:32: 10:2
           StorageDead(_4);                 // scope 1 at $DIR/provenance_soundness.rs:10:1: 10:2
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 78d8f1e213a..283b20fc24d 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -125,16 +125,11 @@ fn check_rvalue<'tcx>(
         Rvalue::Len(place) | Rvalue::Discriminant(place) | Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => {
             check_place(tcx, *place, span, body)
         },
-        Rvalue::Cast(CastKind::Misc, operand, cast_ty) => {
-            use rustc_middle::ty::cast::CastTy;
-            let cast_in = CastTy::from_ty(operand.ty(body, tcx)).expect("bad input type for cast");
-            let cast_out = CastTy::from_ty(*cast_ty).expect("bad output type for cast");
-            match (cast_in, cast_out) {
-                (CastTy::Ptr(_) | CastTy::FnPtr, CastTy::Int(_)) => {
-                    Err((span, "casting pointers to ints is unstable in const fn".into()))
-                },
-                _ => check_operand(tcx, operand, span, body),
-            }
+        Rvalue::Cast(CastKind::PointerAddress, _, _) => {
+            Err((span, "casting pointers to ints is unstable in const fn".into()))
+        },
+        Rvalue::Cast(CastKind::Misc, operand, _) => {
+            check_operand(tcx, operand, span, body)
         },
         Rvalue::Cast(CastKind::Pointer(PointerCast::MutToConstPointer | PointerCast::ArrayToPointer), operand, _) => {
             check_operand(tcx, operand, span, body)