diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 800952f7a5ece..f19a13c8defef 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2303,7 +2303,7 @@ impl Weak { } #[stable(feature = "rc_weak", since = "1.4.0")] -impl Drop for Weak { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Weak { /// Drops the `Weak` pointer. /// /// # Examples diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 17927f5f5fdc4..02a739309cde0 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -2015,7 +2015,7 @@ impl Default for Weak { } #[stable(feature = "arc_weak", since = "1.4.0")] -impl Drop for Weak { +unsafe impl<#[may_dangle] T: ?Sized> Drop for Weak { /// Drops the `Weak` pointer. /// /// # Examples diff --git a/library/alloc/tests/arc.rs b/library/alloc/tests/arc.rs index c02ba267056d6..ce40b5c9b0a0d 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::>()); } + +#[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 501b4f0f816be..efb39a609665b 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::>()); } + +#[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` +}