-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
Stabilize RFC 2345: Allow panicking in constants #89006
Comments
My perspective as someone who is frequently trying to make good error messages:
For example, the existing example 4 | const _: () = std::panic!("{}", MSG);
| --------------^^^^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'custom message', src/main.rs:4:15 would in my opinion be better formatted as 4 | const _: () = std::panic!("{}", MSG);
| --------------^^^^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at src/main.rs:4:15 with:
| custom message The first sample has the virtue of more closely matching runtime behavior; but I think there should be generally higher expectations for readability from messages during compilation than those which must be formatted by handler code embedded in the final binary. |
I agree. I'd also expect multiline panic messages to stay indented, so that they can be easily distinguished from the following compilation errors. I would prefer if both const
to the indented style you're proposing. |
There was some long discussion about error formatting in a previous PR as well, more than a year ago... maybe someone can dig up the link. I think const panic messages should be consistent with other kinds of errors that stop const-evaluation. So, I am not a fan of special-casing const panic error formatting. But I am open to improving const-eval error rendering in general. |
Seems reasonable; let's get consensus: @rfcbot merge |
Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members: No concerns currently listed. Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up! See this document for info about what commands tagged team members can give me. |
Important to note: This will make |
It is not the scope of this issue but I would like to chime to draw the attention of also considering "constifying" const FOO: () = {
let _ = match SOME_OPERATION {
Err(_err) => panic!("SOME ERROR"),
Ok(elem) => elem
};
}; instead of the much simpler const FOO: () = {
let _ = SOME_OPERATION.unwrap();
}; |
But |
@rfcbot reviewed |
🔔 This is now entering its final comment period, as per the review above. 🔔 |
I just checked: Ignoring the message that
with the same error for With regard to |
@jhpratt #![feature(const_panic)]
#![feature(const_precise_live_drops)]
pub const fn unwrap<T>(this: Option<T>) -> T {
match this {
Some(val) => val,
None => panic!("called `Option::unwrap()` on a `None` value"),
}
} |
Certainly. I suspected that was the error I was going to run into, actually. I just didn't bother to keep adding features once I confirmed my suspicion that it wouldn't compile with just |
It's possible to make rust/library/core/src/char/convert.rs Lines 90 to 95 in 673d0db
rust/library/core/src/char/convert.rs Lines 245 to 258 in 673d0db
|
^^ that would require const unwrap when written as-is If there are the appropriate MIRI checks in place (I don't know if there are) it could just be a straight transmute, which is already stabilized. It could theoretically introduce UB in debug builds, but that's the caller's problem (don't use unchecked if it's not valid). |
I found it quite simple to constify #![feature(const_panic)]
pub const fn from_u32(i: u32) -> Option<char> {
if (i > '\u{10ffff}' as u32) || (i >= 0xD800 && i <= 0xDFFF) {
None
} else {
// SAFETY: checked that it's a legal unicode value
Some(unsafe { core::mem::transmute(i) })
}
}
pub const unsafe fn from_u32_unchecked(i: u32) -> char {
if cfg!(debug_assertions) {
match from_u32(i) {
Some(val) => val,
None => panic!("illegal unicode value"),
}
} else {
// SAFETY: checked that it's a legal unicode value
core::mem::transmute(i)
}
} |
Thanks for the explanation, @RalfJung ! Although not yet in the scope of this issue, may I suggest also "constifying" const FOO: () = {
let _ = SOME_RSLT.ok().unwrap();
}; |
That will require const drop too. |
The final comment period, with a disposition to merge, as per the review above, is now complete. As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed. This will be merged soon. |
Just to avoid conflicts with others, I have a commit locally that stabilizes some things only blocked by this. Planning on opening PRs later tonight or tomorrow. |
Are you planning a PR to stablizes |
The latter; I was only planning on stabilizing things that depend on Edit: Working on stabilizing the |
…shtriplett Stabilize `const_panic` Closes rust-lang#51999 FCP completed in rust-lang#89006 `@rustbot` label +A-const-eval +A-const-fn +T-lang cc `@oli-obk` for review (not `r?`'ing as not on lang team)
…shtriplett Stabilize `const_panic` Closes rust-lang#51999 FCP completed in rust-lang#89006 ``@rustbot`` label +A-const-eval +A-const-fn +T-lang cc ``@oli-obk`` for review (not `r?`'ing as not on lang team)
…shtriplett Stabilize `const_panic` Closes rust-lang#51999 FCP completed in rust-lang#89006 ```@rustbot``` label +A-const-eval +A-const-fn +T-lang cc ```@oli-obk``` for review (not `r?`'ing as not on lang team)
With 9866b09 having landed, it looks like this can be closed? |
Ah dang, missed the opportunity to link it in like I did the tracking issue. Yes, this can be closed. |
Since const panics are now [stabilized], I figure it would be good to document some of its gotchas. I couldn't really find documents for the specifics I ran into. I am no const eval expert, and what I wrote is basically a paraphrase of Ralf's comments[^1][^2], but I hope to get the ball rolling for adding some docs. I deliberately chose to not mention the guarantee about syntactically referenced constants in functions that require code generation as it seems hard to explain completely without some ambiguity. It also seems to me that the rules are not completely stable[^3][^4] yet. [stabilized]: rust-lang/rust#89006 [^1]: rust-lang/rust#91877 (comment) [^2]: rust-lang/rust#91877 (comment) [^3]: rust-lang/rust#71800 [^4]: rust-lang/rust#51999 (comment)
Since const panics are now [stabilized], I figure it would be good to document some of its gotchas. I couldn't really find documents for the specifics I ran into. I am no const eval expert, and what I wrote is basically a paraphrase of Ralf's comments[^1][^2], but I hope to get the ball rolling for adding some docs. I deliberately chose to not mention the guarantee about syntactically referenced constants in functions that require code generation as it seems hard to explain completely without some ambiguity. It also seems to me that the rules are not completely stable[^3][^4] yet. [stabilized]: rust-lang/rust#89006 [^1]: rust-lang/rust#91877 (comment) [^2]: rust-lang/rust#91877 (comment) [^3]: rust-lang/rust#71800 [^4]: rust-lang/rust#51999 (comment)
Stabilization report
Summary
This feature allows panicking within constants and reporting a custom message as a compile-time error.
The following code will become valid on stable:
The message looks like:
Motivation for this RFC can be found here: https://rust-lang.github.io/rfcs/2345-const-panic.html#motivation
More examples can be found here: https://github.com/rust-lang/rust/blob/673d0db5e393e9c64897005b470bfeb6d5aec61b/src/test/ui/consts/const-eval/const_panic.rs
Edge cases & tests
Some questions which should be resolved in the future
We have some "unresolved questions" but they aren't an actual blocker.
Or do we just produce the exact message the panic would produce?
Result::unwrap
andOption::unwrap
becomeconst fn
, doing both in one go might be a good idea.See the brief summary comment here: #51999 (comment)
Previous attempt: #85194 (This was blocked because it was not possible to use a generated panic message, only literal strings were allowed, which has been resolved in #88954)
Originally posted by @JohnTitor in #51999 (comment)
cc @rust-lang/wg-const-eval
The text was updated successfully, but these errors were encountered: