@@ -1058,30 +1058,47 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
1058
1058
ty : Ty < ' tcx > ,
1059
1059
region : ty:: Region < ' tcx > ,
1060
1060
) -> Option < Vec < traits:: PredicateObligation < ' tcx > > > {
1061
- // Only attempt to satisfy placeholder-replaced higher-ranked outlives
1062
- if !region. is_placeholder ( ) {
1061
+ if ty. is_ty_infer ( ) {
1063
1062
return None ;
1064
1063
}
1065
1064
1066
1065
for caller_bound in param_env. caller_bounds ( ) {
1066
+ let ty:: PredicateKind :: TypeOutlives ( bound_outlives) =
1067
+ caller_bound. kind ( ) . skip_binder ( ) else { continue } ;
1068
+
1067
1069
// Only use WC bounds that are themselves of the form `for<'a> TY: 'a`
1068
- if let ty:: PredicateKind :: TypeOutlives ( bound_outlives) =
1069
- caller_bound. kind ( ) . skip_binder ( )
1070
- && bound_outlives. 1 . is_late_bound ( )
1071
- {
1072
- if let Ok ( obligations) = self . commit_if_ok :: < _ , TypeError < ' _ > , _ > ( |_| {
1073
- let ty:: OutlivesPredicate ( wc_ty, wc_region) = self . replace_bound_vars_with_fresh_vars (
1070
+ if !bound_outlives. 1 . is_late_bound ( ) {
1071
+ continue ;
1072
+ }
1073
+
1074
+ let satisfies = self . commit_if_ok :: < _ , ( ) , _ > ( |_| {
1075
+ let ty:: OutlivesPredicate ( wc_ty, wc_region) = self
1076
+ . replace_bound_vars_with_fresh_vars (
1074
1077
cause. span ,
1075
1078
LateBoundRegionConversionTime :: HigherRankedType ,
1076
1079
caller_bound. kind ( ) . rebind ( bound_outlives) ,
1077
1080
) ;
1078
- let t = self . at ( cause, param_env) . sub ( wc_ty, ty) ?;
1079
- let mut r = self . at ( cause, param_env) . eq ( wc_region, region) ?;
1081
+
1082
+ let mut r = self . at ( cause, param_env) . eq ( wc_region, region) . map_err ( |_| ( ) ) ?;
1083
+
1084
+ // Specifically use two snapshots here, so we can make sure _not_
1085
+ // to constrain the regions of `Ty` here. We probably should just
1086
+ // use some custom `replace_bound_vars_with_fresh_vars` that doesn't
1087
+ // replace `wc_region` with an infer variable, but eagerly replaces
1088
+ // it with `region` instead.
1089
+ self . commit_if_ok :: < _ , ( ) , _ > ( |snapshot| {
1090
+ let t = self . at ( cause, param_env) . eq ( wc_ty, ty) . map_err ( |_| ( ) ) ?;
1080
1091
r. obligations . extend ( t. into_obligations ( ) ) ;
1081
- Ok ( r. obligations )
1082
- } ) {
1083
- return Some ( obligations) ;
1084
- }
1092
+ if self . region_constraints_added_in_snapshot ( snapshot) . is_none ( ) {
1093
+ Ok ( r. obligations )
1094
+ } else {
1095
+ Err ( ( ) )
1096
+ }
1097
+ } )
1098
+ } ) ;
1099
+
1100
+ if let Ok ( obligations) = satisfies {
1101
+ return Some ( obligations) ;
1085
1102
}
1086
1103
}
1087
1104
0 commit comments