]> git.lizzy.rs Git - rust.git/commitdiff
Move a method used everywhere out of `intrinsic.rs`
authorOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Fri, 28 Jul 2017 08:16:36 +0000 (10:16 +0200)
committerOliver Schneider <git-spam-no-reply9815368754983@oli-obk.de>
Tue, 1 Aug 2017 07:56:21 +0000 (09:56 +0200)
src/librustc_mir/interpret/eval_context.rs
src/librustc_mir/interpret/terminator/intrinsic.rs

index 88f9af75f95087f13ceafdd113efdbf75444f640..2b2e1f30c88e151b32c535cf51bd686745e71023 100644 (file)
@@ -7,7 +7,7 @@
 use rustc::middle::region::CodeExtent;
 use rustc::mir;
 use rustc::traits::Reveal;
-use rustc::ty::layout::{self, Layout, Size};
+use rustc::ty::layout::{self, Layout, Size, Align};
 use rustc::ty::subst::{Subst, Substs, Kind};
 use rustc::ty::{self, Ty, TyCtxt, TypeFoldable, Binder};
 use rustc::traits;
@@ -277,6 +277,98 @@ pub fn erase_lifetimes<T>(&self, value: &Binder<T>) -> T
         self.tcx.erase_regions(&value)
     }
 
+    pub fn size_and_align_of_dst(
+        &mut self,
+        ty: ty::Ty<'tcx>,
+        value: Value,
+    ) -> EvalResult<'tcx, (u64, u64)> {
+        if let Some(size) = self.type_size(ty)? {
+            Ok((size as u64, self.type_align(ty)? as u64))
+        } else {
+            match ty.sty {
+                ty::TyAdt(def, substs) => {
+                    // First get the size of all statically known fields.
+                    // Don't use type_of::sizing_type_of because that expects t to be sized,
+                    // and it also rounds up to alignment, which we want to avoid,
+                    // as the unsized field's alignment could be smaller.
+                    assert!(!ty.is_simd());
+                    let layout = self.type_layout(ty)?;
+                    debug!("DST {} layout: {:?}", ty, layout);
+
+                    let (sized_size, sized_align) = match *layout {
+                        ty::layout::Layout::Univariant { ref variant, .. } => {
+                            (variant.offsets.last().map_or(0, |o| o.bytes()), variant.align)
+                        }
+                        _ => {
+                            bug!("size_and_align_of_dst: expcted Univariant for `{}`, found {:#?}",
+                                 ty, layout);
+                        }
+                    };
+                    debug!("DST {} statically sized prefix size: {} align: {:?}",
+                           ty, sized_size, sized_align);
+
+                    // Recurse to get the size of the dynamically sized field (must be
+                    // the last field).
+                    let last_field = def.struct_variant().fields.last().unwrap();
+                    let field_ty = self.field_ty(substs, last_field);
+                    let (unsized_size, unsized_align) = self.size_and_align_of_dst(field_ty, value)?;
+
+                    // FIXME (#26403, #27023): We should be adding padding
+                    // to `sized_size` (to accommodate the `unsized_align`
+                    // required of the unsized field that follows) before
+                    // summing it with `sized_size`. (Note that since #26403
+                    // is unfixed, we do not yet add the necessary padding
+                    // here. But this is where the add would go.)
+
+                    // Return the sum of sizes and max of aligns.
+                    let size = sized_size + unsized_size;
+
+                    // Choose max of two known alignments (combined value must
+                    // be aligned according to more restrictive of the two).
+                    let align = sized_align.max(Align::from_bytes(unsized_align, unsized_align).unwrap());
+
+                    // Issue #27023: must add any necessary padding to `size`
+                    // (to make it a multiple of `align`) before returning it.
+                    //
+                    // Namely, the returned size should be, in C notation:
+                    //
+                    //   `size + ((size & (align-1)) ? align : 0)`
+                    //
+                    // emulated via the semi-standard fast bit trick:
+                    //
+                    //   `(size + (align-1)) & -align`
+
+                    let size = Size::from_bytes(size).abi_align(align).bytes();
+                    Ok((size, align.abi()))
+                }
+                ty::TyDynamic(..) => {
+                    let (_, vtable) = value.into_ptr_vtable_pair(&mut self.memory)?;
+                    // the second entry in the vtable is the dynamic size of the object.
+                    self.read_size_and_align_from_vtable(vtable)
+                }
+
+                ty::TySlice(_) | ty::TyStr => {
+                    let elem_ty = ty.sequence_element_type(self.tcx);
+                    let elem_size = self.type_size(elem_ty)?.expect("slice element must be sized") as u64;
+                    let (_, len) = value.into_slice(&mut self.memory)?;
+                    let align = self.type_align(elem_ty)?;
+                    Ok((len * elem_size, align as u64))
+                }
+
+                _ => bug!("size_of_val::<{:?}>", ty),
+            }
+        }
+    }
+
+    /// Returns the normalized type of a struct field
+    fn field_ty(
+        &self,
+        param_substs: &Substs<'tcx>,
+        f: &ty::FieldDef,
+    ) -> ty::Ty<'tcx> {
+        self.tcx.normalize_associated_type(&f.ty(self.tcx, param_substs))
+    }
+
     pub(super) fn type_size(&self, ty: Ty<'tcx>) -> EvalResult<'tcx, Option<u64>> {
         self.type_size_with_substs(ty, self.substs())
     }
@@ -1556,8 +1648,8 @@ fn unsize_into(
                 let dest = self.force_allocation(dest)?.to_ptr()?;
                 let iter = src_fields.zip(dst_fields).enumerate();
                 for (i, (src_f, dst_f)) in iter {
-                    let src_fty = monomorphize_field_ty(self.tcx, src_f, substs_a);
-                    let dst_fty = monomorphize_field_ty(self.tcx, dst_f, substs_b);
+                    let src_fty = self.field_ty(substs_a, src_f);
+                    let dst_fty = self.field_ty(substs_b, dst_f);
                     if self.type_size(dst_fty)? == Some(0) {
                         continue;
                     }
@@ -1726,12 +1818,6 @@ fn size(self) -> Size {
     }
 }
 
-
-pub fn monomorphize_field_ty<'a, 'tcx:'a >(tcx: TyCtxt<'a, 'tcx, 'tcx>, f: &ty::FieldDef, substs: &'tcx Substs<'tcx>) -> Ty<'tcx> {
-    let substituted = f.ty(tcx, substs);
-    tcx.normalize_associated_type(&substituted)
-}
-
 pub fn is_inhabited<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty: Ty<'tcx>) -> bool {
     ty.uninhabited_from(&mut HashMap::default(), tcx).is_empty()
 }
