@ticki You are right that breaking some programs somewhere is inevitable while making changes. Even the seemingly most harmless changes, like adding a trait implementation, can break code. But precisely because almost any change is breaking, there must be more nuance to the decision than simply "this could break some program somewhere", and thus changes are weighted by criteria such as (this list is probably not complete):
- How much of a hassle it is to deal with the change when upgrading to a new Rust version. This can range from adding a semicolon somewhere because a lint tells you so for over a year before any change happens, to being rendered unable to do what you were doing beforehand (at least, efficiently and easily).
- How important the change is. This can range from "soundness fix" to "minor ergonomic improvement in some corner cases".
- Related to the first point, how well can the change be managed? Can a future compatibility lint be added? Can a crater run determine how much of crates.io would be affected (true for changes that break compilation, not true for runtime behavioral changes)?
This proposal scores okay on the first point (mostly, just add panic= "unwind" to all binary crates that need it), but not so great on the second and third. As we previously agreed, almost all of the benefits can be had by writing panic = "abort" into new Cargo.tomls — and @sfackler raised a good point about exception safety of unsafe code, not to mention the controversy about how valid reliance on unwinding is. Let's just say that unlike a soundness fix or implementing specialization for to_string, there is no agreement (at least not yet) that this change is desirable and has a better benefit/breakage ratio than the alternatives. Since it's also a run time behavioral change, and I really don't know what a future compatibility lint would look like, the third point looks kinda bleak — and even if crater could run tests, panic behavior is an edge case that's probably less well tested than other aspects of runtime behavior.
(At this point I would also like to stress again that "set panic=unwind in your crate if you rely on unwinding" does not work for library crates in the current implementation. So if there were libraries relying on unwinding, they don't even have the tools yet to mechanically deal with this breakage, and thus it would be cruel to punish them for failing to do so.)
However, I do concede that this may be a good change with manageable impact, and so it may not be ruled out by the stability policy.
So much for the process of breaking changes. Let's return to the justification. A key point of your argument is that unwinding-as-default is unspecified. I disagree. I wrote here previously on why I believe this. To briefly recap:
- Unwinding wasn't just the default, it was the only behavior for a long time (even after 1.0). Unlike non-zeroing drop, there was no long build up where the alternative was considered and desired (which also influenced the next point).
- Much of the documentation written during that time (and significant parts of that have survived to this day) describes unwinding like any other piece of behavior, and makes no mention of any alternative behavior. This includes the reference, which was never really "normative" in a strict sense, but at least is taken as such by people. Unwinding was and is documented, not unspecified.
- The RFC text (another piece of documentation, effectively) even explicitly said that unwinding would continue to be the default.
Consequently, I think it is entirely reasonable for a user to look at all the messaging from the Rust project and determine that, since unwinding is obviously the default, they don't need to go through the hassle of adding some lines to their Cargo.toml that just reaffirm said default. Conversely, I would consider anyone who looks at all that and doesn't decide that unwinding is safe to assume rather paranoid.
This is in stark contrast to filling drop, which to the best of my knowledge was never documented very much (drop flags were probably mentioned, but the details of filling, not really — this was the dark ages where nobody even tried to formalize guidelines for unsafe code). The Nomicon does mention (and IIRC has mentioned since that chapter was written) that drop flags as a whole are slated for removal. Moreover, rust-lang/rust#23535, which I assume you mean by "filling drop future proofing", was merged in March 2015, before Rust 1.0 (= the start of the stability policy).