11use quote:: quote_spanned;
22
33use super :: {
4- DelayType , OpInstGenerics , OperatorCategory , OperatorConstraints , OperatorInstance ,
4+ OpInstGenerics , OperatorCategory , OperatorConstraints , OperatorInstance ,
55 OperatorWriteOutput , Persistence , RANGE_0 , RANGE_1 , WriteContextArgs ,
66} ;
77use crate :: diagnostic:: { Diagnostic , Level } ;
@@ -41,13 +41,14 @@ pub const PERSIST_MUT_KEYED: OperatorConstraints = OperatorConstraints {
4141 flo_type : None ,
4242 ports_inn : None ,
4343 ports_out : None ,
44- input_delaytype_fn : |_| Some ( DelayType :: Stratum ) ,
44+ input_delaytype_fn : |_| None ,
4545 write_fn : |wc @ & WriteContextArgs {
4646 root,
4747 op_span,
4848 work_fn_async,
4949 ident,
5050 inputs,
51+ outputs,
5152 is_pull,
5253 op_name,
5354 op_inst :
@@ -61,8 +62,6 @@ pub const PERSIST_MUT_KEYED: OperatorConstraints = OperatorConstraints {
6162 ..
6263 } ,
6364 diagnostics| {
64- assert ! ( is_pull) ;
65-
6665 if [ Persistence :: Mutable ] != persistence_args[ ..] {
6766 diagnostics. push ( Diagnostic :: spanned (
6867 op_span,
@@ -81,7 +80,7 @@ pub const PERSIST_MUT_KEYED: OperatorConstraints = OperatorConstraints {
8180 #root:: rustc_hash:: FxHashMap :: <_, #root:: util:: sparse_vec:: SparseVec <_>>:: default ( ) ;
8281 } ;
8382
84- let write_iterator = {
83+ let write_iterator = if is_pull {
8584 let input = & inputs[ 0 ] ;
8685 quote_spanned ! { op_span=>
8786 let #ident = {
@@ -116,6 +115,51 @@ pub const PERSIST_MUT_KEYED: OperatorConstraints = OperatorConstraints {
116115 #root:: dfir_pipes:: pull:: iter( iter)
117116 } ;
118117 }
118+ } else {
119+ let output = & outputs[ 0 ] ;
120+ quote_spanned ! { op_span=>
121+ let #ident = {
122+ #[ inline( always) ]
123+ fn check_push<' a, Next , K , V >(
124+ persistdata: & ' a mut #root:: rustc_hash:: FxHashMap <K , #root:: util:: sparse_vec:: SparseVec <V >>,
125+ next: Next ,
126+ )
127+ -> impl ' a + #root:: dfir_pipes:: push:: Push <#root:: util:: PersistenceKeyed :: <K , V >, ( ) >
128+ where
129+ Next : ' a + #root:: dfir_pipes:: push:: Push <( K , V ) , ( ) >,
130+ K : :: std:: clone:: Clone + :: std:: cmp:: Eq + :: std:: hash:: Hash ,
131+ V : :: std:: clone:: Clone + :: std:: cmp:: Eq + :: std:: hash:: Hash ,
132+ {
133+ #root:: dfir_pipes:: push:: fold(
134+ persistdata,
135+ |state: & mut #root:: rustc_hash:: FxHashMap <K , #root:: util:: sparse_vec:: SparseVec <V >>, item| {
136+ match item {
137+ #root:: util:: PersistenceKeyed :: Persist ( k, v) => {
138+ state. entry( k) . or_default( ) . push( v) ;
139+ } ,
140+ #root:: util:: PersistenceKeyed :: Delete ( k) => {
141+ state. remove( & k) ;
142+ }
143+ }
144+ } ,
145+ #root:: dfir_pipes:: push:: flat_map(
146+ #[ allow( clippy:: clone_on_copy) ]
147+ #[ allow( clippy:: disallowed_methods, reason = "FxHasher is deterministic" ) ]
148+ |state: & mut #root:: rustc_hash:: FxHashMap <K , #root:: util:: sparse_vec:: SparseVec <V >>| {
149+ state
150+ . iter( )
151+ . flat_map( |( k, vec) | {
152+ vec. iter( ) . map( move |v| ( k. clone( ) , v. clone( ) ) )
153+ } )
154+ } ,
155+ next,
156+ ) ,
157+ )
158+ }
159+
160+ check_push( & mut #persistdata_ident, #output)
161+ } ;
162+ }
119163 } ;
120164
121165 Ok ( OperatorWriteOutput {
0 commit comments