diff options
| author | Austin Bonander <austin@launchbadge.com> | 2021-01-05 13:54:28 -0800 |
|---|---|---|
| committer | Austin Bonander <austin@launchbadge.com> | 2021-03-01 08:32:15 -0800 |
| commit | 5a33f531cd87988e95a8e811d71b653a7ff9ffca (patch) | |
| tree | bce9a1aa9f8927c8ef4b716018277c8300191842 /compiler/rustc_mir/src/transform | |
| parent | da305a2b00530aa34dea4e48389204c26fa35dbb (diff) | |
| download | rust-5a33f531cd87988e95a8e811d71b653a7ff9ffca.tar.gz rust-5a33f531cd87988e95a8e811d71b653a7ff9ffca.zip | |
check that first arg to `panic!()` in const is `&str`
Diffstat (limited to 'compiler/rustc_mir/src/transform')
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/ops.rs | 12 | ||||
| -rw-r--r-- | compiler/rustc_mir/src/transform/check_consts/validation.rs | 12 |
2 files changed, 22 insertions, 2 deletions
diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 9e90a7519cf..134b6d6fe07 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -360,6 +360,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 { diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index d1c07d1051d..fea5dd3554f 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -796,7 +796,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(); @@ -857,9 +857,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; } |
