-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
RFC: Amend recover
with a PanicSafe
bound
#1323
Conversation
Instead of a `'static` bound on the function, instead add a new marker trait, `PanicSafe`, to encapsulate the concept of exception safety as a trait bound which can be used to serve as a speed bump for users of `panic::recover`.
Before analyzing this new signature, let's take a look at this new | ||
`PanicSafe` trait. | ||
|
||
## An `PanicSafe` marker trait |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
'An' should be 'A'.
In principle I have nothing against this proposal, since it encourages more safety, but I am really concerned about the currently bad interaction of trait objects and OIBITS. I fear that this will make many types non- |
@reem that is indeed a concern! It was explicitly talked about in the section about global complexity, so could you rephrase your concerns with respect to the wording there? For example that section indicates that the only area this is expected to arise is in a "thread-pool-like" scenario with |
@alexcrichton an example I think @reem means: struct Stream {
inner: Box<Read + Send>
}
// else where
let foo = SomethingHoldingAStream();
panic::recover(|| {
foo.something();
}); Since the |
Yes it's trivial to create an example where one would have to think about an OIBIT, but the key quote from that section is:
The example you've shown isn't necessarily idiomatic usage as it's not expected to use |
Sorry, I don't have much to say about the implementation at all, I don't deal with ffi boundaries myself. Just tossing in an example that @reem and I have run in to, thanks to OIBITs behaving the way they do. |
|
||
The only consumer of the `PanicSafe` bound is the `recover` function on the | ||
closure type parameter, and this ends up meaning that the *environment* needs to | ||
be exception safe. In terms of error messages, this cause the compiler to emit |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
*causes
What happened to If we had such an impl, trait objects like |
@dgrunwald The RFC actually answers this. That |
I am slightly confused by the explicit |
I'm adding T-lang just because I think this lies on the intersection of libs and lang. cc @rust-lang/lang |
Given that the language team hasn't decided what this syntax means yet and is considering making it an error, I don't see how we can make useful comments on the implementation. (Basically the question is whether |
@RalfJung yeah I was a little surprised myself to see it work, but in some local testing all the cases I tried appeared to work as intended. |
That's probably part of the semantic mismatch mentioned by @wthrowe above. We should really get the semantics of OIBITS straight before relying more on them... |
It seems inproportionate to add another OIBIT that doesn't govern any safety boundary at all, and just manages the panic recovery speed bump. |
@bluss That's certainly a point of contention! I think a key part of the discussion about this RFC will be whether the "extra safety" is worth the additional complexity of this new marker trait. I believe that this does not add as much complexity as other markers like On the other hand, however, there are also many opinions that some form of "speed bump" is necessary here (and lots of other various opinions about safety guarantees, etc). In other words, although this doesn't necessarily correspond to a memory safety boundary, there are certainly good arguments to be made for including it nonetheless! |
I don't think it's inappropriate to add a safe OIBIT; what else is that for, but something like this? I really like this proposal. |
@dgrunwald I continue to be largely ambivalent about adding more of these traits. The bang-for-the-buck on thread-safety is huge, but exception-safety is a relatively obscure problem. That said, it seems like using these in any kind of generic context is "doing it wrong", so I guess it's fine? |
@pythonesque I should have qualified that: exception safety issues are relatively obscure in Rust. The argument, as far as I recall from the previous thread, is that recover potential subverts this. |
@gankro Yes, that's the argument. And as you said, the global section does a good job of laying out why the OIBIT doesn't really matter here: it shouldn't come up if you're using panic properly for the most part. Honestly, the main reason I want PanicSafe is so anything that plans to catch an exception with your type has to either (1) advertise that fact, or (2) the author has to actually think before doing it (I think Mutex and poisoning is a great example of why that's effective in practice; there's nothing stopping people from writing a function that grabs the poisoned value out of it if necessary, but there's just enough extra effort involved that people usually don't, which is exactly what we want). |
So are raw pointers panic-safe? |
Yes. |
@pythonesque The problem is that the Second problem, the term "panic safe" is stolen, and we have to qualify if we mean |
An easy question: why isn't And a triviality: in the Unresolved Questions section it lists the question of keeping |
Essentially, think of |
However, I also don't really see the point of providing |
@wthrowe the invariants (In this instance,
What do you mean by this? |
I can't think of any way that tricking C into believing it has less space allocated then it actually does could lead to memory unsafety, but perhaps there's something I'm not thinking of. In any case, that might be the same sort of guarantee we want to give with For the second point I was just referring to the issue that has been mentioned several times above that all of this can already be observed in destructor calls during unwinding. |
Hm, maybe. @rust-lang/libs should talk about it.
This isn't appropriate for the same reasons
Hm, I don't see how it is possible to observe an invalid |
Oh, sorry! When I said "observing the broken invariants protected in this case can already be done in safe code" I meant the case discussed in this RFC, not I think I agree with everything you are saying. Sorry for the confusion! |
The libs team discussed this during triage yesterday and the conclusion was to merge it at this time. We're still not 100% sure that this will make it all the way to stabilization, but the general consensus about this RFC seems to be either in approval or "ok, let's try it out". The libs team wants to definitely keep an eye out for the global complexity problem associated with adding a new marker trait, there's rationale here as to why it's mitigated but something new can always pop up! To emphasize, this RFC is now entering what is basically the "implementation phase" where it will still be unstable in the standard library but we'll be able to play around with it on nightly and get feedback about the concrete API. There will be another round of discussion when we move to stabilize this. Thanks again for all the discussion everyone! |
RFC: Amend `recover` with a `PanicSafe` bound
This commit is an implementation of [RFC 1236] and [RFC 1323] which rename the `thread::catch_panic` function to `panic::recover` while also replacing the `Send + 'static` bounds with a new `PanicSafe` bound. [RFC 1236]: rust-lang/rfcs#1236 [RFC 1323]: rust-lang/rfcs#1323 cc rust-lang#27719
This commit is an implementation of [RFC 1236] and [RFC 1323] which rename the `thread::catch_panic` function to `panic::recover` while also replacing the `Send + 'static` bounds with a new `PanicSafe` bound. [RFC 1236]: rust-lang/rfcs#1236 [RFC 1323]: rust-lang/rfcs#1323 cc #27719
This commit is an implementation of [RFC 1236] and [RFC 1323] which rename the `thread::catch_panic` function to `panic::recover` while also replacing the `Send + 'static` bounds with a new `PanicSafe` bound. [RFC 1236]: rust-lang/rfcs#1236 [RFC 1323]: rust-lang/rfcs#1323 cc rust-lang#27719
This commit is an implementation of [RFC 1236] and [RFC 1323] which rename the `thread::catch_panic` function to `panic::recover` while also replacing the `Send + 'static` bounds with a new `PanicSafe` bound. [RFC 1236]: rust-lang/rfcs#1236 [RFC 1323]: rust-lang/rfcs#1323 cc #27719
Instead of a
'static
bound on the function, instead add a new marker trait,PanicSafe
, to encapsulate the concept of exception safety as a trait boundwhich can be used to serve as a speed bump for users of
panic::recover
.