Wrap recursive predicate evaluation with ensure_sufficient_stack
I haven't been able to come up with a minimized test case for #76770, but this fixes a stack overflow in rustc as well.
This commit is contained in:
parent
2c69266c06
commit
6a96aea36a
1 changed files with 147 additions and 133 deletions
|
@ -450,6 +450,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
None => self.check_recursion_limit(&obligation, &obligation)?,
|
||||
}
|
||||
|
||||
ensure_sufficient_stack(|| {
|
||||
match obligation.predicate.skip_binders() {
|
||||
ty::PredicateAtom::Trait(t, _) => {
|
||||
let t = ty::Binder::bind(t);
|
||||
|
@ -483,7 +484,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
) {
|
||||
Some(mut obligations) => {
|
||||
self.add_depth(obligations.iter_mut(), obligation.recursion_depth);
|
||||
self.evaluate_predicates_recursively(previous_stack, obligations.into_iter())
|
||||
self.evaluate_predicates_recursively(
|
||||
previous_stack,
|
||||
obligations.into_iter(),
|
||||
)
|
||||
}
|
||||
None => Ok(EvaluatedToAmbig),
|
||||
},
|
||||
|
@ -557,7 +561,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
}
|
||||
|
||||
ty::PredicateAtom::ConstEquate(c1, c2) => {
|
||||
debug!("evaluate_predicate_recursively: equating consts c1={:?} c2={:?}", c1, c2);
|
||||
debug!(
|
||||
"evaluate_predicate_recursively: equating consts c1={:?} c2={:?}",
|
||||
c1, c2
|
||||
);
|
||||
|
||||
let evaluate = |c: &'tcx ty::Const<'tcx>| {
|
||||
if let ty::ConstKind::Unevaluated(def, substs, promoted) = c.val {
|
||||
|
@ -577,17 +584,23 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
|
||||
match (evaluate(c1), evaluate(c2)) {
|
||||
(Ok(c1), Ok(c2)) => {
|
||||
match self.infcx().at(&obligation.cause, obligation.param_env).eq(c1, c2) {
|
||||
match self
|
||||
.infcx()
|
||||
.at(&obligation.cause, obligation.param_env)
|
||||
.eq(c1, c2)
|
||||
{
|
||||
Ok(_) => Ok(EvaluatedToOk),
|
||||
Err(_) => Ok(EvaluatedToErr),
|
||||
}
|
||||
}
|
||||
(Err(ErrorHandled::Reported(ErrorReported)), _)
|
||||
| (_, Err(ErrorHandled::Reported(ErrorReported))) => Ok(EvaluatedToErr),
|
||||
(Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => span_bug!(
|
||||
(Err(ErrorHandled::Linted), _) | (_, Err(ErrorHandled::Linted)) => {
|
||||
span_bug!(
|
||||
obligation.cause.span(self.tcx()),
|
||||
"ConstEquate: const_eval_resolve returned an unexpected error"
|
||||
),
|
||||
)
|
||||
}
|
||||
(Err(ErrorHandled::TooGeneric), _) | (_, Err(ErrorHandled::TooGeneric)) => {
|
||||
Ok(EvaluatedToAmbig)
|
||||
}
|
||||
|
@ -597,6 +610,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
|||
bug!("TypeWellFormedFromEnv is only used for chalk")
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
fn evaluate_trait_predicate_recursively<'o>(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue