Skip to content

Commit

Permalink
Auto merge of #80851 - m-ou-se:panic-2021, r=petrochenkov
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Feb 1, 2021
2 parents fee0d31 + 5b11a97 commit e0d9f79
Show file tree
Hide file tree
Showing 26 changed files with 592 additions and 425 deletions.
3 changes: 3 additions & 0 deletions compiler/rustc_builtin_macros/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ mod global_allocator;
mod global_asm;
mod llvm_asm;
mod log_syntax;
mod panic;
mod source_util;
mod test;
mod trace_macros;
Expand Down Expand Up @@ -76,6 +77,8 @@ 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,
stringify: source_util::expand_stringify,
trace_macros: trace_macros::expand_trace_macros,
}
Expand Down
48 changes: 48 additions & 0 deletions compiler/rustc_builtin_macros/src/panic.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
use rustc_ast::ptr::P;
use rustc_ast::tokenstream::{DelimSpan, TokenStream};
use rustc_ast::*;
use rustc_expand::base::*;
use rustc_span::symbol::sym;
use rustc_span::Span;

// This expands to either
// - `$crate::panic::panic_2015!(...)` or
// - `$crate::panic::panic_2021!(...)`
// depending on the edition.
//
// This is used for both std::panic!() and core::panic!().
//
// `$crate` will refer to either the `std` or `core` crate depending on which
// one we're expanding from.
pub fn expand_panic<'cx>(
cx: &'cx mut ExtCtxt<'_>,
sp: Span,
tts: TokenStream,
) -> Box<dyn MacResult + 'cx> {
let panic = if sp.rust_2021() { sym::panic_2021 } else { sym::panic_2015 };

let sp = cx.with_call_site_ctxt(sp);

