@@ -733,12 +733,47 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
733
733
. caller_bounds ( )
734
734
. iter ( )
735
735
. filter ( |bound| match bound. kind ( ) . skip_binder ( ) {
736
- ty:: PredicateKind :: RegionOutlives ( _) | ty:: PredicateKind :: TypeOutlives ( _) => {
737
- false
736
+ predicate @ ty:: PredicateKind :: RegionOutlives ( _) => {
737
+ // A bound involving early-bound regions
738
+ // (e.g. `fn foo<'a, 'b>() where 'a: 'b or
739
+ // `fn bar<'a>() where 'a: 'static
740
+ //)
741
+ // cannot affect the evaluation of a predicate with no
742
+ // free regions. Such a predicate only gives us information
743
+ // about some specific caller-chosen lifetime, and does not
744
+ // give us any information about any bound regions within
745
+ // our predicate (e.g. `for<'a> T: MyTrait<'a>`). Since
746
+ // we checked above that our predicate does not include any
747
+ // free regions (which includes early-bound regions), we know
748
+ // that it's safe to discard a predicate involving only
749
+ // early-bound regions.
750
+ //
751
+ // If a `RegionOutLives` predicate has any late-bound regions,
752
+ // we choose to keep it. This might be overly conservative,
753
+ // but should be safe in all cases.
754
+ predicate. has_late_bound_regions ( )
738
755
}
756
+ // If we have a predicate like `T: 'static`, then we need to keep
757
+ // it, since it could legitimately affect the evaluation of our predicate.
758
+ // For exmaple, we could be evaluating `T: MyTrait`, and find
759
+ // `impl<T: 'static> MyTrait for T {}`.
760
+ //
761
+ // We also keep any `TypeOutlives` predicates involving any late-bound
762
+ // regions. This is probably overly conservative, but ensures that we don't
763
+ // run into any weird situations with impossible-to-satisfiy predicates
764
+ // (e.g. `for<'a> &'a u8: 'static).
765
+ predicate @ ty:: PredicateKind :: TypeOutlives ( outlives) => {
766
+ * outlives. 1 == ty:: ReStatic || predicate. has_late_bound_regions ( )
767
+ }
768
+ // We assume that all other bounds can potentially affect
769
+ // the evaluation of our predicates, so we keep them
739
770
_ => true ,
740
771
} )
741
772
. collect ( ) ;
773
+
774
+ // Replace the `ParamEnv` with a new one, which differs
775
+ // only be the removal of some of the caller bounds. This will
776
+ // allow us to use the global cache in more cases.
742
777
obligation. param_env = ty:: ParamEnv :: new (
743
778
self . tcx ( ) . intern_predicates ( & new_bounds) ,
744
779
obligation. param_env . reveal ( ) ,
0 commit comments