diff options
| -rw-r--r-- | library/alloc/src/rc.rs | 2 | ||||
| -rw-r--r-- | library/alloc/src/sync.rs | 2 | ||||
| -rw-r--r-- | library/alloc/tests/arc.rs | 15 | ||||
| -rw-r--r-- | library/alloc/tests/rc.rs | 15 |
4 files changed, 32 insertions, 2 deletions
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 800952f7a5e..f19a13c8def 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2303,7 +2303,7 @@ impl<T: ?Sized> Weak<T> { } #[stable(feature = "rc_weak", since = "1.4.0")] -impl<T: ?Sized> Drop for Weak<T> { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Weak<T> { /// Drops the `Weak` pointer. /// /// # Examples diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 17927f5f5fd..02a739309cd 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2015,7 +2015,7 @@ impl<T> Default for Weak<T> { } #[stable(feature = "arc_weak", since = "1.4.0")] -impl<T: ?Sized> Drop for Weak<T> { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Weak<T> { /// Drops the `Weak` pointer. /// /// # Examples diff --git a/library/alloc/tests/arc.rs b/library/alloc/tests/arc.rs index c02ba267056..ce40b5c9b0a 100644 --- a/library/alloc/tests/arc.rs +++ b/library/alloc/tests/arc.rs @@ -195,3 +195,18 @@ fn shared_from_iter_trustedlen_no_fuse() { assert_trusted_len(&iter); assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>()); } + +#[test] +fn weak_may_dangle() { + fn hmm<'a>(val: &'a mut Weak<&'a str>) -> Weak<&'a str> { + val.clone() + } + + // Without #[may_dangle] we get: + let mut val = Weak::new(); + hmm(&mut val); + // ~~~~~~~~ borrowed value does not live long enough + // + // `val` dropped here while still borrowed + // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::sync::Weak` +} diff --git a/library/alloc/tests/rc.rs b/library/alloc/tests/rc.rs index 501b4f0f816..efb39a60966 100644 --- a/library/alloc/tests/rc.rs +++ b/library/alloc/tests/rc.rs @@ -191,3 +191,18 @@ fn shared_from_iter_trustedlen_no_fuse() { assert_trusted_len(&iter); assert_eq!(&[Box::new(42), Box::new(24)], &*iter.collect::<Rc<[_]>>()); } + +#[test] +fn weak_may_dangle() { + fn hmm<'a>(val: &'a mut Weak<&'a str>) -> Weak<&'a str> { + val.clone() + } + + // Without #[may_dangle] we get: + let mut val = Weak::new(); + hmm(&mut val); + // ~~~~~~~~ borrowed value does not live long enough + // + // `val` dropped here while still borrowed + // borrow might be used here, when `val` is dropped and runs the `Drop` code for type `std::rc::Weak` +} |
