@@ -38,6 +38,7 @@ use rustc_middle::mir::{
38
38
SourceInfo , Statement , StatementKind , TerminatorKind , START_BLOCK ,
39
39
} ;
40
40
use rustc_middle:: query:: Providers ;
41
+ use rustc_middle:: traits:: util:: HasImpossiblePredicates ;
41
42
use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
42
43
use rustc_span:: { source_map:: Spanned , sym, DUMMY_SP } ;
43
44
use rustc_trait_selection:: traits;
@@ -137,6 +138,8 @@ pub fn provide(providers: &mut Providers) {
137
138
is_ctfe_mir_available : |tcx, did| is_mir_available ( tcx, did) ,
138
139
mir_callgraph_reachable : inline:: cycle:: mir_callgraph_reachable,
139
140
mir_inliner_callees : inline:: cycle:: mir_inliner_callees,
141
+ const_prop_lint,
142
+ const_prop_lint_promoteds,
140
143
promoted_mir,
141
144
deduced_param_attrs : deduce_param_attrs:: deduced_param_attrs,
142
145
..* providers
@@ -393,6 +396,39 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
393
396
body
394
397
}
395
398
399
+ fn const_prop_lint ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> Result < ( ) , HasImpossiblePredicates > {
400
+ let ( body, _) = tcx. mir_promoted ( def) ;
401
+ let body = body. borrow ( ) ;
402
+
403
+ let mir_borrowck = tcx. mir_borrowck ( def) ;
404
+
405
+ check_impossible_predicates ( tcx, def) ?;
406
+ if mir_borrowck. tainted_by_errors . is_none ( ) && body. tainted_by_errors . is_none ( ) {
407
+ const_prop_lint:: ConstPropLint . run_lint ( tcx, & body) ;
408
+ }
409
+ Ok ( ( ) )
410
+ }
411
+
412
+ fn const_prop_lint_promoteds (
413
+ tcx : TyCtxt < ' _ > ,
414
+ def : LocalDefId ,
415
+ ) -> Result < ( ) , HasImpossiblePredicates > {
416
+ let ( _, promoteds) = tcx. mir_promoted ( def) ;
417
+ let promoteds = promoteds. borrow ( ) ;
418
+
419
+ let mir_borrowck = tcx. mir_borrowck ( def) ;
420
+
421
+ check_impossible_predicates ( tcx, def) ?;
422
+ if mir_borrowck. tainted_by_errors . is_none ( ) {
423
+ for body in & * promoteds {
424
+ if body. tainted_by_errors . is_none ( ) {
425
+ const_prop_lint:: ConstPropLint . run_lint ( tcx, & body) ;
426
+ }
427
+ }
428
+ }
429
+ Ok ( ( ) )
430
+ }
431
+
396
432
/// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
397
433
/// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
398
434
/// end up missing the source MIR due to stealing happening.
@@ -401,6 +437,7 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
401
437
tcx. ensure_with_value ( ) . mir_coroutine_witnesses ( def) ;
402
438
}
403
439
let mir_borrowck = tcx. mir_borrowck ( def) ;
440
+ let impossible_predicates = tcx. const_prop_lint ( def) ;
404
441
405
442
let is_fn_like = tcx. def_kind ( def) . is_fn_like ( ) ;
406
443
if is_fn_like {
@@ -415,7 +452,30 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
415
452
if let Some ( error_reported) = mir_borrowck. tainted_by_errors {
416
453
body. tainted_by_errors = Some ( error_reported) ;
417
454
}
455
+ if impossible_predicates. is_err ( ) {
456
+ trace ! ( "found unsatisfiable predicates for {:?}" , body. source) ;
457
+ // Clear the body to only contain a single `unreachable` statement.
458
+ let bbs = body. basic_blocks . as_mut ( ) ;
459
+ bbs. raw . truncate ( 1 ) ;
460
+ bbs[ START_BLOCK ] . statements . clear ( ) ;
461
+ bbs[ START_BLOCK ] . terminator_mut ( ) . kind = TerminatorKind :: Unreachable ;
462
+ body. var_debug_info . clear ( ) ;
463
+ body. local_decls . raw . truncate ( body. arg_count + 1 ) ;
464
+ }
418
465
466
+ run_analysis_to_runtime_passes ( tcx, & mut body) ;
467
+
468
+ // Now that drop elaboration has been performed, we can check for
469
+ // unconditional drop recursion.
470
+ rustc_mir_build:: lints:: check_drop_recursion ( tcx, & body) ;
471
+
472
+ tcx. alloc_steal_mir ( body)
473
+ }
474
+
475
+ fn check_impossible_predicates (
476
+ tcx : TyCtxt < ' _ > ,
477
+ def : LocalDefId ,
478
+ ) -> Result < ( ) , HasImpossiblePredicates > {
419
479
// Check if it's even possible to satisfy the 'where' clauses
420
480
// for this item.
421
481
//
@@ -445,28 +505,15 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
445
505
// the normalization code (leading to cycle errors), since
446
506
// it's usually never invoked in this way.
447
507
let predicates = tcx
448
- . predicates_of ( body . source . def_id ( ) )
508
+ . predicates_of ( def )
449
509
. predicates
450
510
. iter ( )
451
511
. filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
452
512
if traits:: impossible_predicates ( tcx, traits:: elaborate ( tcx, predicates) . collect ( ) ) {
453
- trace ! ( "found unsatisfiable predicates for {:?}" , body. source) ;
454
- // Clear the body to only contain a single `unreachable` statement.
455
- let bbs = body. basic_blocks . as_mut ( ) ;
456
- bbs. raw . truncate ( 1 ) ;
457
- bbs[ START_BLOCK ] . statements . clear ( ) ;
458
- bbs[ START_BLOCK ] . terminator_mut ( ) . kind = TerminatorKind :: Unreachable ;
459
- body. var_debug_info . clear ( ) ;
460
- body. local_decls . raw . truncate ( body. arg_count + 1 ) ;
513
+ Err ( HasImpossiblePredicates )
514
+ } else {
515
+ Ok ( ( ) )
461
516
}
462
-
463
- run_analysis_to_runtime_passes ( tcx, & mut body) ;
464
-
465
- // Now that drop elaboration has been performed, we can check for
466
- // unconditional drop recursion.
467
- rustc_mir_build:: lints:: check_drop_recursion ( tcx, & body) ;
468
-
469
- tcx. alloc_steal_mir ( body)
470
517
}
471
518
472
519
// Made public such that `mir_drops_elaborated_and_const_checked` can be overridden
@@ -533,7 +580,6 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
533
580
& elaborate_box_derefs:: ElaborateBoxDerefs ,
534
581
& coroutine:: StateTransform ,
535
582
& add_retag:: AddRetag ,
536
- & Lint ( const_prop_lint:: ConstPropLint ) ,
537
583
] ;
538
584
pm:: run_passes_no_validate ( tcx, body, passes, Some ( MirPhase :: Runtime ( RuntimePhase :: Initial ) ) ) ;
539
585
}
@@ -678,6 +724,7 @@ fn promoted_mir(tcx: TyCtxt<'_>, def: LocalDefId) -> &IndexVec<Promoted, Body<'_
678
724
}
679
725
680
726
tcx. ensure_with_value ( ) . mir_borrowck ( def) ;
727
+ tcx. ensure ( ) . const_prop_lint_promoteds ( def) ;
681
728
let mut promoted = tcx. mir_promoted ( def) . 1 . steal ( ) ;
682
729
683
730
for body in & mut promoted {
0 commit comments