@@ -27,8 +27,8 @@ use rustc_hir::def_id::LocalDefId;
27
27
use rustc_index:: IndexVec ;
28
28
use rustc_middle:: mir:: {
29
29
AnalysisPhase , Body , CallSource , ClearCrossCrate , ConstOperand , ConstQualifs , LocalDecl ,
30
- MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue , START_BLOCK ,
31
- SourceInfo , Statement , StatementKind , TerminatorKind ,
30
+ MirFlags , MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue ,
31
+ START_BLOCK , SourceInfo , Statement , StatementKind , TerminatorKind ,
32
32
} ;
33
33
use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
34
34
use rustc_middle:: util:: Providers ;
@@ -225,6 +225,7 @@ pub fn provide(providers: &mut Providers) {
225
225
promoted_mir,
226
226
deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
227
227
coroutine_by_move_body_def_id : coroutine:: coroutine_by_move_body_def_id,
228
+ mir_flags,
228
229
..providers. queries
229
230
} ;
230
231
}
@@ -425,9 +426,6 @@ fn mir_promoted(
425
426
_ => ConstQualifs :: default ( ) ,
426
427
} ;
427
428
428
- // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run.
429
- tcx. ensure_done ( ) . has_ffi_unwind_calls ( def) ;
430
-
431
429
// the `by_move_body` query uses the raw mir, so make sure it is run.
432
430
if tcx. needs_coroutine_by_move_body_def_id ( def. to_def_id ( ) ) {
433
431
tcx. ensure_done ( ) . coroutine_by_move_body_def_id ( def) ;
@@ -458,6 +456,33 @@ fn mir_promoted(
458
456
( tcx. alloc_steal_mir ( body) , tcx. alloc_steal_promoted ( promoted) )
459
457
}
460
458
459
+ fn mir_flags < ' tcx > ( tcx : TyCtxt < ' tcx > , local_def_id : LocalDefId ) -> MirFlags {
460
+ let mut flags = MirFlags :: default ( ) ;
461
+ // Only perform check on functions because constants cannot call FFI functions.
462
+ let kind = tcx. def_kind ( local_def_id) ;
463
+ if !kind. is_fn_like ( ) {
464
+ return flags;
465
+ }
466
+
467
+ if !tcx. mir_keys ( ( ) ) . contains ( & local_def_id) {
468
+ return flags;
469
+ }
470
+
471
+ let body = & * tcx. mir_promoted ( local_def_id) . 0 . borrow ( ) ;
472
+
473
+ if is_nounwind ( body) {
474
+ flags. insert ( MirFlags :: IS_NOUNWIND ) ;
475
+ }
476
+ if ffi_unwind_calls:: has_ffi_unwind_calls ( tcx, body) {
477
+ flags. insert ( MirFlags :: HAS_FFI_UNWIND_CALLS ) ;
478
+ }
479
+ flags
480
+ }
481
+
482
+ fn is_nounwind < ' tcx > ( body : & Body < ' tcx > ) -> bool {
483
+ body. basic_blocks . iter ( ) . all ( |block| block. terminator ( ) . unwind ( ) . is_none ( ) )
484
+ }
485
+
461
486
/// Compute the MIR that is used during CTFE (and thus has no optimizations run on it)
462
487
fn mir_for_ctfe ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> & Body < ' _ > {
463
488
tcx. arena . alloc ( inner_mir_for_ctfe ( tcx, def_id) )
@@ -508,6 +533,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
508
533
{
509
534
tcx. ensure_done ( ) . mir_inliner_callees ( ty:: InstanceKind :: Item ( def. to_def_id ( ) ) ) ;
510
535
}
536
+ tcx. ensure_done ( ) . mir_flags ( def) ;
511
537
}
512
538
513
539
let ( body, _) = tcx. mir_promoted ( def) ;
0 commit comments