-
Notifications
You must be signed in to change notification settings - Fork 59
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Can Drop::drop invalidate the value? (i.e. can drop_in_place rely on the value staying valid-but-unusable) #394
Comments
I think the comma between "unchanged" and "and" would be spurious in the second interpretation, so I think the first is more likely. Would whoever added that to the docs be able to give useful input to this discussion? |
120% agreement to this. I actually wouldn't mind a PR that removes this phrasing |
I'd rather have something to that effect left in if we can manage to get alignment on what it should be. |
It's worth noting too that this has significance on the I don't know which of these two is more likely to cause issues for users. |
Agreed. But until we can agree on what it should be, I'm not so sure that sentence is better than just saying nothing |
I think we should declare such Drop impls as unsound because:
Overall it feels like declaring these as unsound is low-risk-high-reward.
I wonder if we can make the sentence say something useful for the specific case (where you know the type's Drop impl) as opposed to the generic one. |
At least somewhat relevant is that |
That is the interpretation I always had in mind. Given that |
Strictly speaking, I don't think this is true. Dropping the contents of a |
I would expect that if such a move was wrong that has to be documented in |
This is important in the context of zeroizing cryptographic secrets. For example, we would like to define roughly the following function in the pub unsafe fn zeroize_flat_type<T: Sized>(data: *mut T) {
ptr::drop_in_place(data);
ptr::write_bytes(data, 0, 1);
hint::black_box(data);
}
#[repr(transparent)]
pub struct ZeroizeOnDrop<T: Sized>(pub T);
impl<T: Sized> Drop for ZeroizeOnDrop<T> {
fn drop(&mut self) {
unsafe { zeroize_flat_type(&mut self.0); }
}
} And then it would be really nice for Also, isn't |
Note that your two code snippets are mutually recursive.
It invalidates its own safety invariant but not its validity invariant. |
Ah, yes. I will fix the example. |
Related: whether Zulip discussion: https://rust-lang.zulipchat.com/#narrow/stream/136281-t-opsem/topic/Moving.20.60ManuallyDrop.3CBox.3C_.3E.3E.60 |
See: rust-lang/rust#108684 and this zulip discussion
Firstly, let's assume that
ManuallyDrop::drop()
is equivalent toptr::drop_in_place()
since the docs claim they are.ManuallyDrop::drop()
makes an interesting claim:This can be parsed in two ways:
and
The question becomes: is
Drop::drop()
allowed to invalidate the type? Is it fine for its body to be*self = uninit
or e.g. for abool
something like*self = transmute(73)
?This has different implications in a world with shallow vs deep validity (#77), because if there is deep validity this means that it might be insta-UB to pass an
&mut T
toptr::drop_in_place()
(otoh it might be insta-UB to write aDrop
impl that invalidates its own&mut self
, so it still could be okay, depending on precisely how long validity is supposed to last)As it currently stands with the ambiguity, the note of "as far as the compiler is concerned still holds a bit-pattern which is valid for the type T." is not really useful. We should figure out what it means, and clarify the docs to say so.
The text was updated successfully, but these errors were encountered: