@@ -28,11 +28,10 @@ use rustc_hir::def::DefKind;
2828use rustc_hir:: def_id:: LocalDefId ;
2929use rustc_hir:: intravisit:: { self , Visitor } ;
3030use rustc_index:: IndexVec ;
31- use rustc_middle:: mir:: visit:: Visitor as _;
3231use 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 ,
3635} ;
3736use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
3837use rustc_middle:: util:: Providers ;
@@ -339,12 +338,15 @@ fn mir_promoted(
339338
340339 // Collect `required_consts` *before* promotion, so if there are any consts being promoted
341340 // 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+ }
346349 }
347- body. required_consts = required_consts;
348350
349351 // What we need to run borrowck etc.
350352 let promote_pass = promote_consts:: PromoteTemps :: default ( ) ;
@@ -561,9 +563,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
561563 tcx,
562564 body,
563565 & [
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 ,
567566 // Add some UB checks before any UB gets optimized away.
568567 & check_alignment:: CheckAlignment ,
569568 // Before inlining: trim down MIR with passes to reduce inlining work.
@@ -657,6 +656,19 @@ fn inner_optimized_mir(tcx: TyCtxt<'_>, did: LocalDefId) -> Body<'_> {
657656 return body;
658657 }
659658
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+
660672 // If `mir_drops_elaborated_and_const_checked` found that the current body has unsatisfiable
661673 // predicates, it will shrink the MIR to a single `unreachable` terminator.
662674 // More generally, if MIR is a lone `unreachable`, there is nothing to optimize.
0 commit comments