From bfc10a89c3a1cf2398b4cd8de342577ea96fe98a Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 17 Sep 2020 11:09:52 -0700 Subject: [PATCH] Allow errors to abort const checking when emitted This is a hack for parity with `qualify_min_const_fn`, which only emitted a single error. --- .../src/transform/check_consts/ops.rs | 2 ++ .../src/transform/check_consts/validation.rs | 24 +++++++++++++++---- 2 files changed, 22 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir/src/transform/check_consts/ops.rs b/compiler/rustc_mir/src/transform/check_consts/ops.rs index 66b81b3d111fc..1f0c93eed551e 100644 --- a/compiler/rustc_mir/src/transform/check_consts/ops.rs +++ b/compiler/rustc_mir/src/transform/check_consts/ops.rs @@ -62,6 +62,8 @@ pub enum Status { /// An operation that is not *always* allowed in a const context. pub trait NonConstOp: std::fmt::Debug { + const STOPS_CONST_CHECKING: bool = false; + /// Returns an enum indicating whether this operation is allowed within the given item. fn status_in_item(&self, _ccx: &ConstCx<'_, '_>) -> Status { Status::Forbidden diff --git a/compiler/rustc_mir/src/transform/check_consts/validation.rs b/compiler/rustc_mir/src/transform/check_consts/validation.rs index af9d7cc1aa529..2c6e12e40bc70 100644 --- a/compiler/rustc_mir/src/transform/check_consts/validation.rs +++ b/compiler/rustc_mir/src/transform/check_consts/validation.rs @@ -176,6 +176,8 @@ pub struct Validator<'mir, 'tcx> { /// The span of the current statement. span: Span, + + const_checking_stopped: bool, } impl Deref for Validator<'mir, 'tcx> { @@ -188,7 +190,12 @@ impl Deref for Validator<'mir, 'tcx> { impl Validator<'mir, 'tcx> { pub fn new(ccx: &'mir ConstCx<'mir, 'tcx>) -> Self { - Validator { span: ccx.body.span, ccx, qualifs: Default::default() } + Validator { + span: ccx.body.span, + ccx, + qualifs: Default::default(), + const_checking_stopped: false, + } } pub fn check_body(&mut self) { @@ -226,13 +233,22 @@ impl Validator<'mir, 'tcx> { /// Emits an error if an expression cannot be evaluated in the current context. pub fn check_op(&mut self, op: impl NonConstOp) { - ops::non_const(self.ccx, op, self.span); + self.check_op_spanned(op, self.span); } /// Emits an error at the given `span` if an expression cannot be evaluated in the current /// context. - pub fn check_op_spanned(&mut self, op: impl NonConstOp, span: Span) { - ops::non_const(self.ccx, op, span); + pub fn check_op_spanned(&mut self, op: O, span: Span) { + // HACK: This is for strict equivalence with the old `qualify_min_const_fn` pass, which + // only emitted one error per function. It should be removed and the test output updated. + if self.const_checking_stopped { + return; + } + + let err_emitted = ops::non_const(self.ccx, op, span); + if err_emitted && O::STOPS_CONST_CHECKING { + self.const_checking_stopped = true; + } } fn check_static(&mut self, def_id: DefId, span: Span) {