Skip to content

Commit 0df7b25

Browse files
committed
Add a LocalDrop trait and a derive proc macro for it
1 parent 21f2684 commit 0df7b25

File tree

12 files changed

+249
-28
lines changed

12 files changed

+249
-28
lines changed

Cargo.lock

+32-10
Original file line numberDiff line numberDiff line change
@@ -609,7 +609,7 @@ version = "0.13.0"
609609
source = "registry+https://github.com/rust-lang/crates.io-index"
610610
dependencies = [
611611
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
612-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
612+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
613613
"rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
614614
"syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)",
615615
]
@@ -734,7 +734,7 @@ version = "0.1.2"
734734
source = "registry+https://github.com/rust-lang/crates.io-index"
735735
dependencies = [
736736
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
737-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
737+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
738738
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
739739
"synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)",
740740
]
@@ -1341,7 +1341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
13411341
dependencies = [
13421342
"num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)",
13431343
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
1344-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
1344+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
13451345
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
13461346
]
13471347

@@ -1677,7 +1677,7 @@ dependencies = [
16771677

16781678
[[package]]
16791679
name = "quote"
1680-
version = "0.6.8"
1680+
version = "0.6.10"
16811681
source = "registry+https://github.com/rust-lang/crates.io-index"
16821682
dependencies = [
16831683
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2239,6 +2239,7 @@ dependencies = [
22392239
"rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
22402240
"rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
22412241
"rustc_cratesio_shim 0.0.0",
2242+
"rustc_local_drop_derive 0.1.0",
22422243
"serialize 0.0.0",
22432244
"smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)",
22442245
"stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2334,6 +2335,15 @@ dependencies = [
23342335
"cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)",
23352336
]
23362337

2338+
[[package]]
2339+
name = "rustc_local_drop_derive"
2340+
version = "0.1.0"
2341+
dependencies = [
2342+
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
2343+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
2344+
"synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)",
2345+
]
2346+
23372347
[[package]]
23382348
name = "rustc_lsan"
23392349
version = "0.0.0"
@@ -2664,7 +2674,7 @@ version = "1.0.75"
26642674
source = "registry+https://github.com/rust-lang/crates.io-index"
26652675
dependencies = [
26662676
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
2667-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
2677+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
26682678
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
26692679
]
26702680

@@ -2801,7 +2811,7 @@ version = "0.9.1"
28012811
source = "registry+https://github.com/rust-lang/crates.io-index"
28022812
dependencies = [
28032813
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
2804-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
2814+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
28052815
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
28062816
]
28072817

@@ -2831,7 +2841,7 @@ version = "0.14.9"
28312841
source = "registry+https://github.com/rust-lang/crates.io-index"
28322842
dependencies = [
28332843
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
2834-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
2844+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
28352845
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
28362846
]
28372847

@@ -2841,7 +2851,7 @@ version = "0.15.21"
28412851
source = "registry+https://github.com/rust-lang/crates.io-index"
28422852
dependencies = [
28432853
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
2844-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
2854+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
28452855
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
28462856
]
28472857

@@ -2859,11 +2869,22 @@ version = "0.9.0"
28592869
source = "registry+https://github.com/rust-lang/crates.io-index"
28602870
dependencies = [
28612871
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
2862-
"quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)",
2872+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
28632873
"syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)",
28642874
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
28652875
]
28662876

2877+
[[package]]
2878+
name = "synstructure"
2879+
version = "0.10.1"
2880+
source = "registry+https://github.com/rust-lang/crates.io-index"
2881+
dependencies = [
2882+
"proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)",
2883+
"quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)",
2884+
"syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)",
2885+
"unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
2886+
]
2887+
28672888
[[package]]
28682889
name = "syntax"
28692890
version = "0.0.0"
@@ -3400,7 +3421,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
34003421
"checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45"
34013422
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
34023423
"checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8"
3403-
"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5"
3424+
"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c"
34043425
"checksum racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "344a53b68d889ab5f44d0617f2bbe1f696abe6a730bd41fa619cfc6fa83a6078"
34053426
"checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd"
34063427
"checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c"
@@ -3465,6 +3486,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
34653486
"checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741"
34663487
"checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823"
34673488
"checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6"
3489+
"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015"
34683490
"checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7"
34693491
"checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c"
34703492
"checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76"

src/bootstrap/bin/rustc.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -268,13 +268,6 @@ fn main() {
268268
}
269269
}
270270

271-
// Force all crates compiled by this compiler to (a) be unstable and (b)
272-
// allow the `rustc_private` feature to link to other unstable crates
273-
// also in the sysroot.
274-
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
275-
cmd.arg("-Z").arg("force-unstable-if-unmarked");
276-
}
277-
278271
if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
279272
cmd.arg("--remap-path-prefix").arg(&map);
280273
}
@@ -294,6 +287,13 @@ fn main() {
294287
}
295288
}
296289

