@@ -26,8 +26,8 @@ use rustc_hir::def_id::LocalDefId;
26
26
use rustc_index:: IndexVec ;
27
27
use rustc_middle:: mir:: {
28
28
AnalysisPhase , Body , CallSource , ClearCrossCrate , ConstOperand , ConstQualifs , LocalDecl ,
29
- MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue , START_BLOCK ,
30
- SourceInfo , Statement , StatementKind , TerminatorKind ,
29
+ MirFlags , MirPhase , Operand , Place , ProjectionElem , Promoted , RuntimePhase , Rvalue ,
30
+ START_BLOCK , SourceInfo , Statement , StatementKind , TerminatorKind ,
31
31
} ;
32
32
use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
33
33
use rustc_middle:: util:: Providers ;
@@ -217,6 +217,7 @@ pub fn provide(providers: &mut Providers) {
217
217
promoted_mir,
218
218
deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
219
219
coroutine_by_move_body_def_id : coroutine:: coroutine_by_move_body_def_id,
220
+ mir_flags,
220
221
..providers. queries
221
222
} ;
222
223
}
@@ -410,9 +411,6 @@ fn mir_promoted(
410
411
_ => ConstQualifs :: default ( ) ,
411
412
} ;
412
413
413
- // the `has_ffi_unwind_calls` query uses the raw mir, so make sure it is run.
414
- tcx. ensure_with_value ( ) . has_ffi_unwind_calls ( def) ;
415
-
416
414
// the `by_move_body` query uses the raw mir, so make sure it is run.
417
415
if tcx. needs_coroutine_by_move_body_def_id ( def. to_def_id ( ) ) {
418
416
tcx. ensure_with_value ( ) . coroutine_by_move_body_def_id ( def) ;
@@ -440,6 +438,33 @@ fn mir_promoted(
440
438
( tcx. alloc_steal_mir ( body) , tcx. alloc_steal_promoted ( promoted) )
441
439
}
442
440
441
+ fn mir_flags < ' tcx > ( tcx : TyCtxt < ' tcx > , local_def_id : LocalDefId ) -> MirFlags {
442
+ let mut flags = MirFlags :: default ( ) ;
443
+ // Only perform check on functions because constants cannot call FFI functions.
444
+ let kind = tcx. def_kind ( local_def_id) ;
445
+ if !kind. is_fn_like ( ) {
446
+ return flags;
447
+ }
448
+
449
+ if !tcx. mir_keys ( ( ) ) . contains ( & local_def_id) {
450
+ return flags;
451
+ }
452
+
453
+ let body = & * tcx. mir_promoted ( local_def_id) . 0 . borrow ( ) ;
454
+
455
+ if is_nounwind ( body) {
456
+ flags. insert ( MirFlags :: IS_NOUNWIND ) ;
457
+ }
458
+ if ffi_unwind_calls:: has_ffi_unwind_calls ( tcx, body) {
459
+ flags. insert ( MirFlags :: HAS_FFI_UNWIND_CALLS ) ;
460
+ }
461
+ flags
462
+ }
463
+
464
+ fn is_nounwind < ' tcx > ( body : & Body < ' tcx > ) -> bool {
465
+ body. basic_blocks . iter ( ) . all ( |block| block. terminator ( ) . unwind ( ) . is_none ( ) )
466
+ }
467
+
443
468
/// Compute the MIR that is used during CTFE (and thus has no optimizations run on it)
444
469
fn mir_for_ctfe ( tcx : TyCtxt < ' _ > , def_id : LocalDefId ) -> & Body < ' _ > {
445
470
tcx. arena . alloc ( inner_mir_for_ctfe ( tcx, def_id) )
@@ -488,6 +513,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
488
513
if pm:: should_run_pass ( tcx, & inline:: Inline ) {
489
514
tcx. ensure_with_value ( ) . mir_inliner_callees ( ty:: InstanceKind :: Item ( def. to_def_id ( ) ) ) ;
490
515
}
516
+ tcx. ensure_with_value ( ) . mir_flags ( def) ;
491
517
}
492
518
493
519
let ( body, _) = tcx. mir_promoted ( def) ;
0 commit comments