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
@ -377,6 +377,18 @@ fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, span: Span) -> DiagnosticBuilder<
|
||||
}
|
||||
}
|
||||
|
||||
/// 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 {
|
||||
|
@ -819,7 +819,7 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
|
||||
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();
|
||||
|
||||
@ -881,9 +881,17 @@ fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
|
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() {}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user