@@ -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 ;
@@ -224,6 +224,7 @@ pub fn provide(providers: &mut Providers) {
224
224
promoted_mir,
225
225
deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
226
226
coroutine_by_move_body_def_id : coroutine:: coroutine_by_move_body_def_id,
227
+ mir_flags,
227
228
..providers. queries
228
229
} ;
229
230
}
@@ -420,9 +421,6 @@ fn mir_promoted(
420
421
_ => ConstQualifs :: default ( ) ,
421
422
} ;
422
423
423
- // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run.
424
- tcx. ensure_done ( ) . has_ffi_unwind_calls ( def) ;
425
-
426
424
// the `by_move_body` query uses the raw mir, so make sure it is run.
427
425
if tcx. needs_coroutine_by_move_body_def_id ( def. to_def_id ( ) ) {
428
426
tcx. ensure_done ( ) . coroutine_by_move_body_def_id ( def) ;
@@ -453,6 +451,33 @@ fn mir_promoted(
453
451
( tcx. alloc_steal_mir ( body) , tcx. alloc_steal_promoted ( promoted) )
454
452
}
455
453
454
+ fn mir_flags < ' tcx > ( tcx : TyCtxt < ' tcx > , local_def_id : LocalDefId ) -> MirFlags {
455
+ let mut flags = MirFlags :: default ( ) ;
456
+ // Only perform check on functions because constants cannot call FFI functions.
457
+ let kind = tcx. def_kind ( local_def_id) ;
458
+ if !kind. is_fn_like ( ) {
459
+ return flags;
460
+ }
461
+
462
+ if !tcx. mir_keys ( ( ) ) . contains ( & local_def_id) {
463
+ return flags;
464
+ }
465
+
466
+ let body = & * tcx. mir_promoted ( local_def_id) . 0 . borrow ( ) ;
467
+
468
+ if is_nounwind ( body) {
469
+ flags. insert ( MirFlags :: IS_NOUNWIND ) ;
470
+ }
471
+ if ffi_unwind_calls:: has_ffi_unwind_calls ( tcx, body) {
472
+ flags. insert ( MirFlags :: HAS_FFI_UNWIND_CALLS ) ;
473
+ }
474
+ flags
475
+ }
476
+
477
+ fn is_nounwind < ' tcx > ( body : & Body < ' tcx > ) -> bool {
478
+ body. basic_blocks . iter ( ) . all ( |block| block. terminator ( ) . unwind ( ) . is_none ( ) )
479
+ }
480
+
456
481
/// Compute the MIR that is used during CTFE (and thus has no optimizations run on it)
457
482
fn mir_for_ctfe ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> & Body < ' _ > {
458
483
tcx. arena . alloc ( inner_mir_for_ctfe ( tcx, def_id) )
@@ -503,6 +528,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
503
528
{
504
529
tcx. ensure_done ( ) . mir_inliner_callees ( ty:: InstanceKind :: Item ( def. to_def_id ( ) ) ) ;
505
530
}
531
+ tcx. ensure_done ( ) . mir_flags ( def) ;
506
532
}
507
533
508
534
let ( body, _) = tcx. mir_promoted ( def) ;
0 commit comments