diff options
| author | Mara Bos <m-ou.se@m-ou.se> | 2020-12-30 20:56:54 +0000 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-12-30 20:56:54 +0000 |
| commit | 3d93dfdf6e46d8c685d82b1b57234a20e81ca539 (patch) | |
| tree | bba79c66f00633d88f91671302d86365cac90880 | |
| parent | 46111c1901cc94c5233e3d5141cb0fc68063552b (diff) | |
| parent | 81685e9ad8f80634f0dfd7c1afcab74ba1c78a59 (diff) | |
| download | rust-3d93dfdf6e46d8c685d82b1b57234a20e81ca539.tar.gz rust-3d93dfdf6e46d8c685d82b1b57234a20e81ca539.zip | |
Rollup merge of #80488 - CAD97:drop-weak-without-reference, r=m-ou-se
Do not create dangling &T in Weak<T>::drop Since at this point all strong pointers have been dropped, the wrapped `T` has also been dropped. As such, creating a `&T` to the dropped place is negligent at best (language UB at worst). Since we have `Layout::for_value_raw` now, use that instead of `Layout::for_value` to avoid creating the `&T`. This does have implications for custom (potentially thin) DSTs, though much less severe than those discussed in #80407. Specifically, one of two things has to be true: - It has to be possible to use a `*const T` to a dropped (potentially custom, potentially thin) unsized tailed object to determine the layout (size/align) of the object. This is what is currently implemented (though with `&T` instead of `&T`). The validity of reading some location after it has been dropped is an open question IIUC (https://github.com/rust-lang/unsafe-code-guidelines/issues/188) (except when the whole type is `Copy`, per `drop_in_place`'s docs). In this design, custom DSTs would get a `*mut T` and use that to return layout, and must be able to do so while in the "zombie" (post-drop, pre-free) state. - `RcBox`/`ArcInner` compute and store layout eagerly, so that they don't have to ask the type for its layout after dropping it. Importantly, this is already true today, as you can construct `Rc<DST>`, create a `Weak<DST>`, and drop the `Rc` before the `Weak`. This PR is a strict improvement over the status quo, and the above question about potentially thin DSTs will need to be resolved by any custom DST proposal.
| -rw-r--r-- | library/alloc/src/rc.rs | 2 | ||||
| -rw-r--r-- | library/alloc/src/sync.rs | 2 |
2 files changed, 2 insertions, 2 deletions
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs index 73d12f0a5f4..57df28a15c8 100644 --- a/library/alloc/src/rc.rs +++ b/library/alloc/src/rc.rs @@ -2042,7 +2042,7 @@ impl<T: ?Sized> Drop for Weak<T> { // the strong pointers have disappeared. if inner.weak() == 0 { unsafe { - Global.deallocate(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())); + Global.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())); } } } diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 7c03345aba5..85c0a9f0857 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -1927,7 +1927,7 @@ impl<T: ?Sized> Drop for Weak<T> { if inner.weak.fetch_sub(1, Release) == 1 { acquire!(inner.weak); - unsafe { Global.deallocate(self.ptr.cast(), Layout::for_value(self.ptr.as_ref())) } + unsafe { Global.deallocate(self.ptr.cast(), Layout::for_value_raw(self.ptr.as_ptr())) } } } } |
