1+ use std:: ops:: Deref ;
2+
3+ use rustc_data_structures:: fx:: FxIndexMap ;
14use rustc_data_structures:: undo_log:: UndoLogs ;
25use rustc_middle:: bug;
36use rustc_middle:: ty:: { self , OpaqueHiddenType , OpaqueTypeKey , Ty } ;
47use tracing:: instrument;
58
6- use super :: OpaqueTypeMap ;
79use crate :: infer:: snapshot:: undo_log:: { InferCtxtUndoLogs , UndoLog } ;
810
911#[ 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 > ) > ,
1615}
1716
1817impl < ' tcx > OpaqueTypeStorage < ' tcx > {
@@ -33,6 +32,52 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
3332 }
3433 }
3534
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+
3681 #[ inline]
3782 pub ( crate ) fn with_log < ' a > (
3883 & ' a mut self ,
@@ -44,21 +89,27 @@ impl<'tcx> OpaqueTypeStorage<'tcx> {
4489
4590impl < ' tcx > Drop for OpaqueTypeStorage < ' tcx > {
4691 fn drop ( & mut self ) {
47- if !self . opaque_types . is_empty ( ) {
92+ if !self . is_empty ( ) {
4893 ty:: tls:: with ( |tcx| tcx. dcx ( ) . delayed_bug ( format ! ( "{:?}" , self . opaque_types) ) ) ;
4994 }
5095 }
5196}
5297
53- pub ( crate ) struct OpaqueTypeTable < ' a , ' tcx > {
98+ pub struct OpaqueTypeTable < ' a , ' tcx > {
5499 storage : & ' a mut OpaqueTypeStorage < ' tcx > ,
55100
56101 undo_log : & ' a mut InferCtxtUndoLogs < ' tcx > ,
57102}
103+ impl < ' tcx > Deref for OpaqueTypeTable < ' _ , ' tcx > {
104+ type Target = OpaqueTypeStorage < ' tcx > ;
105+ fn deref ( & self ) -> & Self :: Target {
106+ self . storage
107+ }
108+ }
58109
59110impl < ' a , ' tcx > OpaqueTypeTable < ' a , ' tcx > {
60111 #[ instrument( skip( self ) , level = "debug" ) ]
61- pub ( crate ) fn register (
112+ pub fn register (
62113 & mut self ,
63114 key : OpaqueTypeKey < ' tcx > ,
64115 hidden_type : OpaqueHiddenType < ' tcx > ,
@@ -72,4 +123,9 @@ impl<'a, 'tcx> OpaqueTypeTable<'a, 'tcx> {
72123 self . undo_log . push ( UndoLog :: OpaqueTypes ( key, None ) ) ;
73124 None
74125 }
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+ }
75131}
0 commit comments