rustc_infer/infer/opaque_types/
table.rs1use std::ops::Deref;
2
3use rustc_data_structures::fx::FxIndexMap;
4use rustc_data_structures::undo_log::UndoLogs;
5use rustc_middle::bug;
6use rustc_middle::ty::{self, OpaqueTypeKey, ProvisionalHiddenType, Ty};
7use tracing::instrument;
8
9use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
10
11#[derive(#[automatically_derived]
impl<'tcx> ::core::default::Default for OpaqueTypeStorage<'tcx> {
#[inline]
fn default() -> OpaqueTypeStorage<'tcx> {
OpaqueTypeStorage {
opaque_types: ::core::default::Default::default(),
duplicate_entries: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl<'tcx> ::core::fmt::Debug for OpaqueTypeStorage<'tcx> {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"OpaqueTypeStorage", "opaque_types", &self.opaque_types,
"duplicate_entries", &&self.duplicate_entries)
}
}Debug, #[automatically_derived]
impl<'tcx> ::core::clone::Clone for OpaqueTypeStorage<'tcx> {
#[inline]
fn clone(&self) -> OpaqueTypeStorage<'tcx> {
OpaqueTypeStorage {
opaque_types: ::core::clone::Clone::clone(&self.opaque_types),
duplicate_entries: ::core::clone::Clone::clone(&self.duplicate_entries),
}
}
}Clone)]
12pub struct OpaqueTypeStorage<'tcx> {
13 opaque_types: FxIndexMap<OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>>,
14 duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)>,
15}
16
17#[derive(#[automatically_derived]
impl ::core::default::Default for OpaqueTypeStorageEntries {
#[inline]
fn default() -> OpaqueTypeStorageEntries {
OpaqueTypeStorageEntries {
opaque_types: ::core::default::Default::default(),
duplicate_entries: ::core::default::Default::default(),
}
}
}Default, #[automatically_derived]
impl ::core::fmt::Debug for OpaqueTypeStorageEntries {
#[inline]
fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
::core::fmt::Formatter::debug_struct_field2_finish(f,
"OpaqueTypeStorageEntries", "opaque_types", &self.opaque_types,
"duplicate_entries", &&self.duplicate_entries)
}
}Debug, #[automatically_derived]
impl ::core::clone::Clone for OpaqueTypeStorageEntries {
#[inline]
fn clone(&self) -> OpaqueTypeStorageEntries {
let _: ::core::clone::AssertParamIsClone<usize>;
*self
}
}Clone, #[automatically_derived]
impl ::core::marker::Copy for OpaqueTypeStorageEntries { }Copy, #[automatically_derived]
impl ::core::cmp::PartialEq for OpaqueTypeStorageEntries {
#[inline]
fn eq(&self, other: &OpaqueTypeStorageEntries) -> bool {
self.opaque_types == other.opaque_types &&
self.duplicate_entries == other.duplicate_entries
}
}PartialEq, #[automatically_derived]
impl ::core::cmp::Eq for OpaqueTypeStorageEntries {
#[inline]
#[doc(hidden)]
#[coverage(off)]
fn assert_receiver_is_total_eq(&self) -> () {
let _: ::core::cmp::AssertParamIsEq<usize>;
}
}Eq)]
22pub struct OpaqueTypeStorageEntries {
23 opaque_types: usize,
24 duplicate_entries: usize,
25}
26
27impl rustc_type_ir::inherent::OpaqueTypeStorageEntries for OpaqueTypeStorageEntries {
28 fn needs_reevaluation(self, canonicalized: usize) -> bool {
29 self.opaque_types != canonicalized
30 }
31}
32
33impl<'tcx> OpaqueTypeStorage<'tcx> {
34 #[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("remove",
"rustc_infer::infer::opaque_types::table",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/opaque_types/table.rs"),
::tracing_core::__macro_support::Option::Some(34u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::opaque_types::table"),
::tracing_core::field::FieldSet::new(&["self", "key",
"prev"], ::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,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&self)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&key)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&prev)
as &dyn Value))])
})
} 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;
}
{
if let Some(prev) = prev {
*self.opaque_types.get_mut(&key).unwrap() = prev;
} else {
match self.opaque_types.swap_remove(&key) {
None =>
::rustc_middle::util::bug::bug_fmt(format_args!("reverted opaque type inference that was never registered: {0:?}",
key)),
Some(_) => {}
}
}
}
}
}#[instrument(level = "debug")]
35 pub(crate) fn remove(
36 &mut self,
37 key: OpaqueTypeKey<'tcx>,
38 prev: Option<ProvisionalHiddenType<'tcx>>,
39 ) {
40 if let Some(prev) = prev {
41 *self.opaque_types.get_mut(&key).unwrap() = prev;
42 } else {
43 match self.opaque_types.swap_remove(&key) {
45 None => bug!("reverted opaque type inference that was never registered: {:?}", key),
46 Some(_) => {}
47 }
48 }
49 }
50
51 pub(crate) fn pop_duplicate_entry(&mut self) {
52 let entry = self.duplicate_entries.pop();
53 if !entry.is_some() {
::core::panicking::panic("assertion failed: entry.is_some()")
};assert!(entry.is_some());
54 }
55
56 pub fn is_empty(&self) -> bool {
57 let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
58 opaque_types.is_empty() && duplicate_entries.is_empty()
59 }
60
61 pub(crate) fn take_opaque_types(
62 &mut self,
63 ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
64 let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
65 std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries))
66 }
67
68 pub fn num_entries(&self) -> OpaqueTypeStorageEntries {
69 OpaqueTypeStorageEntries {
70 opaque_types: self.opaque_types.len(),
71 duplicate_entries: self.duplicate_entries.len(),
72 }
73 }
74
75 pub fn opaque_types_added_since(
76 &self,
77 prev_entries: OpaqueTypeStorageEntries,
78 ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
79 self.opaque_types
80 .iter()
81 .skip(prev_entries.opaque_types)
82 .map(|(k, v)| (*k, *v))
83 .chain(self.duplicate_entries.iter().skip(prev_entries.duplicate_entries).copied())
84 }
85
86 pub fn iter_lookup_table(
92 &self,
93 ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
94 self.opaque_types.iter().map(|(k, v)| (*k, *v))
95 }
96
97 pub fn iter_duplicate_entries(
103 &self,
104 ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
105 self.duplicate_entries.iter().copied()
106 }
107
108 pub fn iter_opaque_types(
109 &self,
110 ) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, ProvisionalHiddenType<'tcx>)> {
111 let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
112 opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied())
113 }
114
115 #[inline]
116 pub(crate) fn with_log<'a>(
117 &'a mut self,
118 undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
119 ) -> OpaqueTypeTable<'a, 'tcx> {
120 OpaqueTypeTable { storage: self, undo_log }
121 }
122}
123
124impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
125 fn drop(&mut self) {
126 if !self.is_empty() {
127 ty::tls::with(|tcx| tcx.dcx().delayed_bug(::alloc::__export::must_use({
::alloc::fmt::format(format_args!("{0:?}", self.opaque_types))
})format!("{:?}", self.opaque_types)));
128 }
129 }
130}
131
132pub struct OpaqueTypeTable<'a, 'tcx> {
133 storage: &'a mut OpaqueTypeStorage<'tcx>,
134
135 undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
136}
137impl<'tcx> Deref for OpaqueTypeTable<'_, 'tcx> {
138 type Target = OpaqueTypeStorage<'tcx>;
139 fn deref(&self) -> &Self::Target {
140 self.storage
141 }
142}
143
144impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
145 #[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("register",
"rustc_infer::infer::opaque_types::table",
::tracing::Level::DEBUG,
::tracing_core::__macro_support::Option::Some("compiler/rustc_infer/src/infer/opaque_types/table.rs"),
::tracing_core::__macro_support::Option::Some(145u32),
::tracing_core::__macro_support::Option::Some("rustc_infer::infer::opaque_types::table"),
::tracing_core::field::FieldSet::new(&["key",
"hidden_type"],
::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,
&{
#[allow(unused_imports)]
use ::tracing::field::{debug, display, Value};
let mut iter = meta.fields().iter();
meta.fields().value_set(&[(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&key)
as &dyn Value)),
(&::tracing::__macro_support::Iterator::next(&mut iter).expect("FieldSet corrupted (this is a bug)"),
::tracing::__macro_support::Option::Some(&::tracing::field::debug(&hidden_type)
as &dyn Value))])
})
} 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: Option<Ty<'tcx>> = loop {};
return __tracing_attr_fake_return;
}
{
if let Some(entry) = self.storage.opaque_types.get_mut(&key) {
let prev = std::mem::replace(entry, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
return Some(prev.ty);
}
self.storage.opaque_types.insert(key, hidden_type);
self.undo_log.push(UndoLog::OpaqueTypes(key, None));
None
}
}
}#[instrument(skip(self), level = "debug")]
146 pub fn register(
147 &mut self,
148 key: OpaqueTypeKey<'tcx>,
149 hidden_type: ProvisionalHiddenType<'tcx>,
150 ) -> Option<Ty<'tcx>> {
151 if let Some(entry) = self.storage.opaque_types.get_mut(&key) {
152 let prev = std::mem::replace(entry, hidden_type);
153 self.undo_log.push(UndoLog::OpaqueTypes(key, Some(prev)));
154 return Some(prev.ty);
155 }
156 self.storage.opaque_types.insert(key, hidden_type);
157 self.undo_log.push(UndoLog::OpaqueTypes(key, None));
158 None
159 }
160
161 pub fn add_duplicate(
162 &mut self,
163 key: OpaqueTypeKey<'tcx>,
164 hidden_type: ProvisionalHiddenType<'tcx>,
165 ) {
166 self.storage.duplicate_entries.push((key, hidden_type));
167 self.undo_log.push(UndoLog::DuplicateOpaqueType);
168 }
169}