diff --git a/Cargo.lock b/Cargo.lock index 72f3077d2be40..4ec38c1f39502 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -609,7 +609,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_version 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -734,7 +734,7 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1341,7 +1341,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "num-traits 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)", "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -1677,7 +1677,7 @@ dependencies = [ [[package]] name = "quote" -version = "0.6.8" +version = "0.6.10" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", @@ -1941,6 +1941,7 @@ dependencies = [ "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", "rustc_fs_util 0.0.0", + "rustc_local_drop_derive 0.1.0", "rustc_target 0.0.0", "scoped-tls 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)", "serialize 0.0.0", @@ -2239,6 +2240,7 @@ dependencies = [ "rustc-rayon 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc-rayon-core 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)", "rustc_cratesio_shim 0.0.0", + "rustc_local_drop_derive 0.1.0", "serialize 0.0.0", "smallvec 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "stable_deref_trait 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)", @@ -2334,6 +2336,15 @@ dependencies = [ "cc 1.0.25 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "rustc_local_drop_derive" +version = "0.1.0" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "rustc_lsan" version = "0.0.0" @@ -2664,7 +2675,7 @@ version = "1.0.75" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2801,7 +2812,7 @@ version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2831,7 +2842,7 @@ version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2841,7 +2852,7 @@ version = "0.15.21" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] @@ -2859,11 +2870,22 @@ version = "0.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" dependencies = [ "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", - "quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", "syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)", "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "synstructure" +version = "0.10.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +dependencies = [ + "proc-macro2 0.4.24 (registry+https://github.com/rust-lang/crates.io-index)", + "quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)", + "syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)", + "unicode-xid 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "syntax" version = "0.0.0" @@ -3400,7 +3422,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum quine-mc_cluskey 0.2.4 (registry+https://github.com/rust-lang/crates.io-index)" = "07589615d719a60c8dd8a4622e7946465dfef20d1a428f969e3443e7386d5f45" "checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a" "checksum quote 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9949cfe66888ffe1d53e6ec9d9f3b70714083854be20fd5e271b232a017401e8" -"checksum quote 0.6.8 (registry+https://github.com/rust-lang/crates.io-index)" = "dd636425967c33af890042c483632d33fa7a18f19ad1d7ea72e8998c6ef8dea5" +"checksum quote 0.6.10 (registry+https://github.com/rust-lang/crates.io-index)" = "53fa22a1994bd0f9372d7a816207d8a2677ad0325b073f5c5332760f0fb62b5c" "checksum racer 2.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "344a53b68d889ab5f44d0617f2bbe1f696abe6a730bd41fa619cfc6fa83a6078" "checksum rand 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "8356f47b32624fef5b3301c1be97e5944ecdd595409cc5da11d05f211db6cfbd" "checksum rand 0.5.5 (registry+https://github.com/rust-lang/crates.io-index)" = "e464cd887e869cddcae8792a4ee31d23c7edd516700695608f5b98c67ee0131c" @@ -3465,6 +3487,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" "checksum syn 0.14.9 (registry+https://github.com/rust-lang/crates.io-index)" = "261ae9ecaa397c42b960649561949d69311f08eeaea86a65696e6e46517cf741" "checksum syn 0.15.21 (registry+https://github.com/rust-lang/crates.io-index)" = "816b7af21405b011a23554ea2dc3f6576dc86ca557047c34098c1d741f10f823" "checksum synom 0.11.3 (registry+https://github.com/rust-lang/crates.io-index)" = "a393066ed9010ebaed60b9eafa373d4b1baac186dd7e008555b0f702b51945b6" +"checksum synstructure 0.10.1 (registry+https://github.com/rust-lang/crates.io-index)" = "73687139bf99285483c96ac0add482c3776528beac1d97d444f6e91f203a2015" "checksum synstructure 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "85bb9b7550d063ea184027c9b8c20ac167cd36d3e06b3a40bceb9d746dc1a7b7" "checksum tar 0.4.19 (registry+https://github.com/rust-lang/crates.io-index)" = "69e16840a1e0a1f1a880b739ef1cc6a4b85496c99b8aa786ccffce6e0c15624c" "checksum tempfile 3.0.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c4b103c6d08d323b92ff42c8ce62abcd83ca8efa7fd5bf7927efefec75f58c76" diff --git a/src/bootstrap/bin/rustc.rs b/src/bootstrap/bin/rustc.rs index d18a48e5d2270..e0e124fb4831f 100644 --- a/src/bootstrap/bin/rustc.rs +++ b/src/bootstrap/bin/rustc.rs @@ -268,13 +268,6 @@ fn main() { } } - // Force all crates compiled by this compiler to (a) be unstable and (b) - // allow the `rustc_private` feature to link to other unstable crates - // also in the sysroot. - if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() { - cmd.arg("-Z").arg("force-unstable-if-unmarked"); - } - if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") { cmd.arg("--remap-path-prefix").arg(&map); } @@ -294,6 +287,13 @@ fn main() { } } + // Force all crates compiled by this compiler to (a) be unstable and (b) + // allow the `rustc_private` feature to link to other unstable crates + // also in the sysroot. + if env::var_os("RUSTC_FORCE_UNSTABLE").is_some() { + cmd.arg("-Z").arg("force-unstable-if-unmarked"); + } + if env::var_os("RUSTC_PARALLEL_QUERIES").is_some() { cmd.arg("--cfg").arg("parallel_queries"); } diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b6bb11d07ef04..4f290f6664ea8 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -1064,15 +1064,9 @@ pub fn run_cargo(builder: &Builder, let filename = Path::new(&*filename); - // If this was an output file in the "host dir" we don't actually - // worry about it, it's not relevant for us. - if filename.starts_with(&host_root_dir) { - continue; - } - // If this was output in the `deps` dir then this is a precise file // name (hash included) so we start tracking it. - if filename.starts_with(&target_deps_dir) { + if filename.starts_with(&host_root_dir) || filename.starts_with(&target_deps_dir) { deps.push(filename.to_path_buf()); continue; } diff --git a/src/libarena/lib.rs b/src/libarena/lib.rs index aef3edd9eb64a..870fab97fe5a0 100644 --- a/src/libarena/lib.rs +++ b/src/libarena/lib.rs @@ -35,7 +35,8 @@ extern crate alloc; extern crate rustc_data_structures; -use rustc_data_structures::sync::MTLock; +use rustc_data_structures::local_drop::LocalDrop; +use rustc_data_structures::sync::{MTLock, WorkerLocal}; use std::cell::{Cell, RefCell}; use std::cmp; @@ -447,12 +448,39 @@ impl SyncTypedArena { } } -#[derive(Default)] +struct DropType { + drop_fn: unsafe fn(*mut u8), + obj: *mut u8, +} + +unsafe fn drop_for_type(to_drop: *mut u8) { + std::ptr::drop_in_place(to_drop as *mut T) +} + +impl Drop for DropType { + fn drop(&mut self) { + unsafe { + (self.drop_fn)(self.obj) + } + } +} + pub struct SyncDroplessArena { + // Ordered so `deferred` gets dropped before the arena + // since its destructor can reference memory in the arena + deferred: WorkerLocal>>, lock: MTLock, } impl SyncDroplessArena { + #[inline] + pub fn new() -> Self { + SyncDroplessArena { + lock: Default::default(), + deferred: WorkerLocal::new(|_| Default::default()), + } + } + #[inline(always)] pub fn in_arena(&self, ptr: *const T) -> bool { self.lock.lock().in_arena(ptr) @@ -478,6 +506,26 @@ impl SyncDroplessArena { // Extend the lifetime of the result since it's limited to the lock guard unsafe { &mut *(self.lock.lock().alloc_slice(slice) as *mut [T]) } } + + #[inline] + pub fn promote(&self, object: T) -> &T { + // Validate that T is really LocalDrop at runtime + T::check(); + + let mem = self.alloc_raw(mem::size_of::(), mem::align_of::()) as *mut _ as *mut T; + let result = unsafe { + // Write into uninitialized memory. + ptr::write(mem, object); + &mut *mem + }; + // Record the destructor after doing the allocation as that may panic + // and would cause `object` destuctor to run twice if it was recorded before + self.deferred.borrow_mut().push(DropType { + drop_fn: drop_for_type::, + obj: result as *mut T as *mut u8, + }); + result + } } #[cfg(test)] diff --git a/src/librustc/Cargo.toml b/src/librustc/Cargo.toml index 3316735de663e..c29854d44d13f 100644 --- a/src/librustc/Cargo.toml +++ b/src/librustc/Cargo.toml @@ -22,6 +22,7 @@ rustc-rayon = "0.1.1" rustc-rayon-core = "0.1.1" rustc_apfloat = { path = "../librustc_apfloat" } rustc_target = { path = "../librustc_target" } +rustc_local_drop_derive = { path = "../librustc_local_drop_derive" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_errors = { path = "../librustc_errors" } serialize = { path = "../libserialize" } diff --git a/src/librustc/hir/def_id.rs b/src/librustc/hir/def_id.rs index 319d63f66c465..a52d3620a79de 100644 --- a/src/librustc/hir/def_id.rs +++ b/src/librustc/hir/def_id.rs @@ -17,11 +17,12 @@ use std::u32; newtype_index! { pub struct CrateId { + derive [LocalDrop] ENCODABLE = custom } } -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, LocalDrop)] pub enum CrateNum { /// Virtual crate for builtin macros // FIXME(jseyfried): this is also used for custom derives until proc-macro crates get @@ -124,7 +125,7 @@ impl serialize::UseSpecializedDecodable for CrateNum {} /// Since the DefIndex is mostly treated as an opaque ID, you probably /// don't have to care about these address spaces. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, LocalDrop)] pub struct DefIndex(u32); /// The crate root is always assigned index 0 by the AST Map code, @@ -217,7 +218,7 @@ impl DefIndexAddressSpace { /// A `DefId` identifies a particular *definition*, by combining a crate /// index and a def index. -#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy)] +#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Copy, LocalDrop)] pub struct DefId { pub krate: CrateNum, pub index: DefIndex, diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index e6a7c20f79379..bce07289b1a89 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -855,8 +855,6 @@ impl_stable_hash_for!(struct ty::CrateVariancesMap { impl_stable_hash_for!(struct ty::CratePredicatesMap<'tcx> { predicates, - // This is just an irrelevant helper value. - empty_predicate -> _, }); impl_stable_hash_for!(struct ty::AssociatedItem { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index d8beae45b0ad4..baadf981bab06 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -478,7 +478,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'gcx> { pub fn infer_ctxt(self) -> InferCtxtBuilder<'a, 'gcx, 'tcx> { InferCtxtBuilder { global_tcx: self, - arena: SyncDroplessArena::default(), + arena: SyncDroplessArena::new(), fresh_tables: None, } } diff --git a/src/librustc/lib.rs b/src/librustc/lib.rs index ddb0c5bf22ab6..2ee35270b0d8e 100644 --- a/src/librustc/lib.rs +++ b/src/librustc/lib.rs @@ -86,6 +86,7 @@ extern crate graphviz; extern crate libc; extern crate polonius_engine; extern crate rustc_target; +#[macro_use] extern crate rustc_local_drop_derive; #[macro_use] extern crate rustc_data_structures; extern crate serialize; extern crate parking_lot; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 42a4de1682c39..1364b1fd0325e 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -55,6 +55,7 @@ use util::nodemap::{DefIdMap, DefIdSet, ItemLocalMap}; use util::nodemap::{FxHashMap, FxHashSet}; use rustc_data_structures::interner::HashInterner; use smallvec::SmallVec; +use rustc_data_structures::local_drop::LocalDrop; use rustc_data_structures::stable_hasher::{HashStable, hash_stable_hashmap, StableHasher, StableHasherResult, StableVec}; @@ -92,7 +93,7 @@ impl<'tcx> AllArenas<'tcx> { pub fn new() -> Self { AllArenas { global: WorkerLocal::new(|_| GlobalArenas::default()), - interner: SyncDroplessArena::default(), + interner: SyncDroplessArena::new(), } } } @@ -971,6 +972,16 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } } + #[inline(always)] + pub fn promote(&self, object: T) -> &'gcx T { + self.gcx.global_interners.arena.promote(object) + } + + #[inline(always)] + pub fn promote_vec(&self, vec: Vec) -> &'gcx [T] { + &self.gcx.global_interners.arena.promote(vec)[..] + } + pub fn alloc_generics(self, generics: ty::Generics) -> &'gcx ty::Generics { self.global_arenas.generics.alloc(generics) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 4633ab1166347..86ab8c0b12518 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1052,7 +1052,7 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, LocalDrop)] pub enum Predicate<'tcx> { /// Corresponds to `where Foo: Bar`. `Foo` here would be /// the `Self` type of the trait reference and `A`, `B`, and `C` @@ -1097,10 +1097,7 @@ pub struct CratePredicatesMap<'tcx> { /// For each struct with outlive bounds, maps to a vector of the /// predicate of its outlive bounds. If an item has no outlives /// bounds, it will have no entry. - pub predicates: FxHashMap>>>, - - /// An empty vector, useful for cloning. - pub empty_predicate: Lrc>>, + pub predicates: FxHashMap]>, } impl<'tcx> AsRef> for Predicate<'tcx> { @@ -1203,7 +1200,7 @@ impl<'a, 'gcx, 'tcx> Predicate<'tcx> { } } -#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, LocalDrop)] pub struct TraitPredicate<'tcx> { pub trait_ref: TraitRef<'tcx> } @@ -1231,7 +1228,8 @@ impl<'tcx> PolyTraitPredicate<'tcx> { } } -#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, LocalDrop, + Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct OutlivesPredicate(pub A, pub B); // `A: B` pub type PolyOutlivesPredicate = ty::Binder>; pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, @@ -1241,7 +1239,7 @@ pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder>; pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder>; -#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable, LocalDrop)] pub struct SubtypePredicate<'tcx> { pub a_is_expected: bool, pub a: Ty<'tcx>, @@ -1261,7 +1259,7 @@ pub type PolySubtypePredicate<'tcx> = ty::Binder>; /// equality between arbitrary types. Processing an instance of /// Form #2 eventually yields one of these `ProjectionPredicate` /// instances to normalize the LHS. -#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, LocalDrop)] pub struct ProjectionPredicate<'tcx> { pub projection_ty: ProjectionTy<'tcx>, pub ty: Ty<'tcx>, @@ -2477,7 +2475,8 @@ impl<'a, 'gcx, 'tcx> FieldDef { /// /// You can get the environment type of a closure using /// `tcx.closure_env_ty()`. -#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Clone, Copy, PartialOrd, Ord, PartialEq, LocalDrop, + Eq, Hash, Debug, RustcEncodable, RustcDecodable)] pub enum ClosureKind { // Warning: Ordering is significant here! The ordering is chosen // because the trait Fn is a subtrait of FnMut and so in turn, and diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index 699c2d111c639..6b13b81374fc0 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -142,7 +142,7 @@ define_queries! { <'tcx> /// Returns the inferred outlives predicates (e.g., for `struct /// Foo<'a, T> { x: &'a T }`, this would return `T: 'a`). - [] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> Lrc>>, + [] fn inferred_outlives_of: InferredOutlivesOf(DefId) -> &'tcx [ty::Predicate<'tcx>], /// Maps from the def-id of a trait to the list of /// super-predicates. This is a subset of the full list of diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 1416cb17feaed..2ce16448715cc 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -313,7 +313,8 @@ static_assert!(MEM_SIZE_OF_TY_KIND: ::std::mem::size_of::>() == 24); /// /// It'd be nice to split this struct into ClosureSubsts and /// GeneratorSubsts, I believe. -nmatsakis -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, + Ord, Hash, Debug, RustcEncodable, RustcDecodable, LocalDrop)] pub struct ClosureSubsts<'tcx> { /// Lifetime and type parameters from the enclosing function, /// concatenated with the types of the upvars. @@ -647,7 +648,7 @@ impl<'tcx> Binder<&'tcx List>> { /// Note that a `TraitRef` introduces a level of region binding, to /// account for higher-ranked trait bounds like `T: for<'a> Foo<&'a U>` /// or higher-ranked object types. -#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, LocalDrop)] pub struct TraitRef<'tcx> { pub def_id: DefId, pub substs: &'tcx Substs<'tcx>, @@ -785,7 +786,8 @@ impl<'tcx> PolyExistentialTraitRef<'tcx> { /// erase, or otherwise "discharge" these bound vars, we change the /// type from `Binder` to just `T` (see /// e.g. `liberate_late_bound_regions`). -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, + Debug, RustcEncodable, RustcDecodable, LocalDrop)] pub struct Binder(T); impl Binder { @@ -890,7 +892,8 @@ impl Binder { /// Represents the projection of an associated type. In explicit UFCS /// form this would be written `>::N`. -#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, LocalDrop, + Ord, Hash, Debug, RustcEncodable, RustcDecodable)] pub struct ProjectionTy<'tcx> { /// The parameters of the associated item. pub substs: &'tcx Substs<'tcx>, diff --git a/src/librustc_data_structures/Cargo.toml b/src/librustc_data_structures/Cargo.toml index 188919d063351..860966144f024 100644 --- a/src/librustc_data_structures/Cargo.toml +++ b/src/librustc_data_structures/Cargo.toml @@ -11,6 +11,7 @@ crate-type = ["dylib"] [dependencies] ena = "0.11" log = "0.4" +rustc_local_drop_derive = { path = "../librustc_local_drop_derive" } rustc_cratesio_shim = { path = "../librustc_cratesio_shim" } serialize = { path = "../libserialize" } graphviz = { path = "../libgraphviz" } diff --git a/src/librustc_data_structures/lib.rs b/src/librustc_data_structures/lib.rs index 96cb235a93362..9cf4cb345346f 100644 --- a/src/librustc_data_structures/lib.rs +++ b/src/librustc_data_structures/lib.rs @@ -20,6 +20,7 @@ html_favicon_url = "https://www.rust-lang.org/favicon.ico", html_root_url = "https://doc.rust-lang.org/nightly/")] +#![feature(core_intrinsics)] #![feature(in_band_lifetimes)] #![feature(unboxed_closures)] #![feature(fn_traits)] @@ -42,6 +43,7 @@ extern crate serialize as rustc_serialize; // used by deriving #[cfg(unix)] extern crate libc; extern crate parking_lot; +extern crate rustc_local_drop_derive; #[macro_use] extern crate cfg_if; extern crate stable_deref_trait; @@ -56,9 +58,14 @@ extern crate smallvec; #[allow(unused_extern_crates)] extern crate rustc_cratesio_shim; +mod rustc_data_structures { + pub use ::*; +} + pub use rustc_serialize::hex::ToHex; pub mod macros; +#[macro_use] pub mod local_drop; pub mod svh; pub mod base_n; pub mod bit_set; diff --git a/src/librustc_data_structures/local_drop.rs b/src/librustc_data_structures/local_drop.rs new file mode 100644 index 0000000000000..9ffcc44890165 --- /dev/null +++ b/src/librustc_data_structures/local_drop.rs @@ -0,0 +1,89 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::collections::{HashMap, HashSet}; +use std::hash::BuildHasherDefault; + +/// A type which does not look at references in its destructor +/// but only owned data +pub unsafe trait LocalDrop { + fn check(); +} + +#[inline(always)] +pub fn check(_: &T) { + T::check(); +} + +trait NoDrop { + fn check(); +} + +impl NoDrop for T { + #[inline(always)] + default fn check() {} +} +impl NoDrop for T { + fn check() { + panic!( + "Type {} derives LocalDrop, but has a destructor", + unsafe { std::intrinsics::type_name::() } + ); + } +} + +#[inline(always)] +pub fn ensure_no_drop() { + ::check(); +} + +#[macro_export] +macro_rules! impl_trivial_local_drop { + ([$($p:tt)*] $t:ty) => { + unsafe impl $($p)* $crate::local_drop::LocalDrop for $t { + #[inline(always)] + fn check() { + assert!(!::std::mem::needs_drop::()); + } + } + } +} + +impl_trivial_local_drop!([] bool); +impl_trivial_local_drop!([] u32); +impl_trivial_local_drop!([] u64); +impl_trivial_local_drop!([] usize); +impl_trivial_local_drop!([] BuildHasherDefault); +impl_trivial_local_drop!([<'a, T: 'a + ?Sized>] &'a T); +impl_trivial_local_drop!([<'a, T: 'a + ?Sized>] &'a mut T); + +unsafe impl LocalDrop for Vec { + #[inline(always)] + fn check() { + T::check(); + } +} + +unsafe impl LocalDrop for HashMap { + #[inline(always)] + fn check() { + K::check(); + V::check(); + S::check(); + } +} + +unsafe impl LocalDrop for HashSet { + #[inline(always)] + fn check() { + T::check(); + S::check(); + } +} diff --git a/src/librustc_local_drop_derive/Cargo.toml b/src/librustc_local_drop_derive/Cargo.toml new file mode 100644 index 0000000000000..a93084bcc8d5e --- /dev/null +++ b/src/librustc_local_drop_derive/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "rustc_local_drop_derive" +version = "0.1.0" +authors = ["The Rust Project Developers"] + +[lib] +proc-macro = true + +[dependencies] +synstructure = "0.10.1" +proc-macro2 = "0.4.24" +quote = "0.6.10" \ No newline at end of file diff --git a/src/librustc_local_drop_derive/src/lib.rs b/src/librustc_local_drop_derive/src/lib.rs new file mode 100644 index 0000000000000..8e0bfe0e94440 --- /dev/null +++ b/src/librustc_local_drop_derive/src/lib.rs @@ -0,0 +1,32 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate synstructure; +#[macro_use] +extern crate quote; +extern crate proc_macro2; + +fn local_drop_derive(s: synstructure::Structure) -> proc_macro2::TokenStream { + let body = s.each(|bi| quote!{ + // FIXME Crashes when printed: ::rustc_data_structures::local_drop + ::rustc_data_structures::local_drop::check(#bi); + }); + + s.unsafe_bound_impl(quote!(::rustc_data_structures::local_drop::LocalDrop), quote!{ + fn check() { + ::rustc_data_structures::local_drop::ensure_no_drop::(); + |this: &Self| { + match *this { #body } + }; + } + }) +} +decl_derive!([LocalDrop] => local_drop_derive); diff --git a/src/librustc_typeck/outlives/mod.rs b/src/librustc_typeck/outlives/mod.rs index 1eb53ffc730f6..c1b99b6763c94 100644 --- a/src/librustc_typeck/outlives/mod.rs +++ b/src/librustc_typeck/outlives/mod.rs @@ -33,7 +33,7 @@ pub fn provide(providers: &mut Providers) { fn inferred_outlives_of<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, item_def_id: DefId, -) -> Lrc>> { +) -> &'tcx [ty::Predicate<'tcx>] { let id = tcx .hir .as_local_node_id(item_def_id) @@ -47,8 +47,8 @@ fn inferred_outlives_of<'a, 'tcx>( let predicates = crate_map .predicates .get(&item_def_id) - .unwrap_or(&crate_map.empty_predicate) - .clone(); + .map(|p| *p) + .unwrap_or(&[]); if tcx.has_attr(item_def_id, "rustc_outlives") { let mut pred: Vec = predicates @@ -73,10 +73,10 @@ fn inferred_outlives_of<'a, 'tcx>( predicates } - _ => Lrc::new(Vec::new()), + _ => &[], }, - _ => Lrc::new(Vec::new()), + _ => &[], } } @@ -118,13 +118,10 @@ fn inferred_outlives_crate<'tcx>( ), }, ).collect(); - (def_id, Lrc::new(vec)) + (def_id, tcx.promote_vec(vec)) }).collect(); - let empty_predicate = Lrc::new(Vec::new()); - Lrc::new(ty::CratePredicatesMap { predicates, - empty_predicate, }) } diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs index a40ae8894d5e7..c231c73511e20 100644 --- a/src/tools/tidy/src/deps.rs +++ b/src/tools/tidy/src/deps.rs @@ -107,7 +107,9 @@ const WHITELIST: &[Crate] = &[ Crate("parking_lot_core"), Crate("pkg-config"), Crate("polonius-engine"), + Crate("proc-macro2"), Crate("quick-error"), + Crate("quote"), Crate("rand"), Crate("rand_core"), Crate("redox_syscall"), @@ -123,6 +125,8 @@ const WHITELIST: &[Crate] = &[ Crate("scopeguard"), Crate("smallvec"), Crate("stable_deref_trait"), + Crate("syn"), + Crate("synstructure"), Crate("tempfile"), Crate("termcolor"), Crate("terminon"), @@ -130,6 +134,7 @@ const WHITELIST: &[Crate] = &[ Crate("thread_local"), Crate("ucd-util"), Crate("unicode-width"), + Crate("unicode-xid"), Crate("unreachable"), Crate("utf8-ranges"), Crate("version_check"),