index 116387051041f8de2739fea6f0dc3d9e2214a1fa..7c81b76ba416915bd4b767cf1e7ec720d2f8a15e 100644 (file)
@@ -1,7 +1,6 @@
 use rustc::mir;
 use rustc::traits::Reveal;
-use rustc::ty::layout::{Layout, Size, Align};
-use rustc::ty::subst::Substs;
+use rustc::ty::layout::Layout;
 use rustc::ty::{self, Ty};
 
 use interpret::{
@@ -487,97 +486,6 @@ pub(super) fn call_intrinsic(
         // current frame.
         Ok(())
     }
-
-    pub fn size_and_align_of_dst(
-        &mut self,
-        ty: ty::Ty<'tcx>,
-        value: Value,
-    ) -> EvalResult<'tcx, (u64, u64)> {
-        if let Some(size) = self.type_size(ty)? {
-            Ok((size as u64, self.type_align(ty)? as u64))
-        } else {
-            match ty.sty {
-                ty::TyAdt(def, substs) => {
-                    // First get the size of all statically known fields.
-                    // Don't use type_of::sizing_type_of because that expects t to be sized,
-                    // and it also rounds up to alignment, which we want to avoid,
-                    // as the unsized field's alignment could be smaller.
-                    assert!(!ty.is_simd());
-                    let layout = self.type_layout(ty)?;
-                    debug!("DST {} layout: {:?}", ty, layout);
-
-                    let (sized_size, sized_align) = match *layout {
-                        ty::layout::Layout::Univariant { ref variant, .. } => {
-                            (variant.offsets.last().map_or(0, |o| o.bytes()), variant.align)
-                        }
-                        _ => {
-                            bug!("size_and_align_of_dst: expcted Univariant for `{}`, found {:#?}",
-                                 ty, layout);
-                        }
-                    };
-                    debug!("DST {} statically sized prefix size: {} align: {:?}",
-                           ty, sized_size, sized_align);
-
-                    // Recurse to get the size of the dynamically sized field (must be
-                    // the last field).
-                    let last_field = def.struct_variant().fields.last().unwrap();
-                    let field_ty = self.field_ty(substs, last_field);
-                    let (unsized_size, unsized_align) = self.size_and_align_of_dst(field_ty, value)?;
-
-                    // FIXME (#26403, #27023): We should be adding padding
-                    // to `sized_size` (to accommodate the `unsized_align`
-                    // required of the unsized field that follows) before
-                    // summing it with `sized_size`. (Note that since #26403
-                    // is unfixed, we do not yet add the necessary padding
-                    // here. But this is where the add would go.)
-
-                    // Return the sum of sizes and max of aligns.
-                    let size = sized_size + unsized_size;
-
-                    // Choose max of two known alignments (combined value must
-                    // be aligned according to more restrictive of the two).
-                    let align = sized_align.max(Align::from_bytes(unsized_align, unsized_align).unwrap());
-
-                    // Issue #27023: must add any necessary padding to `size`
-                    // (to make it a multiple of `align`) before returning it.
-                    //
-                    // Namely, the returned size should be, in C notation:
-                    //
-                    //   `size + ((size & (align-1)) ? align : 0)`
-                    //
-                    // emulated via the semi-standard fast bit trick:
-                    //
-                    //   `(size + (align-1)) & -align`
-
-                    let size = Size::from_bytes(size).abi_align(align).bytes();
-                    Ok((size, align.abi()))
-                }
-                ty::TyDynamic(..) => {
-                    let (_, vtable) = value.into_ptr_vtable_pair(&self.memory)?;
-                    // the second entry in the vtable is the dynamic size of the object.
-                    self.read_size_and_align_from_vtable(vtable)
-                }
-
-                ty::TySlice(_) | ty::TyStr => {
-                    let elem_ty = ty.sequence_element_type(self.tcx);
-                    let elem_size = self.type_size(elem_ty)?.expect("slice element must be sized") as u64;
-                    let (_, len) = value.into_slice(&self.memory)?;
-                    let align = self.type_align(elem_ty)?;
-                    Ok((len * elem_size, align as u64))
-                }
-
-                _ => bug!("size_of_val::<{:?}>", ty),
-            }
-        }
-    }
-    /// Returns the normalized type of a struct field
-    fn field_ty(
-        &self,
-        param_substs: &Substs<'tcx>,
-        f: &ty::FieldDef,
-    ) -> ty::Ty<'tcx> {
-        self.tcx.normalize_associated_type(&f.ty(self.tcx, param_substs))
-    }
 }
 
 fn numeric_intrinsic<'tcx>(