diff options
| author | Josh Stone <jistone@redhat.com> | 2021-03-10 17:53:35 -0800 |
|---|---|---|
| committer | Josh Stone <jistone@redhat.com> | 2021-03-10 17:53:35 -0800 |
| commit | f7e75a2124ccd8e0a655220f70fd1eba765cf5d2 (patch) | |
| tree | 51b50a7b51cba1ab58bcadd2558bd86088fb730b /compiler/rustc_arena | |
| parent | f98721f886ab52d32d622ad0a46216ad03f3e525 (diff) | |
| download | rust-f7e75a2124ccd8e0a655220f70fd1eba765cf5d2.tar.gz rust-f7e75a2124ccd8e0a655220f70fd1eba765cf5d2.zip | |
Update to rustc-rayon 0.3.1
This pulls in rust-lang/rustc-rayon#8 to fix #81425. (h/t @ammaraskar) That revealed weak constraints on `rustc_arena::DropArena`, because its `DropType` was holding type-erased raw pointers to generic `T`. We can implement `Send` for `DropType` (under `cfg(parallel_compiler)`) by requiring all `T: Send` before they're type-erased.
Diffstat (limited to 'compiler/rustc_arena')
| -rw-r--r-- | compiler/rustc_arena/Cargo.toml | 1 | ||||
| -rw-r--r-- | compiler/rustc_arena/src/lib.rs | 34 |
2 files changed, 26 insertions, 9 deletions
diff --git a/compiler/rustc_arena/Cargo.toml b/compiler/rustc_arena/Cargo.toml index f2d039c82ab..5d4d47527d3 100644 --- a/compiler/rustc_arena/Cargo.toml +++ b/compiler/rustc_arena/Cargo.toml @@ -5,4 +5,5 @@ version = "0.0.0" edition = "2018" [dependencies] +rustc_data_structures = { path = "../rustc_data_structures" } smallvec = { version = "1.6.1", features = ["union", "may_dangle"] } diff --git a/compiler/rustc_arena/src/lib.rs b/compiler/rustc_arena/src/lib.rs index 721cfdd4459..a9917f50cc2 100644 --- a/compiler/rustc_arena/src/lib.rs +++ b/compiler/rustc_arena/src/lib.rs @@ -17,6 +17,7 @@ #![feature(min_specialization)] #![cfg_attr(test, feature(test))] +use rustc_data_structures::sync; use smallvec::SmallVec; use std::alloc::Layout; @@ -556,8 +557,19 @@ struct DropType { obj: *mut u8, } -unsafe fn drop_for_type<T>(to_drop: *mut u8) { - std::ptr::drop_in_place(to_drop as *mut T) +// SAFETY: we require `T: Send` before type-erasing into `DropType`. +#[cfg(parallel_compiler)] +unsafe impl sync::Send for DropType {} + +impl DropType { + #[inline] + unsafe fn new<T: sync::Send>(obj: *mut T) -> Self { + unsafe fn drop_for_type<T>(to_drop: *mut u8) { + std::ptr::drop_in_place(to_drop as *mut T) + } + + DropType { drop_fn: drop_for_type::<T>, obj: obj as *mut u8 } + } } impl Drop for DropType { @@ -585,21 +597,26 @@ pub struct DropArena { impl DropArena { #[inline] - pub unsafe fn alloc<T>(&self, object: T) -> &mut T { + pub unsafe fn alloc<T>(&self, object: T) -> &mut T + where + T: sync::Send, + { let mem = self.arena.alloc_raw(Layout::new::<T>()) as *mut T; // Write into uninitialized memory. ptr::write(mem, object); let result = &mut *mem; // Record the destructor after doing the allocation as that may panic // and would cause `object`'s destructor to run twice if it was recorded before. - self.destructors - .borrow_mut() - .push(DropType { drop_fn: drop_for_type::<T>, obj: result as *mut T as *mut u8 }); + self.destructors.borrow_mut().push(DropType::new(result)); result } #[inline] - pub unsafe fn alloc_from_iter<T, I: IntoIterator<Item = T>>(&self, iter: I) -> &mut [T] { + pub unsafe fn alloc_from_iter<T, I>(&self, iter: I) -> &mut [T] + where + T: sync::Send, + I: IntoIterator<Item = T>, + { let mut vec: SmallVec<[_; 8]> = iter.into_iter().collect(); if vec.is_empty() { return &mut []; @@ -620,8 +637,7 @@ impl DropArena { // Record the destructors after doing the allocation as that may panic // and would cause `object`'s destructor to run twice if it was recorded before. for i in 0..len { - destructors - .push(DropType { drop_fn: drop_for_type::<T>, obj: start_ptr.add(i) as *mut u8 }); + destructors.push(DropType::new(start_ptr.add(i))); } slice::from_raw_parts_mut(start_ptr, len) |
