hir_ty/next_solver/infer/snapshot/
mod.rs1use ena::undo_log::UndoLogs;
4use rustc_type_ir::UniverseIndex;
5use tracing::{debug, instrument};
6
7use super::InferCtxt;
8use super::region_constraints::RegionSnapshot;
9
10pub(crate) mod undo_log;
11
12use undo_log::{Snapshot, UndoLog};
13
14#[must_use = "once you start a snapshot, you should always consume it"]
15pub struct CombinedSnapshot {
16 pub(super) undo_snapshot: Snapshot,
17 region_constraints_snapshot: RegionSnapshot,
18 universe: UniverseIndex,
19}
20
21struct VariableLengths {
22 region_constraints_len: usize,
23 type_var_len: usize,
24 int_var_len: usize,
25 float_var_len: usize,
26 const_var_len: usize,
27}
28
29impl<'db> InferCtxt<'db> {
30 fn variable_lengths(&self) -> VariableLengths {
31 let mut inner = self.inner.borrow_mut();
32 VariableLengths {
33 region_constraints_len: inner.unwrap_region_constraints().num_region_vars(),
34 type_var_len: inner.type_variables().num_vars(),
35 int_var_len: inner.int_unification_table().len(),
36 float_var_len: inner.float_unification_table().len(),
37 const_var_len: inner.const_unification_table().len(),
38 }
39 }
40
41 pub fn in_snapshot(&self) -> bool {
42 UndoLogs::<UndoLog<'db>>::in_snapshot(&self.inner.borrow_mut().undo_log)
43 }
44
45 pub fn num_open_snapshots(&self) -> usize {
46 UndoLogs::<UndoLog<'db>>::num_open_snapshots(&self.inner.borrow_mut().undo_log)
47 }
48
49 fn start_snapshot(&self) -> CombinedSnapshot {
50 debug!("start_snapshot()");
51
52 let mut inner = self.inner.borrow_mut();
53
54 CombinedSnapshot {
55 undo_snapshot: inner.undo_log.start_snapshot(),
56 region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(),
57 universe: self.universe(),
58 }
59 }
60
61 #[instrument(skip(self, snapshot), level = "debug")]
62 fn rollback_to(&self, snapshot: CombinedSnapshot) {
63 let CombinedSnapshot { undo_snapshot, region_constraints_snapshot, universe } = snapshot;
64
65 self.universe.set(universe);
66
67 let mut inner = self.inner.borrow_mut();
68 inner.rollback_to(undo_snapshot);
69 inner.unwrap_region_constraints().rollback_to(region_constraints_snapshot);
70 }
71
72 #[instrument(skip(self, snapshot), level = "debug")]
73 fn commit_from(&self, snapshot: CombinedSnapshot) {
74 let CombinedSnapshot { undo_snapshot, region_constraints_snapshot: _, universe: _ } =
75 snapshot;
76
77 self.inner.borrow_mut().commit(undo_snapshot);
78 }
79
80 #[instrument(skip(self, f), level = "debug")]
82 pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
83 where
84 F: FnOnce(&CombinedSnapshot) -> Result<T, E>,
85 {
86 let snapshot = self.start_snapshot();
87 let r = f(&snapshot);
88 debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
89 match r {
90 Ok(_) => {
91 self.commit_from(snapshot);
92 }
93 Err(_) => {
94 self.rollback_to(snapshot);
95 }
96 }
97 r
98 }
99
100 #[instrument(skip(self, f), level = "debug")]
102 pub fn probe<R, F>(&self, f: F) -> R
103 where
104 F: FnOnce(&CombinedSnapshot) -> R,
105 {
106 let snapshot = self.start_snapshot();
107 let r = f(&snapshot);
108 self.rollback_to(snapshot);
109 r
110 }
111}