mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-09 22:37:34 +00:00
track if any region constraints involved placeholders
This commit is contained in:
parent
13ea9b877c
commit
2c17af0bf7
@ -867,10 +867,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||
r
|
||||
}
|
||||
|
||||
/// Scan the constraints produced since `snapshot` began and returns:
|
||||
///
|
||||
/// - None -- if none of them involve "region outlives" constraints
|
||||
/// - Some(true) -- if there are `'a: 'b` constraints where `'a` or `'b` is a placehodler
|
||||
/// - Some(false) -- if there are `'a: 'b` constraints but none involve placeholders
|
||||
pub fn region_constraints_added_in_snapshot(
|
||||
&self,
|
||||
snapshot: &CombinedSnapshot<'a, 'tcx>,
|
||||
) -> bool {
|
||||
) -> Option<bool> {
|
||||
self.borrow_region_constraints().region_constraints_added_in_snapshot(
|
||||
&snapshot.region_constraints_snapshot,
|
||||
)
|
||||
|
@ -128,6 +128,16 @@ pub enum Constraint<'tcx> {
|
||||
RegSubReg(Region<'tcx>, Region<'tcx>),
|
||||
}
|
||||
|
||||
impl Constraint<'_> {
|
||||
pub fn involves_placeholders(&self) -> bool {
|
||||
match self {
|
||||
Constraint::VarSubVar(_, _) => false,
|
||||
Constraint::VarSubReg(_, r) | Constraint::RegSubVar(r, _) => r.is_placeholder(),
|
||||
Constraint::RegSubReg(r, s) => r.is_placeholder() || s.is_placeholder(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
|
||||
/// associated type) must outlive the region `R`. `T` is known to
|
||||
/// outlive `RS`. Therefore verify that `R <= RS[i]` for some
|
||||
@ -324,6 +334,8 @@ impl TaintDirections {
|
||||
}
|
||||
}
|
||||
|
||||
pub struct ConstraintInfo {}
|
||||
|
||||
impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||
pub fn new() -> Self {
|
||||
Self::default()
|
||||
@ -485,7 +497,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||
) -> RegionVid {
|
||||
let vid = self.var_infos.push(RegionVariableInfo { origin, universe });
|
||||
|
||||
let u_vid = self.unification_table
|
||||
let u_vid = self
|
||||
.unification_table
|
||||
.new_key(unify_key::RegionVidKey { min_vid: vid });
|
||||
assert_eq!(vid, u_vid);
|
||||
if self.in_snapshot() {
|
||||
@ -517,7 +530,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||
|
||||
assert!(self.in_snapshot());
|
||||
|
||||
let constraints_to_kill: Vec<usize> = self.undo_log
|
||||
let constraints_to_kill: Vec<usize> = self
|
||||
.undo_log
|
||||
.iter()
|
||||
.enumerate()
|
||||
.rev()
|
||||
@ -820,17 +834,18 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||
.filter_map(|&elt| match elt {
|
||||
AddVar(vid) => Some(vid),
|
||||
_ => None,
|
||||
})
|
||||
.collect()
|
||||
}).collect()
|
||||
}
|
||||
|
||||
pub fn region_constraints_added_in_snapshot(&self, mark: &RegionSnapshot) -> bool {
|
||||
/// See [`RegionInference::region_constraints_added_in_snapshot`]
|
||||
pub fn region_constraints_added_in_snapshot(&self, mark: &RegionSnapshot) -> Option<bool> {
|
||||
self.undo_log[mark.length..]
|
||||
.iter()
|
||||
.any(|&elt| match elt {
|
||||
AddConstraint(_) => true,
|
||||
_ => false,
|
||||
})
|
||||
.map(|&elt| match elt {
|
||||
AddConstraint(constraint) => Some(constraint.involves_placeholders()),
|
||||
_ => None,
|
||||
}).max()
|
||||
.unwrap_or(None)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -639,10 +639,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
) -> Result<EvaluationResult, OverflowError> {
|
||||
self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
|
||||
let result = op(self)?;
|
||||
if !self.infcx.region_constraints_added_in_snapshot(snapshot) {
|
||||
Ok(result)
|
||||
} else {
|
||||
Ok(result.max(EvaluatedToOkModuloRegions))
|
||||
match self.infcx.region_constraints_added_in_snapshot(snapshot) {
|
||||
None => Ok(result),
|
||||
Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user