@@ -28,11 +28,10 @@ use rustc_hir::def::DefKind;
28
28
use rustc_hir:: def_id:: LocalDefId ;
29
29
use rustc_hir:: intravisit:: { self , Visitor } ;
30
30
use rustc_index:: IndexVec ;
31
- use rustc_middle:: mir:: visit:: Visitor as _;
32
31
use rustc_middle:: mir:: {
33
- traversal , AnalysisPhase , Body , CallSource , ClearCrossCrate , ConstOperand , ConstQualifs ,
34
- LocalDecl , MirPass , MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue ,
35
- SourceInfo , Statement , StatementKind , TerminatorKind , START_BLOCK ,
32
+ AnalysisPhase , Body , CallSource , ClearCrossCrate , ConstOperand , ConstQualifs , LocalDecl ,
33
+ MirPass , MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue , SourceInfo ,
34
+ Statement , StatementKind , TerminatorKind , START_BLOCK ,
36
35
} ;
37
36
use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
38
37
use rustc_middle:: util:: Providers ;
@@ -339,12 +338,15 @@ fn mir_promoted(
339
338
340
339
// Collect `required_consts` *before* promotion, so if there are any consts being promoted
341
340
// we still add them to the list in the outer MIR body.
342
- let mut required_consts = Vec :: new ( ) ;
343
- let mut required_consts_visitor = RequiredConstsVisitor :: new ( & mut required_consts) ;
344
- for ( bb, bb_data) in traversal:: reverse_postorder ( & body) {
345
- required_consts_visitor. visit_basic_block_data ( bb, bb_data) ;
341
+ RequiredConstsVisitor :: compute_required_consts ( & mut body) ;
342
+ // If this has an associated by-move async closure body, that doesn't get run through these
343
+ // passes itself, it gets "tagged along" by the pass manager. `RequiredConstsVisitor` is not
344
+ // a regular pass so we have to also apply it manually to the other body.
345
+ if let Some ( coroutine) = body. coroutine . as_mut ( ) {
346
+ if let Some ( by_move_body) = coroutine. by_move_body . as_mut ( ) {
347
+ RequiredConstsVisitor :: compute_required_consts ( by_move_body) ;
348
+ }
346
349
}
347
- body. required_consts = required_consts;
348
350
349
351
// What we need to run borrowck etc.
350
352
let promote_pass = promote_consts:: PromoteTemps :: default ( ) ;
@@ -561,9 +563,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
561
563
tcx,
562
564
body,
563
565
& [
564
- // Before doing anything, remember which items are being mentioned so that the set of items
565
- // visited does not depend on the optimization level.
566
- & mentioned_items:: MentionedItems ,
567
566
// Add some UB checks before any UB gets optimized away.
568
567
& check_alignment:: CheckAlignment ,
569
568
// Before inlining: trim down MIR with passes to reduce inlining work.
@@ -657,6 +656,19 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
657
656
return body;
658
657
}
659
658
659
+ // Before doing anything, remember which items are being mentioned so that the set of items
660
+ // visited does not depend on the optimization level.
661
+ // We do not use `run_passes` for this as that might skip the pass if `injection_phase` is set.
662
+ mentioned_items:: MentionedItems . run_pass ( tcx, & mut body) ;
663
+ // If this has an associated by-move async closure body, that doesn't get run through these
664
+ // passes itself, it gets "tagged along" by the pass manager. Since we're not using the pass
665
+ // manager we have to do this by hand.
666
+ if let Some ( coroutine) = body. coroutine . as_mut ( ) {
667
+ if let Some ( by_move_body) = coroutine. by_move_body . as_mut ( ) {
668
+ mentioned_items:: MentionedItems . run_pass ( tcx, by_move_body) ;
669
+ }
670
+ }
671
+
660
672
// If `mir_drops_elaborated_and_const_checked` found that the current body has unsatisfiable
661
673
// predicates, it will shrink the MIR to a single `unreachable` terminator.
662
674
// More generally, if MIR is a lone `unreachable`, there is nothing to optimize.
0 commit comments