@@ -35,6 +35,7 @@ use rustc_middle::mir::{
35
35
use rustc_middle:: ty:: query:: Providers ;
36
36
use rustc_middle:: ty:: { self , TyCtxt , TypeVisitableExt } ;
37
37
use rustc_span:: sym;
38
+ use rustc_trait_selection:: traits;
38
39
39
40
#[ macro_use]
40
41
mod pass_manager;
@@ -481,6 +482,54 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
481
482
WithMinOptLevel ( 1 , x)
482
483
}
483
484
485
+ // Check if it's even possible to satisfy the 'where' clauses
486
+ // for this item.
487
+ // This branch will never be taken for any normal function.
488
+ // However, it's possible to `#!feature(trivial_bounds)]` to write
489
+ // a function with impossible to satisfy clauses, e.g.:
490
+ // `fn foo() where String: Copy {}`
491
+ //
492
+ // We don't usually need to worry about this kind of case,
493
+ // since we would get a compilation error if the user tried
494
+ // to call it. However, since we can do const propagation
495
+ // even without any calls to the function, we need to make
496
+ // sure that it even makes sense to try to evaluate the body.
497
+ // If there are unsatisfiable where clauses, then all bets are
498
+ // off, and we just give up.
499
+ //
500
+ // We manually filter the predicates, skipping anything that's not
501
+ // "global". We are in a potentially generic context
502
+ // (e.g. we are evaluating a function without substituting generic
503
+ // parameters, so this filtering serves two purposes:
504
+ //
505
+ // 1. We skip evaluating any predicates that we would
506
+ // never be able prove are unsatisfiable (e.g. `<T as Foo>`
507
+ // 2. We avoid trying to normalize predicates involving generic
508
+ // parameters (e.g. `<T as Foo>::MyItem`). This can confuse
509
+ // the normalization code (leading to cycle errors), since
510
+ // it's usually never invoked in this way.
511
+ let predicates = tcx
512
+ . predicates_of ( body. source . def_id ( ) )
513
+ . predicates
514
+ . iter ( )
515
+ . filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
516
+ if traits:: impossible_predicates ( tcx, traits:: elaborate ( tcx, predicates) . collect ( ) ) {
517
+ trace ! ( "optimizations skipped for {:?}: found unsatisfiable predicates" , body. source) ;
518
+ pm:: run_passes (
519
+ tcx,
520
+ body,
521
+ & [
522
+ & reveal_all:: RevealAll ,
523
+ & simplify:: SimplifyCfg :: Final ,
524
+ & simplify:: SimplifyLocals :: Final ,
525
+ // Dump the end result for testing and debugging purposes.
526
+ & dump_mir:: Marker ( "PreCodegen" ) ,
527
+ ] ,
528
+ Some ( MirPhase :: Runtime ( RuntimePhase :: Optimized ) ) ,
529
+ ) ;
530
+ return ;
531
+ }
532
+
484
533
// The main optimizations that we do on MIR.
485
534
pm:: run_passes (
486
535
tcx,
0 commit comments