Skip to content
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: Abort by default #1759

Closed
wants to merge 3 commits into from
Closed

RFC: Abort by default #1759

wants to merge 3 commits into from

Conversation

ticki
Copy link
Contributor

@ticki ticki commented Oct 1, 2016

This is a long shot, but let's see...

Rendered

@Ericson2314
Copy link
Contributor

The use-case for unwinding is very narrow (long lived servers one doesn't want to restart, I've never heard anything else). Furthermore, in a futures-based world—our main story for servers—threads are just used to run other tasks and thus dont really encapsulate something concrete and known to the programmer.

@Ericson2314
Copy link
Contributor

Also, this is good for pedagogy—instead of "two ways to do things but one is bad so please don't", there's just one.

Finally, if we wait to do this once std can be transparently rebuilt, we are hardly burdening those that want unwinding.

@hanna-kruppe
Copy link

Silently switching the default is a non-starter IMHO. While it's true that libraries should not depend on the panic strategy, it is clearly valid for applications (i.e., binary crates as well as library crates that are intrinsically tied to an application for organizational purposes) to do so. And since unwinding has been the only option for a long time and has always been the default, most existing crates won't be explicitly setting panic = "unwind" in their Cargo.toml. Switching the compiler's default would then break these application, and it wouldn't even result in a compiler error. This is not acceptable under the stability policy, I'd say.

On the other hand, defaulting to panic = "abort" in new projects seems like a very good idea to me.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

@rkruppe

I disagree. Not even applications should rely on the panicking strategy. The panic strategy is ultimatively a compilation option, and programs ought to be independent of the compiler flags.

Furthermore, all of the cases of code that depends on this behavior I can think of is broken (e.g. using panicking as a form of exceptions/recoverable errors, or placing code needed for consistency in destructors).

Edit: I'm wrong. Code can very well rely on the specified panicking strategy, but not a particular default strategy.

@petrochenkov
Copy link
Contributor

petrochenkov commented Oct 1, 2016

@ticki

Not even applications should rely on the panicking strategy. The panic strategy is ultimatively a compilation option, and programs ought to be independent of the compiler flags.

Okay, why do unwinding panics even exist then, if they are completely useless and aborting is certainly a more performant compilation option?

@BurntSushi
Copy link
Member

quickcheck would break as a result of this change.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

@BurntSushi

quickcheck would break as a result of this change.

Could you elaborate on that?

@petrochenkov

Okay, why do unwinding panics even exist then, if they are completely useless and aborting is certainly a more performant compilation option?

It exists because it has advantages over abort in certain environments. When you use unwinding in order to keep the system up for a long period of time, you don't actually rely on unwinding (e.g. try and catch exceptions), but rather you use it as a safety measure against crashes. Ideally, your program should never unwind, but no code is perfect, and that must be reflected in critical environments.

Edit: See edit note from previous comment.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

I'd like to see a valid, idiomatic example of code which relies on the panicking strategy.

@hanna-kruppe
Copy link

hanna-kruppe commented Oct 1, 2016

@ticki Why does unwinding even exist, then? If all good Rust code should work just as well with panic=abort as with panic=unwind, why don't we remove panic=unwind and forcibly compile everything with panic=abort? (edit: I see this has already been addressed)

I don't buy the "compilation option" argument. It's a good heuristic, and most compiler flags indeed should not alter observable behavior, but there are plenty that necessarily affect whether a program works. Even if we restrict ourselves to the -C category (which is quite artificial), there is -C target-feature (needed if you want to use certain intrinsics), -C rpath , -C link-dead-code and other linker args which can become important in FFI or embedded development, and -C debug_assertions which obviously affects behavior (if all code were bug free it wouldn't, but that's not gonna happen).

I don't want to spend a lot of words defending the use of panic=unwind and catch_unwind, because this is a big topic. I will just say this much: If a program previously successfully completed its job without crashing, and after a Rust update crashes quickly, that is a serious behavioral change.

Finally, even if it were the baddest practice ever, that doesn't give us the right to break code using it. The stability promise is emphatically not "if you write code we like, we'll try to not break it". Transmutes between fn item types and fn types are infinitely more suspect and weird than unwinding, and even that got a several release cycle long compatibility lint!

