track if any region constraints involved placeholders
This commit is contained in:
parent
13ea9b877c
commit
2c17af0bf7
3 changed files with 33 additions and 14 deletions
|
@ -867,10 +867,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
||||||
r
|
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(
|
pub fn region_constraints_added_in_snapshot(
|
||||||
&self,
|
&self,
|
||||||
snapshot: &CombinedSnapshot<'a, 'tcx>,
|
snapshot: &CombinedSnapshot<'a, 'tcx>,
|
||||||
) -> bool {
|
) -> Option<bool> {
|
||||||
self.borrow_region_constraints().region_constraints_added_in_snapshot(
|
self.borrow_region_constraints().region_constraints_added_in_snapshot(
|
||||||
&snapshot.region_constraints_snapshot,
|
&snapshot.region_constraints_snapshot,
|
||||||
)
|
)
|
||||||
|
|
|
@ -128,6 +128,16 @@ pub enum Constraint<'tcx> {
|
||||||
RegSubReg(Region<'tcx>, Region<'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
|
/// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
|
||||||
/// associated type) must outlive the region `R`. `T` is known to
|
/// associated type) must outlive the region `R`. `T` is known to
|
||||||
/// outlive `RS`. Therefore verify that `R <= RS[i]` for some
|
/// outlive `RS`. Therefore verify that `R <= RS[i]` for some
|
||||||
|
@ -324,6 +334,8 @@ impl TaintDirections {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub struct ConstraintInfo {}
|
||||||
|
|
||||||
impl<'tcx> RegionConstraintCollector<'tcx> {
|
impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self::default()
|
Self::default()
|
||||||
|
@ -485,7 +497,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||||
) -> RegionVid {
|
) -> RegionVid {
|
||||||
let vid = self.var_infos.push(RegionVariableInfo { origin, universe });
|
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 });
|
.new_key(unify_key::RegionVidKey { min_vid: vid });
|
||||||
assert_eq!(vid, u_vid);
|
assert_eq!(vid, u_vid);
|
||||||
if self.in_snapshot() {
|
if self.in_snapshot() {
|
||||||
|
@ -517,7 +530,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||||
|
|
||||||
assert!(self.in_snapshot());
|
assert!(self.in_snapshot());
|
||||||
|
|
||||||
let constraints_to_kill: Vec<usize> = self.undo_log
|
let constraints_to_kill: Vec<usize> = self
|
||||||
|
.undo_log
|
||||||
.iter()
|
.iter()
|
||||||
.enumerate()
|
.enumerate()
|
||||||
.rev()
|
.rev()
|
||||||
|
@ -820,17 +834,18 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
|
||||||
.filter_map(|&elt| match elt {
|
.filter_map(|&elt| match elt {
|
||||||
AddVar(vid) => Some(vid),
|
AddVar(vid) => Some(vid),
|
||||||
_ => None,
|
_ => 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..]
|
self.undo_log[mark.length..]
|
||||||
.iter()
|
.iter()
|
||||||
.any(|&elt| match elt {
|
.map(|&elt| match elt {
|
||||||
AddConstraint(_) => true,
|
AddConstraint(constraint) => Some(constraint.involves_placeholders()),
|
||||||
_ => false,
|
_ => None,
|
||||||
})
|
}).max()
|
||||||
|
.unwrap_or(None)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -639,10 +639,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||||
) -> Result<EvaluationResult, OverflowError> {
|
) -> Result<EvaluationResult, OverflowError> {
|
||||||
self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
|
self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
|
||||||
let result = op(self)?;
|
let result = op(self)?;
|
||||||
if !self.infcx.region_constraints_added_in_snapshot(snapshot) {
|
match self.infcx.region_constraints_added_in_snapshot(snapshot) {
|
||||||
Ok(result)
|
None => Ok(result),
|
||||||
} else {
|
Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),
|
||||||
Ok(result.max(EvaluatedToOkModuloRegions))
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue