Skip to content

Commit b9b0732

Browse files
committed
Make unions never have needs_drop
1 parent d2c7959 commit b9b0732

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/librustc/ty/contents.rs

+5
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,11 @@ impl<'a, 'tcx> ty::TyS<'tcx> {
235235
})
236236
});
237237

238+
if def.is_union() {
239+
// unions don't have destructors regardless of the child types
240+
res = res - TC::NeedsDrop;
241+
}
242+
238243
if def.has_dtor() {
239244
res = res | TC::OwnsDtor;
240245
}
+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
#![feature(core_intrinsics)]
12+
#![feature(untagged_unions)]
13+
14+
#![allow(unions_with_drop_fields)]
15+
#![allow(dead_code)]
16+
17+
use std::intrinsics::needs_drop;
18+
19+
// drop types in destructors should not require
20+
// drop_types_in_const
21+
static X: Option<NoDrop<Box<u8>>> = None;
22+
23+
// A union that scrubs the drop glue from its inner type
24+
union NoDrop<T> {inner: T}
25+
26+
// Copy currently can't be implemented on drop-containing unions,
27+
// this may change later
28+
// https://github.com/rust-lang/rust/pull/38934#issuecomment-271219289
29+
30+
// // We should be able to implement Copy for NoDrop
31+
// impl<T> Copy for NoDrop<T> {}
32+
// impl<T> Clone for NoDrop<T> {fn clone(&self) -> Self { *self }}
33+
34+
// // We should be able to implement Copy for things using NoDrop
35+
// #[derive(Copy, Clone)]
36+
struct Foo {
37+
x: NoDrop<Box<u8>>
38+
}
39+
40+
struct Baz {
41+
x: NoDrop<Box<u8>>,
42+
y: Box<u8>,
43+
}
44+
45+
union ActuallyDrop<T> {inner: T}
46+
47+
impl<T> Drop for ActuallyDrop<T> {
48+
fn drop(&mut self) {}
49+
}
50+
51+
fn main() {
52+
unsafe {
53+
// NoDrop should not make needs_drop true
54+
assert!(!needs_drop::<Foo>());
55+
assert!(!needs_drop::<NoDrop<u8>>());
56+
assert!(!needs_drop::<NoDrop<Box<u8>>>());
57+
// presence of other drop types should still work
58+
assert!(needs_drop::<Baz>());
59+
// drop impl on union itself should work
60+
assert!(needs_drop::<ActuallyDrop<u8>>());
61+
assert!(needs_drop::<ActuallyDrop<Box<u8>>>());
62+
}
63+
}

0 commit comments

Comments
 (0)