@@ -390,6 +390,50 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
390390 body. tainted_by_errors = Some ( error_reported) ;
391391 }
392392
393+ // Check if it's even possible to satisfy the 'where' clauses
394+ // for this item.
395+ //
396+ // This branch will never be taken for any normal function.
397+ // However, it's possible to `#!feature(trivial_bounds)]` to write
398+ // a function with impossible to satisfy clauses, e.g.:
399+ // `fn foo() where String: Copy {}`
400+ //
401+ // We don't usually need to worry about this kind of case,
402+ // since we would get a compilation error if the user tried
403+ // to call it. However, since we optimize even without any
404+ // calls to the function, we need to make sure that it even
405+ // makes sense to try to evaluate the body.
406+ //
407+ // If there are unsatisfiable where clauses, then all bets are
408+ // off, and we just give up.
409+ //
410+ // We manually filter the predicates, skipping anything that's not
411+ // "global". We are in a potentially generic context
412+ // (e.g. we are evaluating a function without substituting generic
413+ // parameters, so this filtering serves two purposes:
414+ //
415+ // 1. We skip evaluating any predicates that we would
416+ // never be able prove are unsatisfiable (e.g. `<T as Foo>`
417+ // 2. We avoid trying to normalize predicates involving generic
418+ // parameters (e.g. `<T as Foo>::MyItem`). This can confuse
419+ // the normalization code (leading to cycle errors), since
420+ // it's usually never invoked in this way.
421+ let predicates = tcx
422+ . predicates_of ( body. source . def_id ( ) )
423+ . predicates
424+ . iter ( )
425+ . filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
426+ if traits:: impossible_predicates ( tcx, traits:: elaborate ( tcx, predicates) . collect ( ) ) {
427+ trace ! ( "found unsatisfiable predicates for {:?}" , body. source) ;
428+ // Clear the body to only contain a single `unreachable` statement.
429+ let bbs = body. basic_blocks . as_mut ( ) ;
430+ bbs. raw . truncate ( 1 ) ;
431+ bbs[ START_BLOCK ] . statements . clear ( ) ;
432+ bbs[ START_BLOCK ] . terminator_mut ( ) . kind = TerminatorKind :: Unreachable ;
433+ body. var_debug_info . clear ( ) ;
434+ body. local_decls . raw . truncate ( body. arg_count + 1 ) ;
435+ }
436+
393437 run_analysis_to_runtime_passes ( tcx, & mut body) ;
394438
395439 tcx. alloc_steal_mir ( body)
@@ -482,56 +526,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
482526 WithMinOptLevel ( 1 , x)
483527 }
484528
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 optimize even without any
495- // calls to the function, we need to make sure that it even
496- // makes sense to try to evaluate the body.
497- //
498- // If there are unsatisfiable where clauses, then all bets are
499- // off, and we just give up.
500- //
501- // We manually filter the predicates, skipping anything that's not
502- // "global". We are in a potentially generic context
503- // (e.g. we are evaluating a function without substituting generic
504- // parameters, so this filtering serves two purposes:
505- //
506- // 1. We skip evaluating any predicates that we would
507- // never be able prove are unsatisfiable (e.g. `<T as Foo>`
508- // 2. We avoid trying to normalize predicates involving generic
509- // parameters (e.g. `<T as Foo>::MyItem`). This can confuse
510- // the normalization code (leading to cycle errors), since
511- // it's usually never invoked in this way.
512- let predicates = tcx
513- . predicates_of ( body. source . def_id ( ) )
514- . predicates
515- . iter ( )
516- . filter_map ( |( p, _) | if p. is_global ( ) { Some ( * p) } else { None } ) ;
517- if traits:: impossible_predicates ( tcx, traits:: elaborate ( tcx, predicates) . collect ( ) ) {
518- trace ! ( "optimizations skipped for {:?}: found unsatisfiable predicates" , body. source) ;
519- // Clear the body to only contain a single `unreachable` statement.
520- let bbs = body. basic_blocks . as_mut ( ) ;
521- bbs. raw . truncate ( 1 ) ;
522- bbs[ START_BLOCK ] . statements . clear ( ) ;
523- bbs[ START_BLOCK ] . terminator_mut ( ) . kind = TerminatorKind :: Unreachable ;
524- body. var_debug_info . clear ( ) ;
525- body. local_decls . raw . truncate ( body. arg_count + 1 ) ;
526- pm:: run_passes (
527- tcx,
528- body,
529- & [ & reveal_all:: RevealAll , & dump_mir:: Marker ( "PreCodegen" ) ] ,
530- Some ( MirPhase :: Runtime ( RuntimePhase :: Optimized ) ) ,
531- ) ;
532- return ;
533- }
534-
535529 // The main optimizations that we do on MIR.
536530 pm:: run_passes (
537531 tcx,
0 commit comments