|
| 1 | +- Feature Name: `project-unwind-FFI` |
| 2 | +- Start Date: 2019-10-27 |
| 3 | +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) |
| 4 | +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) |
| 5 | + |
| 6 | +# Summary |
| 7 | +[summary]: #summary |
| 8 | + |
| 9 | +* To create a "project group" with the purpose of designing subsequent RFCs to |
| 10 | + extend the language to support unwinding that crosses FFI boundaries |
| 11 | + * The "project group" term is newly introduced: it is a specific type of |
| 12 | + working group whose goal is to flesh out a particular proposal or complete |
| 13 | + a project. |
| 14 | + * This project group plans to recommend specifications of how "C unwind" will work on major |
| 15 | + platforms. |
| 16 | + * The primary goal is to enable Rust panics to propagate safely across |
| 17 | + foreign frames. |
| 18 | + * A future goal may be to enable foreign exceptions to propagate across Rust |
| 19 | + frames. |
| 20 | + * We do not plan to allow catching or throwing foreign exceptions from Rust |
| 21 | + code |
| 22 | + |
| 23 | +# Motivation |
| 24 | +[motivation]: #motivation |
| 25 | + |
| 26 | +Unwinding through Rust's `extern "C"` ABI is [Undefined Behavior]. There is an |
| 27 | +[existing plan][abort-unwind] to make the behavior of Rust's `panic` |
| 28 | +well-defined by causing Rust functions defined with `extern "C"` to abort the |
| 29 | +application whenever an uncaught `panic` would otherwise escape into the |
| 30 | +caller. Unfortunately, previous attempts to stabilize this behavior have caused |
| 31 | +existing, working projects to break. |
| 32 | + |
| 33 | +The problem here is not that the existing projects break *per se*: they are |
| 34 | +relying on [Undefined Behavior], so breakage is to be expected as a |
| 35 | +possibility. The problem is that there is no alternative available to them that |
| 36 | +would allow them to keep working (even if they are continuing to rely on |
| 37 | +behavior that is not yet fully specified). |
| 38 | + |
| 39 | +Previous attempts to provide a well-defined mechanism for unwinding across FFI |
| 40 | +boundaries have failed to reach consensus. Notably, two proposed RFCs generated |
| 41 | +over 400 comments between them before ultimately being closed: |
| 42 | + |
| 43 | +* [rust-lang/rfcs#2699](https://github.com/rust-lang/rfcs/pull/2699) |
| 44 | +* [rust-lang/rfcs#2753](https://github.com/rust-lang/rfcs/pull/2753) |
| 45 | + |
| 46 | +GitHub comment threads become difficult to follow for discussions this lengthy, |
| 47 | +and the disagreements in these threads have felt less productive than we |
| 48 | +believe they could be if more structure were provided. |
| 49 | + |
| 50 | +We would also like to demonstrate the Rust lang team's commitment to providing |
| 51 | +such a mechanism without needing to agree in advance on what language changes |
| 52 | +will be stabilized in order to do so. |
| 53 | + |
| 54 | +# Prototyping 'shepherded' project groups |
| 55 | +[prototyping-project-groups]: #prototyping-shepherded-project-groups |
| 56 | + |
| 57 | +With this RFC, we formally announce the formation of a project-specific, |
| 58 | +shepherded "project group" to adopt responsibility for driving progress on |
| 59 | +specifying unwinding behavior at FFI boundaries. |
| 60 | + |
| 61 | +## What is a "project group"? |
| 62 | + |
| 63 | +The "project group" term has not previously been used: it is intended to |
| 64 | +formalize a concept that has existed informally for some time, under a number |
| 65 | +of names (including "working group"). |
| 66 | + |
| 67 | +A "project group" is a group of people working on a particular project at the |
| 68 | +behest of an official Rust team. Project groups must have: |
| 69 | + |
| 70 | +* A **charter** defining the project's scope |
| 71 | +* A **liaison** with an official Rust team (who may or may not also be a shepherd) |
| 72 | +* A small number of **shepherds**, who are responsible for summarizing |
| 73 | + conversations and keeping the lang team abreast of interesting developments. |
| 74 | +* A GitHub repository hosted under the `rust-lang` organization containing the |
| 75 | + charter and instructions for how community members can monitor the group's |
| 76 | + progress and/or participate. |
| 77 | + |
| 78 | +[This blog post][shepherds-3.0] explains in detail the role of the |
| 79 | +shepherds. |
| 80 | + |
| 81 | +## Project group roadmap and RFCs |
| 82 | + |
| 83 | +The first step of the project group is to define a **roadmap** indicating the |
| 84 | +planned sequence in which it will design and propose particular behaviors and |
| 85 | +features. Once the project group feels it has completed work on some item in |
| 86 | +the roadmap, that item will be submitted as an RFC or FCP for review by the lang team and the community at large. |
| 87 | + |
| 88 | +## Stabilizing unspecified "TBD" behavior |
| 89 | +[stabilizing-tbd]: stabilizing-unspecified-tbd-behavior |
| 90 | + |
| 91 | +We would like to be able to provide features in stable Rust where some |
| 92 | +of the details are only partially specified. For example, we might add |
| 93 | +a new ABI "C unwind" that can be used from stable Rust, while |
| 94 | +explicitly leaving the behavior when a foreign exception unwinds |
| 95 | +across such a boundary unspecified. In such cases, we would attempt to |
| 96 | +provide some bounds on what might happen -- for example, we might |
| 97 | +state that a Rust panic propagating across a "C unwind" boundary must |
| 98 | +be preserved and handled as normal. |
| 99 | + |
| 100 | +In some cases, we intend to mark some of this unspecified behavior as |
| 101 | +"To Be Determined" (TBD). This classification is meant to convey that |
| 102 | +the behavior is behavior we intend to specify as part of this group, |
| 103 | +although we have not done so *yet*. This categorization is purely |
| 104 | +intental to the working group, however; such behavior would remain |
| 105 | +formally unspecified until an RFC or other binding decision is |
| 106 | +reached. |
| 107 | + |
| 108 | +## Details of the FFI-unwind project group |
| 109 | + |
| 110 | +[Repository][ffi-unwind project] |
| 111 | + |
| 112 | +Initial shepherds: |
| 113 | + |
| 114 | +* [acfoltzer (Adam)](https://github.com/acfoltzer) |
| 115 | +* [batmanaod (Kyle)](https://github.com/batmanaod) |
| 116 | + |
| 117 | +Lang team liaisons: |
| 118 | + |
| 119 | +* [nikmoatsakis (Niko)](https://github.com/nikmoatsakis) |
| 120 | +* [joshtriplett (Josh)](https://github.com/joshtriplett) |
| 121 | + |
| 122 | +### Charter |
| 123 | +[charter]: #charter |
| 124 | + |
| 125 | +The FFI-unwind project group has the following initial scope: |
| 126 | + |
| 127 | +* to define the details of the "C unwind" ABI on major Tier 1 platforms |
| 128 | +* in particular, to define with sufficient detail to enable the use cases |
| 129 | + described in the Motivation section of this RFC |
| 130 | + |
| 131 | +Certain elements are considered out of scope, at least to start: |
| 132 | + |
| 133 | +* We do not expect to add new mechanisms for interacting with or |
| 134 | + throwing foreign exceptions. |
| 135 | + * However, if we specify what happens when a foreign exception |
| 136 | + passes into Rust code, then we must also specify how that |
| 137 | + exception will interact with pre-existing mechanisms like |
| 138 | + destructors and `catch_unwind`. We just don't intend to create |
| 139 | + new mechanisms. |
| 140 | + |
| 141 | + |
| 142 | +### Constraints and considerations |
| 143 | + |
| 144 | +In its work, the project-group should consider various constraints and |
| 145 | +considerations: |
| 146 | + |
| 147 | +* The possibility that C++ may adopt new unwinding mechanisms in the future. |
| 148 | +* The possibility that Rust may alter its unwinding mechanism in the future -- |
| 149 | + in particular, the project group must not propose a design that would |
| 150 | + constrain Rust's unwinding implementation on any target. |
| 151 | + |
| 152 | +### Participation in the project group |
| 153 | + |
| 154 | +Like any Rust group, the FFI-unwind project group intends to operate |
| 155 | +in a public and open fashion and welcomes participation. Visit the |
| 156 | +[repository][ffi-unwind project] for more details. |
| 157 | + |
| 158 | +# Drawbacks |
| 159 | +[drawbacks]: #drawbacks |
| 160 | + |
| 161 | +* The adoption of project groups for major language design efforts is a change |
| 162 | + in the status quo. We believe that this change will be an improvement over |
| 163 | + the current RFC-centric process, but we should be wary of unintended |
| 164 | + consequences of from such a change. |
| 165 | +* [Stabilization of "TBD" features][stabilizing-tbd] may be surprising or |
| 166 | + confusing to users, and it will encourage reliance on (some) unspecified |
| 167 | + behavior. |
| 168 | + |
| 169 | +# Prior art |
| 170 | +[prior-art]: #prior-art |
| 171 | + |
| 172 | +Although the term "project group" is new, some existing efforts, such as the |
| 173 | +Unsafe Code Guidelines effort and the work around defining const evaluation, |
| 174 | +were organized in a similar fashion. |
| 175 | + |
| 176 | +In addition to the [blog post Niko Matsakis][shepherds-3.0] about |
| 177 | +shepherding, James Munns wrote a [more formal shepherding |
| 178 | +proposal][shepherding-3.1]. |
| 179 | + |
| 180 | +The [governance WG][governance-wg] and [lang-team meta working |
| 181 | +group][lang-meta-wg] were both formed at least in part to improve the process |
| 182 | +for large-scale design efforts. One existing proposal is for ["staged |
| 183 | +RFCs"][staged-rfc]; this may be considered a precursor to the current |
| 184 | +"shepherded project group" proposal. |
| 185 | + |
| 186 | + |
| 187 | +# Unresolved questions and Future possibilities |
| 188 | +[unresolved-questions]: #unresolved-questions |
| 189 | + |
| 190 | +Since this RFC merely formalizes the creation of the project group, it |
| 191 | +intentionally leaves all technical details within the project's scope |
| 192 | +unresolved. |
| 193 | + |
| 194 | +# Future possibilities |
| 195 | +[future-possibilities]: #future-possibilities |
| 196 | + |
| 197 | +The project group will start with a fairly [limited scope][charter], but if the |
| 198 | +initial effort to design and stabilize a safe cross-language unwinding feature |
| 199 | +on a limited set of platforms goes well, there are many related areas of |
| 200 | +potential exploration. Three noteworthy examples are: |
| 201 | + |
| 202 | +* Catching foreign unwinding (e.g. Rust catching C++ exceptions, or C++ |
| 203 | + catching Rust `panic`s) |
| 204 | +* Defining coercions among `fn`s using ABIs with different `unwind` |
| 205 | + behavior |
| 206 | +* Monitoring progress, or even participating in discussion about, the [ISO C and |
| 207 | + C++ proposal][c-cpp-unified-proposal] for cross-language error handling |
| 208 | + |
| 209 | +[Undefined Behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html |
| 210 | +[abort-unwind]: https://github.com/rust-lang/rust/issues/52652 |
| 211 | +[ffi-unwind project]: https://github.com/rust-lang/project-ffi-unwind |
| 212 | +[shepherds-3.0]: http://smallcultfollowing.com/babysteps/blog/2019/09/11/aic-shepherds-3-0/ |
| 213 | +[c-cpp-unified-proposal]: http://open-std.org/JTC1/SC22/WG21/docs/papers/2018/p1095r0.pdf |
| 214 | +[shepherding-3.1]: https://jamesmunns.com/blog/shepherding-3-1/ |
| 215 | +[governance-wg]: https://github.com/rust-lang/wg-governance |
| 216 | +[lang-meta-wg]: https://github.com/rust-lang/lang-team/tree/master/working-groups/meta |
| 217 | +[staged-rfc]: http://smallcultfollowing.com/babysteps/blog/2018/06/20/proposal-for-a-staged-rfc-process/ |
0 commit comments