MacEager::expr(
cx.expr(
sp,
ExprKind::MacCall(MacCall {
path: Path {
span: sp,
segments: cx
.std_path(&[sym::panic, panic])
.into_iter()
.map(|ident| PathSegment::from_ident(ident))
.collect(),
tokens: None,
},
args: P(MacArgs::Delimited(
DelimSpan::from_single(sp),
MacDelimiter::Parenthesis,
tts,
)),
prior_type_ascription: None,
}),
),
)
}
23 changes: 14 additions & 9 deletions compiler/rustc_lint/src/panic_fmt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,9 @@ declare_lint! {
///
/// ### Explanation
///
/// `panic!("{}")` panics with the message `"{}"`, as a `panic!()` invocation
/// with a single argument does not use `format_args!()`.
/// A future edition of Rust will interpret this string as format string,
/// which would break this.
/// In Rust 2018 and earlier, `panic!("{}")` panics with the message `"{}"`,
/// as a `panic!()` invocation with a single argument does not use `format_args!()`.
/// Rust 2021 interprets this string as format string, which breaks this.
PANIC_FMT,
Warn,
"detect braces in single-argument panic!() invocations",
Expand Down Expand Up @@ -50,8 +49,8 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
if let ast::LitKind::Str(sym, _) = lit.node {
let mut expn = f.span.ctxt().outer_expn_data();
if let Some(id) = expn.macro_def_id {
if cx.tcx.is_diagnostic_item(sym::std_panic_macro, id)
|| cx.tcx.is_diagnostic_item(sym::core_panic_macro, id)
if cx.tcx.is_diagnostic_item(sym::std_panic_2015_macro, id)
|| cx.tcx.is_diagnostic_item(sym::core_panic_2015_macro, id)
{
let fmt = sym.as_str();
if !fmt.contains(&['{', '}'][..]) {
Expand All @@ -75,9 +74,15 @@ fn check_panic<'tcx>(cx: &LateContext<'tcx>, f: &'tcx hir::Expr<'tcx>, arg: &'tc
let n_arguments =
(&mut fmt_parser).filter(|a| matches!(a, Piece::NextArgument(_))).count();

// Unwrap another level of macro expansion if this panic!()
// was expanded from assert!() or debug_assert!().
for &assert in &[sym::assert_macro, sym::debug_assert_macro] {
// Unwrap more levels of macro expansion, as panic_2015!()
// was likely expanded from panic!() and possibly from
// [debug_]assert!().
for &assert in &[
sym::std_panic_macro,
sym::core_panic_macro,
sym::assert_macro,
sym::debug_assert_macro,
] {
let parent = expn.call_site.ctxt().outer_expn_data();
if parent
.macro_def_id
Expand Down
6 changes: 6 additions & 0 deletions compiler/rustc_span/src/symbol.rs
Original file line number Diff line number Diff line change
Expand Up @@ -398,6 +398,8 @@ symbols! {
copysignf64,
core,
core_intrinsics,
core_panic,
core_panic_2015_macro,
core_panic_macro,
cosf32,
cosf64,
Expand Down Expand Up @@ -795,6 +797,8 @@ symbols! {
owned_box,
packed,
panic,
panic_2015,
panic_2021,
panic_abort,
panic_bounds_check,
panic_handler,
Expand Down Expand Up @@ -1096,6 +1100,8 @@ symbols! {
staticlib,
std,
std_inject,
std_panic,
std_panic_2015_macro,
std_panic_macro,
stmt,
stmt_expr_attributes,
Expand Down
18 changes: 17 additions & 1 deletion library/core/src/macros/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#[cfg(bootstrap)]
#[doc(include = "panic.md")]
#[macro_export]
#[allow_internal_unstable(core_panic, const_caller_location)]
#[allow_internal_unstable(core_panic)]
#[stable(feature = "core", since = "1.6.0")]
#[rustc_diagnostic_item = "core_panic_macro"]
macro_rules! panic {
Expand All @@ -18,6 +19,21 @@ macro_rules! panic {
);
}

#[cfg(not(bootstrap))]
#[doc(include = "panic.md")]
#[macro_export]
#[rustc_builtin_macro = "core_panic"]
#[allow_internal_unstable(edition_panic)]
#[stable(feature = "core", since = "1.6.0")]
#[rustc_diagnostic_item = "core_panic_macro"]
macro_rules! panic {
// Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
// depending on the edition of the caller.
($($arg:tt)*) => {
/* compiler built-in */
};
}

/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
///
/// On panic, this macro will print the values of the expressions with their
Expand Down
34 changes: 34 additions & 0 deletions library/core/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,40 @@
use crate::any::Any;
use crate::fmt;

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
#[allow_internal_unstable(core_panic)]
#[rustc_diagnostic_item = "core_panic_2015_macro"]
#[rustc_macro_transparency = "semitransparent"]
pub macro panic_2015 {
() => (
$crate::panicking::panic("explicit panic")
),
($msg:literal $(,)?) => (
$crate::panicking::panic($msg)
),
($msg:expr $(,)?) => (
$crate::panicking::panic_str($msg)
),
($fmt:expr, $($arg:tt)+) => (
$crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+))
),
}

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
#[allow_internal_unstable(core_panic)]
#[rustc_diagnostic_item = "core_panic_2021_macro"]
#[rustc_macro_transparency = "semitransparent"]
pub macro panic_2021 {
() => (
$crate::panicking::panic("explicit panic")
),
($($t:tt)+) => (
$crate::panicking::panic_fmt($crate::format_args!($($t)+))
),
}

/// A struct providing information about a panic.
///
/// `PanicInfo` structure is passed to a panic hook set by the [`set_hook`]
Expand Down
1 change: 1 addition & 0 deletions library/std/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,7 @@
#![feature(dropck_eyepatch)]
#![feature(duration_constants)]
#![feature(duration_zero)]
#![feature(edition_panic)]
#![feature(exact_size_is_empty)]
#![feature(exhaustive_patterns)]
#![feature(extend_one)]
Expand Down
16 changes: 16 additions & 0 deletions library/std/src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
//! library. Each macro is available for use when linking against the standard
//! library.

#[cfg(bootstrap)]
#[doc(include = "../../core/src/macros/panic.md")]
#[macro_export]
#[stable(feature = "rust1", since = "1.0.0")]
Expand All @@ -17,6 +18,21 @@ macro_rules! panic {
});
}

#[cfg(not(bootstrap))]
#[doc(include = "../../core/src/macros/panic.md")]
#[macro_export]
#[rustc_builtin_macro = "std_panic"]
#[stable(feature = "rust1", since = "1.0.0")]
#[allow_internal_unstable(edition_panic)]
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_macro")]
macro_rules! panic {
// Expands to either `$crate::panic::panic_2015` or `$crate::panic::panic_2021`
// depending on the edition of the caller.
($($arg:tt)*) => {
/* compiler built-in */
};
}

/// Prints to the standard output.
///
/// Equivalent to the [`println!`] macro except that a newline is not printed at
Expand Down
21 changes: 21 additions & 0 deletions library/std/src/panic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,27 @@ use crate::sync::{Arc, Mutex, RwLock};
use crate::task::{Context, Poll};
use crate::thread::Result;

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
#[allow_internal_unstable(libstd_sys_internals)]
#[cfg_attr(not(test), rustc_diagnostic_item = "std_panic_2015_macro")]
#[rustc_macro_transparency = "semitransparent"]
pub macro panic_2015 {
() => ({
$crate::rt::begin_panic("explicit panic")
}),
($msg:expr $(,)?) => ({
$crate::rt::begin_panic($msg)
}),
($fmt:expr, $($arg:tt)+) => ({
$crate::rt::begin_panic_fmt(&$crate::format_args!($fmt, $($arg)+))
}),
}

#[doc(hidden)]
#[unstable(feature = "edition_panic", issue = "none", reason = "use panic!() instead")]
pub use core::panic::panic_2021;

#[stable(feature = "panic_hooks", since = "1.10.0")]
pub use crate::panicking::{set_hook, take_hook};

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

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

bb1: {
StorageLive(_2); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
begin_panic::<&str>(const "explicit panic"); // scope 0 at $SRC_DIR/std/src/macros.rs:LL:COL
StorageLive(_2); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
begin_panic::<&str>(const "explicit panic"); // scope 0 at $SRC_DIR/std/src/panic.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/std/src/macros.rs:LL:COL
// + span: $SRC_DIR/std/src/panic.rs:LL:COL
// + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar(<ZST>)) }
// ty::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 })
// mir::Constant
// + span: $SRC_DIR/std/src/macros.rs:LL:COL
// + span: $SRC_DIR/std/src/panic.rs:LL:COL
// + 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 }) }
}

Expand Down
Loading

0 comments on commit e0d9f79

Please sign in to comment.