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