Skip to content

Commit e0d9f79

Browse files
committed
Auto merge of #80851 - m-ou-se:panic-2021, r=petrochenkov
Implement Rust 2021 panic This implements the Rust 2021 versions of `panic!()`. See #80162 and rust-lang/rfcs#3007. It does so by replacing `{std, core}::panic!()` by a bulitin macro that expands to either `$crate::panic::panic_2015!(..)` or `$crate::panic::panic_2021!(..)` depending on the edition of the caller. This does not yet make std's panic an alias for core's panic on Rust 2021 as the RFC proposes. That will be a separate change: c5273bd That change is blocked on figuring out what to do with #80846 first.
2 parents fee0d31 + 5b11a97 commit e0d9f79

26 files changed

+592
-425
lines changed

compiler/rustc_builtin_macros/src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ mod global_allocator;
3333
mod global_asm;
3434
mod llvm_asm;
3535
mod log_syntax;
36+
mod panic;
3637
mod source_util;
3738
mod test;
3839
mod trace_macros;
@@ -76,6 +77,8 @@ pub fn register_builtin_macros(resolver: &mut dyn ResolverExpand) {
7677
log_syntax: log_syntax::expand_log_syntax,
7778
module_path: source_util::expand_mod,
7879
option_env: env::expand_option_env,
80+
core_panic: panic::expand_panic,
81+
std_panic: panic::expand_panic,
7982
stringify: source_util::expand_stringify,
8083
trace_macros: trace_macros::expand_trace_macros,
8184
}
+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use rustc_ast::ptr::P;
2+
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
3+
use rustc_ast::*;
4+
use rustc_expand::base::*;
5+
use rustc_span::symbol::sym;
6+
use rustc_span::Span;
7+
8+
// This expands to either
9+
// - `$crate::panic::panic_2015!(...)` or
10+
// - `$crate::panic::panic_2021!(...)`
11+
// depending on the edition.
12+
//
13+
// This is used for both std::panic!() and core::panic!().
14+
//
15+
// `$crate` will refer to either the `std` or `core` crate depending on which
16+
// one we're expanding from.
17+
pub fn expand_panic<'cx>(
18+
cx: &'cx mut ExtCtxt<'_>,
19+
sp: Span,
20+
tts: TokenStream,
21+
) -> Box<dyn MacResult + 'cx> {
22+
let panic = if sp.rust_2021() { sym::panic_2021 } else { sym::panic_2015 };
23+
24+
let sp = cx.with_call_site_ctxt(sp);
25+
26+
MacEager::expr(
27+
cx.expr(
28+
sp,
29+
ExprKind::MacCall(MacCall {
30+
path: Path {
31+
span: sp,
32+
segments: cx
33+
.std_path(&[sym::panic, panic])
34+
.into_iter()
35+
.map(|ident| PathSegment::from_ident(ident))
36+
.collect(),
37+
tokens: None,
38+
},
39+
args: P(MacArgs::Delimited(
40+
DelimSpan::from_single(sp),
41+
MacDelimiter::Parenthesis,
42+
tts,
43+
)),
44+
prior_type_ascription: None,
45+
}),
46+
),
47+
)
48+
}

compiler/rustc_lint/src/panic_fmt.rs

