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
}
0 commit comments