290+
// Force all crates compiled by this compiler to (a) be unstable and (b)
291+
// allow the `rustc_private` feature to link to other unstable crates
292+
// also in the sysroot.
293+
if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() {
294+
cmd.arg("-Z").arg("force-unstable-if-unmarked");
295+
}
296+
297297
if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() {
298298
cmd.arg("--cfg").arg("parallel_queries");
299299
}

src/bootstrap/compile.rs

+1-7
Original file line numberDiff line numberDiff line change
@@ -1064,15 +1064,9 @@ pub fn run_cargo(builder: &Builder,
10641064

10651065
let filename = Path::new(&*filename);
10661066

1067-
// If this was an output file in the "host dir" we don't actually
1068-
// worry about it, it's not relevant for us.
1069-
if filename.starts_with(&host_root_dir) {
1070-
continue;
1071-
}
1072-
10731067
// If this was output in the `deps` dir then this is a precise file
10741068
// name (hash included) so we start tracking it.
1075-
if filename.starts_with(&target_deps_dir) {
1069+
if filename.starts_with(&host_root_dir) || filename.starts_with(&target_deps_dir) {
10761070
deps.push(filename.to_path_buf());
10771071
continue;
10781072
}

src/libarena/lib.rs

+50-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,8 @@
3535
extern crate alloc;
3636
extern crate rustc_data_structures;
3737

38-
use rustc_data_structures::sync::MTLock;
38+
use rustc_data_structures::local_drop::LocalDrop;
39+
use rustc_data_structures::sync::{MTLock, WorkerLocal};
3940

4041
use std::cell::{Cell, RefCell};
4142
use std::cmp;
@@ -447,12 +448,39 @@ impl<T> SyncTypedArena<T> {
447448
}
448449
}
449450

450-
#[derive(Default)]
451+
struct DropType {
452+
drop_fn: unsafe fn(*mut u8),
453+
obj: *mut u8,
454+
}
455+
456+
unsafe fn drop_for_type<T>(to_drop: *mut u8) {
457+
std::ptr::drop_in_place(to_drop as *mut T)
458+
}
459+
460+
impl Drop for DropType {
461+
fn drop(&mut self) {
462+
unsafe {
463+
(self.drop_fn)(self.obj)
464+
}
465+
}
466+
}
467+
451468
pub struct SyncDroplessArena {
469+
// Ordered so `deferred` gets dropped before the arena
470+
// since its destructor can reference memory in the arena
471+
deferred: WorkerLocal<RefCell<Vec<DropType>>>,
452472
lock: MTLock<DroplessArena>,
453473
}
454474

455475
impl SyncDroplessArena {
476+
#[inline]
477+
pub fn new() -> Self {
478+
SyncDroplessArena {
479+
lock: Default::default(),
480+
deferred: WorkerLocal::new(|_| Default::default()),
481+
}
482+
}
483+
456484
#[inline(always)]
457485
pub fn in_arena<T: ?Sized>(&self, ptr: *const T) -> bool {
458486
self.lock.lock().in_arena(ptr)
@@ -478,6 +506,26 @@ impl SyncDroplessArena {
478506
// Extend the lifetime of the result since it's limited to the lock guard
479507
unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) }
480508
}
509+
510+
#[inline]
511+
pub fn promote<T: LocalDrop>(&self, object: T) -> &T {
512+
// Validate that T is really LocalDrop at runtime
513+
T::check();
514+
515+
let mem = self.alloc_raw(mem::size_of::<T>(), mem::align_of::<T>()) as *mut _ as *mut T;
516+
let result = unsafe {
517+
// Write into uninitialized memory.
518+
ptr::write(mem, object);
519+
&mut *mem
520+
};
521+
// Record the destructor after doing the allocation as that may panic
522+
// and would cause `object` destuctor to run twice if it was recorded before
523+
self.deferred.borrow_mut().push(DropType {
524+
drop_fn: drop_for_type::<T>,
525+
obj: result as *mut T as *mut u8,
526+
});
527+
result
528+
}
481529
}
482530

