about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDylan MacKenzie <ecstaticmorse@gmail.com>2019-11-03 12:36:13 -0800
committerDylan MacKenzie <ecstaticmorse@gmail.com>2019-11-06 07:03:56 -0800
commit328a898d23ce7f415e61399b687d7cdd70bfc566 (patch)
tree58b08c98ab35d81f86bcf237a5285cad45a70c8e
parent61a551b4939ec1d5596e585351038b8fbd0124ba (diff)
downloadrust-328a898d23ce7f415e61399b687d7cdd70bfc566.tar.gz
rust-328a898d23ce7f415e61399b687d7cdd70bfc566.zip
Remove `valid_promotion_candidates`
We no longer compare the results of
`promote_consts::validate_candidates` with
`checker.promotion_candidates`, and `promote_consts` becomes the
canonical source for determining promotability.
-rw-r--r--src/librustc_mir/transform/qualify_consts.rs112
1 files changed, 39 insertions, 73 deletions
diff --git a/src/librustc_mir/transform/qualify_consts.rs b/src/librustc_mir/transform/qualify_consts.rs
index 76899dad41a..73471bab016 100644
--- a/src/librustc_mir/transform/qualify_consts.rs
+++ b/src/librustc_mir/transform/qualify_consts.rs
@@ -1064,7 +1064,13 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
             }
             self.promotion_candidates.clone()
         } else {
-            self.valid_promotion_candidates()
+            promote_consts::validate_candidates(
+                self.tcx,
+                self.body,
+                self.def_id,
+                &self.temp_promotion_state,
+                &self.unchecked_promotion_candidates,
+            )
         };
         debug!("qualify_const: promotion_candidates={:?}", promotion_candidates);
         for candidate in promotion_candidates {
@@ -1106,49 +1112,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
         (qualifs.encode_to_bits(), self.tcx.arena.alloc(promoted_temps))
     }
 
-    /// Get the subset of `unchecked_promotion_candidates` that are eligible
-    /// for promotion.
-    // FIXME(eddyb) replace the old candidate gathering with this.
-    fn valid_promotion_candidates(&self) -> Vec<Candidate> {
-        // Sanity-check the promotion candidates.
-        let candidates = promote_consts::validate_candidates(
-            self.tcx,
-            self.body,
-            self.def_id,
-            &self.temp_promotion_state,
-            &self.unchecked_promotion_candidates,
-        );
-
-        if candidates != self.promotion_candidates {
-            let report = |msg, candidate| {
-                let span = match candidate {
-                    Candidate::Ref(loc) |
-                    Candidate::Repeat(loc) => self.body.source_info(loc).span,
-                    Candidate::Argument { bb, .. } => {
-                        self.body[bb].terminator().source_info.span
-                    }
-                };
-                self.tcx.sess.span_err(span, &format!("{}: {:?}", msg, candidate));
-            };
-
-            for &c in &self.promotion_candidates {
-                if !candidates.contains(&c) {
-                    report("invalidated old candidate", c);
-                }
-            }
-
-            for &c in &candidates {
-                if !self.promotion_candidates.contains(&c) {
-                    report("extra new candidate", c);
-                }
-            }
-
-            bug!("promotion candidate validation mismatches (see above)");
-        }
-
-        candidates
-    }
-
     /// Returns `true` if the operand of a repeat expression is promotable.
     fn should_promote_repeat_expression(&self, operand: &Operand<'tcx>) -> bool {
         let not_promotable = IsNotImplicitlyPromotable::in_operand(self, operand) ||
@@ -1768,39 +1731,42 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
 
         debug!("run_pass: mode={:?}", mode);
         if let Mode::NonConstFn | Mode::ConstFn = mode {
-            // This is ugly because Checker holds onto mir,
-            // which can't be mutated until its scope ends.
-            let (temps, candidates) = {
-                let mut checker = Checker::new(tcx, def_id, body, mode);
-                if let Mode::ConstFn = mode {
-                    let use_min_const_fn_checks =
-                        !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you &&
-                        tcx.is_min_const_fn(def_id);
-                    if use_min_const_fn_checks {
-                        // Enforce `min_const_fn` for stable `const fn`s.
-                        use super::qualify_min_const_fn::is_min_const_fn;
-                        if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
-                            error_min_const_fn_violation(tcx, span, err);
-                            return;
-                        }
-
-                        // `check_const` should not produce any errors, but better safe than sorry
-                        // FIXME(#53819)
-                        // NOTE(eddyb) `check_const` is actually needed for promotion inside
-                        // `min_const_fn` functions.
+            let mut checker = Checker::new(tcx, def_id, body, mode);
+            if let Mode::ConstFn = mode {
+                let use_min_const_fn_checks =
+                    !tcx.sess.opts.debugging_opts.unleash_the_miri_inside_of_you &&
+                    tcx.is_min_const_fn(def_id);
+                if use_min_const_fn_checks {
+                    // Enforce `min_const_fn` for stable `const fn`s.
+                    use super::qualify_min_const_fn::is_min_const_fn;
+                    if let Err((span, err)) = is_min_const_fn(tcx, def_id, body) {
+                        error_min_const_fn_violation(tcx, span, err);
+                        return;
                     }
 
-                    // Enforce a constant-like CFG for `const fn`.
-                    checker.check_const();
-                } else {
-                    while let Some((bb, data)) = checker.rpo.next() {
-                        checker.visit_basic_block_data(bb, data);
-                    }
+                    // `check_const` should not produce any errors, but better safe than sorry
+                    // FIXME(#53819)
+                    // NOTE(eddyb) `check_const` is actually needed for promotion inside
+                    // `min_const_fn` functions.
                 }
 
-                let promotion_candidates = checker.valid_promotion_candidates();
-                (checker.temp_promotion_state, promotion_candidates)
-            };
+                // Enforce a constant-like CFG for `const fn`.
+                checker.check_const();
+            } else {
+                while let Some((bb, data)) = checker.rpo.next() {
+                    checker.visit_basic_block_data(bb, data);
+                }
+            }
+
+            // Promote only the promotable candidates.
+            let temps = checker.temp_promotion_state;
+            let candidates = promote_consts::validate_candidates(
+                tcx,
+                body,
+                def_id,
+                &temps,
+                &checker.unchecked_promotion_candidates,
+            );
 
             // Do the actual promotion, now that we know what's viable.
             self.promoted.set(