From e9c9b14b841c487b08ee5ef6dfd44a7c91844ae5 Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 10 May 2019 14:23:21 -0600 Subject: [PATCH 01/20] Added template --- text/XXX-annotate-unwind-rust.md | 96 ++++++++++++++++++++++++++++++++ 1 file changed, 96 insertions(+) create mode 100644 text/XXX-annotate-unwind-rust.md diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md new file mode 100644 index 00000000000..0ca5d7f79c0 --- /dev/null +++ b/text/XXX-annotate-unwind-rust.md @@ -0,0 +1,96 @@ +- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) +- Start Date: (fill me in with today's date, YYYY-MM-DD) +- RFC PR: ??? +- Rust Issue: ??? + +# Summary +[summary]: #summary + +One paragraph explanation of the feature. + +# Motivation +[motivation]: #motivation + +Why are we doing this? What use cases does it support? What is the expected outcome? + +# Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: + +- Introducing new named concepts. +- Explaining the feature largely in terms of examples. +- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible. +- If applicable, provide sample error messages, deprecation warnings, or migration guidance. +- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. + +For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms. + +# Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +This is the technical portion of the RFC. Explain the design in sufficient detail that: + +- Its interaction with other features is clear. +- It is reasonably clear how the feature would be implemented. +- Corner cases are dissected by example. + +The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. + +# Drawbacks +[drawbacks]: #drawbacks + +Why should we *not* do this? + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +- Why is this design the best in the space of possible designs? +- What other designs have been considered and what is the rationale for not choosing them? +- What is the impact of not doing this? + +# Prior art +[prior-art]: #prior-art + +Discuss prior art, both the good and the bad, in relation to this proposal. +A few examples of what this can include are: + +- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? +- For community proposals: Is this done by some other community and what were their experiences with it? +- For other teams: What lessons can we learn from what other communities have done here? +- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background. + +This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. +If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. + +Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. +Please also take into consideration that rust sometimes intentionally diverges from common language features. + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +- What parts of the design do you expect to resolve through the RFC process before this gets merged? +- What parts of the design do you expect to resolve through the implementation of this feature before stabilization? +- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC? + +# Future possibilities +[future-possibilities]: #future-possibilities + +Think about what the natural extension and evolution of your proposal would +be and how it would affect the language and project as a whole in a holistic +way. Try to use this section as a tool to more fully consider all possible +interactions with the project and language in your proposal. +Also consider how the this all fits into the roadmap for the project +and of the relevant sub-team. + +This is also a good place to "dump ideas", if they are out of scope for the +RFC you are writing but otherwise related. + +If you have tried and cannot think of any future possibilities, +you may simply state that you cannot think of anything. + +Note that having something written down in the future-possibilities section +is not a reason to accept the current or a future RFC; such notes should be +in the section on motivation or rationale in this or subsequent RFCs. +The section merely provides additional information. + From 83dfc20792cfd59ca2ab5e21c1ea474821206a08 Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 10 May 2019 15:25:40 -0600 Subject: [PATCH 02/20] Add summary, motivation, and guide --- text/XXX-annotate-unwind-rust.md | 75 +++++++++++++++++++++++++++----- 1 file changed, 64 insertions(+), 11 deletions(-) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md index 0ca5d7f79c0..20bdcb85031 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-annotate-unwind-rust.md @@ -6,25 +6,78 @@ # Summary [summary]: #summary -One paragraph explanation of the feature. +A new function annotation, `#[unwind(Rust)]`, will be introduced; it will +explicitly permit `extern` functions to unwind (`panic`) without aborting. No +guarantees are made regarding the specific unwinding implementation. # Motivation [motivation]: #motivation -Why are we doing this? What use cases does it support? What is the expected outcome? +This will enable resolving +[rust-lang/rust#58794](https://github.com/rust-lang/rust/issues/58794) without +breaking existing code. + +Currently, unwinding through an FFI boundary is always undefined behavior. We +would like to make the behavior safe by aborting when the stack is unwound to +an FFI boundary. However, there are existing Rust crates (notably, wrappers +around the `libpng` and `libjpeg` C libraries) that make use of the current +implementation's behavior. The proposed annotation would act as an "opt out" of +the safety guarantee provided by aborting at an FFI boundary. # Guide-level explanation [guide-level-explanation]: #guide-level-explanation -Explain the proposal as if it was already included in the language and you were teaching it to another Rust programmer. That generally means: - -- Introducing new named concepts. -- Explaining the feature largely in terms of examples. -- Explaining how Rust programmers should *think* about the feature, and how it should impact the way they use Rust. It should explain the impact as concretely as possible. -- If applicable, provide sample error messages, deprecation warnings, or migration guidance. -- If applicable, describe the differences between teaching this to existing Rust programmers and new Rust programmers. - -For implementation-oriented RFCs (e.g. for compiler internals), this section should focus on how compiler contributors should think about the change, and give examples of its concrete impact. For policy RFCs, this section should provide an example-driven introduction to the policy, and explain its impact in concrete terms. +Consider an `extern "C"` function that may `panic`: + +```rust +extern "C" fn may_panic(i: i32) { + if i < 0 { + panic!("Oops, I should have used u32."); + } +} +``` + +In a future (TBD) version of Rust, calling this function with an argument less +than zero will cause the program to be aborted. This is the only way the Rust +compiler can ensure that the function is safe, because there is no way for it +to know whether or not the calling code supports the same implementation of +stack-unwinding used for Rust. + +As a concrete example, Rust code marked `exern "C"` may be invoked from C code, +but C code on Linux or BSD may be compiled without support for native +stack-unwinding. This means that the runtime would lack the necessary metadata +to properly perform the unwinding operation. + +However, there are cases in which a `panic` through an `extern` function can be +used safely. For instance, it is possible to invoke `extern` Rust functions +via Rust code built with the same toolchain, in which case it would be +irrelevant to the unwinding operation that the `panic`ing function is an +`extern` function: + +```rust +fn main() { + let result = panic::catch_unwind(|| { + may_panic(-1); + } + assert!(result.is_err()); +} +``` + +In order to ensure that `may_panic` will not simply abort in a future version +of Rust, it must be marked `#[unwind(Rust)]`. This annotation can only be used +with an `unsafe` function, since the compiler is unable to make guarantees +about the behavior of the caller. + +```rust +#[unwind(Rust)] +unsafe extern "C" fn may_panic(i: i32) { + if i < 0 { + panic!("Oops, I should have used u32."); + } +} +``` + + # Reference-level explanation [reference-level-explanation]: #reference-level-explanation From 949ae9f8d44d797fe8c78ca68acd1a5a41991435 Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 10 May 2019 15:33:57 -0600 Subject: [PATCH 03/20] Add caveats --- text/XXX-annotate-unwind-rust.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md index 20bdcb85031..ff3be4b5fc3 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-annotate-unwind-rust.md @@ -77,6 +77,24 @@ unsafe extern "C" fn may_panic(i: i32) { } ``` +**PLEASE NOTE:** Using this annotation **does not** provide any guarantees +about the unwinding implementation. Therefore, using this feature to compile +functions intended to be called by C code **does not make the behavior +well-defined**; in particular, **the behavior may change in a future version of +Rust.** + +The *only* well-defined behavior specified by this annotation is Rust-to-Rust +unwinding. + +It is safe to call such a function from C or C++ code only if that code is +guaranteed to provide the same unwinding implementation as the Rust compiler +used to compile the function. + +Since the behavior may be subject to change without notice as the Rust compiler +is updated, it is recommended that all projects that rely on unwinding from +Rust code into C code lock the project's `rustc` version and only update it +after ensuring that the behavior will remain correct. + # Reference-level explanation From 701129ee2f2e0b57837bbf5d2b1952aea1ed8c80 Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 10 May 2019 15:47:07 -0600 Subject: [PATCH 04/20] Drawbacks --- text/XXX-annotate-unwind-rust.md | 33 +++++++++++++++++++++++--------- 1 file changed, 24 insertions(+), 9 deletions(-) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md index ff3be4b5fc3..98533cc17e7 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-annotate-unwind-rust.md @@ -95,23 +95,38 @@ is updated, it is recommended that all projects that rely on unwinding from Rust code into C code lock the project's `rustc` version and only update it after ensuring that the behavior will remain correct. - - # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -This is the technical portion of the RFC. Explain the design in sufficient detail that: - -- Its interaction with other features is clear. -- It is reasonably clear how the feature would be implemented. -- Corner cases are dissected by example. +Unwinding for functions marked `#[unwind(Rust)]` is performed as if the +function were not marked `extern`. This is identical to the behavior of `rustc` +for all versions prior to 1.35 except for 1.24.0. -The section should return to the examples given in the previous section, and explain more fully how the detailed proposal makes those examples work. +This annotation has no effect on functions not marked `extern`. # Drawbacks [drawbacks]: #drawbacks -Why should we *not* do this? +Since the Rust unwinding implementation is not specified, this annotation is +explicitly designed to expose a potentially non-forward-compatible API. As +mentioned in (the guide-level explanation)[#guide-level-explanation], use of +this annotation will make projects vulnerable to breakage (and specifically to +undefined behavior) simply by updating their Rust compiler. + +Furthermore, this annotation will have different behaviors on different +platforms, and determining whether it is safe to use on a particular platform +is fairly difficult. So far, there are only two safe use cases identified: + +* On Windows, C code built with MSVC always respects SEH, the unwinding + mechanism used by both (MSVC) Rust and C++, so it should always be safe to + invoke such a function when MSVC is the only toolchain used, as long as + `rustc` uses SEH as its `panic` implementation. +* In projects using LLVM or GCC exclusively, the `-fexceptions` flag ensures + that C code is compiled with C++ exception support, so the runtime behavior + should be safe as long as `rustc` uses the native C++ exception mechanism as + its `panic` implementation. + + # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives From 82a5af8b7570401395d90a6e7cfaf81a239118b3 Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 10 May 2019 15:55:17 -0600 Subject: [PATCH 05/20] A bit more in ref section --- text/XXX-annotate-unwind-rust.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md index 98533cc17e7..1683344da69 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-annotate-unwind-rust.md @@ -102,7 +102,9 @@ Unwinding for functions marked `#[unwind(Rust)]` is performed as if the function were not marked `extern`. This is identical to the behavior of `rustc` for all versions prior to 1.35 except for 1.24.0. -This annotation has no effect on functions not marked `extern`. +This annotation has no effect on functions not marked `extern`. It has no +observable effect unless the marked function `panic`s (e.g. it has no +observable effect when a function returns normally or enters an infinite loop). # Drawbacks [drawbacks]: #drawbacks From ee167e1e3fcdafd12c0e2f698a87bdbf8296726c Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 10 May 2019 16:21:39 -0600 Subject: [PATCH 06/20] rationale, alternatives, prior art --- text/XXX-annotate-unwind-rust.md | 49 +++++++++++++++++++++----------- 1 file changed, 32 insertions(+), 17 deletions(-) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md index 1683344da69..1e6cad12165 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-annotate-unwind-rust.md @@ -128,31 +128,46 @@ is fairly difficult. So far, there are only two safe use cases identified: should be safe as long as `rustc` uses the native C++ exception mechanism as its `panic` implementation. - - # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives -- Why is this design the best in the space of possible designs? -- What other designs have been considered and what is the rationale for not choosing them? -- What is the impact of not doing this? +This is the minimum possible change to the language that will permit making +`panic` safe by default while permitting existing users of the current behavior +a way to keep their code working after +[rust-lang/rust#58794](https://github.com/rust-lang/rust/issues/58794) is +resolved. + +The language team has twice attempted to stabilize the desired default behavior +of aborting when unwinding across an FFI boundary without providing a way to +opt-out of this behavior, but it has become clear that the community will not +accept such a change without a means of opting out because of the impact on +existing projects (particularly [mozjpeg](https://crates.io/crates/mozjpeg)). + +Any alternatives that provide guarantees about the specific Rust unwinding +implementation would make implementation more difficult and would lock us in to +a specific annotation semantics for describing unwinding mechanisms. Suggested +notations include: + +- `#[unwind(c)]` +- `#[unwind(c++)]` +- `#[unwind(c++-native)]` +- `#[unwind(seh)]` + +This proposal does not exclude the possibility of introducing one or more of +these notations at a later date, and indeed it will almost certainly be +necessary to introduce a way to specify an unwinding implementation if the +`rustc` default unwinding mechnanism ever changes. However, introducing such +a notation would be a larger change to the language, and there is no consensus +yet on what the notation should be. # Prior art [prior-art]: #prior-art -Discuss prior art, both the good and the bad, in relation to this proposal. -A few examples of what this can include are: - -- For language, library, cargo, tools, and compiler proposals: Does this feature exist in other programming languages and what experience have their community had? -- For community proposals: Is this done by some other community and what were their experiences with it? -- For other teams: What lessons can we learn from what other communities have done here? -- Papers: Are there any published papers or great posts that discuss this? If you have some relevant papers to refer to, this can serve as a more detailed theoretical background. - -This section is intended to encourage you as an author to think about the lessons from other languages, provide readers of your RFC with a fuller picture. -If there is no prior art, that is fine - your ideas are interesting to us whether they are brand new or if it is an adaptation from other languages. +The proposed behavior of this annotation is simply to maintain the existing +behavior for un-annotated functions. -Note that while precedent set by other languages is some motivation, it does not on its own motivate an RFC. -Please also take into consideration that rust sometimes intentionally diverges from common language features. +As mentioned above, GCC and LLVM provide an `-fexceptions` flag that makes the +C++ exception mechanism interoperable with C stackframes. # Unresolved questions [unresolved-questions]: #unresolved-questions From 82133d800d289fca46892549129730f37064ac7f Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 10 May 2019 16:25:38 -0600 Subject: [PATCH 07/20] First draft done --- text/XXX-annotate-unwind-rust.md | 32 ++++++++++++-------------------- 1 file changed, 12 insertions(+), 20 deletions(-) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md index 1e6cad12165..f3fb991f4e1 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-annotate-unwind-rust.md @@ -172,28 +172,20 @@ C++ exception mechanism interoperable with C stackframes. # Unresolved questions [unresolved-questions]: #unresolved-questions -- What parts of the design do you expect to resolve through the RFC process before this gets merged? -- What parts of the design do you expect to resolve through the implementation of this feature before stabilization? -- What related issues do you consider out of scope for this RFC that could be addressed in the future independently of the solution that comes out of this RFC? +As mentioned [above](#rationale-and-alternatives), further work will be +required to provide a means of specifying details of the unwinding +implementation to provide guarnateed-safe interoperability with (some) C and +C++ code. That work is out of scope for this RFC. # Future possibilities [future-possibilities]: #future-possibilities -Think about what the natural extension and evolution of your proposal would -be and how it would affect the language and project as a whole in a holistic -way. Try to use this section as a tool to more fully consider all possible -interactions with the project and language in your proposal. -Also consider how the this all fits into the roadmap for the project -and of the relevant sub-team. - -This is also a good place to "dump ideas", if they are out of scope for the -RFC you are writing but otherwise related. - -If you have tried and cannot think of any future possibilities, -you may simply state that you cannot think of anything. - -Note that having something written down in the future-possibilities section -is not a reason to accept the current or a future RFC; such notes should be -in the section on motivation or rationale in this or subsequent RFCs. -The section merely provides additional information. +As mentioned [above](#rationale-and-alternatives), further work will be +required to provide a means of specifying details of the unwinding +implementation to provide guarnateed-safe interoperability with (some) C and +C++ code. That work is out of scope for this RFC. +Note that this feature _does not_ commit the team to delivering future variants +of the `#[unwind(...)]` annotation. For instance, compatibility with C code +could be provided via a `rustc` flag specifying the (global) unwinding +implementation to use. From ad0f6b9494b6ef006f51626d6d824bdd4aa2eeeb Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Sat, 11 May 2019 22:06:33 -0600 Subject: [PATCH 08/20] Update text/XXX-annotate-unwind-rust.md Fix link markdown Co-Authored-By: Joe ST --- text/XXX-annotate-unwind-rust.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-annotate-unwind-rust.md index f3fb991f4e1..f92dba59480 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-annotate-unwind-rust.md @@ -111,7 +111,7 @@ observable effect when a function returns normally or enters an infinite loop). Since the Rust unwinding implementation is not specified, this annotation is explicitly designed to expose a potentially non-forward-compatible API. As -mentioned in (the guide-level explanation)[#guide-level-explanation], use of +mentioned in [the guide-level explanation](#guide-level-explanation), use of this annotation will make projects vulnerable to breakage (and specifically to undefined behavior) simply by updating their Rust compiler. From 05d0d24263bc86df412b07d7e6e533f1a763a3a5 Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Fri, 5 Jul 2019 19:12:02 -0600 Subject: [PATCH 09/20] Start re-working to use 'unwind(allowed)' and 'panic_runtime' --- ...otate-unwind-rust.md => XXX-unwind-FFI.md} | 46 ++++++++++++++----- 1 file changed, 34 insertions(+), 12 deletions(-) rename text/{XXX-annotate-unwind-rust.md => XXX-unwind-FFI.md} (83%) diff --git a/text/XXX-annotate-unwind-rust.md b/text/XXX-unwind-FFI.md similarity index 83% rename from text/XXX-annotate-unwind-rust.md rename to text/XXX-unwind-FFI.md index f3fb991f4e1..abc58846bec 100644 --- a/text/XXX-annotate-unwind-rust.md +++ b/text/XXX-unwind-FFI.md @@ -1,4 +1,4 @@ -- Feature Name: (fill me in with a unique ident, `my_awesome_feature`) +- Feature Name: `unwind-through-FFI` - Start Date: (fill me in with today's date, YYYY-MM-DD) - RFC PR: ??? - Rust Issue: ??? @@ -6,23 +6,41 @@ # Summary [summary]: #summary -A new function annotation, `#[unwind(Rust)]`, will be introduced; it will -explicitly permit `extern` functions to unwind (`panic`) without aborting. No -guarantees are made regarding the specific unwinding implementation. +Provide a well-defined mechanism for unwinding through FFI boundaries. + +* Stabilize the function annotation `#[unwind(allowed)]`, + which explicitly permits `extern` functions + to unwind (`panic`) without aborting. +* If this annotation is used anywhere in the dependency tree, + generation of the final product will fail + unless the panic strategy is `unwind` + and a non-default panic runtime is specified. +* Provide an `unwind` runtime in the standard library + that guarantees compatibility with the native exception mechanism + provided by the compiler backend. +* Provide a Cargo option under `[profile.def]` to specify a `panic` runtime. # Motivation [motivation]: #motivation This will enable resolving -[rust-lang/rust#58794](https://github.com/rust-lang/rust/issues/58794) without -breaking existing code. +[rust-lang/rust#58794](https://github.com/rust-lang/rust/issues/58794) +without breaking existing code. + +Currently, unwinding through an FFI boundary is always undefined behavior. +We would like to make the behavior safe +by aborting when the stack is unwound to an FFI boundary. +However, there are existing Rust crates +(notably, wrappers around the `libpng` and `libjpeg` C libraries) +that rely on the current implementation's compatibility +with the native exception handling mechanism in +GCC, LLVM, and MSVC. + +This RFC will give crate authors the ability +to initiate stack-unwinding +that can propagate through other languages' stack frames, +as well as tools for ensuring compatibility with those languages. -Currently, unwinding through an FFI boundary is always undefined behavior. We -would like to make the behavior safe by aborting when the stack is unwound to -an FFI boundary. However, there are existing Rust crates (notably, wrappers -around the `libpng` and `libjpeg` C libraries) that make use of the current -implementation's behavior. The proposed annotation would act as an "opt out" of -the safety guarantee provided by aborting at an FFI boundary. # Guide-level explanation [guide-level-explanation]: #guide-level-explanation @@ -37,6 +55,10 @@ extern "C" fn may_panic(i: i32) { } ``` +---------------------------------------------------------------------------- +TODO below this line +---------------------------------------------------------------------------- + In a future (TBD) version of Rust, calling this function with an argument less than zero will cause the program to be aborted. This is the only way the Rust compiler can ensure that the function is safe, because there is no way for it From ae914df522bc10af2a964b91a9851581c213e3ee Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Sat, 6 Jul 2019 00:02:12 -0600 Subject: [PATCH 10/20] continued revisions --- text/XXX-unwind-FFI.md | 141 +++++++++++++++++++++++++---------------- 1 file changed, 87 insertions(+), 54 deletions(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 8a60358b3f2..68227035d58 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -15,6 +15,8 @@ Provide a well-defined mechanism for unwinding through FFI boundaries. generation of the final product will fail unless the panic strategy is `unwind` and a non-default panic runtime is specified. +* Stabilize the `#![panic_runtime]` annotation (from + [RFC #1513](1513-less-unwinding.md)). * Provide an `unwind` runtime in the standard library that guarantees compatibility with the native exception mechanism provided by the compiler backend. @@ -55,67 +57,98 @@ extern "C" fn may_panic(i: i32) { } ``` ----------------------------------------------------------------------------- -TODO below this line ----------------------------------------------------------------------------- - -In a future (TBD) version of Rust, calling this function with an argument less -than zero will cause the program to be aborted. This is the only way the Rust -compiler can ensure that the function is safe, because there is no way for it -to know whether or not the calling code supports the same implementation of -stack-unwinding used for Rust. - -As a concrete example, Rust code marked `exern "C"` may be invoked from C code, -but C code on Linux or BSD may be compiled without support for native -stack-unwinding. This means that the runtime would lack the necessary metadata -to properly perform the unwinding operation. +In a future (TBD) version of Rust, +calling this function with an argument less than +zero will cause the program to be aborted. +This is the only way the compiler can ensure that the function is safe, +because there is no way for it to know whether or not the calling code +supports the same implementation of stack-unwinding used for Rust. + +As a concrete example, +this function may be invoked from C code on Linux or BSD +compiled without support for native stack-unwinding. +The C runtime would lack the necessary metadata +to properly propagate the unwinding operation, +so it would be undefined behavior to let the runtime attempt +to unwind the C stack frames. + +However, if the C code is compiled +with support for the same stack-unwinding mechanism +used to by the Rust code, +unwinding across the FFI boundary is well-defined and safe, +and in fact it can be a useful way to handle errors +when working with certain C libraries, such as `libjpeg`. + +Thus, the `may_panic` function may be makred `#[unwind(allow)]`, +which ensures that the unwinding operation will be propagated to the caller +rather than aborting the process. +This annotation will also prevent the compiler +from marking the function as `noexcept` +(which permits the backend toolchain from optimizing based on the assumption +that an unwinding operation cannot escape from a function). + +This annotation can only be used with an `unsafe` function, +since the compiler is unable to guarantee +that the caller will be compiled with a compatible stack-unwinding mechanism. + +This RFC does, however, provide a tool that will enable users +to provide this guarantee themselves. +We will stabilize the `!#[panic_runtime]` annotation, +which [designates a crate as the provider of the final product's panic runtime] +(1513-less-unwinding.md). +Additionally, the standard library's current `panic=unwind` runtime crate, +`libpanic_unwind`, which is compatible with native C++ style exceptions, +will be provided under another name (such as `libpanic_native`) +that guarantees the implementation will remain compatible with C++ exceptions +(while the implementation of `libpanic_unwind` itself may change +to no longer maintain that compatibility). + +In order for Cargo users to be able +to specify the C++ compatible `panic_runtime` implementation, +a new optional value, runtime, will be added to the `profile.dev.panic` option: + +```toml +[profile.dev] +panic = { 'unwind', runtime = 'native' } +``` -However, there are cases in which a `panic` through an `extern` function can be -used safely. For instance, it is possible to invoke `extern` Rust functions -via Rust code built with the same toolchain, in which case it would be -irrelevant to the unwinding operation that the `panic`ing function is an -`extern` function: +`panic.runtime` may only be specified if the panic strategy is `unwind`. +And just as there may only be one strategy +in the dependency graph for a final product, +there may only be one `runtime`. -```rust -fn main() { - let result = panic::catch_unwind(|| { - may_panic(-1); - } - assert!(result.is_err()); -} -``` +For now, the only valid `runtime` keys will be: -In order to ensure that `may_panic` will not simply abort in a future version -of Rust, it must be marked `#[unwind(Rust)]`. This annotation can only be used -with an `unsafe` function, since the compiler is unable to make guarantees -about the behavior of the caller. +* `default` - identical to `panic = 'unwind'` with no `runtime` selected. + This will use Rust's default unwinding runtime, + unless another crate in the final product's dependency graph +specifies `panic = 'abort'`, + in which case the `abort` strategy will take precedence as usual. + which is not guaranteed to be compatible with native exceptions. +* `native` - as discussed above, this will preserve the behavior of the current + implementation of `libpanic_unwind`. +* `crate` - indicates that a non-`std` crate will use `#![panic_runtime]` to + provide the runtime. +* `self` - indicates that this crate itself provides `#![panic_runtime]`. -```rust -#[unwind(Rust)] -unsafe extern "C" fn may_panic(i: i32) { - if i < 0 { - panic!("Oops, I should have used u32."); - } -} -``` +If the `native` or `crate` key is specified +anywhere in a final product's dependency graph, +no crate in that dependency graph may specify the `panic = abort` strategy; +this mismatch will cause the build to fail. -**PLEASE NOTE:** Using this annotation **does not** provide any guarantees -about the unwinding implementation. Therefore, using this feature to compile -functions intended to be called by C code **does not make the behavior -well-defined**; in particular, **the behavior may change in a future version of -Rust.** +The function annotation `#[panic(allowed)]` will only be permitted in crates +that specify a non-default `panic.runtime`. -The *only* well-defined behavior specified by this annotation is Rust-to-Rust -unwinding. +Crates that do not use the `profile.dev.panic` option at all +will remain compatible with any `profile.dev.panic` configuration +used to generate the final product. -It is safe to call such a function from C or C++ code only if that code is -guaranteed to provide the same unwinding implementation as the Rust compiler -used to compile the function. +For non-Cargo users, equivalent `rustc` flags will be provided +(which will be how Cargo itself implements the option). -Since the behavior may be subject to change without notice as the Rust compiler -is updated, it is recommended that all projects that rely on unwinding from -Rust code into C code lock the project's `rustc` version and only update it -after ensuring that the behavior will remain correct. +------------------------------------------------------------------------------- +TODO - below this line +------------------------------------------------------------------------------- # Reference-level explanation [reference-level-explanation]: #reference-level-explanation @@ -148,7 +181,7 @@ is fairly difficult. So far, there are only two safe use cases identified: * In projects using LLVM or GCC exclusively, the `-fexceptions` flag ensures that C code is compiled with C++ exception support, so the runtime behavior should be safe as long as `rustc` uses the native C++ exception mechanism as - its `panic` implementation. + its `panic` implementation. ` # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives From 5c199dd5e7ae197292e4409685ca24d9813a8028 Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Sat, 6 Jul 2019 15:42:20 -0600 Subject: [PATCH 11/20] More progress --- text/XXX-unwind-FFI.md | 127 ++++++++++++++++++++++------------------- 1 file changed, 67 insertions(+), 60 deletions(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 68227035d58..7a639059a57 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -12,7 +12,7 @@ Provide a well-defined mechanism for unwinding through FFI boundaries. which explicitly permits `extern` functions to unwind (`panic`) without aborting. * If this annotation is used anywhere in the dependency tree, - generation of the final product will fail + generation of the final (binary) product will fail unless the panic strategy is `unwind` and a non-default panic runtime is specified. * Stabilize the `#![panic_runtime]` annotation (from @@ -146,80 +146,87 @@ used to generate the final product. For non-Cargo users, equivalent `rustc` flags will be provided (which will be how Cargo itself implements the option). -------------------------------------------------------------------------------- -TODO - below this line -------------------------------------------------------------------------------- - # Reference-level explanation [reference-level-explanation]: #reference-level-explanation -Unwinding for functions marked `#[unwind(Rust)]` is performed as if the -function were not marked `extern`. This is identical to the behavior of `rustc` -for all versions prior to 1.35 except for 1.24.0. - -This annotation has no effect on functions not marked `extern`. It has no -observable effect unless the marked function `panic`s (e.g. it has no -observable effect when a function returns normally or enters an infinite loop). +Unwinding for functions with the `#[unwind(allowed)]` annotation +is performed as if the function were not marked `extern`. +This annotation has no effect on functions not marked `extern`. +It has no observable effect unless the marked function `panic`s +(e.g. it has no observable effect +when a function returns normally or enters an infinite loop). +The LLVM IR for such functions must not be marked `noexcept`. + +The compiler will have a new stable flag, `-C panic.runtime`, +which will be required to enable the `#[unwind(allowed)]` annotation; +as explained above, the flag will specify the expected source +of the panic runtime to be used in the final (binary) product. +If the source is `default`, +the `libpanic_unwind` crate will provide the runtime, +and the `#[unwind(allowed)]` annotation will not be permitted in that crate. + +Different values of `panic.runtime` will not be permitted for different crates +in a single dependency graph, +with the exception of `self`, which may only be used once +in a dependency graph, +and is only compatible with crates using the `crate` value. +Because the `panic` runtime is lazily selected and linked, +crates that do not specify a value for `panic.strategy` +are compatible with crates using any of the four values. +Crates that explicitly specify the `default` runtime, however, +are not compatible with crates using other runtimes. # Drawbacks [drawbacks]: #drawbacks -Since the Rust unwinding implementation is not specified, this annotation is -explicitly designed to expose a potentially non-forward-compatible API. As -mentioned in [the guide-level explanation](#guide-level-explanation), use of -this annotation will make projects vulnerable to breakage (and specifically to -undefined behavior) simply by updating their Rust compiler. - -Furthermore, this annotation will have different behaviors on different -platforms, and determining whether it is safe to use on a particular platform -is fairly difficult. So far, there are only two safe use cases identified: - -* On Windows, C code built with MSVC always respects SEH, the unwinding - mechanism used by both (MSVC) Rust and C++, so it should always be safe to - invoke such a function when MSVC is the only toolchain used, as long as - `rustc` uses SEH as its `panic` implementation. -* In projects using LLVM or GCC exclusively, the `-fexceptions` flag ensures - that C code is compiled with C++ exception support, so the runtime behavior - should be safe as long as `rustc` uses the native C++ exception mechanism as - its `panic` implementation. ` +* This change involves several elements of the toolchain, + from Cargo all the way to codegen and linking. + It also involves the simultaneous stabilization of multiple features. + Although it may be possible to stabilize some of these features + independently of the others, + the proposed changes are still somewhat complex, + even though implementation should be fairly simple. +* The rules regarding the interaction between + `-C panic`, `-C panic.strategy`, and `#[unwind(allowed)]` + are somewhat complex. +* Even with custom `panic` runtimes, + users may still inadvertently cause undefined behavior + by trying to link shared libraries that use different unwind runtimes. + For instance, there is no easy way to know whether a C shared library + on a non-Windows system + was compiled with the `-fexceptions` GCC or LLVM flag; + with this flag, such a library would be unwind-runtime-compatible + with a Rust shared library compiled with `-C panic.strategy=native`, + but without this flag, any attempt to unwind through the C stack frames + (regardless of the runtime used) + would be undefined behavior. + There is no way for Rust to guard against this scenario. # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives -This is the minimum possible change to the language that will permit making -`panic` safe by default while permitting existing users of the current behavior -a way to keep their code working after -[rust-lang/rust#58794](https://github.com/rust-lang/rust/issues/58794) is -resolved. - -The language team has twice attempted to stabilize the desired default behavior -of aborting when unwinding across an FFI boundary without providing a way to -opt-out of this behavior, but it has become clear that the community will not -accept such a change without a means of opting out because of the impact on -existing projects (particularly [mozjpeg](https://crates.io/crates/mozjpeg)). - -Any alternatives that provide guarantees about the specific Rust unwinding -implementation would make implementation more difficult and would lock us in to -a specific annotation semantics for describing unwinding mechanisms. Suggested -notations include: - -- `#[unwind(c)]` -- `#[unwind(c++)]` -- `#[unwind(c++-native)]` -- `#[unwind(seh)]` - -This proposal does not exclude the possibility of introducing one or more of -these notations at a later date, and indeed it will almost certainly be -necessary to introduce a way to specify an unwinding implementation if the -`rustc` default unwinding mechnanism ever changes. However, introducing such -a notation would be a larger change to the language, and there is no consensus -yet on what the notation should be. +This version of this RFC replaces a prior version +that suggested a much more minimal change. +Specifically, it suggested introduing a different function annotation, +`#[unwind(Rust)]`, which would simply ensure that the marked function +would not be marked `noexcept` and would not `abort` on `panic`. +Because the current implementation of `libpanic_unwind` +is compatible with native (C++ style) exceptions, +no further guarantees were made +regarding the behavior of the unwinding operation itself. + +------------------------------------------------------------------------------- +TODO - below this line +------------------------------------------------------------------------------- + +XXX ...explain why the more complex current version is better # Prior art [prior-art]: #prior-art -The proposed behavior of this annotation is simply to maintain the existing -behavior for un-annotated functions. +1513 + +Existing unstable features As mentioned above, GCC and LLVM provide an `-fexceptions` flag that makes the C++ exception mechanism interoperable with C stackframes. From 0289ef4e80331a73a021d508feac41ae3ee0481a Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Sat, 6 Jul 2019 16:43:54 -0600 Subject: [PATCH 12/20] Finish draft with unwind-allowed --- text/XXX-unwind-FFI.md | 86 ++++++++++++++++++++++++++++-------------- 1 file changed, 57 insertions(+), 29 deletions(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 7a639059a57..373d8343889 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -16,17 +16,19 @@ Provide a well-defined mechanism for unwinding through FFI boundaries. unless the panic strategy is `unwind` and a non-default panic runtime is specified. * Stabilize the `#![panic_runtime]` annotation (from - [RFC #1513](1513-less-unwinding.md)). + [RFC #1513](less-unwinding)). * Provide an `unwind` runtime in the standard library that guarantees compatibility with the native exception mechanism provided by the compiler backend. -* Provide a Cargo option under `[profile.def]` to specify a `panic` runtime. +* Provide a Cargo option under `[profile.foo]` to specify a `panic` runtime. + +[less-unwinding]: https://github.com/rust-lang/rfcs/blob/master/text/1513-less-unwinding.md # Motivation [motivation]: #motivation This will enable resolving -[rust-lang/rust#58794](https://github.com/rust-lang/rust/issues/58794) +[rust-lang/rust#58794](rust-ffi-issue) without breaking existing code. Currently, unwinding through an FFI boundary is always undefined behavior. @@ -43,6 +45,7 @@ to initiate stack-unwinding that can propagate through other languages' stack frames, as well as tools for ensuring compatibility with those languages. +[rust-ffi-issue]: https://github.com/rust-lang/rust/issues/58794 # Guide-level explanation [guide-level-explanation]: #guide-level-explanation @@ -95,7 +98,7 @@ This RFC does, however, provide a tool that will enable users to provide this guarantee themselves. We will stabilize the `!#[panic_runtime]` annotation, which [designates a crate as the provider of the final product's panic runtime] -(1513-less-unwinding.md). +(less-unwinding). Additionally, the standard library's current `panic=unwind` runtime crate, `libpanic_unwind`, which is compatible with native C++ style exceptions, will be provided under another name (such as `libpanic_native`) @@ -105,7 +108,7 @@ to no longer maintain that compatibility). In order for Cargo users to be able to specify the C++ compatible `panic_runtime` implementation, -a new optional value, runtime, will be added to the `profile.dev.panic` option: +a new optional value, runtime, will be added to the `profile.foo.panic` option: ```toml [profile.dev] @@ -139,8 +142,8 @@ this mismatch will cause the build to fail. The function annotation `#[panic(allowed)]` will only be permitted in crates that specify a non-default `panic.runtime`. -Crates that do not use the `profile.dev.panic` option at all -will remain compatible with any `profile.dev.panic` configuration +Crates that do not use the `profile.foo.panic` option at all +will remain compatible with any `profile.foo.panic` configuration used to generate the final product. For non-Cargo users, equivalent `rustc` flags will be provided @@ -215,39 +218,64 @@ is compatible with native (C++ style) exceptions, no further guarantees were made regarding the behavior of the unwinding operation itself. -------------------------------------------------------------------------------- -TODO - below this line -------------------------------------------------------------------------------- - -XXX ...explain why the more complex current version is better +Another possibility would be to add the `panic.runtime` options +as new `strategy` values for the `-C panic=foo` flag. +This may be simpler to teach and to implement, +but crates using `-C panic=native` +would be incompatible with all existing crates. + +The current proposal ensures +that Rust provides full control over unwinding behavior +for maximum compatibility with other languages' runtimes +and with existing crates. +The interaction between the `#[unwind(allowed)]` annotation +and the `panic.strategy` option +provides the maximum safety that the toolchain can provide +without limiting Rust's ability to interoperate +with shared libraries in other languages +(particularly `libpng` and `libjpeg` as mentioned +[above](#motivation)). # Prior art [prior-art]: #prior-art -1513 +[RFC #1513](less-unwinding) introduced +the `#![panic_runtime]` attributes, the `-C panic` compiler flag, and +the corresponding `profile.foo.panic` Cargo option. -Existing unstable features +The `#[unwind(allowed)]` annotation already exists as an unstable feature, +though the current implementation does not impose any requirements +on the `panic` implementation. -As mentioned above, GCC and LLVM provide an `-fexceptions` flag that makes the -C++ exception mechanism interoperable with C stackframes. +As mentioned above, GCC and LLVM provide an `-fexceptions` flag +that makes the C++ exception mechanism interoperable with C stackframes. +The C standard does not refer to exceptions at all, however, +and the C++ standard does not make any guarantees +regarding the behavior of exceptions that escape from C++ stack frames +into stack frames written in another language. # Unresolved questions [unresolved-questions]: #unresolved-questions -As mentioned [above](#rationale-and-alternatives), further work will be -required to provide a means of specifying details of the unwinding -implementation to provide guarnateed-safe interoperability with (some) C and -C++ code. That work is out of scope for this RFC. +* Should the `panic.runtime` option and its permitted values be renamed? +* What is the minimal subset of features listed here that must be released + prior to stabilizing the FFI abort-on-`panic` logic + in order to prevent breaking crates that link with `libpng` and `libjpeg`? +* Would multiple `panic` runtimes within a single process space + be a potentially useful feature in the future? + If so, is this RFC forward-compatible with possible approaches + for providing this feature? +* Will C++ code be able to interact with `panic.runtime=native` + by catching the native exception? + What operations (`Drop`ing, re-throwing, introspecting...) would be safe + for the C++ runtime to perform? # Future possibilities [future-possibilities]: #future-possibilities -As mentioned [above](#rationale-and-alternatives), further work will be -required to provide a means of specifying details of the unwinding -implementation to provide guarnateed-safe interoperability with (some) C and -C++ code. That work is out of scope for this RFC. - -Note that this feature _does not_ commit the team to delivering future variants -of the `#[unwind(...)]` annotation. For instance, compatibility with C code -could be provided via a `rustc` flag specifying the (global) unwinding -implementation to use. +If it is safe for C++ code to interact with `panic` objects from Rust, +it may be useful to create a C header declaring an interface to do so. +Such a header would not necessarily be provided by the Rust team +or as part of the Rust toolchain distribution, +but the author of such a header may need assistance +from the author(s) of the native-unwinding runtime crate. From 7ec6c972839d391bb899100472632b302601acee Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Sat, 6 Jul 2019 16:45:56 -0600 Subject: [PATCH 13/20] Mention metadata, as if I knew anything about rlibs --- text/XXX-unwind-FFI.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 373d8343889..420911b4759 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -179,6 +179,11 @@ are compatible with crates using any of the four values. Crates that explicitly specify the `default` runtime, however, are not compatible with crates using other runtimes. +In order to verify that all crates in a dependency graph +are compatible in this way, +new metadata will need to be added to the `rlib` format. +It may be possible to combine this metadata with the `panic` strategy metadata. + # Drawbacks [drawbacks]: #drawbacks From 7a0b191c913cb465cbf44ff61d4026e646f32654 Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Sun, 7 Jul 2019 09:45:06 -0600 Subject: [PATCH 14/20] Apply suggestions from code review Co-Authored-By: gnzlbg --- text/XXX-unwind-FFI.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 420911b4759..c732c43b6ba 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -8,7 +8,7 @@ Provide a well-defined mechanism for unwinding through FFI boundaries. -* Stabilize the function annotation `#[unwind(allowed)]`, +* Add an `#[unwind(allowed)]` function attribute that's supported on `extern` functions and `extern` function declarations. which explicitly permits `extern` functions to unwind (`panic`) without aborting. * If this annotation is used anywhere in the dependency tree, @@ -86,7 +86,7 @@ Thus, the `may_panic` function may be makred `#[unwind(allow)]`, which ensures that the unwinding operation will be propagated to the caller rather than aborting the process. This annotation will also prevent the compiler -from marking the function as `noexcept` +from marking the function as `nounwind` (which permits the backend toolchain from optimizing based on the assumption that an unwinding operation cannot escape from a function). @@ -154,11 +154,11 @@ For non-Cargo users, equivalent `rustc` flags will be provided Unwinding for functions with the `#[unwind(allowed)]` annotation is performed as if the function were not marked `extern`. -This annotation has no effect on functions not marked `extern`. +This annotation is not permitted on functions not marked `extern`. It has no observable effect unless the marked function `panic`s (e.g. it has no observable effect when a function returns normally or enters an infinite loop). -The LLVM IR for such functions must not be marked `noexcept`. +The LLVM IR for such functions must not be marked `nounwind`. The compiler will have a new stable flag, `-C panic.runtime`, which will be required to enable the `#[unwind(allowed)]` annotation; From 24fd58ae7cc7c839a7a28b089f1239fff1efa0be Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Mon, 8 Jul 2019 10:17:07 -0600 Subject: [PATCH 15/20] Fix accidental s/unwind/panic/ --- text/XXX-unwind-FFI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 420911b4759..9c736216842 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -139,7 +139,7 @@ anywhere in a final product's dependency graph, no crate in that dependency graph may specify the `panic = abort` strategy; this mismatch will cause the build to fail. -The function annotation `#[panic(allowed)]` will only be permitted in crates +The function annotation `#[unwind(allowed)]` will only be permitted in crates that specify a non-default `panic.runtime`. Crates that do not use the `profile.foo.panic` option at all From 24a214b5e8a8cb0ef5448f84f3de9e8f12d7f558 Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Mon, 8 Jul 2019 10:46:17 -0600 Subject: [PATCH 16/20] Update text/XXX-unwind-FFI.md Fix markdown syntax --- text/XXX-unwind-FFI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index def77bb16df..2fd44dc3c86 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -28,7 +28,7 @@ Provide a well-defined mechanism for unwinding through FFI boundaries. [motivation]: #motivation This will enable resolving -[rust-lang/rust#58794](rust-ffi-issue) +[rust-lang/rust#58794][rust-ffi-issue] without breaking existing code. Currently, unwinding through an FFI boundary is always undefined behavior. From 282a61f63051fffa4fc809d207fe2f1a6e3aef0a Mon Sep 17 00:00:00 2001 From: Kyle Strand Date: Mon, 8 Jul 2019 10:47:52 -0600 Subject: [PATCH 17/20] Markdown link fixing --- text/XXX-unwind-FFI.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 2fd44dc3c86..fd88389aec4 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -16,7 +16,7 @@ Provide a well-defined mechanism for unwinding through FFI boundaries. unless the panic strategy is `unwind` and a non-default panic runtime is specified. * Stabilize the `#![panic_runtime]` annotation (from - [RFC #1513](less-unwinding)). + [RFC #1513][less-unwinding]). * Provide an `unwind` runtime in the standard library that guarantees compatibility with the native exception mechanism provided by the compiler backend. @@ -244,7 +244,7 @@ with shared libraries in other languages # Prior art [prior-art]: #prior-art -[RFC #1513](less-unwinding) introduced +[RFC #1513][less-unwinding] introduced the `#![panic_runtime]` attributes, the `-C panic` compiler flag, and the corresponding `profile.foo.panic` Cargo option. From e7c9eaa661ff9f9929339d4ad42333e797272ac5 Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Mon, 8 Jul 2019 10:57:48 -0600 Subject: [PATCH 18/20] Update text/XXX-unwind-FFI.md Fix TOML syntax --- text/XXX-unwind-FFI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index fd88389aec4..1c2584961ab 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -112,7 +112,7 @@ a new optional value, runtime, will be added to the `profile.foo.panic` option: ```toml [profile.dev] -panic = { 'unwind', runtime = 'native' } +panic = { strategy = 'unwind', runtime = 'native' } ``` `panic.runtime` may only be specified if the panic strategy is `unwind`. From 306de900c208f4e8d902420d3a80865a10e776c7 Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Wed, 10 Jul 2019 16:02:28 -0600 Subject: [PATCH 19/20] Remove mention of LLVM IR --- text/XXX-unwind-FFI.md | 1 - 1 file changed, 1 deletion(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 1c2584961ab..9a280f646d1 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -158,7 +158,6 @@ This annotation is not permitted on functions not marked `extern`. It has no observable effect unless the marked function `panic`s (e.g. it has no observable effect when a function returns normally or enters an infinite loop). -The LLVM IR for such functions must not be marked `nounwind`. The compiler will have a new stable flag, `-C panic.runtime`, which will be required to enable the `#[unwind(allowed)]` annotation; From 51339410c19311b42fc7d4f6f91a7fab22a01504 Mon Sep 17 00:00:00 2001 From: BatmanAoD Date: Tue, 16 Jul 2019 08:55:21 -0600 Subject: [PATCH 20/20] Update text/XXX-unwind-FFI.md Fix typo caught in review Co-Authored-By: bjorn3 --- text/XXX-unwind-FFI.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/XXX-unwind-FFI.md b/text/XXX-unwind-FFI.md index 9a280f646d1..27e7c2b1fcd 100644 --- a/text/XXX-unwind-FFI.md +++ b/text/XXX-unwind-FFI.md @@ -82,7 +82,7 @@ unwinding across the FFI boundary is well-defined and safe, and in fact it can be a useful way to handle errors when working with certain C libraries, such as `libjpeg`. -Thus, the `may_panic` function may be makred `#[unwind(allow)]`, +Thus, the `may_panic` function may be marked `#[unwind(allow)]`, which ensures that the unwinding operation will be propagated to the caller rather than aborting the process. This annotation will also prevent the compiler