/// placeholder region. This is the first step of checking subtyping
/// when higher-ranked things are involved.
///
- /// **Important:** you must call this function from within a snapshot.
- /// Moreover, before committing the snapshot, you must eventually call
- /// either `plug_leaks` or `pop_placeholders` to remove the placeholder
- /// regions. If you rollback the snapshot (or are using a probe), then
- /// the pop occurs as part of the rollback, so an explicit call is not
- /// needed (but is also permitted).
- ///
- /// For more information about how placeholders and HRTBs work, see
+ /// **Important:** You have to be careful to not leak these placeholders,
+ /// for more information about how placeholders and HRTBs work, see
/// the [rustc dev guide].
///
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/traits/hrtb.html
/// We added a GLB/LUB "combination variable".
AddCombination(CombineMapType, TwoRegions<'tcx>),
-
- /// During freshening, we sometimes purge entries from the undo
- /// log in a kind of minisnapshot (unlike other snapshots, this
- /// purging actually takes place *on success*). In that case, we
- /// replace the corresponding entry with `Noop` so as to avoid the
- /// need to do a bunch of swapping. (We can't use `swap_remove` as
- /// the order of the vector is important.)
- Purged,
}
#[derive(Copy, Clone, PartialEq)]
fn rollback_undo_entry(&mut self, undo_entry: UndoLog<'tcx>) {
match undo_entry {
- Purged => {
- // nothing to do here
- }
AddVar(vid) => {
self.var_infos.pop().unwrap();
assert_eq!(self.var_infos.len(), vid.index() as usize);
self.var_infos[vid].origin
}
- /// Removes all the edges to/from the placeholder regions that are
- /// in `placeholders`. This is used after a higher-ranked operation
- /// completes to remove all trace of the placeholder regions
- /// created in that time.
- pub fn pop_placeholders(&mut self, placeholders: &FxHashSet<ty::Region<'tcx>>) {
- debug!("pop_placeholders(placeholders={:?})", placeholders);
-
- assert!(UndoLogs::<super::UndoLog<'_>>::in_snapshot(&self.undo_log));
-
- let constraints_to_kill: Vec<usize> = self
- .undo_log
- .iter()
- .enumerate()
- .rev()
- .filter(|&(_, undo_entry)| match undo_entry {
- super::UndoLog::RegionConstraintCollector(undo_entry) => {
- kill_constraint(placeholders, undo_entry)
- }
- _ => false,
- })
- .map(|(index, _)| index)
- .collect();
-
- for index in constraints_to_kill {
- let undo_entry = match &mut self.undo_log[index] {
- super::UndoLog::RegionConstraintCollector(undo_entry) => {
- mem::replace(undo_entry, Purged)
- }
- _ => unreachable!(),
- };
- self.rollback_undo_entry(undo_entry);
- }
-
- return;
-
- fn kill_constraint<'tcx>(
- placeholders: &FxHashSet<ty::Region<'tcx>>,
- undo_entry: &UndoLog<'tcx>,
- ) -> bool {
- match undo_entry {
- &AddConstraint(Constraint::VarSubVar(..)) => false,
- &AddConstraint(Constraint::RegSubVar(a, _)) => placeholders.contains(&a),
- &AddConstraint(Constraint::VarSubReg(_, b)) => placeholders.contains(&b),
- &AddConstraint(Constraint::RegSubReg(a, b)) => {
- placeholders.contains(&a) || placeholders.contains(&b)
- }
- &AddGiven(..) => false,
- &AddVerify(_) => false,
- &AddCombination(_, ref two_regions) => {
- placeholders.contains(&two_regions.a) || placeholders.contains(&two_regions.b)
- }
- &AddVar(..) | &Purged => false,
- }
- }
- }
-
fn add_constraint(&mut self, constraint: Constraint<'tcx>, origin: SubregionOrigin<'tcx>) {
// cannot add constraints once regions are resolved
debug!("RegionConstraintCollector: add_constraint({:?})", constraint);