483531
#[cfg(test)]

src/librustc/infer/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -478,7 +478,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> {
478478
pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> {
479479
InferCtxtBuilder {
480480
global_tcx: self,
481-
arena: SyncDroplessArena::default(),
481+
arena: SyncDroplessArena::new(),
482482
fresh_tables: None,
483483
}
484484
}

src/librustc/ty/context.rs

+12-1
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ use util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap};
5555
use util::nodemap::{FxHashMap, FxHashSet};
5656
use rustc_data_structures::interner::HashInterner;
5757
use smallvec::SmallVec;
58+
use rustc_data_structures::local_drop::LocalDrop;
5859
use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap,
5960
StableHasher, StableHasherResult,
6061
StableVec};
@@ -92,7 +93,7 @@ impl<'tcx> AllArenas<'tcx> {
9293
pub fn new() -> Self {
9394
AllArenas {
9495
global: WorkerLocal::new(|_| GlobalArenas::default()),
95-
interner: SyncDroplessArena::default(),
96+
interner: SyncDroplessArena::new(),
9697
}
9798
}
9899
}
@@ -971,6 +972,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
971972
}
972973
}
973974

975+
#[inline(always)]
976+
pub fn promote<T: LocalDrop>(&self, object: T) -> &'gcx T {
977+
self.gcx.global_interners.arena.promote(object)
978+
}
979+
980+
#[inline(always)]
981+
pub fn promote_vec<T: LocalDrop>(&self, vec: Vec<T>) -> &'gcx [T] {
982+
&self.gcx.global_interners.arena.promote(vec)[..]
983+
}
984+
974985
pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics {
975986
self.global_arenas.generics.alloc(generics)
976987
}

src/librustc_data_structures/Cargo.toml

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ crate-type = ["dylib"]
1111
[dependencies]
1212
ena = "0.11"
1313
log = "0.4"
14+
rustc_local_drop_derive = { path = "../librustc_local_drop_derive" }
1415
rustc_cratesio_shim = { path = "../librustc_cratesio_shim" }
1516
serialize = { path = "../libserialize" }
1617
graphviz = { path = "../libgraphviz" }

src/librustc_data_structures/lib.rs

+7
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
html_favicon_url = "https://www.rust-lang.org/favicon.ico",
2121
html_root_url = "https://doc.rust-lang.org/nightly/")]
2222

23+
#![feature(core_intrinsics)]
2324
#![feature(in_band_lifetimes)]
2425
#![feature(unboxed_closures)]
2526
#![feature(fn_traits)]
@@ -42,6 +43,7 @@ extern crate serialize as rustc_serialize; // used by deriving
4243
#[cfg(unix)]
4344
extern crate libc;
4445
extern crate parking_lot;
46+
extern crate rustc_local_drop_derive;
4547
#[macro_use]
4648
extern crate cfg_if;
4749
extern crate stable_deref_trait;
@@ -56,9 +58,14 @@ extern crate smallvec;
5658
#[allow(unused_extern_crates)]
5759
extern crate rustc_cratesio_shim;
5860

61+
mod rustc_data_structures {
62+
pub use ::*;
63+
}
64+
5965
pub use rustc_serialize::hex::ToHex;
6066

6167
pub mod macros;
68+
#[macro_use] pub mod local_drop;
6269
pub mod svh;
6370
pub mod base_n;
6471
pub mod bit_set;

0 commit comments

Comments
 (0)