Skip to content

Commit fa67abd

Browse files
committed
rustc: don't special-case Box<T> as having a pointer layout.
1 parent 18ecc56 commit fa67abd

File tree

3 files changed

+98
-109
lines changed

3 files changed

+98
-109
lines changed

src/liballoc/boxed.rs

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -151,7 +151,7 @@ impl<T> Place<T> for IntermediateBox<T> {
151151
unsafe fn finalize<T>(b: IntermediateBox<T>) -> Box<T> {
152152
let p = b.ptr as *mut T;
153153
mem::forget(b);
154-
mem::transmute(p)
154+
Box::from_raw(p)
155155
}
156156

157157
fn make_place<T>() -> IntermediateBox<T> {
@@ -300,7 +300,10 @@ impl<T: ?Sized> Box<T> {
300300
issue = "27730")]
301301
#[inline]
302302
pub unsafe fn from_unique(u: Unique<T>) -> Self {
303-
mem::transmute(u)
303+
#[cfg(stage0)]
304+
return mem::transmute(u);
305+
#[cfg(not(stage0))]
306+
return Box(u);
304307
}
305308

306309
/// Consumes the `Box`, returning the wrapped raw pointer.
@@ -362,7 +365,14 @@ impl<T: ?Sized> Box<T> {
362365
issue = "27730")]
363366
#[inline]
364367
pub fn into_unique(b: Box<T>) -> Unique<T> {
365-
unsafe { mem::transmute(b) }
368+
#[cfg(stage0)]
369+
return unsafe { mem::transmute(b) };
370+
#[cfg(not(stage0))]
371+
return {
372+
let unique = b.0;
373+
mem::forget(b);
374+
unique
375+
};
366376
}
367377
}
368378

@@ -627,7 +637,7 @@ impl Box<Any + Send> {
627637
pub fn downcast<T: Any>(self) -> Result<Box<T>, Box<Any + Send>> {
628638
<Box<Any>>::downcast(self).map_err(|s| unsafe {
629639
// reapply the Send marker
630-
mem::transmute::<Box<Any>, Box<Any + Send>>(s)
640+
Box::from_raw(Box::into_raw(s) as *mut (Any + Send))
631641
})
632642
}
633643
}

src/librustc/ty/layout.rs

Lines changed: 73 additions & 95 deletions
Original file line numberDiff line numberDiff line change
@@ -1152,37 +1152,6 @@ impl<'a, 'tcx> CachedLayout {
11521152
};
11531153
assert!(!ty.has_infer_types());
11541154