@hanna-kruppe
Copy link

I'd like to see a valid, idiomatic example of code which relies on the panicking strategy.

It's completely irrelevant whether it's good code. It's irrelevant whether it would be easy to avoid the issue if you knew the change was coming. All that matters is this sequence of events:

  1. Application works
  2. Application gets built using new Rust compiler
  3. Application's behavior changes
  4. people complain

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

Even -C debug_assertions shouldn't alter behavior, unless your program contains bugs.

Finally, even if it were the baddest practice ever, that doesn't give us the right to break code using it. The stability promise is emphatically not "if you write code we like, we'll try to not break it". Transmutes between fn item types and fn types are infinitely more suspect and weird than unwinding, and even that got a several release cycle long compatibility lint!

It isn't just because it's a bad thing to do. It is because it relies on unspecified behavior, and therefore cannot be considered a breakage in the strictest sense.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

It's completely irrelevant whether it's good code. It's irrelevant whether it would be easy to avoid the issue if you knew the change was coming. All that matters is this sequence of events:

Application works
Application gets built using new Rust compiler
Application's behavior changes
people complain

Eh, the same argument could be applied to telling LLVM that transmuting &T to &mut T is UB. As of right now, if you store it in a variable, this transmute "works", but it isn't "valid" and is subject to possible future change.

@hanna-kruppe
Copy link

hanna-kruppe commented Oct 1, 2016

Even -C debug_assertions shouldn't alter behavior, unless your program contains bugs.

Every program on earth contains bugs. "Sorry, your program was buggy, we broke it" is not a nice thing to say, and not a defensible position.

It isn't just because it's a bad thing to do. It is because it relies on unspecified behavior, and therefore cannot be considered a breakage in the strictest sense.

What's unspecified? Please don't get all language lawyers. Virtually every resource that mentions the topic of panics also describes unwinding, including many official ones. There is no binding, formal standard, true, but that doesn't give the Rust project the license to declare anything it wants unspecified. It is, de facto, specified, and there is not even a really good reason to change it (unlike with some breaking changes that have happened in the past). Just switching the default of newly generated Cargo.tomls will have the same effect long-term, without the immediate silent breakage.

UB is very different. For starters, the Nomicon is quite clear that transmuting &T to &mut T is evil. I'm also much more willing to call some dark corner of unsafe code unspecified or UB than I am with prominent aspects of core language features.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

And, I don't buy the "if there's no behavior difference between unwinding and abort, why not just use abort then?" argument, because the fact that there is no difference in behavior in the ideal case doesn't mean there can't be in a realistic environment. Long running programs aren't supposed to panic, but they might do, and it's totally valid for those to prefer unwinding to avoid crashes.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

Every program on earth contains bugs. "Sorry, your program was buggy, we broke it" is not a nice thing to say, and not a defensible position.

You're misunderstanding me here. If you rely on implemention defined behavior, you cannot be sure it actually stays that way, and hence you cannot rely on the behavior for correctness.

What's unspecified? Please don't get all language lawyers. Virtually every resource that mentions the topic of panics also describes unwinding, including many official ones. There is no binding, formal standard, true, but that doesn't give the Rust project the license to declare anything it wants unspecified. It is, de facto, specified, and there is not even a really good reason to change it (unlike with some breaking changes that have happened in the past). Just switching the default of newly generated Cargo.tomls will have the same effect long-term, without the immediate silent breakage.

That's a good point.


I suppose a sensible alternative is to simply make cargo new have panic=unwind and have libraries adapt to the panicking strategy of their dependee.

@hanna-kruppe
Copy link

[...] and it's totally valid for those to prefer unwinding to avoid crashes.

