]> git.lizzy.rs Git - rust.git/commitdiff
Allow errors to abort const checking when emitted
authorDylan MacKenzie <ecstaticmorse@gmail.com>
Thu, 17 Sep 2020 18:09:52 +0000 (11:09 -0700)
committerDylan MacKenzie <ecstaticmorse@gmail.com>
Tue, 22 Sep 2020 17:05:58 +0000 (10:05 -0700)
This is a hack for parity with `qualify_min_const_fn`, which only
emitted a single error.

compiler/rustc_mir/src/transform/check_consts/ops.rs
compiler/rustc_mir/src/transform/check_consts/validation.rs

index 66b81b3d111fcd10c84772e1e8f7a5d03f8c1b10..1f0c93eed551e1d54a2fba44cf5bbe505499ba19 100644 (file)
@@ -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
index af9d7cc1aa529dd7522fe0371d22c2a7f49436b1..2c6e12e40bc704e2cfeec92ade2c09e70e1a155f 100644 (file)
@@ -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 @@ fn deref(&self) -> &Self::Target {
 
 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 @@ pub fn qualifs_in_return_place(&mut self) -> ConstQualifs {
 
     /// 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<O: NonConstOp>(&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) {