Rollup merge of #80734 - abonander:ab/issue-66693, r=oli-obk
check that first arg to `panic!()` in const is `&str` closes #66693 ~~TODO: regression test~~ cc `@RalfJung` for error message wording
This commit is contained in:
commit
865cf0c3b6
8 changed files with 114 additions and 6 deletions
|
@ -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)]
|
#[derive(Debug)]
|
||||||
pub struct RawPtrComparison;
|
pub struct RawPtrComparison;
|
||||||
impl NonConstOp for RawPtrComparison {
|
impl NonConstOp for RawPtrComparison {
|
||||||
|
|
|
@ -819,7 +819,7 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||||
self.super_terminator(terminator, location);
|
self.super_terminator(terminator, location);
|
||||||
|
|
||||||
match &terminator.kind {
|
match &terminator.kind {
|
||||||
TerminatorKind::Call { func, .. } => {
|
TerminatorKind::Call { func, args, .. } => {
|
||||||
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
|
let ConstCx { tcx, body, param_env, .. } = *self.ccx;
|
||||||
let caller = self.def_id().to_def_id();
|
let caller = self.def_id().to_def_id();
|
||||||
|
|
||||||
|
@ -881,9 +881,17 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
// At this point, we are calling a function, `callee`, whose `DefId` is known...
|
// At this point, we are calling a function, `callee`, whose `DefId` is known...
|
||||||
|
|
||||||
if is_lang_panic_fn(tcx, callee) {
|
if is_lang_panic_fn(tcx, callee) {
|
||||||
self.check_op(ops::Panic);
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
src/test/ui/consts/issue-66693-panic-in-array-len.rs
Normal file
17
src/test/ui/consts/issue-66693-panic-in-array-len.rs
Normal file
|
@ -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
src/test/ui/consts/issue-66693-panic-in-array-len.stderr
Normal file
19
src/test/ui/consts/issue-66693-panic-in-array-len.stderr
Normal file
|
@ -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
src/test/ui/consts/issue-66693.rs
Normal file
24
src/test/ui/consts/issue-66693.rs
Normal file
|
@ -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
src/test/ui/consts/issue-66693.stderr
Normal file
26
src/test/ui/consts/issue-66693.stderr
Normal file
|
@ -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
|
||||||
|
|
|
@ -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() {}
|
fn main() {}
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
error[E0658]: panicking in constants is unstable
|
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
|
= 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
|
= help: add `#![feature(const_panic)]` to the crate attributes to enable
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue