@@ -390,6 +390,50 @@ fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &
390
390
body. tainted_by_errors = Some ( error_reported) ;
391
391
}
392
392
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
+
393
437
run_analysis_to_runtime_passes ( tcx, & mut body) ;
394
438
395
439
tcx. alloc_steal_mir ( body)
@@ -482,56 +526,6 @@ fn run_optimization_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
482
526
WithMinOptLevel ( 1 , x)
483
527
}
484
528
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
-
535
529
// The main optimizations that we do on MIR.
536
530
pm:: run_passes (
537
531
tcx,
0 commit comments