@@ -142,35 +142,36 @@ pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
142142fn pred_known_to_hold_modulo_regions < ' tcx > (
143143 infcx : & InferCtxt < ' tcx > ,
144144 param_env : ty:: ParamEnv < ' tcx > ,
145- pred : impl ToPredicate < ' tcx > + TypeVisitable < TyCtxt < ' tcx > > ,
145+ pred : impl ToPredicate < ' tcx > ,
146146) -> bool {
147- let has_non_region_infer = pred. has_non_region_infer ( ) ;
148147 let obligation = Obligation :: new ( infcx. tcx , ObligationCause :: dummy ( ) , param_env, pred) ;
149148
150149 let result = infcx. evaluate_obligation_no_overflow ( & obligation) ;
151150 debug ! ( ?result) ;
152151
153- if result. must_apply_modulo_regions ( ) && !has_non_region_infer {
152+ if result. must_apply_modulo_regions ( ) {
154153 true
155154 } else if result. may_apply ( ) {
156- // Because of inference "guessing", selection can sometimes claim
157- // to succeed while the success requires a guess. To ensure
158- // this function's result remains infallible, we must confirm
159- // that guess. While imperfect, I believe this is sound.
160-
161- // The handling of regions in this area of the code is terrible,
162- // see issue #29149. We should be able to improve on this with
163- // NLL.
164- let ocx = ObligationCtxt :: new ( infcx) ;
165- ocx. register_obligation ( obligation) ;
166- let errors = ocx. select_all_or_error ( ) ;
167- match errors. as_slice ( ) {
168- [ ] => true ,
169- errors => {
170- debug ! ( ?errors) ;
171- false
155+ // Sometimes obligations are ambiguous because the recursive evaluator
156+ // is not smart enough, so we fall back to fulfillment when we're not certain
157+ // that an obligation holds or not. Even still, we must make sure that
158+ // the we do no inference in the process of checking this obligation.
159+ let goal = infcx. resolve_vars_if_possible ( ( obligation. predicate , obligation. param_env ) ) ;
160+ infcx. probe ( |_| {
161+ let ocx = ObligationCtxt :: new_in_snapshot ( infcx) ;
162+ ocx. register_obligation ( obligation) ;
163+
164+ let errors = ocx. select_all_or_error ( ) ;
165+ match errors. as_slice ( ) {
166+ // Only known to hold if we did no inference.
167+ [ ] => infcx. shallow_resolve ( goal) == goal,
168+
169+ errors => {
170+ debug ! ( ?errors) ;
171+ false
172+ }
172173 }
173- }
174+ } )
174175 } else {
175176 false
176177 }
0 commit comments