Track if EvalCtxt has been tainted, make sure it can't be used to make query responses after
This commit is contained in:
parent
b9fd498fa7
commit
4fd7739aac
2 changed files with 20 additions and 0 deletions
|
@ -57,6 +57,13 @@ pub struct EvalCtxt<'a, 'tcx> {
|
||||||
pub(super) search_graph: &'a mut SearchGraph<'tcx>,
|
pub(super) search_graph: &'a mut SearchGraph<'tcx>,
|
||||||
|
|
||||||
pub(super) nested_goals: NestedGoals<'tcx>,
|
pub(super) nested_goals: NestedGoals<'tcx>,
|
||||||
|
|
||||||
|
// Has this `EvalCtxt` errored out with `NoSolution` in `try_evaluate_added_goals`?
|
||||||
|
//
|
||||||
|
// If so, then it can no longer be used to make a canonical query response,
|
||||||
|
// since subsequent calls to `try_evaluate_added_goals` have possibly dropped
|
||||||
|
// ambiguous goals. Instead, use a probe.
|
||||||
|
tainted: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
|
@ -121,6 +128,7 @@ impl<'tcx> InferCtxtEvalExt<'tcx> for InferCtxt<'tcx> {
|
||||||
max_input_universe: ty::UniverseIndex::ROOT,
|
max_input_universe: ty::UniverseIndex::ROOT,
|
||||||
var_values: CanonicalVarValues::dummy(),
|
var_values: CanonicalVarValues::dummy(),
|
||||||
nested_goals: NestedGoals::new(),
|
nested_goals: NestedGoals::new(),
|
||||||
|
tainted: false,
|
||||||
};
|
};
|
||||||
let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal);
|
let result = ecx.evaluate_goal(IsNormalizesToHack::No, goal);
|
||||||
|
|
||||||
|
@ -172,6 +180,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||||
max_input_universe: canonical_goal.max_universe,
|
max_input_universe: canonical_goal.max_universe,
|
||||||
search_graph,
|
search_graph,
|
||||||
nested_goals: NestedGoals::new(),
|
nested_goals: NestedGoals::new(),
|
||||||
|
tainted: false,
|
||||||
};
|
};
|
||||||
ecx.compute_goal(goal)
|
ecx.compute_goal(goal)
|
||||||
})
|
})
|
||||||
|
@ -391,6 +400,10 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if response.is_err() {
|
||||||
|
self.tainted = true;
|
||||||
|
}
|
||||||
|
|
||||||
self.nested_goals = goals;
|
self.nested_goals = goals;
|
||||||
response
|
response
|
||||||
}
|
}
|
||||||
|
@ -404,6 +417,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
max_input_universe: self.max_input_universe,
|
max_input_universe: self.max_input_universe,
|
||||||
search_graph: self.search_graph,
|
search_graph: self.search_graph,
|
||||||
nested_goals: self.nested_goals.clone(),
|
nested_goals: self.nested_goals.clone(),
|
||||||
|
tainted: self.tainted,
|
||||||
};
|
};
|
||||||
self.infcx.probe(|_| f(&mut ecx))
|
self.infcx.probe(|_| f(&mut ecx))
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,6 +51,12 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
||||||
certainty: Certainty,
|
certainty: Certainty,
|
||||||
) -> QueryResult<'tcx> {
|
) -> QueryResult<'tcx> {
|
||||||
let goals_certainty = self.try_evaluate_added_goals()?;
|
let goals_certainty = self.try_evaluate_added_goals()?;
|
||||||
|
assert!(
|
||||||
|
!self.tainted,
|
||||||
|
"EvalCtxt is tainted -- nested goals may have been dropped in a \
|
||||||
|
previous call to `try_evaluate_added_goals!`"
|
||||||
|
);
|
||||||
|
|
||||||
let certainty = certainty.unify_with(goals_certainty);
|
let certainty = certainty.unify_with(goals_certainty);
|
||||||
|
|
||||||
let external_constraints = self.compute_external_query_constraints()?;
|
let external_constraints = self.compute_external_query_constraints()?;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue