add rustc_no_writable to mem::forget and structs it uses#159181
Conversation
|
cc @rust-lang/miri |
|
rustbot has assigned @Mark-Simulacrum. Use Why was this reviewer chosen?The reviewer was selected based on:
|
|
r? @RalfJung |
|
|
What does this mean? Make it pass on Miri? Does it make previously erroring code compile? Is it making something ub into not-ub? |
| unsafe fn transmute<From, To>(from: From) -> To { | ||
| let to = unsafe { mem::transmute_copy(&from) }; | ||
| mem::forget(from); | ||
| to | ||
| } |
There was a problem hiding this comment.
Is there a reason that we want to bless this pattern with mem::forget specifically, as opposed to guiding people to "pre-forgetting" to avoid reborrowing a reference after creating a derived reference? The following replacement of transmute, for example, does not report UB under the same miri settings.
unsafe fn transmute<From, To>(from: From) -> To {
let from = ManuallyDrop::new(from); // effectively already forgotten, but happens first, so no reborrow after the copy
unsafe { mem::transmute_copy(&from) }
}There was a problem hiding this comment.
Adding a test case is not the same as blessing a code pattern. We should still tell people that it is a bad idea to write code like this.
There was a problem hiding this comment.
Specifically adding the attribute to mem::forget was what I was considering "blessing" it, but the test case was the most obvious place I could think of to demonstrate the pattern. But if this attribute is mostly meant as "internally mitigate the real world effects" rather than a "this is fine actually", then it makes more sense.
There was a problem hiding this comment.
The only thing that should be taken as "this is fine actually" is documentation.
There was a problem hiding this comment.
The attribute is part of an experiment by @RalfJung and me and @quiode to see if we can unlock more optimizations w/o breaking too much real-world code and that includes figuring out which places need this attribute (and if that is "too many"). Since this is all highly experimental, we have not yet thought about how much "intentionality" the attribute ought to convey. Currently we're using it for both, at some later point we will need to decide where the attribute is "intended" and where not (if we decide we want to keep it at all). So I hope we do not need to decide that now :)
This builds upon #155207 and is similar to #157202. It adds the
#[rustc_no_writable]attribute tomem::forgetand theMaybeDanglingandManuallyDrop. This makes a pattern found in the cratederive_morework again.As the pattern itself is quite unclean, and I have not seen
mem::forgetto cause trouble before with implicit writes, I'm not sure how much sense it makes to add it tomem::forget. The test works unter Tree Borrows, but fails already for Stacked Borrows. Thus I would be happy for some guidance if the attribute makes sense here @RalfJung @JoJoDeveloping.