From fa67abd12707c34a2def10247c22c336f82cd2c2 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Tue, 10 Oct 2017 20:55:21 +0300 Subject: rustc: don't special-case Box as having a pointer layout. --- src/liballoc/boxed.rs | 18 ++++- src/librustc/ty/layout.rs | 168 ++++++++++++++++++------------------------ src/librustc_trans/type_of.rs | 21 +++--- 3 files changed, 98 insertions(+), 109 deletions(-) (limited to 'src') 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 Place for IntermediateBox { unsafe fn finalize(b: IntermediateBox) -> Box { let p = b.ptr as *mut T; mem::forget(b); - mem::transmute(p) + Box::from_raw(p) } fn make_place() -> IntermediateBox { @@ -300,7 +300,10 @@ impl Box { issue = "27730")] #[inline] pub unsafe fn from_unique(u: Unique) -> 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 Box { issue = "27730")] #[inline] pub fn into_unique(b: Box) -> Unique { - 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 { pub fn downcast(self) -> Result, Box> { >::downcast(self).map_err(|s| unsafe { // reapply the Send marker - mem::transmute::, Box>(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> { 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`, not `Box`. + 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); + } + } + } } } -- cgit 1.4.1-3-g733a5