@@ -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;
@@ -399,51 +400,12 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
399400 body
400401}
401402
402- fn const_prop_lint ( tcx : TyCtxt < ' _ > , def : LocalDefId ) {
403+ fn const_prop_lint ( tcx : TyCtxt < ' _ > , def : LocalDefId ) -> Result < ( ) , HasImpossiblePredicates > {
403404 let ( body, _) = tcx. mir_promoted ( def) ;
404405 let body = body. borrow ( ) ;
405406
406407 let mir_borrowck = tcx. mir_borrowck ( def) ;
407408
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-
447409 // Check if it's even possible to satisfy the 'where' clauses
448410 // for this item.
449411 //
@@ -478,6 +440,40 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
478440 . iter ( )
479441 . filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
480442 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 {
481477 trace ! ( "found unsatisfiable predicates for {:?}" , body. source) ;
482478 // Clear the body to only contain a single `unreachable` statement.
483479 let bbs = body. basic_blocks . as_mut ( ) ;
0 commit comments