1 use rustc_data_structures
::undo_log
::UndoLogs
;
2 use rustc_hir
::OpaqueTyOrigin
;
3 use rustc_middle
::ty
::{self, OpaqueHiddenType, OpaqueTypeKey, Ty}
;
4 use rustc_span
::DUMMY_SP
;
6 use crate::infer
::{InferCtxtUndoLogs, UndoLog}
;
8 use super::{OpaqueTypeDecl, OpaqueTypeMap}
;
10 #[derive(Default, Debug, Clone)]
11 pub struct OpaqueTypeStorage
<'tcx
> {
12 // Opaque types found in explicit return types and their
13 // associated fresh inference variable. Writeback resolves these
14 // variables to get the concrete type, which can be used to
15 // 'de-opaque' OpaqueTypeDecl, after typeck is done with all functions.
16 pub opaque_types
: OpaqueTypeMap
<'tcx
>,
19 impl<'tcx
> OpaqueTypeStorage
<'tcx
> {
20 #[instrument(level = "debug")]
21 pub(crate) fn remove(&mut self, key
: OpaqueTypeKey
<'tcx
>, idx
: Option
<OpaqueHiddenType
<'tcx
>>) {
22 if let Some(idx
) = idx
{
23 self.opaque_types
.get_mut(&key
).unwrap().hidden_type
= idx
;
25 match self.opaque_types
.remove(&key
) {
26 None
=> bug
!("reverted opaque type inference that was never registered: {:?}", key
),
32 #[instrument(level = "debug", ret)]
33 pub fn take_opaque_types(&mut self) -> OpaqueTypeMap
<'tcx
> {
34 std
::mem
::take(&mut self.opaque_types
)
38 pub(crate) fn with_log
<'a
>(
40 undo_log
: &'a
mut InferCtxtUndoLogs
<'tcx
>,
41 ) -> OpaqueTypeTable
<'a
, 'tcx
> {
42 OpaqueTypeTable { storage: self, undo_log }
46 impl<'tcx
> Drop
for OpaqueTypeStorage
<'tcx
> {
48 if !self.opaque_types
.is_empty() {
50 tcx
.sess
.delay_span_bug(DUMMY_SP
, &format
!("{:?}", self.opaque_types
))
56 pub struct OpaqueTypeTable
<'a
, 'tcx
> {
57 storage
: &'a
mut OpaqueTypeStorage
<'tcx
>,
59 undo_log
: &'a
mut InferCtxtUndoLogs
<'tcx
>,
62 impl<'a
, 'tcx
> OpaqueTypeTable
<'a
, 'tcx
> {
63 #[instrument(skip(self), level = "debug")]
64 pub(crate) fn register(
66 key
: OpaqueTypeKey
<'tcx
>,
67 hidden_type
: OpaqueHiddenType
<'tcx
>,
68 origin
: OpaqueTyOrigin
,
69 ) -> Option
<Ty
<'tcx
>> {
70 if let Some(decl
) = self.storage
.opaque_types
.get_mut(&key
) {
71 let prev
= std
::mem
::replace(&mut decl
.hidden_type
, hidden_type
);
72 self.undo_log
.push(UndoLog
::OpaqueTypes(key
, Some(prev
)));
75 let decl
= OpaqueTypeDecl { hidden_type, origin }
;
76 self.storage
.opaque_types
.insert(key
, decl
);
77 self.undo_log
.push(UndoLog
::OpaqueTypes(key
, None
));