-
Notifications
You must be signed in to change notification settings - Fork 501
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
Document guarantees around drop and panicing #348
Comments
Leaving a link here to an assumption we make in generator optimizations: |
Thanks! I feel this is somewhat separate; your assumption is more on the level of MIR semantics that drop shim generation. But it's probably sufficiently closely related. For a different discussion, see rust-lang/rust#60611 and rust-lang/rust#60822. |
struct T(A, B, ManuallyDrop<C>);
impl Drop for T {
fn drop(&mut self) {
let _d = D;
panic!();
unsafe { ManuallyDrop::drop(&mut self.2) };
}
}
struct U(T);
fn main() {
std::panic::catch_unwind(|| {
let _e = E;
let _f = F;
let _t = U(T(A, B, ManuallyDrop::new(C)));
});
// x
} prints:
That is, when a destructor panics:
The type whose We do not guarantee that program execution will reach Doing a For double panics, if already_panicking() {
abort();
} That is, we guarantee that if a program |
Also see the discussion at rust-lang/rust#60766 (comment). Though that's actually more UCG territory? |
I ran into this today, and if we are dropping a struct like: struct H(A, B, C, D, E, F, G); and dropping say field F always panic (playground), all fields except for If dropping two fields panic (playground), then we get a double panic. This obviously extends to slices (one panic and double-panic). |
That seems exactly as expected? What is interesting here? This behavior matches exactly what happens when you have multiple locals ( |
Well, in hindsight, the current behavior makes perfect sense and is consistent with the rest of the language. This came up while reviewing a PR that modifies |
Except for the order, of course. Structs are dropped first field first while locals are dropped last local first.
I see. Yes, I can imagine many of our collections would not be quite as careful as the compiler-generated drop glue is. |
Yes. By consistency I meant that all aggregates are dropped first field first (both structs and arrays), but I know you call all aggregates structs so all is fine 😄 |
Currently, when a panic occurs during a regular (i.e., non-unwinding) drop of a local variable, the remaining local variables are still going to have their
drop
called as usual: https://play.rust-lang.org/?gist=1e2b47513bbfebb71cb6d4e05eca822d&version=stable&mode=debugFurthermore, if a panic occurs during the drop of a struct with members, the member's drop is also still going to be executed: https://play.rust-lang.org/?gist=69c5e0e922f96dbdc939dad6453ecc6c&version=stable&mode=debug
It would be nice to have such guarantees spelled out explicitly somewhere. Given that this is externally visible behavior, it is probably covered by the stability guarantee, but still -- these guarantees will be really important for providing safe stack pinning APIs.
I am not sure what would be a good place for this to be documented, maybe somewhere in https://doc.rust-lang.org/stable/reference/?
Cc @pythonesque
(Moved here from rust-lang/rust#50765)
The text was updated successfully, but these errors were encountered: