Remove the stored obligation in OverflowError to simplify things

We will shortly refactor things so that it is no longer needed
This commit is contained in:
Aravind Gollakota 2018-04-19 02:49:21 -05:00
parent e5535fc7dd
commit 5cb0372160
5 changed files with 24 additions and 26 deletions

View File

@ -831,7 +831,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
err.struct_error(self.tcx, span, "constant expression") err.struct_error(self.tcx, span, "constant expression")
} }
Overflow(_) => { Overflow => {
bug!("overflow should be handled before the `report_selection_error` path"); bug!("overflow should be handled before the `report_selection_error` path");
} }
}; };

View File

@ -362,8 +362,7 @@ pub enum SelectionError<'tcx> {
ty::error::TypeError<'tcx>), ty::error::TypeError<'tcx>),
TraitNotObjectSafe(DefId), TraitNotObjectSafe(DefId),
ConstEvalFailure(ConstEvalErr<'tcx>), ConstEvalFailure(ConstEvalErr<'tcx>),
// upon overflow, stores the obligation that hit the recursion limit Overflow,
Overflow(TraitObligation<'tcx>),
} }
pub struct FulfillmentError<'tcx> { pub struct FulfillmentError<'tcx> {

View File

@ -421,14 +421,13 @@ impl_stable_hash_for!(enum self::EvaluationResult {
EvaluatedToErr EvaluatedToErr
}); });
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Copy, Clone, Debug, PartialEq, Eq)]
/// Indicates that trait evaluation caused overflow. Stores the obligation /// Indicates that trait evaluation caused overflow.
/// that hit the recursion limit. pub struct OverflowError;
pub struct OverflowError<'tcx>(pub TraitObligation<'tcx>);
impl<'tcx> From<OverflowError<'tcx>> for SelectionError<'tcx> { impl<'tcx> From<OverflowError> for SelectionError<'tcx> {
fn from(OverflowError(o): OverflowError<'tcx>) -> SelectionError<'tcx> { fn from(OverflowError: OverflowError) -> SelectionError<'tcx> {
SelectionError::Overflow(o) SelectionError::Overflow
} }
} }
@ -573,7 +572,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
assert!(self.query_mode == TraitQueryMode::Standard); assert!(self.query_mode == TraitQueryMode::Standard);
let candidate = match self.candidate_from_obligation(&stack) { let candidate = match self.candidate_from_obligation(&stack) {
Err(SelectionError::Overflow(_)) => Err(SelectionError::Overflow) =>
bug!("Overflow should be caught earlier in standard query mode"), bug!("Overflow should be caught earlier in standard query mode"),
Err(e) => { return Err(e); }, Err(e) => { return Err(e); },
Ok(None) => { return Ok(None); }, Ok(None) => { return Ok(None); },
@ -581,7 +580,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
}; };
match self.confirm_candidate(obligation, candidate) { match self.confirm_candidate(obligation, candidate) {
Err(SelectionError::Overflow(_)) => Err(SelectionError::Overflow) =>
bug!("Overflow should be caught earlier in standard query mode"), bug!("Overflow should be caught earlier in standard query mode"),
Err(e) => Err(e), Err(e) => Err(e),
Ok(candidate) => Ok(Some(candidate)) Ok(candidate) => Ok(Some(candidate))
@ -619,7 +618,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
/// an `EvaluationResult`. /// an `EvaluationResult`.
pub fn evaluate_obligation_recursively(&mut self, pub fn evaluate_obligation_recursively(&mut self,
obligation: &PredicateObligation<'tcx>) obligation: &PredicateObligation<'tcx>)
-> Result<EvaluationResult, OverflowError<'tcx>> -> Result<EvaluationResult, OverflowError>
{ {
self.probe(|this, _| { self.probe(|this, _| {
this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation) this.evaluate_predicate_recursively(TraitObligationStackList::empty(), obligation)
@ -632,7 +631,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn evaluate_predicates_recursively<'a,'o,I>(&mut self, fn evaluate_predicates_recursively<'a,'o,I>(&mut self,
stack: TraitObligationStackList<'o, 'tcx>, stack: TraitObligationStackList<'o, 'tcx>,
predicates: I) predicates: I)
-> Result<EvaluationResult, OverflowError<'tcx>> -> Result<EvaluationResult, OverflowError>
where I : IntoIterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a where I : IntoIterator<Item=&'a PredicateObligation<'tcx>>, 'tcx:'a
{ {
let mut result = EvaluatedToOk; let mut result = EvaluatedToOk;
@ -654,7 +653,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn evaluate_predicate_recursively<'o>(&mut self, fn evaluate_predicate_recursively<'o>(&mut self,
previous_stack: TraitObligationStackList<'o, 'tcx>, previous_stack: TraitObligationStackList<'o, 'tcx>,
obligation: &PredicateObligation<'tcx>) obligation: &PredicateObligation<'tcx>)
-> Result<EvaluationResult, OverflowError<'tcx>> -> Result<EvaluationResult, OverflowError>
{ {
debug!("evaluate_predicate_recursively({:?})", debug!("evaluate_predicate_recursively({:?})",
obligation); obligation);
@ -775,7 +774,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn evaluate_trait_predicate_recursively<'o>(&mut self, fn evaluate_trait_predicate_recursively<'o>(&mut self,
previous_stack: TraitObligationStackList<'o, 'tcx>, previous_stack: TraitObligationStackList<'o, 'tcx>,
mut obligation: TraitObligation<'tcx>) mut obligation: TraitObligation<'tcx>)
-> Result<EvaluationResult, OverflowError<'tcx>> -> Result<EvaluationResult, OverflowError>
{ {
debug!("evaluate_trait_predicate_recursively({:?})", debug!("evaluate_trait_predicate_recursively({:?})",
obligation); obligation);
@ -810,7 +809,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn evaluate_stack<'o>(&mut self, fn evaluate_stack<'o>(&mut self,
stack: &TraitObligationStack<'o, 'tcx>) stack: &TraitObligationStack<'o, 'tcx>)
-> Result<EvaluationResult, OverflowError<'tcx>> -> Result<EvaluationResult, OverflowError>
{ {
// In intercrate mode, whenever any of the types are unbound, // In intercrate mode, whenever any of the types are unbound,
// there can always be an impl. Even if there are no impls in // there can always be an impl. Even if there are no impls in
@ -921,7 +920,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
match self.candidate_from_obligation(stack) { match self.candidate_from_obligation(stack) {
Ok(Some(c)) => self.evaluate_candidate(stack, &c), Ok(Some(c)) => self.evaluate_candidate(stack, &c),
Ok(None) => Ok(EvaluatedToAmbig), Ok(None) => Ok(EvaluatedToAmbig),
Err(Overflow(o)) => Err(OverflowError(o)), Err(Overflow) => Err(OverflowError),
Err(..) => Ok(EvaluatedToErr) Err(..) => Ok(EvaluatedToErr)
} }
} }
@ -960,7 +959,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn evaluate_candidate<'o>(&mut self, fn evaluate_candidate<'o>(&mut self,
stack: &TraitObligationStack<'o, 'tcx>, stack: &TraitObligationStack<'o, 'tcx>,
candidate: &SelectionCandidate<'tcx>) candidate: &SelectionCandidate<'tcx>)
-> Result<EvaluationResult, OverflowError<'tcx>> -> Result<EvaluationResult, OverflowError>
{ {
debug!("evaluate_candidate: depth={} candidate={:?}", debug!("evaluate_candidate: depth={} candidate={:?}",
stack.obligation.recursion_depth, candidate); stack.obligation.recursion_depth, candidate);
@ -1056,7 +1055,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
self.infcx().report_overflow_error(&stack.obligation, true); self.infcx().report_overflow_error(&stack.obligation, true);
}, },
TraitQueryMode::Canonical => { TraitQueryMode::Canonical => {
return Err(Overflow(stack.obligation.clone())); return Err(Overflow);
}, },
} }
} }
@ -1144,7 +1143,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
.vec .vec
.iter() .iter()
.map(|c| self.evaluate_candidate(stack, &c)) .map(|c| self.evaluate_candidate(stack, &c))
.collect::<Result<Vec<_>, OverflowError<'_>>>()? .collect::<Result<Vec<_>, OverflowError>>()?
.iter() .iter()
.all(|r| !r.may_apply()); .all(|r| !r.may_apply());
if !candidate_set.ambiguous && no_candidates_apply { if !candidate_set.ambiguous && no_candidates_apply {
@ -1224,7 +1223,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
evaluation: eval, evaluation: eval,
})), })),
Ok(_) => Ok(None), Ok(_) => Ok(None),
Err(OverflowError(o)) => Err(Overflow(o)), Err(OverflowError) => Err(Overflow),
}) })
.collect(); .collect();
@ -1621,7 +1620,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
fn evaluate_where_clause<'o>(&mut self, fn evaluate_where_clause<'o>(&mut self,
stack: &TraitObligationStack<'o, 'tcx>, stack: &TraitObligationStack<'o, 'tcx>,
where_clause_trait_ref: ty::PolyTraitRef<'tcx>) where_clause_trait_ref: ty::PolyTraitRef<'tcx>)
-> Result<EvaluationResult, OverflowError<'tcx>> -> Result<EvaluationResult, OverflowError>
{ {
self.probe(move |this, _| { self.probe(move |this, _| {
match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) { match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {

View File

@ -177,7 +177,7 @@ impl<'a, 'tcx> Lift<'tcx> for traits::SelectionError<'a> {
super::ConstEvalFailure(ref err) => { super::ConstEvalFailure(ref err) => {
tcx.lift(err).map(super::ConstEvalFailure) tcx.lift(err).map(super::ConstEvalFailure)
} }
super::Overflow(_) => bug!() // FIXME: ape ConstEvalFailure? super::Overflow => bug!() // FIXME: ape ConstEvalFailure?
} }
} }
} }

View File

@ -32,8 +32,8 @@ crate fn evaluate_obligation<'tcx>(
match selcx.evaluate_obligation_recursively(&obligation) { match selcx.evaluate_obligation_recursively(&obligation) {
Ok(result) => result, Ok(result) => result,
Err(OverflowError(o)) => { Err(OverflowError) => {
infcx.report_overflow_error(&o, true) infcx.report_overflow_error(&obligation, true)
} }
} }
}) })