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

Fix invalid special casing of the unreachable! macro #93179

Merged
merged 2 commits into from
Feb 7, 2022

Conversation

Urgau
Copy link
Member

@Urgau Urgau commented Jan 21, 2022

This pull-request fix an invalid special casing of the unreachable! macro in the same way the panic! macro was solved, by adding two new internal only macros unreachable_2015 and unreachable_2021 edition dependent and turn unreachable! into a built-in macro that do dispatching. This logic is stolen from the panic! macro.

This pull-request also adds an internal feature format_args_capture_non_literal that allows capturing arguments from formatted string that expanded from macros. The original RFC #2795 mentioned this as a future possibility. This feature is required because of concatenation that needs to be done inside the macro:

$crate::concat!("internal error: entered unreachable code: ", $fmt)

In summary the new behavior for the unreachable! macro with this pr is:

Edition 2021:

let x = 5;
unreachable!("x is {x}");
internal error: entered unreachable code: x is 5

Edition <= 2018:

let x = 5;
unreachable!("x is {x}");
internal error: entered unreachable code: x is {x}

Also note that the change in this PR are insta-stable and breaking changes but this a considered as being a bug.
If someone could start a perf run and then a crater run this would be appreciated.

Fixes #92137

@rust-highfive
Copy link
Collaborator

r? @oli-obk

(rust-highfive has picked a reviewer for you, use r? to override)

@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Jan 21, 2022
@rust-highfive rust-highfive added the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jan 21, 2022
@rust-log-analyzer

This comment has been minimized.

@camelid
Copy link
Member

camelid commented Jan 22, 2022

@bors try @rust-timer queue

@rust-timer
Copy link
Collaborator

Awaiting bors try build completion.

@rustbot label: +S-waiting-on-perf

@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 22, 2022
@bors
Copy link
Contributor

bors commented Jan 22, 2022

⌛ Trying commit 7331ddeed4310ba606bae8479850985251a35dd3 with merge 07d94fb27d02adc112536d7c6439de6a373f2e03...

@camelid
Copy link
Member

camelid commented Jan 22, 2022

cc discussion about implementation strategy: #92137 (comment)

@camelid
Copy link
Member

camelid commented Jan 22, 2022

cc @m-ou-se

@bors
Copy link
Contributor

bors commented Jan 22, 2022

☀️ Try build successful - checks-actions
Build commit: 07d94fb27d02adc112536d7c6439de6a373f2e03 (07d94fb27d02adc112536d7c6439de6a373f2e03)

@rust-timer
Copy link
Collaborator

Queued 07d94fb27d02adc112536d7c6439de6a373f2e03 with parent 17d29dc, future comparison URL.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (07d94fb27d02adc112536d7c6439de6a373f2e03): comparison url.

Summary: This benchmark run did not return any relevant changes.

If you disagree with this performance assessment, please file an issue in rust-lang/rustc-perf.

Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. While you can manually mark this PR as fit for rollup, we strongly recommend not doing so since this PR led to changes in compiler perf.

@bors rollup=never
@rustbot label: +S-waiting-on-review -S-waiting-on-perf -perf-regression

@rustbot rustbot removed the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 22, 2022
@m-ou-se
Copy link
Member

m-ou-se commented Jan 22, 2022

Thanks for working on this! I'll try to review this soon.

I'll have to note that for any edition-specific changes, we also need to add a migration lint to automatically upgrade code from older editions. (Just like we already have for panic!().) Unfortuantely, because Rust 2021 is already stable, this will have to happen at the same time in this case.

This pull-request also adds an internal feature format_args_capture_non_literal that allows capturing arguments from formatted string that expanded from macros. The original RFC #2795 mentioned this as a future possibility. This feature is required because of concatenation that needs to be done inside the macro:

Another option is to make that work using a nested format_args:

-        $crate::panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
+        $crate::panic!("internal error: entered unreachable code: {}", $crate::format_args!($fmt, $($arg)*))

(Edit: In general I try to avoid using concat!() for format strings, because concat automatically converts non-string literals to strings. E.g. unreachable!(1, 2) happily appends "1" to the format string, and only complains because the 2 argument is unused. Screenshot.)

