@@ -49,6 +49,7 @@ pub(crate) fn provide(providers: &mut Providers<'_>) {
49
49
mir_const,
50
50
mir_const_qualif,
51
51
mir_validated,
52
+ mir_drops_elaborated_and_const_checked,
52
53
optimized_mir,
53
54
is_mir_available,
54
55
promoted_mir,
@@ -294,12 +295,31 @@ fn mir_validated(
294
295
( tcx. alloc_steal_mir ( body) , tcx. alloc_steal_promoted ( promoted) )
295
296
}
296
297
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 > (
298
316
tcx : TyCtxt < ' tcx > ,
299
317
body : & mut Body < ' tcx > ,
300
318
def_id : LocalDefId ,
301
319
promoted : Option < Promoted > ,
302
320
) {
321
+ debug ! ( "post_borrowck_cleanup({:?})" , def_id) ;
322
+
303
323
let post_borrowck_cleanup: & [ & dyn MirPass < ' tcx > ] = & [
304
324
// Remove all things only needed by analysis
305
325
& no_landing_pads:: NoLandingPads :: new ( tcx) ,
@@ -318,9 +338,24 @@ fn run_optimization_passes<'tcx>(
318
338
// but before optimizations begin.
319
339
& add_retag:: AddRetag ,
320
340
& simplify:: SimplifyCfg :: new ( "elaborate-drops" ) ,
321
- // No lifetime analysis based on borrowing can be done from here on out.
322
341
] ;
323
342
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
+ ) {
324
359
let optimizations: & [ & dyn MirPass < ' tcx > ] = & [
325
360
& unreachable_prop:: UnreachablePropagation ,
326
361
& uninhabited_enum_branching:: UninhabitedEnumBranching ,
@@ -368,14 +403,14 @@ fn run_optimization_passes<'tcx>(
368
403
369
404
let mir_opt_level = tcx. sess . opts . debugging_opts . mir_opt_level ;
370
405
406
+ #[ rustfmt:: skip]
371
407
run_passes (
372
408
tcx,
373
409
body,
374
410
InstanceDef :: Item ( def_id. to_def_id ( ) ) ,
375
411
promoted,
376
412
MirPhase :: Optimized ,
377
413
& [
378
- post_borrowck_cleanup,
379
414
if mir_opt_level > 0 { optimizations } else { no_optimizations } ,
380
415
pre_codegen_cleanup,
381
416
] ,
@@ -393,12 +428,7 @@ fn optimized_mir(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
393
428
394
429
let def_id = def_id. expect_local ( ) ;
395
430
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 ( ) ;
402
432
run_optimization_passes ( tcx, & mut body, def_id, None ) ;
403
433
404
434
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<'_>>
418
448
let mut promoted = promoted. steal ( ) ;
419
449
420
450
for ( p, mut body) in promoted. iter_enumerated_mut ( ) {
451
+ run_post_borrowck_cleanup_passes ( tcx, & mut body, def_id, Some ( p) ) ;
421
452
run_optimization_passes ( tcx, & mut body, def_id, Some ( p) ) ;
422
453
}
423
454
0 commit comments