Panicking infra uses &core::panic::Location.
This allows us to remove `static_panic_msg` from the SSA<->LLVM boundary, along with its fat pointer representation for &str. Also changes the signature of PanicInfo::internal_contructor to avoid copying. Closes #65856.
This commit is contained in:
parent
743964ad3f
commit
aec97e050e
10 changed files with 130 additions and 127 deletions
|
|
@ -1,8 +1,9 @@
|
|||
/// Panics the current thread.
|
||||
///
|
||||
/// For details, see `std::macros`.
|
||||
#[cfg(bootstrap)]
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable(core_panic)]
|
||||
#[allow_internal_unstable(core_panic, panic_internals)]
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
macro_rules! panic {
|
||||
() => (
|
||||
|
|
@ -20,6 +21,38 @@ macro_rules! panic {
|
|||
});
|
||||
}
|
||||
|
||||
/// Panics the current thread.
|
||||
///
|
||||
/// For details, see `std::macros`.
|
||||
#[cfg(not(bootstrap))]
|
||||
#[macro_export]
|
||||
#[allow_internal_unstable(core_panic, panic_internals)]
|
||||
#[stable(feature = "core", since = "1.6.0")]
|
||||
macro_rules! panic {
|
||||
() => (
|
||||
$crate::panic!("explicit panic")
|
||||
);
|
||||
($msg:expr) => ({
|
||||
const LOC: &$crate::panic::Location<'_> = &$crate::panic::Location::internal_constructor(
|
||||
$crate::file!(),
|
||||
$crate::line!(),
|
||||
$crate::column!(),
|
||||
);
|
||||
$crate::panicking::panic($msg, LOC)
|
||||
});
|
||||
($msg:expr,) => (
|
||||
$crate::panic!($msg)
|
||||
);
|
||||
($fmt:expr, $($arg:tt)+) => ({
|
||||
const LOC: &$crate::panic::Location<'_> = &$crate::panic::Location::internal_constructor(
|
||||
$crate::file!(),
|
||||
$crate::line!(),
|
||||
$crate::column!(),
|
||||
);
|
||||
$crate::panicking::panic_fmt($crate::format_args!($fmt, $($arg)+), LOC)
|
||||
});
|
||||
}
|
||||
|
||||
/// Asserts that two expressions are equal to each other (using [`PartialEq`]).
|
||||
///
|
||||
/// On panic, this macro will print the values of the expressions with their
|
||||
|
|
|
|||
|
|
@ -35,7 +35,7 @@ use crate::fmt;
|
|||
pub struct PanicInfo<'a> {
|
||||
payload: &'a (dyn Any + Send),
|
||||
message: Option<&'a fmt::Arguments<'a>>,
|
||||
location: Location<'a>,
|
||||
location: &'a Location<'a>,
|
||||
}
|
||||
|
||||
impl<'a> PanicInfo<'a> {
|
||||
|
|
@ -45,11 +45,16 @@ impl<'a> PanicInfo<'a> {
|
|||
issue = "0")]
|
||||
#[doc(hidden)]
|
||||
#[inline]
|
||||
pub fn internal_constructor(message: Option<&'a fmt::Arguments<'a>>,
|
||||
location: Location<'a>)
|
||||
-> Self {
|
||||
pub fn internal_constructor(
|
||||
message: Option<&'a fmt::Arguments<'a>>,
|
||||
location: &'a Location<'a>,
|
||||
) -> Self {
|
||||
struct NoPayload;
|
||||
PanicInfo { payload: &NoPayload, location, message }
|
||||
PanicInfo {
|
||||
location,
|
||||
message,
|
||||
payload: &NoPayload,
|
||||
}
|
||||
}
|
||||
|
||||
#[doc(hidden)]
|
||||
|
|
@ -177,7 +182,7 @@ impl<'a> Location<'a> {
|
|||
and related macros",
|
||||
issue = "0")]
|
||||
#[doc(hidden)]
|
||||
pub fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
|
||||
pub const fn internal_constructor(file: &'a str, line: u32, col: u32) -> Self {
|
||||
Location { file, line, col }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@
|
|||
use crate::fmt;
|
||||
use crate::panic::{Location, PanicInfo};
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[cold]
|
||||
// never inline unless panic_immediate_abort to avoid code
|
||||
// bloat at the call sites as much as possible
|
||||
|
|
@ -49,6 +50,27 @@ pub fn panic(expr_file_line_col: &(&'static str, &'static str, u32, u32)) -> ! {
|
|||
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), &(file, line, col))
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[cold]
|
||||
// never inline unless panic_immediate_abort to avoid code
|
||||
// bloat at the call sites as much as possible
|
||||
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
|
||||
#[lang = "panic"]
|
||||
pub fn panic(expr: &str, location: &Location<'_>) -> ! {
|
||||
if cfg!(feature = "panic_immediate_abort") {
|
||||
unsafe { super::intrinsics::abort() }
|
||||
}
|
||||
|
||||
// Use Arguments::new_v1 instead of format_args!("{}", expr) to potentially
|
||||
// reduce size overhead. The format_args! macro uses str's Display trait to
|
||||
// write expr, which calls Formatter::pad, which must accommodate string
|
||||
// truncation and padding (even though none is used here). Using
|
||||
// Arguments::new_v1 may allow the compiler to omit Formatter::pad from the
|
||||
// output binary, saving up to a few kilobytes.
|
||||
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]), location)
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[cold]
|
||||
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
|
||||
#[lang = "panic_bounds_check"]
|
||||
|
|
@ -62,6 +84,22 @@ fn panic_bounds_check(file_line_col: &(&'static str, u32, u32),
|
|||
len, index), file_line_col)
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[cold]
|
||||
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
|
||||
#[lang = "panic_bounds_check"]
|
||||
fn panic_bounds_check(location: &Location<'_>, index: usize, len: usize) -> ! {
|
||||
if cfg!(feature = "panic_immediate_abort") {
|
||||
unsafe { super::intrinsics::abort() }
|
||||
}
|
||||
|
||||
panic_fmt(
|
||||
format_args!("index out of bounds: the len is {} but the index is {}", len, index),
|
||||
location
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(bootstrap)]
|
||||
#[cold]
|
||||
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
|
||||
#[cfg_attr( feature="panic_immediate_abort" ,inline)]
|
||||
|
|
@ -77,9 +115,26 @@ pub fn panic_fmt(fmt: fmt::Arguments<'_>, file_line_col: &(&'static str, u32, u3
|
|||
}
|
||||
|
||||
let (file, line, col) = *file_line_col;
|
||||
let pi = PanicInfo::internal_constructor(
|
||||
Some(&fmt),
|
||||
Location::internal_constructor(file, line, col),
|
||||
);
|
||||
let location = Location::internal_constructor(file, line, col);
|
||||
let pi = PanicInfo::internal_constructor(Some(&fmt), &location);
|
||||
unsafe { panic_impl(&pi) }
|
||||
}
|
||||
|
||||
#[cfg(not(bootstrap))]
|
||||
#[cold]
|
||||
#[cfg_attr(not(feature="panic_immediate_abort"),inline(never))]
|
||||
#[cfg_attr( feature="panic_immediate_abort" ,inline)]
|
||||
pub fn panic_fmt(fmt: fmt::Arguments<'_>, location: &Location<'_>) -> ! {
|
||||
if cfg!(feature = "panic_immediate_abort") {
|
||||
unsafe { super::intrinsics::abort() }
|
||||
}
|
||||
|
||||
// NOTE This function never crosses the FFI boundary; it's a Rust-to-Rust call
|
||||
extern "Rust" {
|
||||
#[lang = "panic_impl"]
|
||||
fn panic_impl(pi: &PanicInfo<'_>) -> !;
|
||||
}
|
||||
|
||||
let pi = PanicInfo::internal_constructor(Some(&fmt), location);
|
||||
unsafe { panic_impl(&pi) }
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue