rustc_infer/infer/snapshot/
mod.rs1use rustc_data_structures::undo_log::UndoLogs;
2use rustc_middle::ty;
3use tracing::{debug, instrument};
4
5use super::InferCtxt;
6use super::region_constraints::RegionSnapshot;
7
8pub(crate) mod fudge;
9pub(crate) mod undo_log;
10
11use undo_log::{Snapshot, UndoLog};
12
13#[must_use = "once you start a snapshot, you should always consume it"]
14pub struct CombinedSnapshot<'tcx> {
15 pub(super) undo_snapshot: Snapshot<'tcx>,
16 region_constraints_snapshot: RegionSnapshot,
17 universe: ty::UniverseIndex,
18}
19
20struct VariableLengths {
21 region_constraints_len: usize,
22 type_var_len: usize,
23 int_var_len: usize,
24 float_var_len: usize,
25 const_var_len: usize,
26}
27
28impl<'tcx> InferCtxt<'tcx> {
29 fn variable_lengths(&self) -> VariableLengths {
30 let mut inner = self.inner.borrow_mut();
31 VariableLengths {
32 region_constraints_len: inner.unwrap_region_constraints().num_region_vars(),
33 type_var_len: inner.type_variables().num_vars(),
34 int_var_len: inner.int_unification_table().len(),
35 float_var_len: inner.float_unification_table().len(),
36 const_var_len: inner.const_unification_table().len(),
37 }
38 }
39
40 pub fn in_snapshot(&self) -> bool {
41 UndoLogs::<UndoLog<'tcx>>::in_snapshot(&self.inner.borrow_mut().undo_log)
42 }
43
44 pub fn num_open_snapshots(&self) -> usize {
45 UndoLogs::<UndoLog<'tcx>>::num_open_snapshots(&self.inner.borrow_mut().undo_log)
46 }
47
48 fn start_snapshot(&self) -> CombinedSnapshot<'tcx> {
49 {
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/snapshot/mod.rs:49",
"rustc_infer::infer::snapshot", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/snapshot/mod.rs"),
::tracing_core::__macro_support::Option::Some(49u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::snapshot"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("start_snapshot()")
as &dyn Value))])
});
} else { ; }
};debug!("start_snapshot()");
50
51 let mut inner = self.inner.borrow_mut();
52
53 CombinedSnapshot {
54 undo_snapshot: inner.undo_log.start_snapshot(),
55 region_constraints_snapshot: inner.unwrap_region_constraints().start_snapshot(),
56 universe: self.universe(),
57 }
58 }
59
60 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("rollback_to",
"rustc_infer::infer::snapshot", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/snapshot/mod.rs"),
::tracing_core::__macro_support::Option::Some(60u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::snapshot"),
::tracing_core::field::FieldSet::new(&[],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{ meta.fields().value_set(&[]) })
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: () = loop {};
return __tracing_attr_fake_return;
}
{
let CombinedSnapshot {
undo_snapshot, region_constraints_snapshot, universe } =
snapshot;
self.universe.set(universe);
let mut inner = self.inner.borrow_mut();
inner.rollback_to(undo_snapshot);
inner.unwrap_region_constraints().rollback_to(region_constraints_snapshot);
}
}
}#[instrument(skip(self, snapshot), level = "debug")]
61 fn rollback_to(&self, snapshot: CombinedSnapshot<'tcx>) {
62 let CombinedSnapshot { undo_snapshot, region_constraints_snapshot, universe } = snapshot;
63
64 self.universe.set(universe);
65
66 let mut inner = self.inner.borrow_mut();
67 inner.rollback_to(undo_snapshot);
68 inner.unwrap_region_constraints().rollback_to(region_constraints_snapshot);
69 }
70
71 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("commit_from",
"rustc_infer::infer::snapshot", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/snapshot/mod.rs"),
::tracing_core::__macro_support::Option::Some(71u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::snapshot"),
::tracing_core::field::FieldSet::new(&[],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{ meta.fields().value_set(&[]) })
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: () = loop {};
return __tracing_attr_fake_return;
}
{
let CombinedSnapshot {
undo_snapshot, region_constraints_snapshot: _, universe: _
} = snapshot;
self.inner.borrow_mut().commit(undo_snapshot);
}
}
}#[instrument(skip(self, snapshot), level = "debug")]
72 fn commit_from(&self, snapshot: CombinedSnapshot<'tcx>) {
73 let CombinedSnapshot { undo_snapshot, region_constraints_snapshot: _, universe: _ } =
74 snapshot;
75
76 self.inner.borrow_mut().commit(undo_snapshot);
77 }
78
79 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("commit_if_ok",
"rustc_infer::infer::snapshot", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/snapshot/mod.rs"),
::tracing_core::__macro_support::Option::Some(80u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::snapshot"),
::tracing_core::field::FieldSet::new(&[],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{ meta.fields().value_set(&[]) })
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: Result<T, E> = loop {};
return __tracing_attr_fake_return;
}
{
let snapshot = self.start_snapshot();
let r = f(&snapshot);
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("event compiler/rustc_infer/src/infer/snapshot/mod.rs:87",
"rustc_infer::infer::snapshot", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/snapshot/mod.rs"),
::tracing_core::__macro_support::Option::Some(87u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::snapshot"),
::tracing_core::field::FieldSet::new(&["message"],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::EVENT)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let enabled =
::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{
let interest = __CALLSITE.interest();
!interest.is_never() &&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest)
};
if enabled {
(|value_set: ::tracing::field::ValueSet|
{
let meta = __CALLSITE.metadata();
::tracing::Event::dispatch(meta, &value_set);
;
})({
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = __CALLSITE.metadata().fields().iter();
__CALLSITE.metadata().fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&format_args!("commit_if_ok() -- r.is_ok() = {0}",
r.is_ok()) as &dyn Value))])
});
} else { ; }
};
match r {
Ok(_) => { self.commit_from(snapshot); }
Err(_) => { self.rollback_to(snapshot); }
}
r
}
}
}#[instrument(skip(self, f), level = "debug")]
81 pub fn commit_if_ok<T, E, F>(&self, f: F) -> Result<T, E>
82 where
83 F: FnOnce(&CombinedSnapshot<'tcx>) -> Result<T, E>,
84 {
85 let snapshot = self.start_snapshot();
86 let r = f(&snapshot);
87 debug!("commit_if_ok() -- r.is_ok() = {}", r.is_ok());
88 match r {
89 Ok(_) => {
90 self.commit_from(snapshot);
91 }
92 Err(_) => {
93 self.rollback_to(snapshot);
94 }
95 }
96 r
97 }
98
99 #[allow(clippy :: suspicious_else_formatting)]
{
let __tracing_attr_span;
let __tracing_attr_guard;
if ::tracing::Level::DEBUG <= ::tracing::level_filters::STATIC_MAX_LEVEL
&&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() ||
{ false } {
__tracing_attr_span =
{
use ::tracing::__macro_support::Callsite as _;
static __CALLSITE: ::tracing::callsite::DefaultCallsite =
{
static META: ::tracing::Metadata<'static> =
{
::tracing_core::metadata::Metadata::new("probe",
"rustc_infer::infer::snapshot", ::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/snapshot/mod.rs"),
::tracing_core::__macro_support::Option::Some(100u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::snapshot"),
::tracing_core::field::FieldSet::new(&[],
::tracing_core::callsite::Identifier(&__CALLSITE)),
::tracing::metadata::Kind::SPAN)
};
::tracing::callsite::DefaultCallsite::new(&META)
};
let mut interest = ::tracing::subscriber::Interest::never();
if ::tracing::Level::DEBUG <=
::tracing::level_filters::STATIC_MAX_LEVEL &&
::tracing::Level::DEBUG <=
::tracing::level_filters::LevelFilter::current() &&
{ interest = __CALLSITE.interest(); !interest.is_never() }
&&
::tracing::__macro_support::__is_enabled(__CALLSITE.metadata(),
interest) {
let meta = __CALLSITE.metadata();
::tracing::Span::new(meta,
&{ meta.fields().value_set(&[]) })
} else {
let span =
::tracing::__macro_support::__disabled_span(__CALLSITE.metadata());
{};
span
}
};
__tracing_attr_guard = __tracing_attr_span.enter();
}
#[warn(clippy :: suspicious_else_formatting)]
{
#[allow(unknown_lints, unreachable_code, clippy ::
diverging_sub_expression, clippy :: empty_loop, clippy ::
let_unit_value, clippy :: let_with_type_underscore, clippy ::
needless_return, clippy :: unreachable)]
if false {
let __tracing_attr_fake_return: R = loop {};
return __tracing_attr_fake_return;
}
{
let snapshot = self.start_snapshot();
let r = f(&snapshot);
self.rollback_to(snapshot);
r
}
}
}#[instrument(skip(self, f), level = "debug")]
101 pub fn probe<R, F>(&self, f: F) -> R
102 where
103 F: FnOnce(&CombinedSnapshot<'tcx>) -> R,
104 {
105 let snapshot = self.start_snapshot();
106 let r = f(&snapshot);
107 self.rollback_to(snapshot);
108 r
109 }
110
111 pub fn region_constraints_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
114 self.inner
115 .borrow_mut()
116 .unwrap_region_constraints()
117 .region_constraints_added_in_snapshot(&snapshot.undo_snapshot)
118 }
119
120 pub fn opaque_types_added_in_snapshot(&self, snapshot: &CombinedSnapshot<'tcx>) -> bool {
121 self.inner.borrow().undo_log.opaque_types_in_snapshot(&snapshot.undo_snapshot)
122 }
123}