use rustc_data_structures::undo_log::{Rollback, UndoLogs};
+/// Represents a single undo-able action that affects a type inference variable.
pub(crate) enum UndoLog<'tcx> {
EqRelation(sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>),
SubRelation(sv::UndoLog<ut::Delegate<ty::TyVid>>),
Values(sv::UndoLog<Delegate>),
}
+/// Convert from a specific kind of undo to the more general UndoLog
impl<'tcx> From<sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>> for UndoLog<'tcx> {
fn from(l: sv::UndoLog<ut::Delegate<TyVidEqKey<'tcx>>>) -> Self {
UndoLog::EqRelation(l)
}
}
+/// Convert from a specific kind of undo to the more general UndoLog
impl<'tcx> From<sv::UndoLog<ut::Delegate<ty::TyVid>>> for UndoLog<'tcx> {
fn from(l: sv::UndoLog<ut::Delegate<ty::TyVid>>) -> Self {
UndoLog::SubRelation(l)
}
}
+/// Convert from a specific kind of undo to the more general UndoLog
impl<'tcx> From<sv::UndoLog<Delegate>> for UndoLog<'tcx> {
fn from(l: sv::UndoLog<Delegate>) -> Self {
UndoLog::Values(l)
}
}
+/// Convert from a specific kind of undo to the more general UndoLog
impl<'tcx> From<Instantiate> for UndoLog<'tcx> {
fn from(l: Instantiate) -> Self {
UndoLog::Values(sv::UndoLog::Other(l))
}
pub struct TypeVariableTable<'a, 'tcx> {
- values: &'a mut sv::SnapshotVecStorage<Delegate>,
-
- eq_relations: &'a mut ut::UnificationTableStorage<TyVidEqKey<'tcx>>,
-
- sub_relations: &'a mut ut::UnificationTableStorage<ty::TyVid>,
+ storage: &'a mut TypeVariableStorage<'tcx>,
undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
}
}
}
-pub struct Snapshot<'tcx> {
- value_count: u32,
- _marker: PhantomData<&'tcx ()>,
-}
-
pub(crate) struct Instantiate {
vid: ty::TyVid,
}
}
}
+ #[inline]
pub(crate) fn with_log<'a>(
&'a mut self,
undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
) -> TypeVariableTable<'a, 'tcx> {
- let TypeVariableStorage { values, eq_relations, sub_relations } = self;
- TypeVariableTable { values, eq_relations, sub_relations, undo_log }
+ TypeVariableTable { storage: self, undo_log }
}
}
/// Note that this function does not return care whether
/// `vid` has been unified with something else or not.
pub fn var_diverges(&self, vid: ty::TyVid) -> bool {
- self.values.get(vid.index as usize).diverging
+ self.storage.values.get(vid.index as usize).diverging
}
/// Returns the origin that was given when `vid` was created.
/// Note that this function does not return care whether
/// `vid` has been unified with something else or not.
pub fn var_origin(&self, vid: ty::TyVid) -> &TypeVariableOrigin {
- &self.values.get(vid.index as usize).origin
+ &self.storage.values.get(vid.index as usize).origin
}
/// Records that `a == b`, depending on `dir`.
/// Returns the number of type variables created thus far.
pub fn num_vars(&self) -> usize {
- self.values.len()
+ self.storage.values.len()
}
/// Returns the "root" variable of `vid` in the `eq_relations`
}
}
- /// Creates a snapshot of the type variable state. This snapshot
- /// must later be committed (`commit()`) or rolled back
- /// (`rollback_to()`). Nested snapshots are permitted, but must
- /// be processed in a stack-like fashion.
- pub fn snapshot(&mut self) -> Snapshot<'tcx> {
- Snapshot { value_count: self.eq_relations().len() as u32, _marker: PhantomData }
- }
-
+ #[inline]
fn values(
&mut self,
) -> sv::SnapshotVec<Delegate, &mut Vec<TypeVariableData>, &mut InferCtxtUndoLogs<'tcx>> {
- self.values.with_log(self.undo_log)
+ self.storage.values.with_log(self.undo_log)
}
+ #[inline]
fn eq_relations(&mut self) -> super::UnificationTable<'_, 'tcx, TyVidEqKey<'tcx>> {
- self.eq_relations.with_log(self.undo_log)
+ self.storage.eq_relations.with_log(self.undo_log)
}
+ #[inline]
fn sub_relations(&mut self) -> super::UnificationTable<'_, 'tcx, ty::TyVid> {
- self.sub_relations.with_log(self.undo_log)
+ self.storage.sub_relations.with_log(self.undo_log)
}
/// Returns a range of the type variables created during the snapshot.
pub fn vars_since_snapshot(
&mut self,
- s: &Snapshot<'tcx>,
+ value_count: usize,
) -> (Range<TyVid>, Vec<TypeVariableOrigin>) {
- let range =
- TyVid { index: s.value_count }..TyVid { index: self.eq_relations().len() as u32 };
+ let range = TyVid { index: value_count as u32 }..TyVid { index: self.num_vars() as u32 };
(
range.start..range.end,
(range.start.index..range.end.index)
- .map(|index| self.values.get(index as usize).origin)
+ .map(|index| self.storage.values.get(index as usize).origin)
.collect(),
)
}
// quick check to see if this variable was
// created since the snapshot started or not.
let mut eq_relations = ut::UnificationTable::with_log(
- &mut *self.eq_relations,
+ &mut self.storage.eq_relations,
&mut *self.undo_log,
);
let escaping_type = match eq_relations.probe_value(vid) {
/// Returns indices of all variables that are not yet
/// instantiated.
pub fn unsolved_variables(&mut self) -> Vec<ty::TyVid> {
- (0..self.values.len())
+ (0..self.storage.values.len())
.filter_map(|i| {
let vid = ty::TyVid { index: i as u32 };
match self.probe(vid) {