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:
@@ -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 {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user