diff options
| author | Guillaume Gomez <guillaume1.gomez@gmail.com> | 2021-09-17 17:41:19 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2021-09-17 17:41:19 +0200 |
| commit | eb62779f2d6dc5cfe9208416e13392744b4e76ac (patch) | |
| tree | 5886a363f22f0a69a8f58f55933c56eb6ed637e3 /compiler/rustc_const_eval/src/transform | |
| parent | 723d27934bcf7b8ded74c8a90298fdaece99ebd2 (diff) | |
| parent | 11c0e58c7489df3f71c3aebe04ad6d1b6a9f6262 (diff) | |
| download | rust-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.rs | 13 | ||||
| -rw-r--r-- | compiler/rustc_const_eval/src/transform/check_consts/mod.rs | 1 |
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() |
