about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2017-10-10 20:55:21 +0300
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2017-11-19 02:43:55 +0200
commitfa67abd12707c34a2def10247c22c336f82cd2c2 (patch)
tree64e70b9c296d09188d5628de3860cf9df4c94755 /src
parent18ecc564f2cee4da3ef9397ba58e19d3fd9be3de (diff)
downloadrust-fa67abd12707c34a2def10247c22c336f82cd2c2.tar.gz
rust-fa67abd12707c34a2def10247c22c336f82cd2c2.zip
rustc: don't special-case Box<T> as having a pointer layout.
Diffstat (limited to 'src')
-rw-r--r--src/liballoc/boxed.rs18
-rw-r--r--src/librustc/ty/layout.rs168
-rw-r--r--src/librustc_trans/type_of.rs21
3 files changed, 98 insertions, 109 deletions
diff --git a/src/liballoc/boxed.rs b/src/liballoc/boxed.rs
index 79292d390e5..2226cee6e36 100644
--- a/src/liballoc/boxed.rs
+++ b/src/liballoc/boxed.rs
@@ -151,7 +151,7 @@ impl<T> Place<T> for IntermediateBox<T> {
 unsafe fn finalize<T>(b: IntermediateBox<T>) -> Box<T> {
     let p = b.ptr as *mut T;
     mem::forget(b);
-    mem::transmute(p)
+    Box::from_raw(p)
 }
 
 fn make_place<T>() -> IntermediateBox<T> {
@@ -300,7 +300,10 @@ impl<T: ?Sized> Box<T> {
                issue = "27730")]
     #[inline]
     pub unsafe fn from_unique(u: Unique<T>) -> Self {
-        mem::transmute(u)
+        #[cfg(stage0)]
+        return mem::transmute(u);
+        #[cfg(not(stage0))]
+        return Box(u);
     }
 
     /// Consumes the `Box`, returning the wrapped raw pointer.
@@ -362,7 +365,14 @@ impl<T: ?Sized> Box<T> {
                issue = "27730")]
     #[inline]
     pub fn into_unique(b: Box<T>) -> Unique<T> {
-        unsafe { mem::transmute(b) }
+        #[cfg(stage0)]
+        return unsafe { mem::transmute(b) };
+        #[cfg(not(stage0))]
+        return {
+            let unique = b.0;
+            mem::forget(b);
+            unique
+        };
     }
 }
 
@@ -627,7 +637,7 @@ impl Box<Any + Send> {
     pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> {
         <Box<Any>>::downcast(self).map_err(|s| unsafe {
             // reapply the Send marker
-            mem::transmute::<Box<Any>, Box<Any + Send>>(s)
+            Box::from_raw(Box::into_raw(s) as *mut (Any + Send))
         })
     }
 }
diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs
index fc5d4213949..761897f6266 100644
--- a/src/librustc/ty/layout.rs
+++ b/src/librustc/ty/layout.rs
@@ -1152,37 +1152,6 @@ impl<'a, 'tcx> CachedLayout {
         };
         assert!(!ty.has_infer_types());
 
