summaryrefslogtreecommitdiffstats
path: root/library/alloc/src/sync
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--library/alloc/src/sync.rs22
-rw-r--r--library/alloc/src/sync/tests.rs19
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();
+ }
+}