Auto merge of #140607 - lcnr:opaque-type-storage, r= · rust-lang/rust@93308d9 (original) (raw)
``
1
`+
use std::ops::Deref;
`
``
2
+
``
3
`+
use rustc_data_structures::fx::FxIndexMap;
`
1
4
`use rustc_data_structures::undo_log::UndoLogs;
`
2
5
`use rustc_middle::bug;
`
3
6
`use rustc_middle::ty::{self, OpaqueHiddenType, OpaqueTypeKey, Ty};
`
4
7
`use tracing::instrument;
`
5
8
``
6
``
`-
use super::OpaqueTypeMap;
`
7
9
`use crate::infer::snapshot::undo_log::{InferCtxtUndoLogs, UndoLog};
`
8
10
``
9
11
`#[derive(Default, Debug, Clone)]
`
10
``
`-
pub(crate) struct OpaqueTypeStorage<'tcx> {
`
11
``
`-
/// Opaque types found in explicit return types and their
`
12
``
`-
/// associated fresh inference variable. Writeback resolves these
`
13
``
`-
/// variables to get the concrete type, which can be used to
`
14
``
`-
/// 'de-opaque' OpaqueHiddenType, after typeck is done with all functions.
`
15
``
`-
pub opaque_types: OpaqueTypeMap<'tcx>,
`
``
12
`+
pub struct OpaqueTypeStorage<'tcx> {
`
``
13
`+
opaque_types: FxIndexMap<OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>>,
`
``
14
`+
duplicate_entries: Vec<(OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)>,
`
16
15
`}
`
17
16
``
18
17
`impl<'tcx> OpaqueTypeStorage<'tcx> {
`
`@@ -33,6 +32,52 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
`
33
32
`}
`
34
33
`}
`
35
34
``
``
35
`+
pub(crate) fn pop_duplicate_entry(&mut self) {
`
``
36
`+
let entry = self.duplicate_entries.pop();
`
``
37
`+
assert!(entry.is_some());
`
``
38
`+
}
`
``
39
+
``
40
`+
pub(crate) fn is_empty(&self) -> bool {
`
``
41
`+
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
`
``
42
`+
opaque_types.is_empty() && duplicate_entries.is_empty()
`
``
43
`+
}
`
``
44
+
``
45
`+
pub(crate) fn take_opaque_types(
`
``
46
`+
&mut self,
`
``
47
`+
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
`
``
48
`+
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
`
``
49
`+
std::mem::take(opaque_types).into_iter().chain(std::mem::take(duplicate_entries))
`
``
50
`+
}
`
``
51
+
``
52
`+
/// Only returns the opaque types from the lookup table. These are used
`
``
53
`+
/// when normalizing opaque types and have a unique key.
`
``
54
`+
///
`
``
55
`` +
/// Outside of canonicalization one should generally use iter_opaque_types
``
``
56
`+
/// to also consider duplicate entries.
`
``
57
`+
pub fn iter_lookup_table(
`
``
58
`+
&self,
`
``
59
`+
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
`
``
60
`+
self.opaque_types.iter().map(|(k, v)| (*k, *v))
`
``
61
`+
}
`
``
62
+
``
63
`` +
/// Only returns the opaque types which are stored in duplicate_entries
.
``
``
64
`+
///
`
``
65
`+
/// These have to considered when checking all opaque type uses but are e.g.
`
``
66
`+
/// irrelevant for canonical inputs as nested queries never meaningfully
`
``
67
`+
/// accesses them.
`
``
68
`+
pub fn iter_duplicate_entries(
`
``
69
`+
&self,
`
``
70
`+
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
`
``
71
`+
self.duplicate_entries.iter().copied()
`
``
72
`+
}
`
``
73
+
``
74
`+
pub fn iter_opaque_types(
`
``
75
`+
&self,
`
``
76
`+
) -> impl Iterator<Item = (OpaqueTypeKey<'tcx>, OpaqueHiddenType<'tcx>)> {
`
``
77
`+
let OpaqueTypeStorage { opaque_types, duplicate_entries } = self;
`
``
78
`+
opaque_types.iter().map(|(k, v)| (*k, *v)).chain(duplicate_entries.iter().copied())
`
``
79
`+
}
`
``
80
+
36
81
`#[inline]
`
37
82
`pub(crate) fn with_log<'a>(
`
38
83
`&'a mut self,
`
`@@ -44,21 +89,27 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
`
44
89
``
45
90
`impl<'tcx> Drop for OpaqueTypeStorage<'tcx> {
`
46
91
`fn drop(&mut self) {
`
47
``
`-
if !self.opaque_types.is_empty() {
`
``
92
`+
if !self.is_empty() {
`
48
93
` ty::tls::with(|tcx| tcx.dcx().delayed_bug(format!("{:?}", self.opaque_types)));
`
49
94
`}
`
50
95
`}
`
51
96
`}
`
52
97
``
53
``
`-
pub(crate) struct OpaqueTypeTable<'a, 'tcx> {
`
``
98
`+
pub struct OpaqueTypeTable<'a, 'tcx> {
`
54
99
`storage: &'a mut OpaqueTypeStorage<'tcx>,
`
55
100
``
56
101
`undo_log: &'a mut InferCtxtUndoLogs<'tcx>,
`
57
102
`}
`
``
103
`+
impl<'tcx> Deref for OpaqueTypeTable<'_, 'tcx> {
`
``
104
`+
type Target = OpaqueTypeStorage<'tcx>;
`
``
105
`+
fn deref(&self) -> &Self::Target {
`
``
106
`+
self.storage
`
``
107
`+
}
`
``
108
`+
}
`
58
109
``
59
110
`impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
`
60
111
`#[instrument(skip(self), level = "debug")]
`
61
``
`-
pub(crate) fn register(
`
``
112
`+
pub fn register(
`
62
113
`&mut self,
`
63
114
`key: OpaqueTypeKey<'tcx>,
`
64
115
`hidden_type: OpaqueHiddenType<'tcx>,
`
`@@ -72,4 +123,9 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
`
72
123
`self.undo_log.push(UndoLog::OpaqueTypes(key, None));
`
73
124
`None
`
74
125
`}
`
``
126
+
``
127
`+
pub fn add_duplicate(&mut self, key: OpaqueTypeKey<'tcx>, hidden_type: OpaqueHiddenType<'tcx>) {
`
``
128
`+
self.storage.duplicate_entries.push((key, hidden_type));
`
``
129
`+
self.undo_log.push(UndoLog::DuplicateOpaqueType);
`
``
130
`+
}
`
75
131
`}
`