(Edit 2: I've started a discussion on optimizing nested format_args on Zulip.)

@m-ou-se
Copy link
Member

m-ou-se commented Jan 22, 2022

we also need to add a migration lint

I'd be happy to extend the non_fmt_panics lint to also cover unreachable. It's not trivial as panic!(123) and unreachable!(123) are a bit different: the first throws a i32 as a Box<dyn Any>, while the latter just formats the i32 with "{}". But it shouldn't be too much work.

@Urgau
Copy link
Member Author

Urgau commented Jan 23, 2022

I've updated the implementation to use a nested format_args! and reverted the introduction of format_args_capture_non_literal. I've also updated and improved the test using revisions as camelid suggested.

we also need to add a migration lint

I'd be happy to extend the non_fmt_panics lint to also cover unreachable. It's not trivial as panic!(123) and unreachable!(123) are a bit different: the first throws a i32 as a Box<dyn Any>, while the latter just formats the i32 with "{}". But it shouldn't be too much work.

I tried to expand the current non_fmt_panics but I'm stuck on the fact that the argument passed to panic_str is the result of $crate::concat!("internal error: entered unreachable code: ", $fmt) and I don't know how (if even possible) to get the argument passed to concat or unreachable_2015. Any suggestions ?

@@ -0,0 +1,14 @@
// ignore-emscripten no processes
Copy link
Member

Choose a reason for hiding this comment

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

Why are you ignoring emscripten in these tests?

Copy link
Member Author

Choose a reason for hiding this comment

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

I did the same as this test unreachable-fmt-msg.rs

@m-ou-se
Copy link
Member

m-ou-se commented Jan 23, 2022

I tried to expand the current non_fmt_panics but I'm stuck on the fact that the argument passed to panic_str is the result of $crate::concat!("internal error: entered unreachable code: ", $fmt) and I don't know how (if even possible) to get the argument passed to concat or unreachable_2015. Any suggestions ?

Maybe you could make the second case of unreachable_2015 expand to a function call instead: unreachable_display(&$msg) and then define a fn unreachable_display(_: &impl Display) -> !; to do the panic. Then you can detect that function in the lint, similar to how it detects panic_any / panic_str / etc.

library/core/src/panic.rs Outdated Show resolved Hide resolved
@Urgau
Copy link
Member Author

Urgau commented Jan 23, 2022

I tried to expand the current non_fmt_panics but I'm stuck on the fact that the argument passed to panic_str is the result of $crate::concat!("internal error: entered unreachable code: ", $fmt) and I don't know how (if even possible) to get the argument passed to concat or unreachable_2015. Any suggestions ?

Maybe you could make the second case of unreachable_2015 expand to a function call instead: unreachable_display(&$msg) and then define a fn unreachable_display(_: &impl Display) -> !; to do the panic. Then you can detect that function in the lint, similar to how it detects panic_any / panic_str / etc.

Added in 8f00aed and update of non_fmt_panic in d8de238.

Copy link
Member

@m-ou-se m-ou-se left a comment

Choose a reason for hiding this comment

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

Nice! Thanks for working on this!

I have a few more comments:

library/core/src/panicking.rs Outdated Show resolved Hide resolved
library/core/src/panicking.rs Outdated Show resolved Hide resolved
library/core/src/panic.rs Outdated Show resolved Hide resolved
compiler/rustc_lint/src/non_fmt_panic.rs Outdated Show resolved Hide resolved
library/core/src/panic.rs Outdated Show resolved Hide resolved
compiler/rustc_lint/src/non_fmt_panic.rs Outdated Show resolved Hide resolved
compiler/rustc_lint/src/non_fmt_panic.rs Outdated Show resolved Hide resolved
@Urgau
Copy link
Member Author

Urgau commented Jan 23, 2022

I've address all of review comments. Let me know if there is something else that I should modify or improve.

@Urgau Urgau requested a review from m-ou-se January 23, 2022 15:59
@camelid
Copy link
Member

camelid commented Feb 7, 2022

@jhpratt It is weird that the changes are so large, but it's almost entirely improvements. There's only one regression, which means it's probably spurious.

@Urgau
Copy link
Member Author

Urgau commented Feb 8, 2022

Based on this comment from @m-ou-se:

Can you squash the commits a bit? There's now a few commits that undo changes of previous commits in this PR, potentially making history tracking and backporting a bit complicated. Ideally this change would be backported to 1.59 (beta) too.

Shouldn't this PR be marked as beta-nominated ? or even stable-nominated ?

@m-ou-se m-ou-se added the beta-nominated Nominated for backporting to the compiler in the beta channel. label Feb 8, 2022
@jhpratt
Copy link
Member

jhpratt commented Feb 8, 2022

Beta seems reasonable. Not sure we need a point release for this, though.

@Urgau
Copy link
Member Author

Urgau commented Feb 8, 2022

Beta seems reasonable. Not sure we need a point release for this, though.

Well #93394 is in the same wane as this PR and was stable-nominated and stable-accepted.

@m-ou-se
Copy link
Member

m-ou-se commented Feb 8, 2022

Not sure we need a point release for this, though.

As I was recently told, stable-nominated doesn't mean it's worth a point release. It means that if a new stable point release happens, this should be included.

I'm not sure if even in that case it should be backported, considering this change is a bit more complex than #93394, but it's a discussion that can be had. (But we're getting close to the next release anyway, so a point release seems unlikely at this point.)

@m-ou-se m-ou-se added the stable-nominated Nominated for backporting to the compiler in the stable channel. label Feb 8, 2022
@Mark-Simulacrum
Copy link
Member

Marking as perf-regression-triaged -- only regression appears to be due to codegen unit reshuffling, not directly related to this PR.

@Mark-Simulacrum Mark-Simulacrum added the perf-regression-triaged The performance regression has been triaged. label Feb 8, 2022
@alice-i-cecile
Copy link

This broke bevy_ecs on nightly. Here was our fix: bevyengine/bevy#3889

@Urgau
Copy link
Member Author

Urgau commented Feb 8, 2022

@alice-i-cecile This is expected, see #92137 (comment) for more context about this change and why the breaking change is considered acceptable. Also note that this change will probably be at least back-ported to beta.

@jhpratt
Copy link
Member

jhpratt commented Feb 8, 2022

I think I've said this before, but a crater run would be nice to have here. Limited to 2021 edition if it's possible (I don't think it is).

@Urgau
Copy link
Member Author

Urgau commented Feb 8, 2022

I think I've said this before, but a crater run would be nice to have here. Limited to 2021 edition if it's possible (I don't think it is).

It will be done as part of the crater run done for every new stable (it's actually done with beta but you see the point).

@jhpratt
Copy link
Member

jhpratt commented Feb 8, 2022

Yeah, I just meant to do it before so we don't have to rush a last-minute revert if it breaks too much.

@apiraino
Copy link
Contributor

Beta backport accepted as per compiler team on Zulip

Stable backport declined (zulip discussion)

@rustbot label +beta-accepted -stable-nominated

@rustbot rustbot added beta-accepted Accepted for backporting to the compiler in the beta channel. and removed stable-nominated Nominated for backporting to the compiler in the stable channel. labels Feb 10, 2022
@Mark-Simulacrum Mark-Simulacrum removed the beta-nominated Nominated for backporting to the compiler in the beta channel. label Feb 11, 2022
@Mark-Simulacrum Mark-Simulacrum modified the milestones: 1.60.0, 1.59.0 Feb 11, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 12, 2022
…ulacrum

[beta] backports

This backports:

*  Complete removal of #[main] attribute from compiler rust-lang#93753
*  Resolve lifetimes for const generic defaults rust-lang#93669
*  backport llvm fix for issue 91671. rust-lang#93426
*  Fix invalid special casing of the unreachable! macro rust-lang#93179
*  Fix hashing for windows paths containing a CurDir component rust-lang#93697

r? `@Mark-Simulacrum`
@Mark-Simulacrum Mark-Simulacrum added the relnotes Marks issues that should be documented in the release notes of the next release. label Feb 22, 2022
bors added a commit to rust-lang-ci/rust that referenced this pull request Feb 23, 2022
…imulacrum

[stable] 1.59.0 artifacts (second round)

This backports (from 1.60, landed in rust-lang#93001):

*  Move return_self_not_must_use to pedantic rust-lang/rust-clippy#8302

Per a user report on the internals feedback thread, this lint is not behaving well in 1.59.

cc `@rust-lang/clippy` -- this is a stable backport of a patch, which we'll likely want to land in fairly short order to be in time for the release Thursday.

This PR also includes an adjustment to the release notes to reflect "Fix invalid special casing of the unreachable! macro rust-lang#93179".

r? `@Mark-Simulacrum`
@Urgau Urgau deleted the unreachable-2021 branch May 5, 2023 16:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
beta-accepted Accepted for backporting to the compiler in the beta channel. merged-by-bors This PR was explicitly merged by bors. perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. relnotes Marks issues that should be documented in the release notes of the next release. S-waiting-on-bors Status: Waiting on bors to run and complete tests. Bors will change the label on completion. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

unreachable!("{}") works on Rust 2021