1
Fork 0

rustc: don't special-case Box<T> as having a pointer layout.

This commit is contained in:
Eduard-Mihai Burtescu 2017-10-10 20:55:21 +03:00
parent 18ecc564f2
commit fa67abd127
3 changed files with 98 additions and 109 deletions

View file

@ -151,7 +151,7 @@ impl<T> Place<T> for IntermediateBox<T> {
unsafe fn finalize<T>(b: IntermediateBox<T>) -> Box<T> { unsafe fn finalize<T>(b: IntermediateBox<T>) -> Box<T> {
let p = b.ptr as *mut T; let p = b.ptr as *mut T;
mem::forget(b); mem::forget(b);
mem::transmute(p) Box::from_raw(p)
} }
fn make_place<T>() -> IntermediateBox<T> { fn make_place<T>() -> IntermediateBox<T> {
@ -300,7 +300,10 @@ impl<T: ?Sized> Box<T> {
issue = "27730")] issue = "27730")]
#[inline] #[inline]
pub unsafe fn from_unique(u: Unique<T>) -> Self { 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. /// Consumes the `Box`, returning the wrapped raw pointer.
@ -362,7 +365,14 @@ impl<T: ?Sized> Box<T> {
issue = "27730")] issue = "27730")]
#[inline] #[inline]
pub fn into_unique(b: Box<T>) -> Unique<T> { 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>> { pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> {
<Box<Any>>::downcast(self).map_err(|s| unsafe { <Box<Any>>::downcast(self).map_err(|s| unsafe {
// reapply the Send marker // reapply the Send marker
mem::transmute::<Box<Any>, Box<Any + Send>>(s) Box::from_raw(Box::into_raw(s) as *mut (Any + Send))
}) })
} }
} }

View file

@ -1152,37 +1152,6 @@ impl<'a, 'tcx> CachedLayout {
}; };
assert!(!ty.has_infer_types()); 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 { Ok(match ty.sty {
// Basic scalars. // Basic scalars.
ty::TyBool => { ty::TyBool => {
@ -1219,10 +1188,34 @@ impl<'a, 'tcx> CachedLayout {
// Potentially-fat pointers. // Potentially-fat pointers.
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) | ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => { ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
ptr_layout(pointee)? let mut data_ptr = scalar_unit(Pointer);
if !ty.is_unsafe_ptr() {
data_ptr.valid_range.start = 1;
} }
ty::TyAdt(def, _) if def.is_box() => {
ptr_layout(ty.boxed_ty())? 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. // Arrays and slices.
@ -1861,7 +1854,9 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
Err(err) => err Err(err) => err
}; };
let ptr_skeleton = |pointee: Ty<'tcx>| { match ty.sty {
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
let non_zero = !ty.is_unsafe_ptr(); let non_zero = !ty.is_unsafe_ptr();
let tail = tcx.struct_tail(pointee); let tail = tcx.struct_tail(pointee);
match tail.sty { match tail.sty {
@ -1878,15 +1873,6 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
ty, err, tail) 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())
} }
ty::TyAdt(def, substs) => { ty::TyAdt(def, substs) => {
@ -2148,7 +2134,23 @@ impl<'a, 'tcx> TyLayout<'tcx> {
C::TyLayout: MaybeResult<TyLayout<'tcx>> C::TyLayout: MaybeResult<TyLayout<'tcx>>
{ {
let tcx = cx.tcx(); let tcx = cx.tcx();
let ptr_field_layout = |pointee: Ty<'tcx>| { cx.layout_of(match self.ty.sty {
ty::TyBool |
ty::TyChar |
ty::TyInt(_) |
ty::TyUint(_) |
ty::TyFloat(_) |
ty::TyFnPtr(_) |
ty::TyNever |
ty::TyFnDef(..) |
ty::TyDynamic(..) |
ty::TyForeign(..) => {
bug!("TyLayout::field_type({:?}): not applicable", self)
}
// Potentially-fat pointers.
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
assert!(i < 2); assert!(i < 2);
// Reuse the fat *T type as its own thin pointer data field. // Reuse the fat *T type as its own thin pointer data field.
@ -2168,7 +2170,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
}); });
} }
let meta_ty = match tcx.struct_tail(pointee).sty { match tcx.struct_tail(pointee).sty {
ty::TySlice(_) | ty::TySlice(_) |
ty::TyStr => tcx.types.usize, ty::TyStr => tcx.types.usize,
ty::TyDynamic(..) => { ty::TyDynamic(..) => {
@ -2177,31 +2179,7 @@ impl<'a, 'tcx> TyLayout<'tcx> {
tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil()) tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil())
} }
_ => bug!("TyLayout::field_type({:?}): not applicable", self) _ => bug!("TyLayout::field_type({:?}): not applicable", self)
};
cx.layout_of(meta_ty)
};
cx.layout_of(match self.ty.sty {
ty::TyBool |
ty::TyChar |
ty::TyInt(_) |
ty::TyUint(_) |
ty::TyFloat(_) |
ty::TyFnPtr(_) |
ty::TyNever |
ty::TyFnDef(..) |
ty::TyDynamic(..) |
ty::TyForeign(..) => {
bug!("TyLayout::field_type({:?}): not applicable", self)
} }
// 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());
} }
// Arrays and slices. // Arrays and slices.

View file

@ -321,7 +321,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
return self.field(ccx, index).llvm_type(ccx); return self.field(ccx, index).llvm_type(ccx);
} }
ty::TyAdt(def, _) if def.is_box() => { 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 { let mut data_variant = match self.variants {
layout::Variants::NicheFilling { dataful_variant, .. } => { 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);
}
}
}
} }
} }