Skip to content

Commit 8007e31

Browse files
committed
Ban #[unsafe_no_drop_flag] on zero-sized types.
1 parent e88defe commit 8007e31

File tree

6 files changed

+22
-58
lines changed

6 files changed

+22
-58
lines changed

src/librustc/ty/layout.rs

+14-2
Original file line numberDiff line numberDiff line change
@@ -882,13 +882,19 @@ impl<'a, 'gcx, 'tcx> Layout {
882882
// won't actually be in the location we say it is because it'll be after
883883
// the unsized field. Several other pieces of code assume that the unsized
884884
// field is definitely the last one.
885-
if def.dtor_kind().has_drop_flag() &&
885+
let dtor_kind = def.dtor_kind();
886+
if dtor_kind.has_drop_flag() &&
886887
ty.is_sized(tcx, &infcx.parameter_environment, DUMMY_SP) {
887888
st.extend(dl, Some(Ok(&Scalar {
888889
value: Int(I8),
889890
non_zero: false
890891
})).into_iter(), ty)?;
891892
}
893+
if dtor_kind == ty::TraitDtor(false) && st.min_size().bytes() == 0 {
894+
let span = tcx.map.def_id_span(def.did, DUMMY_SP);
895+
tcx.sess.span_fatal(span, &format!(
896+
"cannot have a destructor for zero-sized type `{}`", ty));
897+
}
892898
Univariant {
893899
variant: st,
894900
non_zero: Some(def.did) == tcx.lang_items.non_zero()
@@ -898,7 +904,8 @@ impl<'a, 'gcx, 'tcx> Layout {
898904
let hint = *tcx.lookup_repr_hints(def.did).get(0)
899905
.unwrap_or(&attr::ReprAny);
900906

901-
let dtor = def.dtor_kind().has_drop_flag();
907+
let dtor_kind = def.dtor_kind();
908+
let dtor = dtor_kind.has_drop_flag();
902909
let drop_flag = if dtor {
903910
Some(Scalar { value: Int(I8), non_zero: false })
904911
} else {
@@ -953,6 +960,11 @@ impl<'a, 'gcx, 'tcx> Layout {
953960
});
954961
let mut st = Struct::new(dl, false);
955962
st.extend(dl, fields.chain(drop_flag.iter().map(Ok)), ty)?;
963+
if dtor_kind == ty::TraitDtor(false) && st.min_size().bytes() == 0 {
964+
let span = tcx.map.def_id_span(def.did, DUMMY_SP);
965+
tcx.sess.span_fatal(span, &format!(
966+
"cannot have a destructor for zero-sized type `{}`", ty));
967+
}
956968
return Ok(Univariant { variant: st, non_zero: false });
957969
}
958970

src/librustc/ty/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ pub struct CrateAnalysis<'a> {
117117
pub glob_map: Option<hir::GlobMap>,
118118
}
119119

120-
#[derive(Copy, Clone)]
120+
#[derive(Copy, Clone, PartialEq, Eq)]
121121
pub enum DtorKind {
122122
NoDtor,
123123
TraitDtor(bool)

src/librustc_trans/type_of.rs

+5
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,11 @@ pub fn in_memory_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>, t: Ty<'tcx>) ->
231231
return llty;
232232
}
233233

234+
// FIXME(eddyb) use the layout to actually compute the LLVM type.
235+
let _layout = cx.tcx().normalizing_infer_ctxt(ProjectionMode::Any).enter(|infcx| {
236+
t.layout(&infcx)
237+
});
238+
234239
let mut llty = match t.sty {
235240
ty::TyBool => Type::bool(cx),
236241
ty::TyChar => Type::char(cx),

src/test/run-pass/zero-size-type-destructors.rs renamed to src/test/compile-fail/zero-size-type-destructors.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -8,16 +8,14 @@
88
// option. This file may not be copied, modified, or distributed
99
// except according to those terms.
1010

11-
#![feature(rustc_attrs, unsafe_no_drop_flag)]
12-
13-
// ignore-pretty : (#23623) problems when ending with // comments
11+
#![feature(unsafe_no_drop_flag)]
1412

1513
static mut destructions : isize = 3;
1614

17-
#[rustc_no_mir] // FIXME #29855 MIR doesn't handle all drops correctly.
1815
pub fn foo() {
1916
#[unsafe_no_drop_flag]
2017
struct Foo;
18+
//~^ ERROR cannot have a destructor for zero-sized type `foo::Foo`
2119

2220
impl Drop for Foo {
2321
fn drop(&mut self) {

src/test/run-pass/auxiliary/issue-10028.rs

-22
This file was deleted.

src/test/run-pass/issue-10028.rs

-29
This file was deleted.

0 commit comments

Comments
 (0)