@@ -135,6 +135,12 @@ enum ValueSource<'a, 'tcx> {
135135 } ,
136136}
137137
138+ /// A "qualif" is a way to lookg for something "bad" in the MIR that would prevent
139+ /// proper const evaluation. So `return true` means "I found something bad, no reason
140+ /// to go on searching". `false` is only returned if we definitely cannot find anything
141+ /// bad anywhere.
142+ ///
143+ /// The default implementations proceed structurally.
138144trait Qualif {
139145 const IDX : usize ;
140146
@@ -285,7 +291,9 @@ trait Qualif {
285291 }
286292}
287293
288- // Constant containing interior mutability (UnsafeCell).
294+ /// Constant containing interior mutability (UnsafeCell).
295+ /// This must be ruled out to make sure that evaluating the constant at compile-time
296+ /// and run-time would produce the same result.
289297struct HasMutInterior ;
290298
291299impl Qualif for HasMutInterior {
@@ -343,7 +351,9 @@ impl Qualif for HasMutInterior {
343351 }
344352}
345353
346- // Constant containing an ADT that implements Drop.
354+ /// Constant containing an ADT that implements Drop.
355+ /// This must be ruled out because we cannot run `Drop` during compile-time
356+ /// as that might not be a `const fn`.
347357struct NeedsDrop ;
348358
349359impl Qualif for NeedsDrop {
@@ -366,8 +376,11 @@ impl Qualif for NeedsDrop {
366376 }
367377}
368378
369- // Not promotable at all - non-`const fn` calls, asm!,
370- // pointer comparisons, ptr-to-int casts, etc.
379+ /// Not promotable at all - non-`const fn` calls, asm!,
380+ /// pointer comparisons, ptr-to-int casts, etc.
381+ /// Inside a const context all constness rules apply, so promotion simply has to follow the regular
382+ /// constant rules (modulo interior mutability or `Drop` rules which are handled `HasMutInterior`
383+ /// and `NeedsDrop` respectively).
371384struct IsNotPromotable ;
372385
373386impl Qualif for IsNotPromotable {
@@ -511,12 +524,9 @@ impl Qualif for IsNotPromotable {
511524
512525/// Refers to temporaries which cannot be promoted *implicitly*.
513526/// Explicit promotion happens e.g. for constant arguments declared via `rustc_args_required_const`.
514- /// Inside a const context all constness rules
515- /// apply, so implicit promotion simply has to follow the regular constant rules (modulo interior
516- /// mutability or `Drop` rules which are handled `HasMutInterior` and `NeedsDrop` respectively).
517- /// Implicit promotion inside regular functions does not happen if `const fn` calls are involved,
518- /// as the call may be perfectly alright at runtime, but fail at compile time e.g. due to addresses
519- /// being compared inside the function.
527+ /// Implicit promotion has almost the same rules, except that it does not happen if `const fn`
528+ /// calls are involved. The call may be perfectly alright at runtime, but fail at compile time
529+ /// e.g. due to addresses being compared inside the function.
520530struct IsNotImplicitlyPromotable ;
521531
522532impl Qualif for IsNotImplicitlyPromotable {
@@ -589,6 +599,11 @@ impl ConstCx<'_, 'tcx> {
589599 }
590600}
591601
602+ /// Checks MIR for const-correctness, using `ConstCx`
603+ /// for value qualifications, and accumulates writes of
604+ /// rvalue/call results to locals, in `local_qualif`.
605+ /// For functions (constant or not), it also records
606+ /// candidates for promotion in `promotion_candidates`.
592607struct Checker < ' a , ' tcx > {
593608 cx : ConstCx < ' a , ' tcx > ,
594609
@@ -757,6 +772,9 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
757772 // `let _: &'static _ = &(Cell::new(1), 2).1;`
758773 let mut local_qualifs = self . qualifs_in_local ( local) ;
759774 local_qualifs[ HasMutInterior ] = false ;
775+ // Make sure there is no reason to prevent promotion.
776+ // This is, in particular, the "implicit promotion" version of
777+ // the check making sure that we don't run drop glue during const-eval.
760778 if !local_qualifs. 0 . iter ( ) . any ( |& qualif| qualif) {
761779 debug ! ( "qualify_consts: promotion candidate: {:?}" , candidate) ;
762780 self . promotion_candidates . push ( candidate) ;
@@ -920,11 +938,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
920938 }
921939}
922940
923- /// Checks MIR for const-correctness, using `ConstCx`
924- /// for value qualifications, and accumulates writes of
925- /// rvalue/call results to locals, in `local_qualif`.
926- /// For functions (constant or not), it also records
927- /// candidates for promotion in `promotion_candidates`.
928941impl < ' a , ' tcx > Visitor < ' tcx > for Checker < ' a , ' tcx > {
929942 fn visit_place_base (
930943 & mut self ,
0 commit comments