@@ -49,6 +49,7 @@ pub(crate) fn provide(providers: &mut Providers<'_>) {
4949 mir_const,
5050 mir_const_qualif,
5151 mir_validated,
52+ mir_drops_elaborated_and_const_checked,
5253 optimized_mir,
5354 is_mir_available,
5455 promoted_mir,
@@ -294,12 +295,31 @@ fn mir_validated(
294295 ( tcx. alloc_steal_mir ( body) , tcx. alloc_steal_promoted ( promoted) )
295296}
296297
297- fn run_optimization_passes < ' tcx > (
298+ fn mir_drops_elaborated_and_const_checked < ' tcx > (
299+ tcx : TyCtxt < ' tcx > ,
300+ def_id : LocalDefId ,
301+ ) -> Steal < Body < ' tcx > > {
302+ // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
303+ // execute before we can steal.
304+ tcx. ensure ( ) . mir_borrowck ( def_id) ;
305+
306+ let ( body, _) = tcx. mir_validated ( def_id) ;
307+ let mut body = body. steal ( ) ;
308+
309+ run_post_borrowck_cleanup_passes ( tcx, & mut body, def_id, None ) ;
310+ check_consts:: post_drop_elaboration:: check_live_drops ( tcx, def_id, & body) ;
311+ tcx. alloc_steal_mir ( body)
312+ }
313+
314+ /// After this series of passes, no lifetime analysis based on borrowing can be done.
315+ fn run_post_borrowck_cleanup_passes < ' tcx > (
298316 tcx : TyCtxt < ' tcx > ,
299317 body : & mut Body < ' tcx > ,
300318 def_id : LocalDefId ,
301319 promoted : Option < Promoted > ,
302320) {
321+ debug ! ( "post_borrowck_cleanup({:?})" , def_id) ;
322+
303323 let post_borrowck_cleanup: & [ & dyn MirPass < ' tcx > ] = & [
304324 // Remove all things only needed by analysis
305325 & no_landing_pads:: NoLandingPads :: new ( tcx) ,
@@ -318,9 +338,24 @@ fn run_optimization_passes<'tcx>(
318338 // but before optimizations begin.
319339 & add_retag:: AddRetag ,
320340 & simplify:: SimplifyCfg :: new ( "elaborate-drops" ) ,
321- // No lifetime analysis based on borrowing can be done from here on out.
322341 ] ;
323342
343+ run_passes (
344+ tcx,
345+ body,
346+ InstanceDef :: Item ( def_id. to_def_id ( ) ) ,
347+ promoted,
348+ MirPhase :: DropElab ,
349+ & [ post_borrowck_cleanup] ,
350+ ) ;
351+ }
352+
353+ fn run_optimization_passes < ' tcx > (
354+ tcx : TyCtxt < ' tcx > ,
355+ body : & mut Body < ' tcx > ,
356+ def_id : LocalDefId ,
357+ promoted : Option < Promoted > ,
358+ ) {
324359 let optimizations: & [ & dyn MirPass < ' tcx > ] = & [
325360 & unreachable_prop:: UnreachablePropagation ,
326361 & uninhabited_enum_branching:: UninhabitedEnumBranching ,
@@ -368,14 +403,14 @@ fn run_optimization_passes<'tcx>(
368403
369404 let mir_opt_level = tcx. sess . opts . debugging_opts . mir_opt_level ;
370405
406+ #[ rustfmt:: skip]
371407 run_passes (
372408 tcx,
373409 body,
374410 InstanceDef :: Item ( def_id. to_def_id ( ) ) ,
375411 promoted,
376412 MirPhase :: Optimized ,
377413 & [
378- post_borrowck_cleanup,
379414 if mir_opt_level > 0 { optimizations } else { no_optimizations } ,
380415 pre_codegen_cleanup,
381416 ] ,
@@ -393,12 +428,7 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
393428
394429 let def_id = def_id. expect_local ( ) ;
395430
396- // (Mir-)Borrowck uses `mir_validated`, so we have to force it to
397- // execute before we can steal.
398- tcx. ensure ( ) . mir_borrowck ( def_id) ;
399-
400- let ( body, _) = tcx. mir_validated ( def_id) ;
401- let mut body = body. steal ( ) ;
431+ let mut body = tcx. mir_drops_elaborated_and_const_checked ( def_id) . steal ( ) ;
402432 run_optimization_passes ( tcx, & mut body, def_id, None ) ;
403433
404434 debug_assert ! ( !body. has_free_regions( ) , "Free regions in optimized MIR" ) ;
@@ -418,6 +448,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def_id: DefId) -> IndexVec<Promoted, Body<'_>>
418448 let mut promoted = promoted. steal ( ) ;
419449
420450 for ( p, mut body) in promoted. iter_enumerated_mut ( ) {
451+ run_post_borrowck_cleanup_passes ( tcx, & mut body, def_id, Some ( p) ) ;
421452 run_optimization_passes ( tcx, & mut body, def_id, Some ( p) ) ;
422453 }
423454
0 commit comments