@@ -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;
@@ -399,51 +400,12 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
399
400
body
400
401
}
401
402
402
- fn const_prop_lint ( tcx : TyCtxt < ' _ > , def : LocalDefId ) {
403
+ fn const_prop_lint ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> Result < ( ) , HasImpossiblePredicates > {
403
404
let ( body, _) = tcx. mir_promoted ( def) ;
404
405
let body = body. borrow ( ) ;
405
406
406
407
let mir_borrowck = tcx. mir_borrowck ( def) ;
407
408
408
- // If there are impossible bounds on the body being const prop linted,
409
- // the const eval logic used in const prop may ICE unexpectedly.
410
- let predicates = tcx
411
- . predicates_of ( body. source . def_id ( ) )
412
- . predicates
413
- . iter ( )
414
- . filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
415
- if !traits:: impossible_predicates ( tcx, traits:: elaborate ( tcx, predicates) . collect ( ) )
416
- && mir_borrowck. tainted_by_errors . is_none ( )
417
- && body. tainted_by_errors . is_none ( )
418
- {
419
- const_prop_lint:: ConstPropLint . run_lint ( tcx, & body) ;
420
- }
421
- }
422
-
423
- /// Obtain just the main MIR (no promoteds) and run some cleanups on it. This also runs
424
- /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't
425
- /// end up missing the source MIR due to stealing happening.
426
- fn mir_drops_elaborated_and_const_checked ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> & Steal < Body < ' _ > > {
427
- if tcx. is_coroutine ( def. to_def_id ( ) ) {
428
- tcx. ensure_with_value ( ) . mir_coroutine_witnesses ( def) ;
429
- }
430
- let mir_borrowck = tcx. mir_borrowck ( def) ;
431
- tcx. ensure ( ) . const_prop_lint ( def) ;
432
-
433
- let is_fn_like = tcx. def_kind ( def) . is_fn_like ( ) ;
434
- if is_fn_like {
435
- // Do not compute the mir call graph without said call graph actually being used.
436
- if pm:: should_run_pass ( tcx, & inline:: Inline ) {
437
- tcx. ensure_with_value ( ) . mir_inliner_callees ( ty:: InstanceDef :: Item ( def. to_def_id ( ) ) ) ;
438
- }
439
- }
440
-
441
- let ( body, _) = tcx. mir_promoted ( def) ;
442
- let mut body = body. steal ( ) ;
443
- if let Some ( error_reported) = mir_borrowck. tainted_by_errors {
444
- body. tainted_by_errors = Some ( error_reported) ;
445
- }
446
-
447
409
// Check if it's even possible to satisfy the 'where' clauses
448
410
// for this item.
449
411
//
@@ -478,6 +440,40 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
478
440
. iter ( )
479
441
. filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
480
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 {
481
477
trace ! ( "found unsatisfiable predicates for {:?}" , body. source) ;
482
478
// Clear the body to only contain a single `unreachable` statement.
483
479
let bbs = body. basic_blocks . as_mut ( ) ;
0 commit comments