@@ -135,6 +135,12 @@ enum ValueSource<'a, 'tcx> {
135
135
} ,
136
136
}
137
137
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.
138
144
trait Qualif {
139
145
const IDX : usize ;
140
146
@@ -285,7 +291,9 @@ trait Qualif {
285
291
}
286
292
}
287
293
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.
289
297
struct HasMutInterior ;
290
298
291
299
impl Qualif for HasMutInterior {
@@ -343,7 +351,9 @@ impl Qualif for HasMutInterior {
343
351
}
344
352
}
345
353
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`.
347
357
struct NeedsDrop ;
348
358
349
359
impl Qualif for NeedsDrop {
@@ -366,8 +376,11 @@ impl Qualif for NeedsDrop {
366
376
}
367
377
}
368
378
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).
371
384
struct IsNotPromotable ;
372
385
373
386
impl Qualif for IsNotPromotable {
@@ -511,12 +524,9 @@ impl Qualif for IsNotPromotable {
511
524
512
525
/// Refers to temporaries which cannot be promoted *implicitly*.
513
526
/// 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.
520
530
struct IsNotImplicitlyPromotable ;
521
531
522
532
impl Qualif for IsNotImplicitlyPromotable {
@@ -589,6 +599,11 @@ impl ConstCx<'_, 'tcx> {
589
599
}
590
600
}
591
601
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`.
592
607
struct Checker < ' a , ' tcx > {
593
608
cx : ConstCx < ' a , ' tcx > ,
594
609
@@ -757,6 +772,9 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
757
772
// `let _: &'static _ = &(Cell::new(1), 2).1;`
758
773
let mut local_qualifs = self . qualifs_in_local ( local) ;
759
774
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.
760
778
if !local_qualifs. 0 . iter ( ) . any ( |& qualif| qualif) {
761
779
debug ! ( "qualify_consts: promotion candidate: {:?}" , candidate) ;
762
780
self . promotion_candidates . push ( candidate) ;
@@ -920,11 +938,6 @@ impl<'a, 'tcx> Checker<'a, 'tcx> {
920
938
}
921
939
}
922
940
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`.
928
941
impl < ' a , ' tcx > Visitor < ' tcx > for Checker < ' a , ' tcx > {
929
942
fn visit_place_base (
930
943
& mut self ,
0 commit comments