]> git.lizzy.rs Git - rust.git/commitdiff
Move the const casting code into its dedicated file
authorOliver Schneider <github35764891676564198441@oli-obk.de>
Wed, 18 Jul 2018 09:39:17 +0000 (11:39 +0200)
committerOliver Schneider <github35764891676564198441@oli-obk.de>
Wed, 18 Jul 2018 09:39:17 +0000 (11:39 +0200)
src/librustc_mir/interpret/cast.rs
src/librustc_mir/interpret/eval_context.rs

index e69e7a522ab73e62bfdc7d5014db72f3cb7392a5..7bcf4ef6588d53d9335a767b077016d5b798b817 100644 (file)
-use rustc::ty::Ty;
-use rustc::ty::layout::LayoutOf;
+use rustc::ty::{self, Ty};
+use rustc::ty::layout::{self, LayoutOf};
 use syntax::ast::{FloatTy, IntTy, UintTy};
 
 use rustc_apfloat::ieee::{Single, Double};
 use super::{EvalContext, Machine};
-use rustc::mir::interpret::{Scalar, EvalResult, Pointer, PointerArithmetic};
+use rustc::mir::interpret::{Scalar, EvalResult, Pointer, PointerArithmetic, Value, EvalErrorKind};
+use rustc::mir::CastKind;
 use rustc_apfloat::Float;
