diff options
Diffstat (limited to '')
-rw-r--r-- | library/alloc/src/sync.rs | 22 | ||||
-rw-r--r-- | library/alloc/src/sync/tests.rs | 19 |
2 files changed, 41 insertions, 0 deletions
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 4c03cc3ed..4377edeee 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2763,3 +2763,25 @@ fn data_offset_align(align: usize) -> usize { let layout = Layout::new::<ArcInner<()>>(); layout.size() + layout.padding_needed_for(align) } + +#[cfg(not(bootstrap))] +#[stable(feature = "arc_error", since = "1.52.0")] +impl<T: core::error::Error + ?Sized> core::error::Error for Arc<T> { + #[allow(deprecated, deprecated_in_future)] + fn description(&self) -> &str { + core::error::Error::description(&**self) + } + + #[allow(deprecated)] + fn cause(&self) -> Option<&dyn core::error::Error> { + core::error::Error::cause(&**self) + } + + fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { + core::error::Error::source(&**self) + } + + fn provide<'a>(&'a self, req: &mut core::any::Demand<'a>) { + core::error::Error::provide(&**self, req); + } +} diff --git a/library/alloc/src/sync/tests.rs b/library/alloc/src/sync/tests.rs index 202d0e7f0..0fae8953a 100644 --- a/library/alloc/src/sync/tests.rs +++ b/library/alloc/src/sync/tests.rs @@ -618,3 +618,22 @@ fn test_arc_cyclic_two_refs() { assert_eq!(Arc::strong_count(&two_refs), 3); assert_eq!(Arc::weak_count(&two_refs), 2); } + +/// Test for Arc::drop bug (https://github.com/rust-lang/rust/issues/55005) +#[test] +#[cfg(miri)] // relies on Stacked Borrows in Miri +fn arc_drop_dereferenceable_race() { + // The bug seems to take up to 700 iterations to reproduce with most seeds (tested 0-9). + for _ in 0..750 { + let arc_1 = Arc::new(()); + let arc_2 = arc_1.clone(); + let thread = thread::spawn(|| drop(arc_2)); + // Spin a bit; makes the race more likely to appear + let mut i = 0; + while i < 256 { + i += 1; + } + drop(arc_1); + thread.join().unwrap(); + } +} |