Rollup merge of #78069 - fusion-engineering-forks:core-const-panic-str, r=RalfJung

Fix const core::panic!(non_literal_str).

Invocations of `core::panic!(x)` where `x` is not a string literal expand to `panic!("{}", x)`, which is not understood by the const panic logic right now. This adds `panic_str` as a lang item, and modifies the const eval implementation to hook into this item as well.

This fixes the issue mentioned here: https://github.com/rust-lang/rust/issues/51999#issuecomment-687604248

r? `@RalfJung`

`@rustbot` modify labels: +A-const-eval
This commit is contained in:
Jonas Schievink 2020-10-24 22:39:49 +02:00 committed by GitHub
commit 0a06d7344b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 60 additions and 20 deletions

View File

@ -263,6 +263,7 @@ language_item_table! {
// is required to define it somewhere. Additionally, there are restrictions on crates that use
// a weak lang item, but do not have it defined.
Panic, sym::panic, panic_fn, Target::Fn;
PanicStr, sym::panic_str, panic_str, Target::Fn;
PanicBoundsCheck, sym::panic_bounds_check, panic_bounds_check_fn, Target::Fn;
PanicInfo, sym::panic_info, panic_info, Target::Struct;
PanicLocation, sym::panic_location, panic_location, Target::Struct;

View File

@ -70,9 +70,10 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
) -> InterpResult<'tcx> {
let def_id = instance.def_id();
if Some(def_id) == self.tcx.lang_items().panic_fn()
|| Some(def_id) == self.tcx.lang_items().panic_str()
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
{
// &'static str
// &str
assert!(args.len() == 1);
let msg_place = self.deref_operand(args[0])?;

View File

@ -74,7 +74,9 @@ impl ConstCx<'mir, 'tcx> {
/// Returns `true` if this `DefId` points to one of the official `panic` lang items.
pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
Some(def_id) == tcx.lang_items().panic_fn() || Some(def_id) == tcx.lang_items().begin_panic_fn()
Some(def_id) == tcx.lang_items().panic_fn()
|| Some(def_id) == tcx.lang_items().panic_str()
|| Some(def_id) == tcx.lang_items().begin_panic_fn()
}
pub fn allow_internal_unstable(tcx: TyCtxt<'tcx>, def_id: DefId, feature_gate: Symbol) -> bool {

View File

@ -777,6 +777,7 @@ symbols! {
panic_info,
panic_location,
panic_runtime,
panic_str,
panic_unwind,
param_attrs,
parent_trait,

View File

@ -10,7 +10,7 @@ macro_rules! panic {
$crate::panicking::panic($msg)
);
($msg:expr) => (
$crate::panic!("{}", $crate::convert::identity::<&str>($msg))
$crate::panicking::panic_str($msg)
);
($msg:expr,) => (
$crate::panic!($msg)

View File

@ -50,6 +50,13 @@ pub fn panic(expr: &'static str) -> ! {
panic_fmt(fmt::Arguments::new_v1(&[expr], &[]));
}
#[inline]
#[track_caller]
#[cfg_attr(not(bootstrap), lang = "panic_str")] // needed for const-evaluated panics
pub fn panic_str(expr: &str) -> ! {
panic_fmt(format_args!("{}", expr));
}
#[cold]
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
#[track_caller]

View File

@ -1,6 +1,8 @@
#![feature(const_panic)]
#![crate_type = "lib"]
const MSG: &str = "hello";
const Z: () = std::panic!("cheese");
//~^ ERROR any use of this value will cause an error
@ -12,6 +14,9 @@ const Y: () = std::unreachable!();
const X: () = std::unimplemented!();
//~^ ERROR any use of this value will cause an error
//
const W: () = std::panic!(MSG);
//~^ ERROR any use of this value will cause an error
const Z_CORE: () = core::panic!("cheese");
//~^ ERROR any use of this value will cause an error
@ -24,3 +29,6 @@ const Y_CORE: () = core::unreachable!();
const X_CORE: () = core::unimplemented!();
//~^ ERROR any use of this value will cause an error
const W_CORE: () = core::panic!(MSG);
//~^ ERROR any use of this value will cause an error

View File

@ -1,83 +1,103 @@
error: any use of this value will cause an error
--> $DIR/const_panic.rs:4:15
--> $DIR/const_panic.rs:6:15
|
LL | const Z: () = std::panic!("cheese");
| --------------^^^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:4:15
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:6:15
|
= note: `#[deny(const_err)]` on by default
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:7:16
--> $DIR/const_panic.rs:9:16
|
LL | const Z2: () = std::panic!();
| ---------------^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:7:16
| the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:9:16
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:10:15
--> $DIR/const_panic.rs:12:15
|
LL | const Y: () = std::unreachable!();
| --------------^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:10:15
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:12:15
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:13:15
--> $DIR/const_panic.rs:15:15
|
LL | const X: () = std::unimplemented!();
| --------------^^^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:13:15
| the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:15:15
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:16:20
--> $DIR/const_panic.rs:18:15
|
LL | const W: () = std::panic!(MSG);
| --------------^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'hello', $DIR/const_panic.rs:18:15
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:21:20
|
LL | const Z_CORE: () = core::panic!("cheese");
| -------------------^^^^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:16:20
| the evaluated program panicked at 'cheese', $DIR/const_panic.rs:21:20
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:19:21
--> $DIR/const_panic.rs:24:21
|
LL | const Z2_CORE: () = core::panic!();
| --------------------^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:19:21
| the evaluated program panicked at 'explicit panic', $DIR/const_panic.rs:24:21
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:22:20
--> $DIR/const_panic.rs:27:20
|
LL | const Y_CORE: () = core::unreachable!();
| -------------------^^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:22:20
| the evaluated program panicked at 'internal error: entered unreachable code', $DIR/const_panic.rs:27:20
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: any use of this value will cause an error
--> $DIR/const_panic.rs:25:20
--> $DIR/const_panic.rs:30:20
|
LL | const X_CORE: () = core::unimplemented!();
| -------------------^^^^^^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:25:20
| the evaluated program panicked at 'not implemented', $DIR/const_panic.rs:30:20
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 8 previous errors
error: any use of this value will cause an error
--> $DIR/const_panic.rs:33:20
|
LL | const W_CORE: () = core::panic!(MSG);
| -------------------^^^^^^^^^^^^^^^^^-
| |
| the evaluated program panicked at 'hello', $DIR/const_panic.rs:33:20
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
error: aborting due to 10 previous errors