Skip to content

Commit b34112c

Browse files
committed
Constify panic!("{}", non_str) and panic!(non_str) under const_panic_extra
1 parent ce8e327 commit b34112c

File tree

6 files changed

+27
-27
lines changed

6 files changed

+27
-27
lines changed

compiler/rustc_const_eval/src/const_eval/machine.rs

+4-11
Original file line numberDiff line numberDiff line change
@@ -48,18 +48,10 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
4848
.unwrap(),
4949
));
5050
}
51-
} else if Some(def_id) == self.tcx.lang_items().panic_display()
52-
|| Some(def_id) == self.tcx.lang_items().begin_panic_fn()
53-
{
54-
// &str or &&str
51+
} else if Some(def_id) == self.tcx.lang_items().begin_panic_fn() {
5552
assert!(args.len() == 1);
56-
57-
let mut msg_place = self.deref_operand(&args[0])?;
58-
while msg_place.layout.ty.is_ref() {
59-
msg_place = self.deref_operand(&msg_place.into())?;
60-
}
61-
62-
let msg = Symbol::intern(self.read_str(&msg_place)?);
53+
let msg = self.eval_const_panic_any(args[0])?;
54+
let msg = Symbol::intern(&msg);
6355
let span = self.find_closest_untracked_caller_location();
6456
let (file, line, col) = self.location_triple_for_span(span);
6557
return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
@@ -71,6 +63,7 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
7163
let (file, line, col) = self.location_triple_for_span(span);
7264
return Err(ConstEvalErrKind::Panic { msg, file, line, col }.into());
7365
}
66+
7467
Ok(None)
7568
}
7669
}

compiler/rustc_const_eval/src/const_eval/panic.rs

+18
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
158158
ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::Arguments, adt.did) => {
159159
return self.fmt_arguments(arg, f);
160160
}
161+
ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did) => {
162+
// NOTE(nbdd0121): const `String` can only be empty.
163+
dispatch_fmt!("", Display);
164+
}
161165

162166
// FIXME(nbdd0121): ty::Adt(..) => (),
163167
_ => {
@@ -241,4 +245,18 @@ impl<'mir, 'tcx> InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> {
241245
self.fmt_arguments(arguments, &mut formatter)?;
242246
Ok(msg)
243247
}
248+
249+
pub(super) fn eval_const_panic_any(&mut self, arg: OpTy<'tcx>) -> InterpResult<'tcx, String> {
250+
match arg.layout.ty.kind() {
251+
ty::Ref(_, ty, _) if ty.is_str() => {
252+
let place = self.deref_operand(&arg)?;
253+
Ok(self.read_str(&place)?.to_string())
254+
}
255+
ty::Adt(adt, _) if self.tcx.is_diagnostic_item(sym::String, adt.did) => {
256+
// NOTE(nbdd0121): const `String` can only be empty.
257+
Ok(String::new())
258+
}
259+
_ => Ok("Box<dyn Any>".to_string()),
260+
}
261+
}
244262
}

compiler/rustc_const_eval/src/transform/check_consts/check.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
893893
if Some(callee) == tcx.lang_items().begin_panic_fn() {
894894
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
895895
ty::Ref(_, ty, _) if ty.is_str() => return,
896-
_ => self.check_op(ops::PanicNonStr),
896+
_ => (),
897897
}
898898
}
899899

@@ -904,7 +904,7 @@ impl Visitor<'tcx> for Checker<'mir, 'tcx> {
904904
{
905905
return;
906906
}
907-
_ => self.check_op(ops::PanicNonStr),
907+
_ => (),
908908
}
909909
}
910910

compiler/rustc_const_eval/src/transform/check_consts/ops.rs

-12
Original file line numberDiff line numberDiff line change
@@ -368,18 +368,6 @@ impl NonConstOp for MutDeref {
368368
}
369369
}
370370

371-
/// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
372-
#[derive(Debug)]
373-
pub struct PanicNonStr;
374-
impl NonConstOp for PanicNonStr {
375-
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
376-
ccx.tcx.sess.struct_span_err(
377-
span,
378-
"argument to `panic!()` in a const context must have type `&str`",
379-
)
380-
}
381-
}
382-
383371
/// Comparing raw pointers for equality.
384372
/// Not currently intended to ever be allowed, even behind a feature gate: operation depends on
385373
/// allocation base addresses that are not known at compile-time.

library/core/src/panicking.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -51,13 +51,13 @@ pub const fn panic(expr: &'static str) -> ! {
5151
#[track_caller]
5252
#[lang = "panic_str"] // needed for `non-fmt-panics` lint
5353
pub const fn panic_str(expr: &str) -> ! {
54-
panic_display(&expr);
54+
panic_fmt(format_args!("{}", expr));
5555
}
5656

5757
#[inline]
5858
#[track_caller]
5959
#[lang = "panic_display"] // needed for const-evaluated panics
60-
#[rustc_do_not_const_check] // hooked by const-eval
60+
#[rustc_const_unstable(feature = "const_panic_extra", issue = "none")]
6161
pub const fn panic_display<T: fmt::Display>(x: &T) -> ! {
6262
panic_fmt(format_args!("{}", *x));
6363
}

library/std/src/panicking.rs

+1
Original file line numberDiff line numberDiff line change
@@ -515,6 +515,7 @@ pub fn begin_panic_handler(info: &PanicInfo<'_>) -> ! {
515515
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
516516
#[cold]
517517
#[track_caller]
518+
#[rustc_const_unstable(feature = "const_panic_extra", issue = "none")]
518519
#[rustc_do_not_const_check] // hooked by const-eval
519520
pub const fn begin_panic<M: Any + Send>(msg: M) -> ! {
520521
if cfg!(feature = "panic_immediate_abort") {

0 commit comments

Comments
 (0)