Skip to content

Commit a80c1cc

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

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.
@@ -1866,32 +1859,25 @@ impl<'a, 'tcx> SizeSkeleton<'tcx> {
18661859
Err(err) => err
18671860
};
18681861

1869-
let ptr_skeleton = |pointee: Ty<'tcx>| {
1870-
let non_zero = !ty.is_unsafe_ptr();
1871-
let tail = tcx.struct_tail(pointee);
1872-
match tail.sty {
1873-
ty::TyParam(_) | ty::TyProjection(_) => {
1874-
assert!(tail.has_param_types() || tail.has_self_ty());
1875-
Ok(SizeSkeleton::Pointer {
1876-
non_zero,
1877-
tail: tcx.erase_regions(&tail)
1878-
})
1879-
}
1880-
_ => {
1881-
bug!("SizeSkeleton::compute({}): layout errored ({}), yet \
1882-
tail `{}` is not a type parameter or a projection",
1883-
ty, err, tail)
1884-
}
1885-
}
1886-
};
1887-
18881862
match ty.sty {
18891863
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
18901864
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
1891-
ptr_skeleton(pointee)
1892-
}
1893-
ty::TyAdt(def, _) if def.is_box() => {
1894-
ptr_skeleton(ty.boxed_ty())
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+
}
18951881
}
18961882

18971883
ty::TyAdt(def, substs) => {
@@ -2153,39 +2139,6 @@ impl<'a, 'tcx> TyLayout<'tcx> {
21532139
C::TyLayout: MaybeResult<TyLayout<'tcx>>
21542140
{
21552141
let tcx = cx.tcx();
2156-
let ptr_field_layout = |pointee: Ty<'tcx>| {
2157-
assert!(i < 2);
2158-
2159-
// Reuse the fat *T type as its own thin pointer data field.
2160-
// This provides information about e.g. DST struct pointees
2161-
// (which may have no non-DST form), and will work as long
2162-
// as the `Abi` or `FieldPlacement` is checked by users.
2163-
if i == 0 {
2164-
let nil = tcx.mk_nil();
2165-
let ptr_ty = if self.ty.is_unsafe_ptr() {
2166-
tcx.mk_mut_ptr(nil)
2167-
} else {
2168-
tcx.mk_mut_ref(tcx.types.re_static, nil)
2169-
};
2170-
return cx.layout_of(ptr_ty).map_same(|mut ptr_layout| {
2171-
ptr_layout.ty = self.ty;
2172-
ptr_layout
2173-
});
2174-
}
2175-
2176-
let meta_ty = match tcx.struct_tail(pointee).sty {
2177-
ty::TySlice(_) |
2178-
ty::TyStr => tcx.types.usize,
2179-
ty::TyDynamic(..) => {
2180-
// FIXME(eddyb) use an usize/fn() array with
2181-
// the correct number of vtables slots.
2182-
tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil())
2183-
}
2184-
_ => bug!("TyLayout::field_type({:?}): not applicable", self)
2185-
};
2186-
cx.layout_of(meta_ty)
2187-
};
2188-
21892142
cx.layout_of(match self.ty.sty {
21902143
ty::TyBool |
21912144
ty::TyChar |
@@ -2203,10 +2156,35 @@ impl<'a, 'tcx> TyLayout<'tcx> {
22032156
// Potentially-fat pointers.
22042157
ty::TyRef(_, ty::TypeAndMut { ty: pointee, .. }) |
22052158
ty::TyRawPtr(ty::TypeAndMut { ty: pointee, .. }) => {
2206-
return ptr_field_layout(pointee);
2207-
}
2208-
ty::TyAdt(def, _) if def.is_box() => {
2209-
return ptr_field_layout(self.ty.boxed_ty());
2159+
assert!(i < 2);
2160+
2161+
// Reuse the fat *T type as its own thin pointer data field.
2162+
// This provides information about e.g. DST struct pointees
2163+
// (which may have no non-DST form), and will work as long
2164+
// as the `Abi` or `FieldPlacement` is checked by users.
2165+
if i == 0 {
2166+
let nil = tcx.mk_nil();
2167+
let ptr_ty = if self.ty.is_unsafe_ptr() {
2168+
tcx.mk_mut_ptr(nil)
2169+
} else {
2170+
tcx.mk_mut_ref(tcx.types.re_static, nil)
2171+
};
2172+
return cx.layout_of(ptr_ty).map_same(|mut ptr_layout| {
2173+
ptr_layout.ty = self.ty;
2174+
ptr_layout
2175+
});
2176+
}
2177+
2178+
match tcx.struct_tail(pointee).sty {
2179+
ty::TySlice(_) |
2180+
ty::TyStr => tcx.types.usize,
2181+
ty::TyDynamic(..) => {
2182+
// FIXME(eddyb) use an usize/fn() array with
2183+
// the correct number of vtables slots.
2184+
tcx.mk_imm_ref(tcx.types.re_static, tcx.mk_nil())
2185+
}
2186+
_ => bug!("TyLayout::field_type({:?}): not applicable", self)
2187+
}
22102188
}
22112189

22122190
// 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, .. } => {
@@ -481,6 +473,15 @@ impl<'tcx> LayoutLlvmExt<'tcx> for TyLayout<'tcx> {
481473
}
482474
}
483475
}
476+
477+
// FIXME(eddyb) This should be for `ptr::Unique<T>`, not `Box<T>`.
478+
if let Some(ref mut pointee) = result {
479+
if let ty::TyAdt(def, _) = self.ty.sty {
480+
if def.is_box() && offset.bytes() == 0 {
481+
pointee.safe = Some(PointerKind::UniqueOwned);
482+
}
483+
}
484+
}
484485
}
485486
}
486487

0 commit comments

Comments
 (0)