about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan DPC <99973273+Dylan-DPC@users.noreply.github.com>2022-10-26 17:32:55 +0530
committerGitHub <noreply@github.com>2022-10-26 17:32:55 +0530
commit709462bfe113c20ed780e6ca2d8fe3516be2d124 (patch)
tree9abb6f3a0c855375ad370bdcec2ea70ebd752b75
parent14f601bc8423a961127dc05b9e4e5e1f3cd22bbb (diff)
parent52fda858ddb5f4a6ce2826f7305ac83973a0ad43 (diff)
downloadrust-709462bfe113c20ed780e6ca2d8fe3516be2d124.tar.gz
rust-709462bfe113c20ed780e6ca2d8fe3516be2d124.zip
Rollup merge of #103546 - RalfJung:cast, r=oli-obk
interpret: a bit of cast cleanup

r? `@oli-obk`
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs61
1 files changed, 30 insertions, 31 deletions
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index cb33c4d4c46..269ae15d497 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -138,21 +138,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         Ok(())
     }
 
+    /// Handles 'IntToInt' and 'IntToFloat' casts.
     pub fn int_to_int_or_float(
         &self,
         src: &ImmTy<'tcx, M::Provenance>,
         cast_ty: Ty<'tcx>,
     ) -> InterpResult<'tcx, Immediate<M::Provenance>> {
-        if (src.layout.ty.is_integral() || src.layout.ty.is_char() || src.layout.ty.is_bool())
-            && (cast_ty.is_floating_point() || cast_ty.is_integral() || cast_ty.is_char())
-        {
-            let scalar = src.to_scalar();
-            Ok(self.cast_from_int_like(scalar, src.layout, cast_ty)?.into())
-        } else {
-            bug!("Unexpected cast from type {:?}", src.layout.ty)
-        }
+        assert!(src.layout.ty.is_integral() || src.layout.ty.is_char() || src.layout.ty.is_bool());
+        assert!(cast_ty.is_floating_point() || cast_ty.is_integral() || cast_ty.is_char());
+
+        Ok(self.cast_from_int_like(src.to_scalar(), src.layout, cast_ty)?.into())
     }
 
+    /// Handles 'FloatToFloat' and 'FloatToInt' casts.
     pub fn float_to_float_or_int(
         &self,
         src: &ImmTy<'tcx, M::Provenance>,
@@ -180,31 +178,29 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         src: &ImmTy<'tcx, M::Provenance>,
         cast_ty: Ty<'tcx>,
     ) -> InterpResult<'tcx, Immediate<M::Provenance>> {
+        assert!(src.layout.ty.is_any_ptr());
+        assert!(cast_ty.is_unsafe_ptr());
         // Handle casting any ptr to raw ptr (might be a fat ptr).
-        if src.layout.ty.is_any_ptr() && cast_ty.is_unsafe_ptr() {
-            let dest_layout = self.layout_of(cast_ty)?;
-            if dest_layout.size == src.layout.size {
-                // Thin or fat pointer that just hast the ptr kind of target type changed.
-                return Ok(**src);
-            } else {
-                // Casting the metadata away from a fat ptr.
-                assert_eq!(src.layout.size, 2 * self.pointer_size());
-                assert_eq!(dest_layout.size, self.pointer_size());
-                assert!(src.layout.ty.is_unsafe_ptr());
-                return match **src {
-                    Immediate::ScalarPair(data, _) => Ok(data.into()),
-                    Immediate::Scalar(..) => span_bug!(
-                        self.cur_span(),
-                        "{:?} input to a fat-to-thin cast ({:?} -> {:?})",
-                        *src,
-                        src.layout.ty,
-                        cast_ty
-                    ),
-                    Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
-                };
-            }
+        let dest_layout = self.layout_of(cast_ty)?;
+        if dest_layout.size == src.layout.size {
+            // Thin or fat pointer that just hast the ptr kind of target type changed.
+            return Ok(**src);
         } else {
-            bug!("Can't cast 'Ptr' or 'FnPtr' into {:?}", cast_ty);
+            // Casting the metadata away from a fat ptr.
+            assert_eq!(src.layout.size, 2 * self.pointer_size());
+            assert_eq!(dest_layout.size, self.pointer_size());
+            assert!(src.layout.ty.is_unsafe_ptr());
+            return match **src {
+                Immediate::ScalarPair(data, _) => Ok(data.into()),
+                Immediate::Scalar(..) => span_bug!(
+                    self.cur_span(),
+                    "{:?} input to a fat-to-thin cast ({:?} -> {:?})",
+                    *src,
+                    src.layout.ty,
+                    cast_ty
+                ),
+                Immediate::Uninit => throw_ub!(InvalidUninitBytes(None)),
+            };
         }
     }
 
@@ -243,6 +239,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         Ok(Scalar::from_maybe_pointer(ptr, self).into())
     }
 
+    /// Low-level cast helper function. This works directly on scalars and can take 'int-like' input
+    /// type (basically everything with a scalar layout) to int/float/char types.
     pub fn cast_from_int_like(
         &self,
         scalar: Scalar<M::Provenance>, // input value (there is no ScalarTy so we separate data+layout)
@@ -282,6 +280,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         })
     }
 
+    /// Low-level cast helper function. Converts an apfloat `f` into int or float types.
     fn cast_from_float<F>(&self, f: F, dest_ty: Ty<'tcx>) -> Scalar<M::Provenance>
     where
         F: Float + Into<Scalar<M::Provenance>> + FloatConvert<Single> + FloatConvert<Double>,