Skip to content

Commit

Permalink
Rollup merge of #80734 - abonander:ab/issue-66693, r=oli-obk
Browse files Browse the repository at this point in the history
check that first arg to `panic!()` in const is `&str`

closes #66693

~~TODO: regression test~~

cc `@RalfJung` for error message wording
  • Loading branch information
GuillaumeGomez authored Mar 1, 2021
2 parents 4f20caa + 5a33f53 commit 865cf0c
Show file tree
Hide file tree
Showing 8 changed files with 114 additions and 6 deletions.
12 changes: 12 additions & 0 deletions compiler/rustc_mir/src/transform/check_consts/ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -377,6 +377,18 @@ impl NonConstOp for Panic {
}
}

/// A call to a `panic()` lang item where the first argument is _not_ a `&str`.
#[derive(Debug)]
pub struct PanicNonStr;
impl NonConstOp for PanicNonStr {
fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<'tcx> {
ccx.tcx.sess.struct_span_err(
span,
"argument to `panic!()` in a const context must have type `&str`",
)
}
}

#[derive(Debug)]
pub struct RawPtrComparison;
impl NonConstOp for RawPtrComparison {
Expand Down
12 changes: 10 additions & 2 deletions compiler/rustc_mir/src/transform/check_consts/validation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
self.super_terminator(terminator, location);

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

Expand Down Expand Up @@ -881,9 +881,17 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
}

// At this point, we are calling a function, `callee`, whose `DefId` is known...

if is_lang_panic_fn(tcx, callee) {
self.check_op(ops::Panic);

// 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() {
ty::Ref(_, ty, _) if ty.is_str() => (),
_ => self.check_op(ops::PanicNonStr),
}
}

return;
}

Expand Down
17 changes: 17 additions & 0 deletions src/test/ui/consts/issue-66693-panic-in-array-len.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// This is a separate test from `issue-66693.rs` because array lengths are evaluated
// in a separate stage before `const`s and `statics` and so the error below is hit and
// the compiler exits before generating errors for the others.

#![feature(const_panic)]

fn main() {
let _ = [0i32; panic!(2f32)];
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`

// ensure that conforming panics are handled correctly
let _ = [false; panic!()];
//~^ ERROR: evaluation of constant value failed

// typechecking halts before getting to this one
let _ = ['a', panic!("panic in array len")];
}
19 changes: 19 additions & 0 deletions src/test/ui/consts/issue-66693-panic-in-array-len.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
error: argument to `panic!()` in a const context must have type `&str`
--> $DIR/issue-66693-panic-in-array-len.rs:8:20
|
LL | let _ = [0i32; panic!(2f32)];
| ^^^^^^^^^^^^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error[E0080]: evaluation of constant value failed
--> $DIR/issue-66693-panic-in-array-len.rs:12:21
|
LL | let _ = [false; panic!()];
| ^^^^^^^^ the evaluated program panicked at 'explicit panic', $DIR/issue-66693-panic-in-array-len.rs:12:21
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0080`.
24 changes: 24 additions & 0 deletions src/test/ui/consts/issue-66693.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Tests that the compiler does not ICE when const-evaluating a `panic!()` invocation with a
// non-`&str` argument.

#![feature(const_panic)]

const _: () = panic!(1);
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`

static _FOO: () = panic!(true);
//~^ ERROR: argument to `panic!()` in a const context must have type `&str`

const fn _foo() {
panic!(&1); //~ ERROR: argument to `panic!()` in a const context must have type `&str`
}

// ensure that conforming panics don't cause an error
const _: () = panic!();
static _BAR: () = panic!("panic in static");

const fn _bar() {
panic!("panic in const fn");
}

fn main() {}
26 changes: 26 additions & 0 deletions src/test/ui/consts/issue-66693.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
error: argument to `panic!()` in a const context must have type `&str`
--> $DIR/issue-66693.rs:13:5
|
LL | panic!(&1);
| ^^^^^^^^^^^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: argument to `panic!()` in a const context must have type `&str`
--> $DIR/issue-66693.rs:6:15
|
LL | const _: () = panic!(1);
| ^^^^^^^^^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: argument to `panic!()` in a const context must have type `&str`
--> $DIR/issue-66693.rs:9:19
|
LL | static _FOO: () = panic!(true);
| ^^^^^^^^^^^^
|
= note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info)

error: aborting due to 3 previous errors

4 changes: 3 additions & 1 deletion src/test/ui/consts/issue-76064.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
struct Bug([u8; panic!(1)]); //~ ERROR panicking in constants is unstable
// Note: non-`&str` panic arguments gained a separate error in PR #80734
// which is why this doesn't match the issue
struct Bug([u8; panic!("panic")]); //~ ERROR panicking in constants is unstable

fn main() {}
6 changes: 3 additions & 3 deletions src/test/ui/consts/issue-76064.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0658]: panicking in constants is unstable
--> $DIR/issue-76064.rs:1:17
--> $DIR/issue-76064.rs:3:17
|
LL | struct Bug([u8; panic!(1)]);
| ^^^^^^^^^
LL | struct Bug([u8; panic!("panic")]);
| ^^^^^^^^^^^^^^^
|
= note: see issue #51999 <https://github.com/rust-lang/rust/issues/51999> for more information
= help: add `#![feature(const_panic)]` to the crate attributes to enable
Expand Down

0 comments on commit 865cf0c

Please sign in to comment.