-        let ptr_layout = |pointee: Ty<'tcx>| {
-            let mut data_ptr = scalar_unit(Pointer);
-            if !ty.is_unsafe_ptr() {
-                data_ptr.valid_range.start = 1;
-            }
-
-            let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
-            if pointee.is_sized(tcx, param_env, DUMMY_SP) {
-                return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
-            }
-
-            let unsized_part = tcx.struct_tail(pointee);
-            let metadata = match unsized_part.sty {
-                ty::TyForeign(..) => {
-                    return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
-                }
-                ty::TySlice(_) | ty::TyStr => {
-                    scalar_unit(Int(dl.ptr_sized_integer(), false))
-                }
-                ty::TyDynamic(..) => {
-                    let mut vtable = scalar_unit(Pointer);
-                    vtable.valid_range.start = 1;
-                    vtable
-                }
-                _ => return Err(LayoutError::Unknown(unsized_part))
-            };
-
-            // Effectively a (ptr, meta) tuple.
-            Ok(tcx.intern_layout(scalar_pair(data_ptr, metadata)))
-        };
-
         Ok(match ty.sty {
             // Basic scalars.
             ty::TyBool => {
@@ -1219,10 +1188,34 @@ impl<'a, 'tcx> CachedLayout {
             // Potentially-fat pointers.
             ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
             ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                ptr_layout(pointee)?
-            }
-            ty::TyAdt(def, _) if def.is_box() => {
-                ptr_layout(ty.boxed_ty())?
+                let mut data_ptr = scalar_unit(Pointer);
+                if !ty.is_unsafe_ptr() {
+                    data_ptr.valid_range.start = 1;
+                }
+
+                let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
+                if pointee.is_sized(tcx, param_env, DUMMY_SP) {
+                    return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
+                }
+
+                let unsized_part = tcx.struct_tail(pointee);
+                let metadata = match unsized_part.sty {
+                    ty::TyForeign(..) => {
+                        return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
+                    }
+                    ty::TySlice(_) | ty::TyStr => {
+                        scalar_unit(Int(dl.ptr_sized_integer(), false))
+                    }
+                    ty::TyDynamic(..) => {
+                        let mut vtable = scalar_unit(Pointer);
+                        vtable.valid_range.start = 1;
+                        vtable
+                    }
+                    _ => return Err(LayoutError::Unknown(unsized_part))
+                };
+
+                // Effectively a (ptr, meta) tuple.
+                tcx.intern_layout(scalar_pair(data_ptr, metadata))
             }
 
             // Arrays and slices.
@@ -1861,32 +1854,25 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
             Err(err) => err
         };
 
-        let ptr_skeleton = |pointee: Ty<'tcx>| {
-            let non_zero = !ty.is_unsafe_ptr();
-            let tail = tcx.struct_tail(pointee);
-            match tail.sty {
-                ty::TyParam(_) | ty::TyProjection(_) => {
-                    assert!(tail.has_param_types() || tail.has_self_ty());
-                    Ok(SizeSkeleton::Pointer {
-                        non_zero,
-                        tail: tcx.erase_regions(&tail)
-                    })
-                }
-                _ => {
-                    bug!("SizeSkeleton::compute({}): layout errored ({}), yet \
-                            tail `{}` is not a type parameter or a projection",
-                            ty, err, tail)
-                }
-            }
-        };
-
         match ty.sty {
             ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
             ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                ptr_skeleton(pointee)
-            }
-            ty::TyAdt(def, _) if def.is_box() => {
-                ptr_skeleton(ty.boxed_ty())
+                let non_zero = !ty.is_unsafe_ptr();
+                let tail = tcx.struct_tail(pointee);
+                match tail.sty {
+                    ty::TyParam(_) | ty::TyProjection(_) => {
+                        assert!(tail.has_param_types() || tail.has_self_ty());
+                        Ok(SizeSkeleton::Pointer {
+                            non_zero,
+                            tail: tcx.erase_regions(&tail)
+                        })
+                    }
+                    _ => {
+                        bug!("SizeSkeleton::compute({}): layout errored ({}), yet \
+                              tail `{}` is not a type parameter or a projection",
+                             ty, err, tail)
+                    }
+                }
             }
 
             ty::TyAdt(def, substs) => {
@@ -2148,39 +2134,6 @@ impl<'a, 'tcx> TyLayout<'tcx> {
               C::TyLayout: MaybeResult<TyLayout<'tcx>>
     {
         let tcx = cx.tcx();
-        let ptr_field_layout = |pointee: Ty<'tcx>| {
-            assert!(i < 2);
-
-            // Reuse the fat *T type as its own thin pointer data field.
-            // This provides information about e.g. DST struct pointees
-            // (which may have no non-DST form), and will work as long
-            // as the `Abi` or `FieldPlacement` is checked by users.
-            if i == 0 {
-                let nil = tcx.mk_nil();
-                let ptr_ty = if self.ty.is_unsafe_ptr() {
-                    tcx.mk_mut_ptr(nil)
-                } else {
-                    tcx.mk_mut_ref(tcx.types.re_static, nil)
-                };
-                return cx.layout_of(ptr_ty).map_same(|mut ptr_layout| {
-                    ptr_layout.ty = self.ty;
-                    ptr_layout
-                });
-            }
-
-            let meta_ty = match tcx.struct_tail(pointee).sty {
-                ty::TySlice(_) |
-                ty::TyStr => tcx.types.usize,
-                ty::TyDynamic(..) => {
-                    // FIXME(eddyb) use an usize/fn() array with
-                    // the correct number of vtables slots.
-                    tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil())
-                }
-                _ => bug!("TyLayout::field_type({:?}): not applicable", self)
-            };
-            cx.layout_of(meta_ty)
-        };
-
         cx.layout_of(match self.ty.sty {
             ty::TyBool |
             ty::TyChar |
@@ -2198,10 +2151,35 @@ impl<'a, 'tcx> TyLayout<'tcx> {
             // Potentially-fat pointers.
             ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
             ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
-                return ptr_field_layout(pointee);
-            }
-            ty::TyAdt(def, _) if def.is_box() => {
-                return ptr_field_layout(self.ty.boxed_ty());
+                assert!(i < 2);
+
+                // Reuse the fat *T type as its own thin pointer data field.
+                // This provides information about e.g. DST struct pointees
+                // (which may have no non-DST form), and will work as long
+                // as the `Abi` or `FieldPlacement` is checked by users.
+                if i == 0 {
+                    let nil = tcx.mk_nil();
+                    let ptr_ty = if self.ty.is_unsafe_ptr() {
+                        tcx.mk_mut_ptr(nil)
+                    } else {
+                        tcx.mk_mut_ref(tcx.types.re_static, nil)
+                    };
+                    return cx.layout_of(ptr_ty).map_same(|mut ptr_layout| {
+                        ptr_layout.ty = self.ty;
+                        ptr_layout
+                    });
+                }
+
+                match tcx.struct_tail(pointee).sty {
+                    ty::TySlice(_) |
+                    ty::TyStr => tcx.types.usize,
+                    ty::TyDynamic(..) => {
+                        // FIXME(eddyb) use an usize/fn() array with
+                        // the correct number of vtables slots.
+                        tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil())
+                    }
+                    _ => bug!("TyLayout::field_type({:?}): not applicable", self)
+                }
             }
 
             // Arrays and slices.
diff --git a/src/librustc_trans/type_of.rs b/src/librustc_trans/type_of.rs
index 35da258cdb3..60e5e4ced2c 100644
--- a/src/librustc_trans/type_of.rs
+++ b/src/librustc_trans/type_of.rs
@@ -321,7 +321,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
                 return self.field(ccx, index).llvm_type(ccx);
             }
             ty::TyAdt(def, _) if def.is_box() => {
-                return self.field(ccx, index).llvm_type(ccx);
+                let ptr_ty = ccx.tcx().mk_mut_ptr(self.ty.boxed_ty());
+                return ccx.layout_of(ptr_ty).scalar_pair_element_llvm_type(ccx, index);
             }
             _ => {}
         }
@@ -438,15 +439,6 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
                 });
             }
 
-            ty::TyAdt(def, _) if def.is_box() && offset.bytes() == 0 => {
-                let (size, align) = ccx.size_and_align_of(self.ty.boxed_ty());
-                result = Some(PointeeInfo {
-                    size,
-                    align,
-                    safe: Some(PointerKind::UniqueOwned)
-                });
-            }
-
             _ => {
                 let mut data_variant = match self.variants {
                     layout::Variants::NicheFilling { dataful_variant, .. } => {
@@ -491,6 +483,15 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
                         }
                     }
                 }
+
+                // FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
+                if let Some(ref mut pointee) = result {
+                    if let ty::TyAdt(def, _) = self.ty.sty {
+                        if def.is_box() && offset.bytes() == 0 {
+                            pointee.safe = Some(PointerKind::UniqueOwned);
+                        }
+                    }
+                }
             }
         }