+use interpret::eval_context::ValTy;
+use interpret::Place;
 
 impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> {
+    crate fn cast(
+        &mut self,
+        src: ValTy<'tcx>,
+        kind: CastKind,
+        dest_ty: Ty<'tcx>,
+        dest: Place,
+    ) -> EvalResult<'tcx> {
+        use rustc::mir::CastKind::*;
+        match kind {
+            Unsize => {
+                let src_layout = self.layout_of(src.ty)?;
+                let dst_layout = self.layout_of(dest_ty)?;
+                self.unsize_into(src.value, src_layout, dest, dst_layout)?;
+            }
+
+            Misc => {
+                if self.type_is_fat_ptr(src.ty) {
+                    match (src.value, self.type_is_fat_ptr(dest_ty)) {
+                        (Value::ByRef { .. }, _) |
+                        // pointers to extern types
+                        (Value::Scalar(_),_) |
+                        // slices and trait objects to other slices/trait objects
+                        (Value::ScalarPair(..), true) => {
+                            let valty = ValTy {
+                                value: src.value,
+                                ty: dest_ty,
+                            };
+                            self.write_value(valty, dest)?;
+                        }
+                        // slices and trait objects to thin pointers (dropping the metadata)
+                        (Value::ScalarPair(data, _), false) => {
+                            let valty = ValTy {
+                                value: Value::Scalar(data),
+                                ty: dest_ty,
+                            };
+                            self.write_value(valty, dest)?;
+                        }
+                    }
+                } else {
+                    let src_layout = self.layout_of(src.ty)?;
+                    match src_layout.variants {
+                        layout::Variants::Single { index } => {
+                            if let Some(def) = src.ty.ty_adt_def() {
+                                let discr_val = def
+                                    .discriminant_for_variant(*self.tcx, index)
+                                    .val;
+                                let defined = self
+                                    .layout_of(dest_ty)
+                                    .unwrap()
+                                    .size
+                                    .bits() as u8;
+                                return self.write_scalar(
+                                    dest,
+                                    Scalar::Bits {
+                                        bits: discr_val,
+                                        defined,
+                                    },
+                                    dest_ty);
+                            }
+                        }
+                        layout::Variants::Tagged { .. } |
+                        layout::Variants::NicheFilling { .. } => {},
+                    }
+
+                    let src_val = self.value_to_scalar(src)?;
+                    let dest_val = self.cast_scalar(src_val, src.ty, dest_ty)?;
+                    let valty = ValTy {
+                        value: Value::Scalar(dest_val),
+                        ty: dest_ty,
+                    };
+                    self.write_value(valty, dest)?;
+                }
+            }
+
+            ReifyFnPointer => {
+                match src.ty.sty {
+                    ty::TyFnDef(def_id, substs) => {
+                        if self.tcx.has_attr(def_id, "rustc_args_required_const") {
+                            bug!("reifying a fn ptr that requires \
+                                    const arguments");
+                        }
+                        let instance: EvalResult<'tcx, _> = ty::Instance::resolve(
+                            *self.tcx,
+                            self.param_env,
+                            def_id,
+                            substs,
+                        ).ok_or_else(|| EvalErrorKind::TooGeneric.into());
+                        let fn_ptr = self.memory.create_fn_alloc(instance?);
+                        let valty = ValTy {
+                            value: Value::Scalar(fn_ptr.into()),
+                            ty: dest_ty,
+                        };
+                        self.write_value(valty, dest)?;
+                    }
+                    ref other => bug!("reify fn pointer on {:?}", other),
+                }
+            }
+
+            UnsafeFnPointer => {
+                match dest_ty.sty {
+                    ty::TyFnPtr(_) => {
+                        let mut src = src;
+                        src.ty = dest_ty;
+                        self.write_value(src, dest)?;
+                    }
+                    ref other => bug!("fn to unsafe fn cast on {:?}", other),
+                }
+            }
+
+            ClosureFnPointer => {
+                match src.ty.sty {
+                    ty::TyClosure(def_id, substs) => {
+                        let substs = self.tcx.subst_and_normalize_erasing_regions(
+                            self.substs(),
+                            ty::ParamEnv::reveal_all(),
+                            &substs,
+                        );
+                        let instance = ty::Instance::resolve_closure(
+                            *self.tcx,
+                            def_id,
+                            substs,
+                            ty::ClosureKind::FnOnce,
+                        );
+                        let fn_ptr = self.memory.create_fn_alloc(instance);
+                        let valty = ValTy {
+                            value: Value::Scalar(fn_ptr.into()),
+                            ty: dest_ty,
+                        };
+                        self.write_value(valty, dest)?;
+                    }
+                    ref other => bug!("closure fn pointer on {:?}", other),
+                }
+            }
+        }
+        Ok(())
+    }
+
     pub(super) fn cast_scalar(
         &self,
         val: Scalar,
index 96d0563c12d5127faa8d28793b747cedabde3d54..fac6e8b69efaba35e83ff9922a710e5f83370d61 100644 (file)
@@ -770,134 +770,8 @@ pub(super) fn eval_rvalue_into_place(
 
             Cast(kind, ref operand, cast_ty) => {
                 debug_assert_eq!(self.monomorphize(cast_ty, self.substs()), dest_ty);
-                use rustc::mir::CastKind::*;
                 let src = self.eval_operand(operand)?;
-                match kind {
-                    Unsize => {
-                        let src_layout = self.layout_of(src.ty)?;
-                        let dst_layout = self.layout_of(dest_ty)?;
-                        self.unsize_into(src.value, src_layout, dest, dst_layout)?;
-                    }
-
-                    Misc => {
-                        if self.type_is_fat_ptr(src.ty) {
-                            match (src.value, self.type_is_fat_ptr(dest_ty)) {
-                                (Value::ByRef { .. }, _) |
-                                // pointers to extern types
-                                (Value::Scalar(_),_) |
-                                // slices and trait objects to other slices/trait objects
-                                (Value::ScalarPair(..), true) => {
-                                    let valty = ValTy {
-                                        value: src.value,
-                                        ty: dest_ty,
-                                    };
-                                    self.write_value(valty, dest)?;
-                                }
-                                // slices and trait objects to thin pointers (dropping the metadata)
-                                (Value::ScalarPair(data, _), false) => {
-                                    let valty = ValTy {
-                                        value: Value::Scalar(data),
-                                        ty: dest_ty,
-                                    };
-                                    self.write_value(valty, dest)?;
-                                }
-                            }
-                        } else {
-                            let src_layout = self.layout_of(src.ty)?;
-                            match src_layout.variants {
-                                layout::Variants::Single { index } => {
-                                    if let Some(def) = src.ty.ty_adt_def() {
-                                        let discr_val = def
-                                            .discriminant_for_variant(*self.tcx, index)
-                                            .val;
-                                        let defined = self
-                                            .layout_of(dest_ty)
-                                            .unwrap()
-                                            .size
-                                            .bits() as u8;
-                                        return self.write_scalar(
-                                            dest,
-                                            Scalar::Bits {
-                                                bits: discr_val,
-                                                defined,
-                                            },
-                                            dest_ty);
-                                    }
-                                }
-                                layout::Variants::Tagged { .. } |
-                                layout::Variants::NicheFilling { .. } => {},
-                            }
-
-                            let src_val = self.value_to_scalar(src)?;
-                            let dest_val = self.cast_scalar(src_val, src.ty, dest_ty)?;
-                            let valty = ValTy {
-                                value: Value::Scalar(dest_val),
-                                ty: dest_ty,
-                            };
-                            self.write_value(valty, dest)?;
-                        }
-                    }
-
-                    ReifyFnPointer => {
-                        match src.ty.sty {
-                            ty::TyFnDef(def_id, substs) => {
-                                if self.tcx.has_attr(def_id, "rustc_args_required_const") {
-                                    bug!("reifying a fn ptr that requires \
-                                          const arguments");
-                                }
-                                let instance: EvalResult<'tcx, _> = ty::Instance::resolve(
-                                    *self.tcx,
-                                    self.param_env,
-                                    def_id,
-                                    substs,
-                                ).ok_or_else(|| EvalErrorKind::TooGeneric.into());
-                                let fn_ptr = self.memory.create_fn_alloc(instance?);
-                                let valty = ValTy {
-                                    value: Value::Scalar(fn_ptr.into()),
-                                    ty: dest_ty,
-                                };
-                                self.write_value(valty, dest)?;
-                            }
-                            ref other => bug!("reify fn pointer on {:?}", other),
-                        }
-                    }
-
-                    UnsafeFnPointer => {
-                        match dest_ty.sty {
-                            ty::TyFnPtr(_) => {
-                                let mut src = src;
-                                src.ty = dest_ty;
-                                self.write_value(src, dest)?;
-                            }
-                            ref other => bug!("fn to unsafe fn cast on {:?}", other),
-                        }
-                    }
-
-                    ClosureFnPointer => {
-                        match src.ty.sty {
-                            ty::TyClosure(def_id, substs) => {
-                                let substs = self.tcx.subst_and_normalize_erasing_regions(
-                                    self.substs(),
-                                    ty::ParamEnv::reveal_all(),
-                                    &substs,
-                                );
-                                let instance = ty::Instance::resolve_closure(
-                                    *self.tcx,
-                                    def_id,
-                                    substs,
-                                    ty::ClosureKind::FnOnce,
-                                );
-                                let fn_ptr = self.memory.create_fn_alloc(instance);
-                                let valty = ValTy {
-                                    value: Value::Scalar(fn_ptr.into()),
-                                    ty: dest_ty,
-                                };
-                                self.write_value(valty, dest)?;
-                            }
-                            ref other => bug!("closure fn pointer on {:?}", other),
-                        }
-                    }
-                }
+                self.cast(src, kind, dest_ty, dest)?;
             }
 
             Discriminant(ref place) => {
@@ -1564,7 +1438,7 @@ fn unsize_into_ptr(
         }
     }
 
-    fn unsize_into(
+    crate fn unsize_into(
         &mut self,
         src: Value,
         src_layout: TyLayout<'tcx>,