Skip to content

Commit c027ee1

Browse files
committed
Auto merge of #93179 - Urgau:unreachable-2021, r=m-ou-se,oli-obk
Fix invalid special casing of the unreachable! macro 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](#92137 (comment)) because of concatenation that needs to be done inside the macro:~~ ```rust $crate::concat!("internal error: entered unreachable code: ", $fmt) ``` **In summary** the new behavior for the `unreachable!` macro with this pr is: Edition 2021: ```rust let x = 5; unreachable!("x is {x}"); ``` ``` internal error: entered unreachable code: x is 5 ``` Edition <= 2018: ```rust 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](#92137 (comment)). If someone could start a perf run and then a crater run this would be appreciated. Fixes #92137
2 parents 85a3518 + 45d9779 commit c027ee1

File tree

3 files changed

+58
-1
lines changed

3 files changed

+58
-1
lines changed

core/src/macros/mod.rs

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -594,6 +594,22 @@ macro_rules! writeln {
594594
/// unreachable!("The loop should always return");
595595
/// }
596596
/// ```
597+
#[cfg(not(bootstrap))]
598+
#[macro_export]
599+
#[rustc_builtin_macro(unreachable)]
600+
#[allow_internal_unstable(edition_panic)]
601+
#[stable(feature = "rust1", since = "1.0.0")]
602+
#[cfg_attr(not(test), rustc_diagnostic_item = "unreachable_macro")]
603+
macro_rules! unreachable {
604+
// Expands to either `$crate::panic::unreachable_2015` or `$crate::panic::unreachable_2021`
605+
// depending on the edition of the caller.
606+
($($arg:tt)*) => {
607+
/* compiler built-in */
608+
};
609+
}
610+
611+
/// unreachable!() macro
612+
#[cfg(bootstrap)]
597613
#[macro_export]
598614
#[stable(feature = "rust1", since = "1.0.0")]
599615
#[cfg_attr(not(test), rustc_diagnostic_item = "unreachable_macro")]

core/src/panic.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,39 @@ pub macro panic_2021 {
5858
),
5959
}
6060

61+
#[doc(hidden)]
62+
#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")]
63+
#[allow_internal_unstable(core_panic)]
64+
#[rustc_diagnostic_item = "unreachable_2015_macro"]
65+
#[rustc_macro_transparency = "semitransparent"]
66+
pub macro unreachable_2015 {
67+
() => (
68+
$crate::panicking::panic("internal error: entered unreachable code")
69+
),
70+
// Use of `unreachable_display` for non_fmt_panic lint.
71+
// NOTE: the message ("internal error ...") is embeded directly in unreachable_display
72+
($msg:expr $(,)?) => (
73+
$crate::panicking::unreachable_display(&$msg)
74+
),
75+
($fmt:expr, $($arg:tt)*) => (
76+
$crate::panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*)
77+
),
78+
}
79+
80+
#[doc(hidden)]
81+
#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")]
82+
#[allow_internal_unstable(core_panic)]
83+
#[rustc_diagnostic_item = "unreachable_2021_macro"]
84+
#[rustc_macro_transparency = "semitransparent"]
85+
pub macro unreachable_2021 {
86+
() => (
87+
$crate::panicking::panic("internal error: entered unreachable code")
88+
),
89+
($($t:tt)+) => (
90+
$crate::panic!("internal error: entered unreachable code: {}", $crate::format_args!($($t)+))
91+
),
92+
}
93+
6194
/// An internal trait used by libstd to pass data from libstd to `panic_unwind`
6295
/// and other panic runtimes. Not intended to be stabilized any time soon, do
6396
/// not use.

core/src/panicking.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,20 @@ pub const fn panic(expr: &'static str) -> ! {
5050

5151
#[inline]
5252
#[track_caller]
53-
#[lang = "panic_str"] // needed for `non-fmt-panics` lint
53+
#[rustc_diagnostic_item = "panic_str"]
5454
#[rustc_const_unstable(feature = "core_panic", issue = "none")]
5555
pub const fn panic_str(expr: &str) -> ! {
5656
panic_display(&expr);
5757
}
5858

59+
#[cfg(not(bootstrap))]
60+
#[inline]
61+
#[track_caller]
62+
#[rustc_diagnostic_item = "unreachable_display"] // needed for `non-fmt-panics` lint
63+
pub fn unreachable_display<T: fmt::Display>(x: &T) -> ! {
64+
panic_fmt(format_args!("internal error: entered unreachable code: {}", *x));
65+
}
66+
5967
#[inline]
6068
#[track_caller]
6169
#[lang = "panic_display"] // needed for const-evaluated panics

0 commit comments

Comments
 (0)