Skip to content

Commit 68b4257

Browse files
committed
Revert "remove pred_known_to_hold_modulo_regions"
This reverts commit 399a258.
1 parent 54f8db8 commit 68b4257

File tree

1 file changed

+47
-3
lines changed
  • compiler/rustc_trait_selection/src/traits

1 file changed

+47
-3
lines changed

compiler/rustc_trait_selection/src/traits/mod.rs

+47-3
Original file line numberDiff line numberDiff line change
@@ -119,16 +119,60 @@ pub fn predicates_for_generics<'tcx>(
119119

120120
/// Determines whether the type `ty` is known to meet `bound` and
121121
/// returns true if so. Returns false if `ty` either does not meet
122-
/// `bound` or is not known to meet bound.
122+
/// `bound` or is not known to meet bound (note that this is
123+
/// conservative towards *no impl*, which is the opposite of the
124+
/// `evaluate` methods).
123125
pub fn type_known_to_meet_bound_modulo_regions<'tcx>(
124126
infcx: &InferCtxt<'tcx>,
125127
param_env: ty::ParamEnv<'tcx>,
126128
ty: Ty<'tcx>,
127129
def_id: DefId,
128130
) -> bool {
129131
let trait_ref = ty::TraitRef::new(infcx.tcx, def_id, [ty]);
130-
let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, trait_ref);
131-
infcx.predicate_must_hold_modulo_regions(&obligation)
132+
pred_known_to_hold_modulo_regions(infcx, param_env, trait_ref)
133+
}
134+
135+
/// FIXME(@lcnr): this function doesn't seem right and shouldn't exist?
136+
///
137+
/// Ping me on zulip if you want to use this method and need help with finding
138+
/// an appropriate replacement.
139+
#[instrument(level = "debug", skip(infcx, param_env, pred), ret)]
140+
fn pred_known_to_hold_modulo_regions<'tcx>(
141+
infcx: &InferCtxt<'tcx>,
142+
param_env: ty::ParamEnv<'tcx>,
143+
pred: impl ToPredicate<'tcx>,
144+
) -> bool {
145+
let obligation = Obligation::new(infcx.tcx, ObligationCause::dummy(), param_env, pred);
146+
147+
let result = infcx.evaluate_obligation_no_overflow(&obligation);
148+
debug!(?result);
149+
150+
if result.must_apply_modulo_regions() {
151+
true
152+
} else if result.may_apply() {
153+
// Sometimes obligations are ambiguous because the recursive evaluator
154+
// is not smart enough, so we fall back to fulfillment when we're not certain
155+
// that an obligation holds or not. Even still, we must make sure that
156+
// the we do no inference in the process of checking this obligation.
157+
let goal = infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
158+
infcx.probe(|_| {
159+
let ocx = ObligationCtxt::new(infcx);
160+
ocx.register_obligation(obligation);
161+
162+
let errors = ocx.select_all_or_error();
163+
match errors.as_slice() {
164+
// Only known to hold if we did no inference.
165+
[] => infcx.shallow_resolve(goal) == goal,
166+
167+
errors => {
168+
debug!(?errors);
169+
false
170+
}
171+
}
172+
})
173+
} else {
174+
false
175+
}
132176
}
133177

134178
#[instrument(level = "debug", skip(tcx, elaborated_env))]

0 commit comments

Comments
 (0)