@@ -40,6 +40,7 @@ use rustc_middle::mir::{
40
40
SourceInfo , Statement , StatementKind , TerminatorKind , START_BLOCK ,
41
41
} ;
42
42
use rustc_middle:: query:: Providers ;
43
+ use rustc_middle:: traits:: util:: HasImpossiblePredicates ;
43
44
use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
44
45
use rustc_span:: { source_map:: Spanned , sym, DUMMY_SP } ;
45
46
use rustc_trait_selection:: traits;
@@ -142,6 +143,7 @@ pub fn provide(providers: &mut Providers) {
142
143
is_ctfe_mir_available : |tcx, did| is_mir_available ( tcx, did) ,
143
144
mir_callgraph_reachable : inline:: cycle:: mir_callgraph_reachable,
144
145
mir_inliner_callees : inline:: cycle:: mir_inliner_callees,
146
+ const_prop_lint,
145
147
promoted_mir,
146
148
deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
147
149
..* providers
@@ -398,28 +400,11 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
398
400
body
399
401
}
400
402
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 > {
418
404
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) ;
423
408
424
409
// Check if it's even possible to satisfy the 'where' clauses
425
410
// for this item.
@@ -455,6 +440,40 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
455
440
. iter ( )
456
441
. filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
457
442
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 {
458
477
trace ! ( "found unsatisfiable predicates for {:?}" , body. source) ;
459
478
// Clear the body to only contain a single `unreachable` statement.
460
479
let bbs = body. basic_blocks . as_mut ( ) ;
@@ -538,7 +557,6 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
538
557
& elaborate_box_derefs:: ElaborateBoxDerefs ,
539
558
& coroutine:: StateTransform ,
540
559
& add_retag:: AddRetag ,
541
- & Lint ( const_prop_lint:: ConstPropLint ) ,
542
560
] ;
543
561
pm:: run_passes_no_validate ( tcx, body, passes, Some ( MirPhase :: Runtime ( RuntimePhase :: Initial ) ) ) ;
544
562
}
0 commit comments