@@ -40,6 +40,7 @@ use rustc_middle::mir::{
4040 SourceInfo , Statement , StatementKind , TerminatorKind , START_BLOCK ,
4141} ;
4242use rustc_middle:: query:: Providers ;
43+ use rustc_middle:: traits:: util:: HasImpossiblePredicates ;
4344use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
4445use rustc_span:: { source_map:: Spanned , sym, DUMMY_SP } ;
4546use rustc_trait_selection:: traits;
@@ -142,6 +143,7 @@ pub fn provide(providers: &mut Providers) {
142143 is_ctfe_mir_available : |tcx, did| is_mir_available ( tcx, did) ,
143144 mir_callgraph_reachable : inline:: cycle:: mir_callgraph_reachable,
144145 mir_inliner_callees : inline:: cycle:: mir_inliner_callees,
146+ const_prop_lint,
145147 promoted_mir,
146148 deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
147149 ..* providers
@@ -398,28 +400,11 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
398400 body
399401}
400402
401- /// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
402- /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
403- /// end up missing the source MIR due to stealing happening.
404- fn mir_drops_elaborated_and_const_checked ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> & Steal < Body < ' _ > > {
405- if tcx. is_coroutine ( def. to_def_id ( ) ) {
406- tcx. ensure_with_value ( ) . mir_coroutine_witnesses ( def) ;
407- }
408- let mir_borrowck = tcx. mir_borrowck ( def) ;
409-
410- let is_fn_like = tcx. def_kind ( def) . is_fn_like ( ) ;
411- if is_fn_like {
412- // Do not compute the mir call graph without said call graph actually being used.
413- if pm:: should_run_pass ( tcx, & inline:: Inline ) {
414- tcx. ensure_with_value ( ) . mir_inliner_callees ( ty:: InstanceDef :: Item ( def. to_def_id ( ) ) ) ;
415- }
416- }
417-
403+ fn const_prop_lint ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> Result < ( ) , HasImpossiblePredicates > {
418404 let ( body, _) = tcx. mir_promoted ( def) ;
419- let mut body = body. steal ( ) ;
420- if let Some ( error_reported) = mir_borrowck. tainted_by_errors {
421- body. tainted_by_errors = Some ( error_reported) ;
422- }
405+ let body = body. borrow ( ) ;
406+
407+ let mir_borrowck = tcx. mir_borrowck ( def) ;
423408
424409 // Check if it's even possible to satisfy the 'where' clauses
425410 // for this item.
@@ -455,6 +440,40 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
455440 . iter ( )
456441 . filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
457442 if traits:: impossible_predicates ( tcx, traits:: elaborate ( tcx, predicates) . collect ( ) ) {
443+ Err ( HasImpossiblePredicates )
444+ } else {
445+ if mir_borrowck. tainted_by_errors . is_none ( ) && body. tainted_by_errors . is_none ( ) {
446+ const_prop_lint:: ConstPropLint . run_lint ( tcx, & body) ;
447+ }
448+ Ok ( ( ) )
449+ }
450+ }
451+
452+ /// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
453+ /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
454+ /// end up missing the source MIR due to stealing happening.
455+ fn mir_drops_elaborated_and_const_checked ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> & Steal < Body < ' _ > > {
456+ if tcx. is_coroutine ( def. to_def_id ( ) ) {
457+ tcx. ensure_with_value ( ) . mir_coroutine_witnesses ( def) ;
458+ }
459+ let mir_borrowck = tcx. mir_borrowck ( def) ;
460+ let has_impossible_predicates = tcx. const_prop_lint ( def) ;
461+
462+ let is_fn_like = tcx. def_kind ( def) . is_fn_like ( ) ;
463+ if is_fn_like {
464+ // Do not compute the mir call graph without said call graph actually being used.
465+ if pm:: should_run_pass ( tcx, & inline:: Inline ) {
466+ tcx. ensure_with_value ( ) . mir_inliner_callees ( ty:: InstanceDef :: Item ( def. to_def_id ( ) ) ) ;
467+ }
468+ }
469+
470+ let ( body, _) = tcx. mir_promoted ( def) ;
471+ let mut body = body. steal ( ) ;
472+ if let Some ( error_reported) = mir_borrowck. tainted_by_errors {
473+ body. tainted_by_errors = Some ( error_reported) ;
474+ }
475+
476+ if let Err ( HasImpossiblePredicates ) = has_impossible_predicates {
458477 trace ! ( "found unsatisfiable predicates for {:?}" , body. source) ;
459478 // Clear the body to only contain a single `unreachable` statement.
460479 let bbs = body. basic_blocks . as_mut ( ) ;
@@ -538,7 +557,6 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
538557 & elaborate_box_derefs:: ElaborateBoxDerefs ,
539558 & coroutine:: StateTransform ,
540559 & add_retag:: AddRetag ,
541- & Lint ( const_prop_lint:: ConstPropLint ) ,
542560 ] ;
543561 pm:: run_passes_no_validate ( tcx, body, passes, Some ( MirPhase :: Runtime ( RuntimePhase :: Initial ) ) ) ;
544562}
0 commit comments