@@ -1064,7 +1064,13 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
10641064 }
10651065 self . promotion_candidates . clone ( )
10661066 } else {
1067- self . valid_promotion_candidates ( )
1067+ promote_consts:: validate_candidates (
1068+ self . tcx ,
1069+ self . body ,
1070+ self . def_id ,
1071+ & self . temp_promotion_state ,
1072+ & self . unchecked_promotion_candidates ,
1073+ )
10681074 } ;
10691075 debug ! ( "qualify_const: promotion_candidates={:?}" , promotion_candidates) ;
10701076 for candidate in promotion_candidates {
@@ -1106,49 +1112,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
11061112 ( qualifs. encode_to_bits ( ) , self . tcx . arena . alloc ( promoted_temps) )
11071113 }
11081114
1109- /// Get the subset of `unchecked_promotion_candidates` that are eligible
1110- /// for promotion.
1111- // FIXME(eddyb) replace the old candidate gathering with this.
1112- fn valid_promotion_candidates ( & self ) -> Vec < Candidate > {
1113- // Sanity-check the promotion candidates.
1114- let candidates = promote_consts:: validate_candidates (
1115- self . tcx ,
1116- self . body ,
1117- self . def_id ,
1118- & self . temp_promotion_state ,
1119- & self . unchecked_promotion_candidates ,
1120- ) ;
1121-
1122- if candidates != self . promotion_candidates {
1123- let report = |msg, candidate| {
1124- let span = match candidate {
1125- Candidate :: Ref ( loc) |
1126- Candidate :: Repeat ( loc) => self . body . source_info ( loc) . span ,
1127- Candidate :: Argument { bb, .. } => {
1128- self . body [ bb] . terminator ( ) . source_info . span
1129- }
1130- } ;
1131- self . tcx . sess . span_err ( span, & format ! ( "{}: {:?}" , msg, candidate) ) ;
1132- } ;
1133-
1134- for & c in & self . promotion_candidates {
1135- if !candidates. contains ( & c) {
1136- report ( "invalidated old candidate" , c) ;
1137- }
1138- }
1139-
1140- for & c in & candidates {
1141- if !self . promotion_candidates . contains ( & c) {
1142- report ( "extra new candidate" , c) ;
1143- }
1144- }
1145-
1146- bug ! ( "promotion candidate validation mismatches (see above)" ) ;
1147- }
1148-
1149- candidates
1150- }
1151-
11521115 /// Returns `true` if the operand of a repeat expression is promotable.
11531116 fn should_promote_repeat_expression ( & self , operand : & Operand < ' tcx > ) -> bool {
11541117 let not_promotable = IsNotImplicitlyPromotable :: in_operand ( self , operand) ||
@@ -1768,39 +1731,42 @@ impl<'tcx> MirPass<'tcx> for QualifyAndPromoteConstants<'tcx> {
17681731
17691732 debug ! ( "run_pass: mode={:?}" , mode) ;
17701733 if let Mode :: NonConstFn | Mode :: ConstFn = mode {
1771- // This is ugly because Checker holds onto mir,
1772- // which can't be mutated until its scope ends.
1773- let ( temps, candidates) = {
1774- let mut checker = Checker :: new ( tcx, def_id, body, mode) ;
1775- if let Mode :: ConstFn = mode {
1776- let use_min_const_fn_checks =
1777- !tcx. sess . opts . debugging_opts . unleash_the_miri_inside_of_you &&
1778- tcx. is_min_const_fn ( def_id) ;
1779- if use_min_const_fn_checks {
1780- // Enforce `min_const_fn` for stable `const fn`s.
1781- use super :: qualify_min_const_fn:: is_min_const_fn;
1782- if let Err ( ( span, err) ) = is_min_const_fn ( tcx, def_id, body) {
1783- error_min_const_fn_violation ( tcx, span, err) ;
1784- return ;
1785- }
1786-
1787- // `check_const` should not produce any errors, but better safe than sorry
1788- // FIXME(#53819)
1789- // NOTE(eddyb) `check_const` is actually needed for promotion inside
1790- // `min_const_fn` functions.
1734+ let mut checker = Checker :: new ( tcx, def_id, body, mode) ;
1735+ if let Mode :: ConstFn = mode {
1736+ let use_min_const_fn_checks =
1737+ !tcx. sess . opts . debugging_opts . unleash_the_miri_inside_of_you &&
1738+ tcx. is_min_const_fn ( def_id) ;
1739+ if use_min_const_fn_checks {
1740+ // Enforce `min_const_fn` for stable `const fn`s.
1741+ use super :: qualify_min_const_fn:: is_min_const_fn;
1742+ if let Err ( ( span, err) ) = is_min_const_fn ( tcx, def_id, body) {
1743+ error_min_const_fn_violation ( tcx, span, err) ;
1744+ return ;
17911745 }
17921746
1793- // Enforce a constant-like CFG for `const fn`.
1794- checker. check_const ( ) ;
1795- } else {
1796- while let Some ( ( bb, data) ) = checker. rpo . next ( ) {
1797- checker. visit_basic_block_data ( bb, data) ;
1798- }
1747+ // `check_const` should not produce any errors, but better safe than sorry
1748+ // FIXME(#53819)
1749+ // NOTE(eddyb) `check_const` is actually needed for promotion inside
1750+ // `min_const_fn` functions.
17991751 }
18001752
1801- let promotion_candidates = checker. valid_promotion_candidates ( ) ;
1802- ( checker. temp_promotion_state , promotion_candidates)
1803- } ;
1753+ // Enforce a constant-like CFG for `const fn`.
1754+ checker. check_const ( ) ;
1755+ } else {
1756+ while let Some ( ( bb, data) ) = checker. rpo . next ( ) {
1757+ checker. visit_basic_block_data ( bb, data) ;
1758+ }
1759+ }
1760+
1761+ // Promote only the promotable candidates.
1762+ let temps = checker. temp_promotion_state ;
1763+ let candidates = promote_consts:: validate_candidates (
1764+ tcx,
1765+ body,
1766+ def_id,
1767+ & temps,
1768+ & checker. unchecked_promotion_candidates ,
1769+ ) ;
18041770
18051771 // Do the actual promotion, now that we know what's viable.
18061772 self . promoted . set (
0 commit comments