Skip to content

Commit 865cf0c

Browse files
Rollup merge of rust-lang#80734 - abonander:ab/issue-66693, r=oli-obk
check that first arg to `panic!()` in const is `&str` closes rust-lang#66693 ~~TODO: regression test~~ cc `@RalfJung` for error message wording
2 parents 4f20caa + 5a33f53 commit 865cf0c

File tree

8 files changed

+114
-6
lines changed

8 files changed

+114
-6
lines changed

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

+12
Original file line numberDiff line numberDiff line change
@@ -377,6 +377,18 @@ impl NonConstOp for Panic {
377377
}
378378
}
379379

380+
/// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
381+
#[derive(Debug)]
382+
pub struct PanicNonStr;
383+
impl NonConstOp for PanicNonStr {
384+
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
385+
ccx.tcx.sess.struct_span_err(
386+
span,
387+
"argument to `panic!()` in a const context must have type `&str`",
388+
)
389+
}
390+
}
391+
380392
#[derive(Debug)]
381393
pub struct RawPtrComparison;
382394
impl NonConstOp for RawPtrComparison {

compiler/rustc_mir/src/transform/check_consts/validation.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
819819
self.super_terminator(terminator, location);
820820

821821
match &terminator.kind {
822-
TerminatorKind::Call { func, .. } => {
822+
TerminatorKind::Call { func, args, .. } => {
823823
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
824824
let caller = self.def_id().to_def_id();
825825

@@ -881,9 +881,17 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
881881
}
882882

883883
// At this point, we are calling a function, `callee`, whose `DefId` is known...
884-
885884
if is_lang_panic_fn(tcx, callee) {
886885
self.check_op(ops::Panic);
886+
887+
// const-eval of the `begin_panic` fn assumes the argument is `&str`
888+
if Some(callee) == tcx.lang_items().begin_panic_fn() {
889+
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
890+
ty::Ref(_, ty, _) if ty.is_str() => (),
891+
_ => self.check_op(ops::PanicNonStr),
892+
}
893+
}
894+
887895
return;
888896
}
889897

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// This is a separate test from `issue-66693.rs` because array lengths are evaluated
2+
// in a separate stage before `const`s and `statics` and so the error below is hit and
3+
// the compiler exits before generating errors for the others.
4+
5+
#![feature(const_panic)]
6+
7+
fn main() {
8+
let _ = [0i32; panic!(2f32)];
9+
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`
10+
11+
// ensure that conforming panics are handled correctly
12+
let _ = [false; panic!()];
13+
//~^ ERROR: evaluation of constant value failed
14+
15+
// typechecking halts before getting to this one
16+
let _ = ['a', panic!("panic in array len")];
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
error: argument to `panic!()` in a const context must have type `&str`
2+
--> $DIR/issue-66693-panic-in-array-len.rs:8:20
3+
|
4+
LL | let _ = [0i32; panic!(2f32)];
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error[E0080]: evaluation of constant value failed
10+
--> $DIR/issue-66693-panic-in-array-len.rs:12:21
11+
|
12+
LL | let _ = [false; panic!()];
13+
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:12:21
14+
|
15+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
error: aborting due to 2 previous errors
18+
19+
For more information about this error, try `rustc --explain E0080`.

src/test/ui/consts/issue-66693.rs

+24
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// Tests that the compiler does not ICE when const-evaluating a `panic!()` invocation with a
2+
// non-`&str` argument.
3+
4+
#![feature(const_panic)]
5+
6+
const _: () = panic!(1);
7+
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`
8+
9+
static _FOO: () = panic!(true);
10+
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`
11+
12+
const fn _foo() {
13+
panic!(&1); //~ ERROR: argument to `panic!()` in a const context must have type `&str`
14+
}
15+
16+
// ensure that conforming panics don't cause an error
17+
const _: () = panic!();
18+
static _BAR: () = panic!("panic in static");
19+
20+
const fn _bar() {
21+
panic!("panic in const fn");
22+
}
23+
24+
fn main() {}

src/test/ui/consts/issue-66693.stderr

+26
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
error: argument to `panic!()` in a const context must have type `&str`
2+
--> $DIR/issue-66693.rs:13:5
3+
|
4+
LL | panic!(&1);
5+
| ^^^^^^^^^^^
6+
|
7+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
8+
9+
error: argument to `panic!()` in a const context must have type `&str`
10+
--> $DIR/issue-66693.rs:6:15
11+
|
12+
LL | const _: () = panic!(1);
13+
| ^^^^^^^^^
14+
|
15+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
16+
17+
error: argument to `panic!()` in a const context must have type `&str`
18+
--> $DIR/issue-66693.rs:9:19
19+
|
20+
LL | static _FOO: () = panic!(true);
21+
| ^^^^^^^^^^^^
22+
|
23+
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)
24+
25+
error: aborting due to 3 previous errors
26+

src/test/ui/consts/issue-76064.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1-
struct Bug([u8; panic!(1)]); //~ ERROR panicking in constants is unstable
1+
// Note: non-`&str` panic arguments gained a separate error in PR #80734
2+
// which is why this doesn't match the issue
3+
struct Bug([u8; panic!("panic")]); //~ ERROR panicking in constants is unstable
24

35
fn main() {}

src/test/ui/consts/issue-76064.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
error[E0658]: panicking in constants is unstable
2-
--> $DIR/issue-76064.rs:1:17
2+
--> $DIR/issue-76064.rs:3:17
33
|
4-
LL | struct Bug([u8; panic!(1)]);
5-
| ^^^^^^^^^
4+
LL | struct Bug([u8; panic!("panic")]);
5+
| ^^^^^^^^^^^^^^^
66
|
77
= note: see issue #51999 <https://github.com/rust-lang/rust/issues/51999> for more information
88
= help: add `#![feature(const_panic)]` to the crate attributes to enable

0 commit comments

Comments
 (0)