diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs index 1e2646e4d34..9a45dec55f3 100644 --- a/compiler/rustc_builtin_macros/src/assert.rs +++ b/compiler/rustc_builtin_macros/src/assert.rs @@ -1,4 +1,4 @@ -use crate::panic::use_panic_2021; +use crate::edition_panic::use_panic_2021; use rustc_ast::ptr::P; use rustc_ast::token; use rustc_ast::tokenstream::{DelimSpan, TokenStream}; diff --git a/compiler/rustc_builtin_macros/src/panic.rs b/compiler/rustc_builtin_macros/src/edition_panic.rs similarity index 73% rename from compiler/rustc_builtin_macros/src/panic.rs rename to compiler/rustc_builtin_macros/src/edition_panic.rs index 54ab596bf3e..518b88dec6a 100644 --- a/compiler/rustc_builtin_macros/src/panic.rs +++ b/compiler/rustc_builtin_macros/src/edition_panic.rs @@ -20,8 +20,29 @@ pub fn expand_panic<'cx>( sp: Span, tts: TokenStream, ) -> Box { - let panic = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 }; + let mac = if use_panic_2021(sp) { sym::panic_2021 } else { sym::panic_2015 }; + expand(mac, cx, sp, tts) +} +// This expands to either +// - `$crate::panic::unreachable_2015!(...)` or +// - `$crate::panic::unreachable_2021!(...)` +// depending on the edition. +pub fn expand_unreachable<'cx>( + cx: &'cx mut ExtCtxt<'_>, + sp: Span, + tts: TokenStream, +) -> Box { + let mac = if use_panic_2021(sp) { sym::unreachable_2021 } else { sym::unreachable_2015 }; + expand(mac, cx, sp, tts) +} + +fn expand<'cx>( + mac: rustc_span::Symbol, + cx: &'cx mut ExtCtxt<'_>, + sp: Span, + tts: TokenStream, +) -> Box { let sp = cx.with_call_site_ctxt(sp); MacEager::expr( @@ -31,7 +52,7 @@ pub fn expand_panic<'cx>( path: Path { span: sp, segments: cx - .std_path(&[sym::panic, panic]) + .std_path(&[sym::panic, mac]) .into_iter() .map(|ident| PathSegment::from_ident(ident)) .collect(), diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs index 6c16c285492..98c94dfc686 100644 --- a/compiler/rustc_builtin_macros/src/lib.rs +++ b/compiler/rustc_builtin_macros/src/lib.rs @@ -31,12 +31,12 @@ mod concat_bytes; mod concat_idents; mod derive; mod deriving; +mod edition_panic; mod env; mod format; mod format_foreign; mod global_allocator; mod log_syntax; -mod panic; mod source_util; mod test; mod trace_macros; @@ -82,8 +82,9 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) { log_syntax: log_syntax::expand_log_syntax, module_path: source_util::expand_mod, option_env: env::expand_option_env, - core_panic: panic::expand_panic, - std_panic: panic::expand_panic, + core_panic: edition_panic::expand_panic, + std_panic: edition_panic::expand_panic, + unreachable: edition_panic::expand_unreachable, stringify: source_util::expand_stringify, trace_macros: trace_macros::expand_trace_macros, } diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 757c430e799..7068b86572f 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -1437,7 +1437,12 @@ symbols! { unmarked_api, unpin, unreachable, + unreachable_2015, + unreachable_2015_macro, + unreachable_2021, + unreachable_2021_macro, unreachable_code, + unreachable_display, unreachable_macro, unrestricted_attribute_tokens, unsafe_block_in_unsafe_fn, diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs index 0cc428d6962..a9e90556f6c 100644 --- a/library/core/src/macros/mod.rs +++ b/library/core/src/macros/mod.rs @@ -594,6 +594,22 @@ macro_rules! writeln { /// unreachable!("The loop should always return"); /// } /// ``` +#[cfg(not(bootstrap))] +#[macro_export] +#[rustc_builtin_macro(unreachable)] +#[allow_internal_unstable(edition_panic)] +#[stable(feature = "rust1", since = "1.0.0")] +#[cfg_attr(not(test), rustc_diagnostic_item = "unreachable_macro")] +macro_rules! unreachable { + // Expands to either `$crate::panic::unreachable_2015` or `$crate::panic::unreachable_2021` + // depending on the edition of the caller. + ($($arg:tt)*) => { + /* compiler built-in */ + }; +} + +/// unreachable!() macro +#[cfg(bootstrap)] #[macro_export] #[stable(feature = "rust1", since = "1.0.0")] #[cfg_attr(not(test), rustc_diagnostic_item = "unreachable_macro")] diff --git a/library/core/src/panic.rs b/library/core/src/panic.rs index 7a8b04d6f3c..0be3f06ff6c 100644 --- a/library/core/src/panic.rs +++ b/library/core/src/panic.rs @@ -58,6 +58,39 @@ pub macro panic_2021 { ), } +#[doc(hidden)] +#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")] +#[allow_internal_unstable(core_panic)] +#[rustc_diagnostic_item = "unreachable_2015_macro"] +#[rustc_macro_transparency = "semitransparent"] +pub macro unreachable_2015 { + () => ( + $crate::panicking::panic("internal error: entered unreachable code") + ), + // Use of `unreachable_display` for non_fmt_panic lint. + // NOTE: the message ("internal error ...") is embeded directly in unreachable_display + ($msg:expr $(,)?) => ( + $crate::panicking::unreachable_display(&$msg) + ), + ($fmt:expr, $($arg:tt)*) => ( + $crate::panic!($crate::concat!("internal error: entered unreachable code: ", $fmt), $($arg)*) + ), +} + +#[doc(hidden)] +#[unstable(feature = "edition_panic", issue = "none", reason = "use unreachable!() instead")] +#[allow_internal_unstable(core_panic)] +#[rustc_diagnostic_item = "unreachable_2021_macro"] +#[rustc_macro_transparency = "semitransparent"] +pub macro unreachable_2021 { + () => ( + $crate::panicking::panic("internal error: entered unreachable code") + ), + ($($t:tt)+) => ( + $crate::panic!("internal error: entered unreachable code: {}", $crate::format_args!($($t)+)) + ), +} + /// An internal trait used by libstd to pass data from libstd to `panic_unwind` /// and other panic runtimes. Not intended to be stabilized any time soon, do /// not use. diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs index 5078eea07a1..d857b4948b5 100644 --- a/library/core/src/panicking.rs +++ b/library/core/src/panicking.rs @@ -56,6 +56,14 @@ pub const fn panic_str(expr: &str) -> ! { panic_display(&expr); } +#[cfg(not(bootstrap))] +#[inline] +#[track_caller] +#[rustc_diagnostic_item = "unreachable_display"] // needed for `non-fmt-panics` lint +pub fn unreachable_display(x: &T) -> ! { + panic_fmt(format_args!("internal error: entered unreachable code: {}", *x)); +} + #[inline] #[track_caller] #[lang = "panic_display"] // needed for const-evaluated panics diff --git a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff index 57485993dce..1a454bab4d0 100644 --- a/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff +++ b/src/test/mir-opt/issue_76432.test.SimplifyComparisonIntegral.diff @@ -21,7 +21,7 @@ let mut _19: *const T; // in scope 0 at $DIR/issue_76432.rs:9:54: 9:68 let mut _20: *const T; // in scope 0 at $DIR/issue_76432.rs:9:70: 9:84 let mut _21: *const T; // in scope 0 at $DIR/issue_76432.rs:9:70: 9:84 - let mut _22: !; // in scope 0 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + let mut _22: !; // in scope 0 at $SRC_DIR/core/src/panic.rs:LL:COL let mut _23: &[T; 3]; // in scope 0 at $DIR/issue_76432.rs:7:19: 7:29 scope 1 { debug v => _2; // in scope 1 at $DIR/issue_76432.rs:7:9: 7:10 @@ -66,16 +66,16 @@ } bb1: { - StorageLive(_22); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL - core::panicking::panic(const "internal error: entered unreachable code"); // scope 1 at $SRC_DIR/core/src/macros/mod.rs:LL:COL + StorageLive(_22); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL + core::panicking::panic(const "internal error: entered unreachable code"); // scope 1 at $SRC_DIR/core/src/panic.rs:LL:COL // mir::Constant - // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + span: $SRC_DIR/core/src/panic.rs:LL:COL // + literal: Const { ty: fn(&'static str) -> ! {core::panicking::panic}, val: Value(Scalar()) } // ty::Const // + ty: &str // + val: Value(Slice { data: Allocation { bytes: [105, 110, 116, 101, 114, 110, 97, 108, 32, 101, 114, 114, 111, 114, 58, 32, 101, 110, 116, 101, 114, 101, 100, 32, 117, 110, 114, 101, 97, 99, 104, 97, 98, 108, 101, 32, 99, 111, 100, 101], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1099511627775], len: Size { raw: 40 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 40 }) // mir::Constant - // + span: $SRC_DIR/core/src/macros/mod.rs:LL:COL + // + span: $SRC_DIR/core/src/panic.rs:LL:COL // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [105, 110, 116, 101, 114, 110, 97, 108, 32, 101, 114, 114, 111, 114, 58, 32, 101, 110, 116, 101, 114, 101, 100, 32, 117, 110, 114, 101, 97, 99, 104, 97, 98, 108, 101, 32, 99, 111, 100, 101], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [1099511627775], len: Size { raw: 40 } }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 40 }) } } diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr index 8da697fe7ef..2955f11716c 100644 --- a/src/test/ui/consts/const-eval/const_panic.stderr +++ b/src/test/ui/consts/const-eval/const_panic.stderr @@ -20,7 +20,7 @@ error[E0080]: evaluation of constant value failed LL | const Y: () = std::unreachable!(); | ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:12:15 | - = note: this error originates in the macro `std::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::unreachable_2015` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:15:15 @@ -68,7 +68,7 @@ error[E0080]: evaluation of constant value failed LL | const Y_CORE: () = core::unreachable!(); | ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:30:20 | - = note: this error originates in the macro `core::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::unreachable_2015` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/const_panic.rs:33:20 diff --git a/src/test/ui/consts/const-eval/const_panic_2021.stderr b/src/test/ui/consts/const-eval/const_panic_2021.stderr index 62fe1715fec..cb3b08e0e09 100644 --- a/src/test/ui/consts/const-eval/const_panic_2021.stderr +++ b/src/test/ui/consts/const-eval/const_panic_2021.stderr @@ -20,7 +20,7 @@ error[E0080]: evaluation of constant value failed LL | const C: () = std::unreachable!(); | ^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:12:15 | - = note: this error originates in the macro `std::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::unreachable_2021` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:15:15 @@ -60,7 +60,7 @@ error[E0080]: evaluation of constant value failed LL | const C_CORE: () = core::unreachable!(); | ^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_2021.rs:27:20 | - = note: this error originates in the macro `core::unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::unreachable_2021` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/const_panic_2021.rs:30:20 diff --git a/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr b/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr index 52c0c136366..417120c453e 100644 --- a/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr +++ b/src/test/ui/consts/const-eval/const_panic_libcore_bin.stderr @@ -12,7 +12,7 @@ error[E0080]: evaluation of constant value failed LL | const Y: () = unreachable!(); | ^^^^^^^^^^^^^^ the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic_libcore_bin.rs:11:15 | - = note: this error originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info) + = note: this error originates in the macro `$crate::panic::unreachable_2015` (in Nightly builds, run with -Z macro-backtrace for more info) error[E0080]: evaluation of constant value failed --> $DIR/const_panic_libcore_bin.rs:14:15 diff --git a/src/test/ui/macros/unreachable-format-arg.rs b/src/test/ui/macros/unreachable-format-arg.rs new file mode 100644 index 00000000000..7d83b698d79 --- /dev/null +++ b/src/test/ui/macros/unreachable-format-arg.rs @@ -0,0 +1,13 @@ +// run-fail +// ignore-emscripten no processes + +// revisions: edition_2015 edition_2021 +// [edition_2015]edition:2015 +// [edition_2021]edition:2021 +// [edition_2015]error-pattern:internal error: entered unreachable code: x is {x} +// [edition_2021]error-pattern:internal error: entered unreachable code: x is 5 + +fn main() { + let x = 5; + unreachable!("x is {x}"); +} diff --git a/src/test/ui/macros/unreachable-format-args.edition_2015.stderr b/src/test/ui/macros/unreachable-format-args.edition_2015.stderr new file mode 100644 index 00000000000..dda45d14a3f --- /dev/null +++ b/src/test/ui/macros/unreachable-format-args.edition_2015.stderr @@ -0,0 +1,12 @@ +error: there is no argument named `x` + --> $DIR/unreachable-format-args.rs:13:5 + | +LL | unreachable!("x is {x} and y is {y}", y = 0); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: did you intend to capture a variable `x` from the surrounding scope? + = note: to avoid ambiguity, `format_args!` cannot capture variables when the format string is expanded from a macro + = note: this error originates in the macro `$crate::concat` (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error + diff --git a/src/test/ui/macros/unreachable-format-args.rs b/src/test/ui/macros/unreachable-format-args.rs new file mode 100644 index 00000000000..04a31fc1ba3 --- /dev/null +++ b/src/test/ui/macros/unreachable-format-args.rs @@ -0,0 +1,14 @@ +// ignore-emscripten no processes + +// revisions: edition_2015 edition_2021 +// [edition_2015]edition:2015 +// [edition_2021]edition:2021 +// [edition_2015]check-fail +// [edition_2021]run-fail +// [edition_2015]error-pattern:there is no argument named `x` +// [edition_2021]error-pattern:internal error: entered unreachable code: x is 5 and y is 0 + +fn main() { + let x = 5; + unreachable!("x is {x} and y is {y}", y = 0); +} diff --git a/src/test/ui/proc-macro/quote-debug.stdout b/src/test/ui/proc-macro/quote-debug.stdout index 79651f01b95..3738bffd733 100644 --- a/src/test/ui/proc-macro/quote-debug.stdout +++ b/src/test/ui/proc-macro/quote-debug.stdout @@ -33,9 +33,7 @@ fn main() { lit.set_span(crate::Span::recover_proc_macro_span(2)); lit } else { - { - ::core::panicking::panic("internal error: entered unreachable code") - } + ::core::panicking::panic("internal error: entered unreachable code") } })), crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3b}',