about summary refs log tree commit diff
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-10-24 22:39:49 +0200
committerGitHub <noreply@github.com>2020-10-24 22:39:49 +0200
commit0a06d7344b5e83c304b926d03452f4c95d2c89dc (patch)
treee7707c041083b92e099eb28e63c01666b7cbb219
parent7428de1583b5ebee2e8b35f79ecdcf3590f0b9ea (diff)
parent713012780fd6d7d236f040e6cdc78aaad9d926e4 (diff)
downloadrust-0a06d7344b5e83c304b926d03452f4c95d2c89dc.tar.gz
rust-0a06d7344b5e83c304b926d03452f4c95d2c89dc.zip
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
-rw-r--r--compiler/rustc_hir/src/lang_items.rs1
-rw-r--r--compiler/rustc_mir/src/const_eval/machine.rs3
-rw-r--r--compiler/rustc_mir/src/transform/check_consts/mod.rs4
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--library/core/src/macros/mod.rs2
-rw-r--r--library/core/src/panicking.rs7
-rw-r--r--src/test/ui/consts/const-eval/const_panic.rs8
-rw-r--r--src/test/ui/consts/const-eval/const_panic.stderr54
8 files changed, 60 insertions, 20 deletions
diff --git a/compiler/rustc_hir/src/lang_items.rs b/compiler/rustc_hir/src/lang_items.rs
index 5e4c03bec83..3e4eb9eafd7 100644
--- a/compiler/rustc_hir/src/lang_items.rs
+++ b/compiler/rustc_hir/src/lang_items.rs
@@ -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;
diff --git a/compiler/rustc_mir/src/const_eval/machine.rs b/compiler/rustc_mir/src/const_eval/machine.rs
index 73ca7e0d471..7e2cae09481 100644
--- a/compiler/rustc_mir/src/const_eval/machine.rs
+++ b/compiler/rustc_mir/src/const_eval/machine.rs
@@ -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])?;
diff --git a/compiler/rustc_mir/src/transform/check_consts/mod.rs b/compiler/rustc_mir/src/transform/check_consts/mod.rs
index 33815ceba62..b93d63b4fdd 100644
--- a/compiler/rustc_mir/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_mir/src/transform/check_consts/mod.rs
@@ -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 {
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 9cf530d57c0..3133090575e 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -777,6 +777,7 @@ symbols! {
         panic_info,
         panic_location,
         panic_runtime,
+        panic_str,
         panic_unwind,
         param_attrs,
         parent_trait,
diff --git a/library/core/src/macros/mod.rs b/library/core/src/macros/mod.rs
index 4c62c16f506..ac45e819cf6 100644
--- a/library/core/src/macros/mod.rs
+++ b/library/core/src/macros/mod.rs
@@ -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)
diff --git a/library/core/src/panicking.rs b/library/core/src/panicking.rs
index 15fd638bef8..09dd19b8f5f 100644
--- a/library/core/src/panicking.rs
+++ b/library/core/src/panicking.rs
@@ -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]
diff --git a/src/test/ui/consts/const-eval/const_panic.rs b/src/test/ui/consts/const-eval/const_panic.rs
index ada9feec897..799c185fb8e 100644
--- a/src/test/ui/consts/const-eval/const_panic.rs
+++ b/src/test/ui/consts/const-eval/const_panic.rs
@@ -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
diff --git a/src/test/ui/consts/const-eval/const_panic.stderr b/src/test/ui/consts/const-eval/const_panic.stderr
index e4ca1f4fa26..c2711952d58 100644
--- a/src/test/ui/consts/const-eval/const_panic.stderr
+++ b/src/test/ui/consts/const-eval/const_panic.stderr
@@ -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: 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 8 previous errors
+error: aborting due to 10 previous errors