Skip to content

Commit 5a33f53

Browse files
committed
check that first arg to panic!() in const is &str
1 parent da305a2 commit 5a33f53

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
@@ -360,6 +360,18 @@ impl NonConstOp for Panic {
360360
}
361361
}
362362

363+
/// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
364+
#[derive(Debug)]
365+
pub struct PanicNonStr;
366+
impl NonConstOp for PanicNonStr {
367+
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
368+
ccx.tcx.sess.struct_span_err(
369+
span,
370+
"argument to `panic!()` in a const context must have type `&str`",
371+
)
372+
}
373+
}
374+
363375
#[derive(Debug)]
364376
pub struct RawPtrComparison;
365377
impl NonConstOp for RawPtrComparison {

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

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

798798
match &terminator.kind {
799-
TerminatorKind::Call { func, .. } => {
799+
TerminatorKind::Call { func, args, .. } => {
800800
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
801801
let caller = self.def_id().to_def_id();
802802

@@ -857,9 +857,17 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
857857
}
858858

859859
// At this point, we are calling a function, `callee`, whose `DefId` is known...
860-
861860
if is_lang_panic_fn(tcx, callee) {
862861
self.check_op(ops::Panic);
862+
863+
// const-eval of the `begin_panic` fn assumes the argument is `&str`
864+
if Some(callee) == tcx.lang_items().begin_panic_fn() {
865+
match args[0].ty(&self.ccx.body.local_decls, tcx).kind() {
866+
ty::Ref(_, ty, _) if ty.is_str() => (),
867+
_ => self.check_op(ops::PanicNonStr),
868+
}
869+
}
870+
863871
return;
864872
}
865873

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)