+14-9
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ declare_lint! {
1919
///
2020
/// ### Explanation
2121
///
22-
/// `panic!("{}")` panics with the message `"{}"`, as a `panic!()` invocation
23-
/// with a single argument does not use `format_args!()`.
24-
/// A future edition of Rust will interpret this string as format string,
25-
/// which would break this.
22+
/// In Rust 2018 and earlier, `panic!("{}")` panics with the message `"{}"`,
23+
/// as a `panic!()` invocation with a single argument does not use `format_args!()`.
24+
/// Rust 2021 interprets this string as format string, which breaks this.
2625
PANIC_FMT,
2726
Warn,
2827
"detect braces in single-argument panic!() invocations",
@@ -50,8 +49,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
5049
if let ast::LitKind::Str(sym, _) = lit.node {
5150
let mut expn = f.span.ctxt().outer_expn_data();
5251
if let Some(id) = expn.macro_def_id {
53-
if cx.tcx.is_diagnostic_item(sym::std_panic_macro, id)
54-
|| cx.tcx.is_diagnostic_item(sym::core_panic_macro, id)
52+
if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id)
53+
|| cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id)
5554
{
5655
let fmt = sym.as_str();
5756
if !fmt.contains(&['{', '}'][..]) {
@@ -75,9 +74,15 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
7574
let n_arguments =
7675
(&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();
7776

78-
// Unwrap another level of macro expansion if this panic!()
79-
// was expanded from assert!() or debug_assert!().
80-
for &assert in &[sym::assert_macro, sym::debug_assert_macro] {
77+
// Unwrap more levels of macro expansion, as panic_2015!()
78+
// was likely expanded from panic!() and possibly from
79+
// [debug_]assert!().
80+
for &assert in &[
81+
sym::std_panic_macro,
82+
sym::core_panic_macro,
83+
sym::assert_macro,
84+
sym::debug_assert_macro,
85+
] {
8186
let parent = expn.call_site.ctxt().outer_expn_data();
8287
if parent
8388
.macro_def_id

compiler/rustc_span/src/symbol.rs

+6
Original file line numberDiff line numberDiff line change
@@ -398,6 +398,8 @@ symbols! {
398398
copysignf64,
399399
core,
400400
core_intrinsics,
401+
core_panic,
402+
core_panic_2015_macro,
401403
core_panic_macro,
402404
cosf32,
403405
cosf64,
@@ -795,6 +797,8 @@ symbols! {
795797
owned_box,
796798
packed,
797799
panic,
800+
panic_2015,
801+
panic_2021,
798802
panic_abort,
799803
panic_bounds_check,
800804
panic_handler,
@@ -1096,6 +1100,8 @@ symbols! {
10961100
staticlib,
10971101
std,
10981102
std_inject,
1103+
std_panic,
1104+
std_panic_2015_macro,
10991105
std_panic_macro,
11001106
stmt,
11011107
stmt_expr_attributes,

library/core/src/macros/mod.rs

+17-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1+
#[cfg(bootstrap)]
12
#[doc(include = "panic.md")]
23
#[macro_export]
3-
#[allow_internal_unstable(core_panic, const_caller_location)]
4+
#[allow_internal_unstable(core_panic)]
45
#[stable(feature = "core", since = "1.6.0")]
56
#[rustc_diagnostic_item = "core_panic_macro"]
67
macro_rules! panic {
@@ -18,6 +19,21 @@ macro_rules! panic {
1819
);
1920
}
2021

22+
#[cfg(not(bootstrap))]
23+
#[doc(include = "panic.md")]
24+
#[macro_export]
25+
#[rustc_builtin_macro = "core_panic"]
26+
#[allow_internal_unstable(edition_panic)]
27+
#[stable(feature = "core", since = "1.6.0")]
28+
#[rustc_diagnostic_item = "core_panic_macro"]
29+
macro_rules! panic {
30+
// Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
31+
// depending on the edition of the caller.
32+
($($arg:tt)*) => {
33+
/* compiler built-in */
34+
};
35+
}
36+
2137
/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
2238
///
2339
/// On panic, this macro will print the values of the expressions with their

library/core/src/panic.rs

+34
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,40 @@
55
use crate::any::Any;
66
use crate::fmt;
77

8+
#[doc(hidden)]
9+
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
10+
#[allow_internal_unstable(core_panic)]
11+
#[rustc_diagnostic_item = "core_panic_2015_macro"]
12+
#[rustc_macro_transparency = "semitransparent"]
13+
pub macro panic_2015 {
14+
() => (
15+
$crate::panicking::panic("explicit panic")
16+
),
17+
($msg:literal $(,)?) => (
18+
$crate::panicking::panic($msg)
19+
),
20+
($msg:expr $(,)?) => (
21+
$crate::panicking::panic_str($msg)
22+
),
23+
($fmt:expr, $($arg:tt)+) => (
24+
$crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
25+
),
26+
}
27+
28+
#[doc(hidden)]
29+
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
30+
#[allow_internal_unstable(core_panic)]
31+
#[rustc_diagnostic_item = "core_panic_2021_macro"]
32+
#[rustc_macro_transparency = "semitransparent"]
33+
pub macro panic_2021 {
34+
() => (
35+
$crate::panicking::panic("explicit panic")
36+
),
37+
($($t:tt)+) => (
38+
$crate::panicking::panic_fmt($crate::format_args!($($t)+))
39+
),
40+
}
41+
842
/// A struct providing information about a panic.
943
///
1044
/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]

library/std/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@
259259
#![feature(dropck_eyepatch)]
260260
#![feature(duration_constants)]
261261
#![feature(duration_zero)]
262+
#![feature(edition_panic)]
262263
#![feature(exact_size_is_empty)]
263264
#![feature(exhaustive_patterns)]
264265
#![feature(extend_one)]

library/std/src/macros.rs

+16
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
//! library. Each macro is available for use when linking against the standard
55
//! library.
66
7+
#[cfg(bootstrap)]
78
#[doc(include = "../../core/src/macros/panic.md")]
89
#[macro_export]
910
#[stable(feature = "rust1", since = "1.0.0")]
@@ -17,6 +18,21 @@ macro_rules! panic {
1718
});
1819
}
1920

21+
#[cfg(not(bootstrap))]
22+
#[doc(include = "../../core/src/macros/panic.md")]
23+
#[macro_export]
24+
#[rustc_builtin_macro = "std_panic"]
25+
#[stable(feature = "rust1", since = "1.0.0")]
26+
#[allow_internal_unstable(edition_panic)]
27+
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
28+
macro_rules! panic {
29+
// Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
30+
// depending on the edition of the caller.
31+
($($arg:tt)*) => {
32+
/* compiler built-in */
33+
};
34+
}
35+
2036
/// Prints to the standard output.
2137
///
2238
/// Equivalent to the [`println!`] macro except that a newline is not printed at

library/std/src/panic.rs

+21
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,27 @@ use crate::sync::{Arc, Mutex, RwLock};
1818
use crate::task::{Context, Poll};
1919
use crate::thread::Result;
2020

21+
#[doc(hidden)]
22+
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
23+
#[allow_internal_unstable(libstd_sys_internals)]
24+
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
25+
#[rustc_macro_transparency = "semitransparent"]
26+
pub macro panic_2015 {
27+
() => ({
28+
$crate::rt::begin_panic("explicit panic")
29+
}),
30+
($msg:expr $(,)?) => ({
31+
$crate::rt::begin_panic($msg)
32+
}),
33+
($fmt:expr, $($arg:tt)+) => ({
34+
$crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+))
35+
}),
36+
}
37+
38+
#[doc(hidden)]
39+
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
40+
pub use core::panic::panic_2021;
41+
2142
#[stable(feature = "panic_hooks", since = "1.10.0")]
2243
pub use crate::panicking::{set_hook, take_hook};
2344

src/test/mir-opt/const_prop/control_flow_simplification.hello.ConstProp.diff

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
fn hello() -> () {
55
let mut _0: (); // return place in scope 0 at $DIR/control-flow-simplification.rs:11:14: 11:14
66
let mut _1: bool; // in scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21
7-
let mut _2: !; // in scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
7+
let mut _2: !; // in scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
88

99
bb0: {
1010
StorageLive(_1); // scope 0 at $DIR/control-flow-simplification.rs:12:8: 12:21
@@ -15,16 +15,16 @@
1515
}
1616

1717
bb1: {
18-
StorageLive(_2); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
19-
begin_panic::<&str>(const "explicit panic"); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
18+
StorageLive(_2); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
19+
begin_panic::<&str>(const "explicit panic"); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
2020
// mir::Constant
21-
// + span: $SRC_DIR/std/src/macros.rs:LL:COL
21+
// + span: $SRC_DIR/std/src/panic.rs:LL:COL
2222
// + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar(<ZST>)) }
2323
// ty::Const
2424
// + ty: &str
2525
// + val: Value(Slice { data: Allocation { bytes: [101, 120, 112, 108, 105, 99, 105, 116, 32, 112, 97, 110, 105, 99], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16383], len: Size { raw: 14 } }, size: Size { raw: 14 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 14 })
2626
// mir::Constant
27-
// + span: $SRC_DIR/std/src/macros.rs:LL:COL
27+
// + span: $SRC_DIR/std/src/panic.rs:LL:COL
2828
// + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [101, 120, 112, 108, 105, 99, 105, 116, 32, 112, 97, 110, 105, 99], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16383], len: Size { raw: 14 } }, size: Size { raw: 14 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 14 }) }
2929
}
3030

0 commit comments

Comments
 (0)