about summary refs log tree commit diff
path: root/compiler/rustc_const_eval/src/transform
diff options
context:
space:
mode:
authorGuillaume Gomez <guillaume1.gomez@gmail.com>2021-09-17 17:41:19 +0200
committerGitHub <noreply@github.com>2021-09-17 17:41:19 +0200
commiteb62779f2d6dc5cfe9208416e13392744b4e76ac (patch)
tree5886a363f22f0a69a8f58f55933c56eb6ed637e3 /compiler/rustc_const_eval/src/transform
parent723d27934bcf7b8ded74c8a90298fdaece99ebd2 (diff)
parent11c0e58c7489df3f71c3aebe04ad6d1b6a9f6262 (diff)
downloadrust-eb62779f2d6dc5cfe9208416e13392744b4e76ac.tar.gz
rust-eb62779f2d6dc5cfe9208416e13392744b4e76ac.zip
Rollup merge of #88954 - nbdd0121:panic3, r=oli-obk
Allow `panic!("{}", computed_str)` in const fn.

Special-case `panic!("{}", arg)` and translate it to `panic_display(&arg)`. `panic_display` will behave like `panic_any` in cosnt eval and behave like `panic!(format_args!("{}", arg))` in runtime.

This should bring Rust 2015 and 2021 to feature parity in terms of `const_panic`; and hopefully would unblock the stabilisation of #51999.

`@rustbot` modify labels: +T-compiler +T-libs +A-const-eval +A-const-fn

r? `@oli-obk`
Diffstat (limited to 'compiler/rustc_const_eval/src/transform')
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs13
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/mod.rs1
2 files changed, 14 insertions, 0 deletions
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index d5682f702ba..0e5a896a8f1 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -888,6 +888,10 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
                 if is_lang_panic_fn(tcx, callee) {
                     self.check_op(ops::Panic);
 
+                    // `begin_panic` and `panic_display` are generic functions that accept
+                    // types other than str. Check to enforce that only str can be used in
+                    // const-eval.
+
                     // const-eval of the `begin_panic` fn assumes the argument is `&str`
                     if Some(callee) == tcx.lang_items().begin_panic_fn() {
                         match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
@@ -896,6 +900,15 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
                         }
                     }
 
+                    // const-eval of the `panic_display` fn assumes the argument is `&&str`
+                    if Some(callee) == tcx.lang_items().panic_display() {
+                        match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
+                            ty::Ref(_, ty, _) if matches!(ty.kind(), ty::Ref(_, ty, _) if ty.is_str()) =>
+                                {}
+                            _ => self.check_op(ops::PanicNonStr),
+                        }
+                    }
+
                     return;
                 }
 
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
index a5cb0f4e14b..d1fd3ceaa58 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/mod.rs
@@ -79,6 +79,7 @@ pub fn is_lang_panic_fn(tcx: TyCtxt<'tcx>, def_id: DefId) -> bool {
     // Keep in sync with what that function handles!
     Some(def_id) == tcx.lang_items().panic_fn()
         || Some(def_id) == tcx.lang_items().panic_str()
+        || Some(def_id) == tcx.lang_items().panic_display()
         || Some(def_id) == tcx.lang_items().begin_panic_fn()
         || Some(def_id) == tcx.lang_items().panic_fmt()
         || Some(def_id) == tcx.lang_items().begin_panic_fmt()