@@ -406,14 +406,31 @@ impl Visitor<'tcx> for Validator<'mir, 'tcx> {
406
406
) ;
407
407
}
408
408
409
- fn visit_operand ( & mut self , op : & Operand < ' tcx > , location : Location ) {
410
- self . super_operand ( op, location) ;
411
- if let Operand :: Constant ( c) = op {
412
- if let Some ( def_id) = c. check_static_ptr ( self . tcx ) {
413
- self . check_static ( def_id, self . span ) ;
409
+ fn visit_constant ( & mut self , constant : & Constant < ' tcx > , location : Location ) {
410
+ self . super_constant ( constant, location) ;
411
+
412
+ if let ty:: ConstKind :: Unevaluated ( def_id, _, promoted) = constant. literal . val {
413
+ assert ! ( promoted. is_none( ) , "Const-checking should run before promotion" ) ;
414
+
415
+ // If a cyclic data dependency exists within a const initializer, try to find
416
+ // it during const-checking. This is important because MIR optimizations could
417
+ // eliminate a cycle before const-eval runs. See #71078 for an example of this.
418
+ //
419
+ // FIXME: This means we don't look for cycles involving associated constants, but we
420
+ // should handle fully monomorphized ones here at least.
421
+ if self . tcx . trait_of_item ( def_id) . is_none ( ) {
422
+ let _ = self . tcx . at ( self . span ) . mir_const_qualif ( def_id) ;
414
423
}
415
424
}
425
+
426
+ if let Some ( def_id) = constant. check_static_ptr ( self . tcx ) {
427
+ self . check_static ( def_id, self . span ) ;
428
+
429
+ // NOTE: Because we are allowed to refer to the address of a static within its
430
+ // initializer, we don't try to trigger cycle errors every time we see a static.
431
+ }
416
432
}
433
+
417
434
fn visit_projection_elem (
418
435
& mut self ,
419
436
place_local : Local ,
0 commit comments