And the change proposed here will suddenly, silently, with no warning (no release notes don't count) make it so that people who prefer this mode of operation suddenly won't have it any more. Even if you don't want to call it a breaking change, that's a dick move. That alone would be enough for me to oppose it.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

@rkruppe

I suppose a sensible alternative is to simply make cargo new have panic=unwind and have libraries adapt to the panicking strategy of their dependee.

What do you think about this idea ^

@hanna-kruppe
Copy link

I've been advocating it since my very first comment! (The "libraries adopt the strategy of the dependee" part has always been true.)

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

The "libraries adopt the strategy of the dependee" part has always been true.

There's one exception to this: I think an abort-library should be able to link to a panic-runtime, since they can interact flawlessly.

@hanna-kruppe
Copy link

We appear to be on the same page now, but I do have one more rant in the pipeline about the justification of changing the default, sorry:

You're misunderstanding me here. If you rely on implemention defined behavior, you cannot be sure it actually stays that way, and hence you cannot rely on the behavior for correctness.

It's no more implementation defined than + on numbers producing the sum of the arguments rather than the difference (overflow non-withstanding). It is not only the de facto standard, it is widely documented (including in the reference and in the book and the standard library documentation) and none of the descriptions are accompanied by a disclaimer that it's implementation defined. No user could be expected to read about unwinding and go "you know, this doesn't sound like it's guaranteed, I'm not gonna rely on that". In fact, some parts of the documentation still haven't been updated to reflect that unwinding can be disabled — something which, I might add, was added long after the language was declared stable. What is the user to do? Doubt every piece of behavior described in the documentation?

@hanna-kruppe
Copy link

There's one exception to this: I think an abort-library should be able to link to a panic-runtime, since they can interact flawlessly.

This, too, is already true: std is compiled with unwinding support and can link to panic=abort binaries. But Cargo uses the application's panic strategy for everything it compiles.

@apasel422
Copy link
Contributor

apasel422 commented Oct 1, 2016

futures-cpupool uses catch_unwind to propagate a task's panic to its future.

quickcheck uses catch_unwind to test for expected panics and to handle unexpected panics.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

This, too, is already true: std is compiled with unwinding support and can link to panic=abort binaries. But Cargo uses the application's panic strategy for everything it compiles.

It definitely isn't. I can't link against panicking runtimes when I have panic=abort libraries.

@hanna-kruppe
Copy link

@ticki That's weird. What exactly do you mean by "runtime"? std is distributed as a panic=unwind build, and it works just fine with panic=abort crates.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

@rkruppe The converse: Linking aborting libraries against panicking applications.

@ticki
Copy link
Contributor Author

ticki commented Oct 1, 2016

It might originate due to another compiler flag. In any case, I think it is irrelevant for this discussion.

@steveklabnik
Copy link
Member

I thought that in the panic=abort RFC, there was a way to specify if your crate relied on either behavior, and to fail compilation if you tried to, for example, compile a panic=unwind crate against a panic=abort application. I cannot find that text now. 😦

If that was there, QuickCheck and other crates could specify that they rely on unwinding, and things would be peachy.

@hanna-kruppe
Copy link

@steveklabnik No, changing the default in the compiler still wouldn't be peachy, because there will most likely be many crates which should set that flag but don't. These would still be broken, and the above argument about whether it's okay to break people's application when they should have known better still applies (to a lesser extent).


## Correctness

You often see people abusing `std::panic::catch_unwind` for exception handling. Forcing the user to explicitly opt in to unwinding will make it harder to unintentionally misuse it.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think I have ever actually seen this in practice. Where does this pop up often?

Copy link

@codyps codyps Oct 2, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On /r/rust people regularly talk about how "nice it is to have exceptions".

Copy link

@ArtemGr ArtemGr Oct 5, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Forcing the user to explicitly opt in to unwinding will make it harder to unintentionally misuse it."

At least one person has done this

It was an intentional misuse though. Cf. https://www.reddit.com/r/rust/comments/53ft4m/my_experience_rewriting_enjarify_in_rust/d7ss1vy

@Ericson2314
Copy link
Contributor

Ericson2314 commented Oct 2, 2016

From the docs of UnwindSafe

Note, however, that this is not an unsafe trait, so there is not a succinct contract that this trait is providing. Instead it is intended as more of a "speed bump" to alert users of catch_unwind that broken invariants may be witnessed and may need to be accounted for.

Woah... that trait reassured me a lot when I saw the name, and now a lot less. This is very subpar by Rust's standard's and if catch_unwinding becomes something transitively used by most programs due to futures, we should be very sad and very afraid.

@sfackler
Copy link
Member

sfackler commented Oct 2, 2016

I see big performance penalty on restart, but good guarantee of eventual progress per restart because restarting is expensive and simple. In other words, does one you care more about preventing unlikely-but possible crazy behavior, or simply maximizing uptime?

Your user does not care about whatever eventual progress is being made; they care that the thing they are trying to do doesn't work. Most bugs are not likely-and-not-crazy.

It'd be a pain in the ass, yes, but it's possible to write a tiny process that never panics and holds open expensive-to-initialize connections, talking to the main server via cheap pipes.

What language is that written in then? We never intend our code to be broken and panic, and yet it sometimes does.

Code that assumes !Send / !Sync => doesn't cross panic boundary. In fact, I have never heard of (UnwindSafe)[https://doc.rust-lang.org/std/panic/trait.UnwindSafe.html] until now.

Again, how much code actually cares about that distinction? There was quite a lot of discussion around whether UnwindSafe was worth its weight to even include. In my experience in Java, code that runs into the kinds of issues that UnwindSafe and Mutex poisoning are intended to protect against is extremely rare.

@Ericson2314
Copy link
Contributor

There was quite a lot of discussion around whether UnwindSafe was worth its weight to even include. In my experience in Java, code that runs into the kinds of issues that UnwindSafe and Mutex poisoning are intended to protect against is extremely rare.

In Rust, I wonder how much rarer those issues are than unwinding itself? On a different note, I am probably in a rare group that believes auditing all panic points is quiet feasible.

What language is that written in then? We never intend our code to be broken and panic, and yet it sometimes does.

I am hoping that for such a small program, the feasibility of auditing all panic points is less a controversial opinion.

@Ericson2314
Copy link
Contributor

Your user does not care about whatever eventual progress is being made; they care that the thing they are trying to do doesn't work. Most bugs are not likely-and-not-crazy.

I don't want to be moving the goal posts, because we were talking about webserver-like stuff, but in other domains the client is non-human with different timing preferences.

@Ericson2314
Copy link
Contributor

Ericson2314 commented Oct 2, 2016

I think my entire opinion rests on these assumptions:

  1. Idiomatic panicking only happens in the case of programmer error.
  2. Things that go wrong when unwinding are not that much less common than unwinding, when panicking is used idiomatically.
  3. (somewhat separately) Confidence in reasoning about what happens when programmer reasoning fails (i.e. during unwinding due to idiomatic panicking), is only one small philosophical step away from confidence that programmer reasoning never fails.

@sfackler
Copy link
Member

sfackler commented Oct 2, 2016

I don't want to be moving the goal posts, because we were talking about webserver-like stuff, but in other domains the client is non-human with different timing preferences.

Even if the immediate consumer is non-human, there is (unless some very significant advances in AI research have been made recently that I'm not aware of :P) a human waiting on the result of that computation somewhere down the line.

For those assumptions:

  1. Yep, absolutely.
  2. I may be misinterpreting this one, but IME almost all panics occur in "boring" contexts where program state is totally fine (e.g. even if you have a mutex protecting some shared data structure, you probably just tried to perform an out of bounds read on some vector inside of it).
  3. Rust exists because programmer reasoning fails so often!

@Ericson2314
Copy link
Contributor

Ericson2314 commented Oct 2, 2016

I may be misinterpreting this one, but IME almost all panics occur in "boring" contexts where program state is totally fine (e.g. even if you have a mutex protecting some shared data structure, you probably just tried to perform an out of bounds read on some vector inside of it).

I guess I've never had much need to index arrays or use RefCell and friends---I can't recall panicking outside of unimplemented!(), poisoning unwraps, debug_assert!(), and of course (hopefully temporary) sloppiness.

@ticki
Copy link
Contributor Author

ticki commented Oct 3, 2016

If stability is what is blocking this, Rust can be declared immutable forever.

The default is unspecified and you should not rely on the behavior unless you manually specify another strategy. If we have to make sure no unspecified behavior changes, what's the point of keeping it unspecified?

The whole point of a thing being unspecified is that it can be changed and you should not rely on it's behavior, and I'm tired of the "we cannot change this because somebody might assume that it is like this, despite not being specified." altitude. It keeps Rust from improving. If your code is broken, it's broken, and I'd go all the way and say that broken code should not be silent, because that simply enforces it's status quo. Safe crashing is perfectly legitimate in order to inform the programmer that the code is broken.

Programmer errors happens, yes, but if you rely on unwinding, you should specify that your crate is unwinding.

The first thing that comes to my mind is the filling drop future proofing RFC. It changed unspecified behavior, which broke some crates, and I think that it broke broken crates would be a poor reason to oppose it. You could argue that this was due to drop flags being in the pipeline, but ultimately it did change unspecified behavior.

I'd also like to emphasize that this does not introduce any form of unsafety. The worst case scenario is that a program might stop with an error message.

One thing I think is especially dangerous is crates which do not specify panic=unwind and relies on landing pads, these could introduce unsafety if a downstream crate sets panic=abort. Even such code doesn't rely on the default, rather it assumes that no crates could be compiled with aborting panics, which is already to this date considered Undefined Behavior my @nikomatsakis's 'Tootsie Pop' model.

@hanna-kruppe
Copy link

@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).

@aturon
Copy link
Member

aturon commented Oct 3, 2016

Quick note: the libs team discussed this RFC a bit, and everyone felt strongly that we cannot make the change as written -- we consider this a massive breaking change in behavior.

A couple of notes about the formalities here:

  • We made an explicit list of language-level concerns where we expected change, most of which affects unsafe code; this was part of the Language Semver RFC. Default panic behavior was not on this list.
  • As others have pointed out, at 1.0 this was the only panic strategy.
  • In general, we do not have comprehensive reference documentation outlining the precise promises we want to make for every area of the language. That's something to strive for, but it takes time, and only asymptotically approached perfection. In the meantime, there will be behavior that is not explicitly promised, but which code nevertheless relies on, where changing that behavior could cause non-trivial breakage in the ecosystem. Even when we are clearly "within rights" to make changes (e.g. as part of our semver guide), we still test those changes against the ecosystem to make sure those changes don't incur widespread breakage. Rust's promises about stability are about people's experiences in practice, more so than in theory.

Now, all of the above is separate from the question of something like having cargo new use panic=abort for binaries, which is listed as one of the alternatives. That's a more plausible move, but one that should be debated.

It's also disappointing that the RFC gives no discussion or weight to the fact that unwinding is ever useful or desirable. If we want to have a meaningful debate about the right defaults going forward, we need to take a clear-eyed look at the pros/cons on both sides.

@aturon aturon self-assigned this Oct 3, 2016
@brson
Copy link
Contributor

brson commented Oct 3, 2016

I'll also weigh in on my brief thoughts. The bottom line is that this cannot be done as proposed because it is a massive breaking change to the long expected Rust semantics. There is code that relies on unwinding in Rust - for example, the standard test runner, which nearly every project depends on, does not work without unwinding. Such code works today on all existing platforms and forcing it to break would be incredibly user-hostile and counter to the spirit of Rust's stability guarantees.

@Ericson2314
Copy link
Contributor

Ericson2314 commented Oct 4, 2016

Is it reasonable for Cargo to eventually require a panic strategy for binaries? FWIW, cargo is pre-1.0, and libraries/crates.io wouldn't be affected so there's no cascading breakage.

@ticki
Copy link
Contributor Author

ticki commented Oct 4, 2016

@aturon 😢

Anyway, I'll update the RFC.

It's also disappointing that the RFC gives no discussion or weight to the fact that unwinding is ever useful or desirable. If we want to have a meaningful debate about the right defaults going forward, we need to take a clear-eyed look at the pros/cons on both sides.

Yeah, I should add that.

@sfackler
Copy link
Member

sfackler commented Oct 4, 2016

Is it reasonable for Cargo to eventually require a panic strategy for binaries?

What value does that provide to the end user? Why will developers say "thank you for breaking my project until I added more stuff to my Cargo.toml"?

How will this work logistically? The panic strategy is attached to a compilation profile, not the crate itself. Is this proposal really going to be to make people add this to every project they work on?

[profile.dev]
panic = "unwind"

[profile.release]
panic = "unwind"

[profile.test]
panic = "unwind"

[profile.bench]
panic = "unwind"

[profile.doc]
panic = "unwind"

FWIW, cargo is pre-1.0

No. The number returned when you run cargo --version is entirely irrelevant. Cargo is the build system for Rust. It is astonishingly user hostile to break every build of Rust code in existence. It is not 2014 anymore. Rust is a stable language that we intention to be used for real things in the real world.

@codyps
Copy link

codyps commented Oct 4, 2016

How will this work logistically? The panic strategy is attached to a compilation profile, not the crate itself.

It might make sense to allow specification of the panic strategy to be placed on the crate itself. How that would be applied to various pieces (testing, bench, doc, and binary/library generation) would need to be specified. Consider that at the moment those wanting to disable unwinding need a similar amount of boilerplate.

What value does that provide to the end user?

It could encourage the author to consider "does the functionality of my crate rely on unwinding", where at the moment that choice is mostly unconsidered. That said, I don't think only specifying this on the final crate is very useful, as it requires the consumer crate to completely understand their complete dependencies.

@Valloric
Copy link

Valloric commented Oct 5, 2016

A possibly doable way of making this change would be to do it in stages: for the next say six months, cargo prints a warning if a crate does not specify a panic strategy. So basically all crates would end up specifying one of the two. After that period, you flip the switch and the default becomes abort.

It's not pretty, but it would probably work well enough to cover all crates anyone cares about.

I'll leave the argument about should we do this at all to others.

@gnzlbg
Copy link
Contributor

gnzlbg commented Oct 5, 2016

@rkruppe

No, changing the default in the compiler still wouldn't be peachy, because there will most likely be many crates which should set that flag but don't. These would still be broken, and the above argument about whether it's okay to break people's application when they should have known better still applies (to a lesser extent).

I cannot but wonder whether we would be breaking Cargo or Rust.

What I mean is that if we switch the default panicking strategy in rustc to panic=abort we could in the same release cycle switch cargo to require an explicit panic strategy, so that old crates would need to specify it to compile with the new rustc version. "Technically we would not be breaking their code" since their code is still fine, the only thing that is not fine is the Cargo.Toml file.

Anyhow, this is just a thought, I've still have not made my mind about any of this although for new projects a panic=abort sounds like a better default (if you don't need unwinding or anything that does, you don't pay for it).

@hanna-kruppe
Copy link

@gnzlbg As has been pointed out by several people multiple times, weaseling ourselves out on basis of "exact words" goes completely against the spirit of the stability policy. If a project works before updating and doesn't work afterward, that's bad, period.

@nikomatsakis
Copy link
Contributor

nikomatsakis commented Oct 5, 2016

@rfcbot fcp close

Like many others, I think that this change isn't sufficiently well-motivated and not worth the chance of perturbing existing code. The discussion in the @rust-lang/libs team team seems to have come to a similar conclusion. Moreover, my sense is that the major arguments which are going to be made have already been made. Therefore, I propose that we go to FCP with the intention of closing this RFC. (If you feel I'm being too hasty here, though, please do object!)

Major points raised in the conversation thus far:

@ticki
Copy link
Contributor Author

ticki commented Oct 5, 2016

@nikomatsakis The RFC is updated such that there is no breaking changes. Could you reverse the FCP? I believe all of the criticism expressed in this thread is no longer relevant to the new text.

@rfcbot
Copy link
Collaborator

rfcbot commented Oct 5, 2016

FCP proposed with disposition to close. Review requested from:

No concerns currently listed.
See this document for info about what commands tagged team members can give me.

@frewsxcv
Copy link
Member

frewsxcv commented Oct 5, 2016

@ticki Considering the changes you just made pivot the RFC, it might be better to start fresh and open a new pull request.

@ticki ticki closed this Oct 5, 2016
@ticki ticki mentioned this pull request Oct 5, 2016
@ticki
Copy link
Contributor Author

ticki commented Oct 5, 2016

Superseded by #1765

@nikomatsakis
Copy link
Contributor

@rfcbot fcp cancel

@rfcbot
Copy link
Collaborator

rfcbot commented Oct 6, 2016

@nikomatsakis FCP proposal cancelled.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-lang Relevant to the language team, which will review and decide on the RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC.
Projects
None yet
Development

Successfully merging this pull request may close these issues.