1155-
let ptr_layout = |pointee: Ty<'tcx>| {
1156-
let mut data_ptr = scalar_unit(Pointer);
1157-
if !ty.is_unsafe_ptr() {
1158-
data_ptr.valid_range.start = 1;
1159-
}
1160-
1161-
let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
1162-
if pointee.is_sized(tcx, param_env, DUMMY_SP) {
1163-
return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
1164-
}
1165-
1166-
let unsized_part = tcx.struct_tail(pointee);
1167-
let metadata = match unsized_part.sty {
1168-
ty::TyForeign(..) => {
1169-
return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
1170-
}
1171-
ty::TySlice(_) | ty::TyStr => {
1172-
scalar_unit(Int(dl.ptr_sized_integer(), false))
1173-
}
1174-
ty::TyDynamic(..) => {
1175-
let mut vtable = scalar_unit(Pointer);
1176-
vtable.valid_range.start = 1;
1177-
vtable
1178-
}
1179-
_ => return Err(LayoutError::Unknown(unsized_part))
1180-
};
1181-
1182-
// Effectively a (ptr, meta) tuple.
1183-
Ok(tcx.intern_layout(scalar_pair(data_ptr, metadata)))
1184-
};
1185-
11861155
Ok(match ty.sty {
11871156
// Basic scalars.
11881157
ty::TyBool => {
@@ -1219,10 +1188,34 @@ impl<'a, 'tcx> CachedLayout {
12191188
// Potentially-fat pointers.
12201189
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
12211190
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
1222-
ptr_layout(pointee)?
1223-
}
1224-
ty::TyAdt(def, _) if def.is_box() => {
1225-
ptr_layout(ty.boxed_ty())?
1191+
let mut data_ptr = scalar_unit(Pointer);
1192+
if !ty.is_unsafe_ptr() {
1193+
data_ptr.valid_range.start = 1;
1194+
}
1195+
1196+
let pointee = tcx.normalize_associated_type_in_env(&pointee, param_env);
1197+
if pointee.is_sized(tcx, param_env, DUMMY_SP) {
1198+
return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
1199+
}
1200+
1201+
let unsized_part = tcx.struct_tail(pointee);
1202+
let metadata = match unsized_part.sty {
1203+
ty::TyForeign(..) => {
1204+
return Ok(tcx.intern_layout(CachedLayout::scalar(cx, data_ptr)));
1205+
}
1206+
ty::TySlice(_) | ty::TyStr => {
1207+
scalar_unit(Int(dl.ptr_sized_integer(), false))
1208+
}
1209+
ty::TyDynamic(..) => {
1210+
let mut vtable = scalar_unit(Pointer);
1211+
vtable.valid_range.start = 1;
1212+
vtable
1213+
}
1214+
_ => return Err(LayoutError::Unknown(unsized_part))
1215+
};
1216+
1217+
// Effectively a (ptr, meta) tuple.
1218+
tcx.intern_layout(scalar_pair(data_ptr, metadata))
12261219
}
12271220

12281221
// Arrays and slices.
@@ -1861,32 +1854,25 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
18611854
Err(err) => err
18621855
};
18631856

1864-
let ptr_skeleton = |pointee: Ty<'tcx>| {
1865-
let non_zero = !ty.is_unsafe_ptr();
1866-
let tail = tcx.struct_tail(pointee);
1867-
match tail.sty {
1868-
ty::TyParam(_) | ty::TyProjection(_) => {
1869-
assert!(tail.has_param_types() || tail.has_self_ty());
1870-
Ok(SizeSkeleton::Pointer {
1871-
non_zero,
1872-
tail: tcx.erase_regions(&tail)
1873-
})
1874-
}
1875-
_ => {
1876-
bug!("SizeSkeleton::compute({}): layout errored ({}), yet \
1877-
tail `{}` is not a type parameter or a projection",
1878-
ty, err, tail)
1879-
}
1880-
}
1881-
};
1882-
18831857
match ty.sty {
18841858
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
18851859
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
1886-
ptr_skeleton(pointee)
1887-
}
1888-
ty::TyAdt(def, _) if def.is_box() => {
1889-
ptr_skeleton(ty.boxed_ty())
1860+
let non_zero = !ty.is_unsafe_ptr();
1861+
let tail = tcx.struct_tail(pointee);
1862+
match tail.sty {
1863+
ty::TyParam(_) | ty::TyProjection(_) => {
1864+
assert!(tail.has_param_types() || tail.has_self_ty());
1865+
Ok(SizeSkeleton::Pointer {
1866+
non_zero,
1867+
tail: tcx.erase_regions(&tail)
1868+
})
1869+
}
1870+
_ => {
1871+
bug!("SizeSkeleton::compute({}): layout errored ({}), yet \
1872+
tail `{}` is not a type parameter or a projection",
1873+
ty, err, tail)
1874+
}
1875+
}
18901876
}
18911877

18921878
ty::TyAdt(def, substs) => {
@@ -2148,39 +2134,6 @@ impl<'a, 'tcx> TyLayout<'tcx> {
21482134
C::TyLayout: MaybeResult<TyLayout<'tcx>>
21492135
{
21502136
let tcx = cx.tcx();
2151-
let ptr_field_layout = |pointee: Ty<'tcx>| {
2152-
assert!(i < 2);
2153-
2154-
// Reuse the fat *T type as its own thin pointer data field.
2155-
// This provides information about e.g. DST struct pointees
2156-
// (which may have no non-DST form), and will work as long
2157-
// as the `Abi` or `FieldPlacement` is checked by users.
2158-
if i == 0 {
2159-
let nil = tcx.mk_nil();
2160-
let ptr_ty = if self.ty.is_unsafe_ptr() {
2161-
tcx.mk_mut_ptr(nil)
2162-
} else {
2163-
tcx.mk_mut_ref(tcx.types.re_static, nil)
2164-
};
2165-
return cx.layout_of(ptr_ty).map_same(|mut ptr_layout| {
2166-
ptr_layout.ty = self.ty;
2167-
ptr_layout
2168-
});
2169-
}
2170-
2171-
let meta_ty = match tcx.struct_tail(pointee).sty {
2172-
ty::TySlice(_) |
2173-
ty::TyStr => tcx.types.usize,
2174-
ty::TyDynamic(..) => {
2175-
// FIXME(eddyb) use an usize/fn() array with
2176-
// the correct number of vtables slots.
2177-
tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil())
2178-
}
2179-
_ => bug!("TyLayout::field_type({:?}): not applicable", self)
2180-
};
2181-
cx.layout_of(meta_ty)
2182-
};
2183-
21842137
cx.layout_of(match self.ty.sty {
21852138
ty::TyBool |
21862139
ty::TyChar |
@@ -2198,10 +2151,35 @@ impl<'a, 'tcx> TyLayout<'tcx> {
21982151
// Potentially-fat pointers.
21992152
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
22002153
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
2201-
return ptr_field_layout(pointee);
2202-
}
2203-
ty::TyAdt(def, _) if def.is_box() => {
2204-
return ptr_field_layout(self.ty.boxed_ty());
2154+
assert!(i < 2);
2155+
2156+
// Reuse the fat *T type as its own thin pointer data field.
2157+
// This provides information about e.g. DST struct pointees
2158+
// (which may have no non-DST form), and will work as long
2159+
// as the `Abi` or `FieldPlacement` is checked by users.
2160+
if i == 0 {
2161+
let nil = tcx.mk_nil();
2162+
let ptr_ty = if self.ty.is_unsafe_ptr() {
2163+
tcx.mk_mut_ptr(nil)
2164+
} else {
2165+
tcx.mk_mut_ref(tcx.types.re_static, nil)
2166+
};
2167+
return cx.layout_of(ptr_ty).map_same(|mut ptr_layout| {
2168+
ptr_layout.ty = self.ty;
2169+
ptr_layout
2170+
});
2171+
}
2172+
2173+
match tcx.struct_tail(pointee).sty {
2174+
ty::TySlice(_) |
2175+
ty::TyStr => tcx.types.usize,
2176+
ty::TyDynamic(..) => {
2177+
// FIXME(eddyb) use an usize/fn() array with
2178+
// the correct number of vtables slots.
2179+
tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil())
2180+
}
2181+
_ => bug!("TyLayout::field_type({:?}): not applicable", self)
2182+
}
22052183
}
22062184

22072185
// Arrays and slices.

src/librustc_trans/type_of.rs

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -321,7 +321,8 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
321321
return self.field(ccx, index).llvm_type(ccx);
322322
}
323323
ty::TyAdt(def, _) if def.is_box() => {
324-
return self.field(ccx, index).llvm_type(ccx);
324+
let ptr_ty = ccx.tcx().mk_mut_ptr(self.ty.boxed_ty());
325+
return ccx.layout_of(ptr_ty).scalar_pair_element_llvm_type(ccx, index);
325326
}
326327
_ => {}
327328
}
@@ -438,15 +439,6 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
438439
});
439440
}
440441

441-
ty::TyAdt(def, _) if def.is_box() && offset.bytes() == 0 => {
442-
let (size, align) = ccx.size_and_align_of(self.ty.boxed_ty());
443-
result = Some(PointeeInfo {
444-
size,
445-
align,
446-
safe: Some(PointerKind::UniqueOwned)
447-
});
448-
}
449-
450442
_ => {
451443
let mut data_variant = match self.variants {
452444
layout::Variants::NicheFilling { dataful_variant, .. } => {
@@ -491,6 +483,15 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
491483
}
492484
}
493485
}
486+
487+
// FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
488+
if let Some(ref mut pointee) = result {
489+
if let ty::TyAdt(def, _) = self.ty.sty {
490+
if def.is_box() && offset.bytes() == 0 {
491+
pointee.safe = Some(PointerKind::UniqueOwned);
492+
}
493+
}
494+
}
494495
}
495496
}
496497

0 commit comments

Comments
 (0)