@@ -41,6 +41,15 @@ impl DataflowOpTrait for TailLoop {
41
41
Signature :: new ( inputs, outputs) . with_extension_delta ( self . extension_delta . clone ( ) ) ,
42
42
)
43
43
}
44
+
45
+ fn substitute ( & self , subst : & crate :: types:: Substitution ) -> Self {
46
+ Self {
47
+ just_inputs : self . just_inputs . substitute ( subst) ,
48
+ just_outputs : self . just_outputs . substitute ( subst) ,
49
+ rest : self . rest . substitute ( subst) ,
50
+ extension_delta : self . extension_delta . substitute ( subst) ,
51
+ }
52
+ }
44
53
}
45
54
46
55
impl TailLoop {
@@ -111,6 +120,15 @@ impl DataflowOpTrait for Conditional {
111
120
. with_extension_delta ( self . extension_delta . clone ( ) ) ,
112
121
)
113
122
}
123
+
124
+ fn substitute ( & self , subst : & crate :: types:: Substitution ) -> Self {
125
+ Self {
126
+ sum_rows : self . sum_rows . iter ( ) . map ( |r| r. substitute ( subst) ) . collect ( ) ,
127
+ other_inputs : self . other_inputs . substitute ( subst) ,
128
+ outputs : self . outputs . substitute ( subst) ,
129
+ extension_delta : self . extension_delta . substitute ( subst) ,
130
+ }
131
+ }
114
132
}
115
133
116
134
impl Conditional {
@@ -140,6 +158,12 @@ impl DataflowOpTrait for CFG {
140
158
fn signature ( & self ) -> Cow < ' _ , Signature > {
141
159
Cow :: Borrowed ( & self . signature )
142
160
}
161
+
162
+ fn substitute ( & self , subst : & crate :: types:: Substitution ) -> Self {
163
+ Self {
164
+ signature : self . signature . substitute ( subst) ,
165
+ }
166
+ }
143
167
}
144
168
145
169
#[ derive( Clone , Debug , PartialEq , Eq , serde:: Serialize , serde:: Deserialize ) ]
@@ -223,6 +247,15 @@ impl OpTrait for DataflowBlock {
223
247
Direction :: Outgoing => self . sum_rows . len ( ) ,
224
248
}
225
249
}
250
+
251
+ fn substitute ( & self , subst : & crate :: types:: Substitution ) -> Self {
252
+ Self {
253
+ inputs : self . inputs . substitute ( subst) ,
254
+ other_outputs : self . other_outputs . substitute ( subst) ,
255
+ sum_rows : self . sum_rows . iter ( ) . map ( |r| r. substitute ( subst) ) . collect ( ) ,
256
+ extension_delta : self . extension_delta . substitute ( subst) ,
257
+ }
258
+ }
226
259
}
227
260
228
261
impl OpTrait for ExitBlock {
@@ -248,6 +281,12 @@ impl OpTrait for ExitBlock {
248
281
Direction :: Outgoing => 0 ,
249
282
}
250
283
}
284
+
285
+ fn substitute ( & self , subst : & crate :: types:: Substitution ) -> Self {
286
+ Self {
287
+ cfg_outputs : self . cfg_outputs . substitute ( subst) ,
288
+ }
289
+ }
251
290
}
252
291
253
292
/// Functionality shared by DataflowBlock and Exit CFG block types.
@@ -311,6 +350,12 @@ impl OpTrait for Case {
311
350
fn tag ( & self ) -> OpTag {
312
351
<Self as StaticTag >:: TAG
313
352
}
353
+
354
+ fn substitute ( & self , subst : & crate :: types:: Substitution ) -> Self {
355
+ Self {
356
+ signature : self . signature . substitute ( subst) ,
357
+ }
358
+ }
314
359
}
315
360
316
361
impl Case {
@@ -324,3 +369,100 @@ impl Case {
324
369
& self . signature . output
325
370
}
326
371
}
372
+
373
+ #[ cfg( test) ]
374
+ mod test {
375
+ use crate :: {
376
+ extension:: {
377
+ prelude:: { qb_t, usize_t, PRELUDE_ID } ,
378
+ ExtensionSet , PRELUDE_REGISTRY ,
379
+ } ,
380
+ ops:: { Conditional , DataflowOpTrait , DataflowParent } ,
381
+ types:: { Signature , Substitution , Type , TypeArg , TypeBound , TypeRV } ,
382
+ } ;
383
+
384
+ use super :: { DataflowBlock , TailLoop } ;
385
+
386
+ #[ test]
387
+ fn test_subst_dataflow_block ( ) {
388
+ use crate :: ops:: OpTrait ;
389
+ let tv0 = Type :: new_var_use ( 0 , TypeBound :: Any ) ;
390
+ let dfb = DataflowBlock {
391
+ inputs : vec ! [ usize_t( ) , tv0. clone( ) ] . into ( ) ,
392
+ other_outputs : vec ! [ tv0. clone( ) ] . into ( ) ,
393
+ sum_rows : vec ! [ usize_t( ) . into( ) , vec![ qb_t( ) , tv0. clone( ) ] . into( ) ] ,
394
+ extension_delta : ExtensionSet :: type_var ( 1 ) ,
395
+ } ;
396
+ let dfb2 = dfb. substitute ( & Substitution :: new (
397
+ & [
398
+ qb_t ( ) . into ( ) ,
399
+ TypeArg :: Extensions {
400
+ es : PRELUDE_ID . into ( ) ,
401
+ } ,
402
+ ] ,
403
+ & PRELUDE_REGISTRY ,
404
+ ) ) ;
405
+ let st = Type :: new_sum ( vec ! [ vec![ usize_t( ) ] , vec![ qb_t( ) ; 2 ] ] ) ;
406
+ assert_eq ! (
407
+ dfb2. inner_signature( ) ,
408
+ Signature :: new( vec![ usize_t( ) , qb_t( ) ] , vec![ st, qb_t( ) ] )
409
+ . with_extension_delta( PRELUDE_ID )
410
+ ) ;
411
+ }
412
+
413
+ #[ test]
414
+ fn test_subst_conditional ( ) {
415
+ let tv1 = Type :: new_var_use ( 1 , TypeBound :: Any ) ;
416
+ let cond = Conditional {
417
+ sum_rows : vec ! [ usize_t( ) . into( ) , tv1. clone( ) . into( ) ] ,
418
+ other_inputs : vec ! [ Type :: new_tuple( TypeRV :: new_row_var_use( 0 , TypeBound :: Any ) ) ] . into ( ) ,
419
+ outputs : vec ! [ usize_t( ) , tv1] . into ( ) ,
420
+ extension_delta : ExtensionSet :: new ( ) ,
421
+ } ;
422
+ let cond2 = cond. substitute ( & Substitution :: new (
423
+ & [
424
+ TypeArg :: Sequence {
425
+ elems : vec ! [ usize_t( ) . into( ) ; 3 ] ,
426
+ } ,
427
+ qb_t ( ) . into ( ) ,
428
+ ] ,
429
+ & PRELUDE_REGISTRY ,
430
+ ) ) ;
431
+ let st = Type :: new_sum ( vec ! [ usize_t( ) , qb_t( ) ] ) ; //both single-element variants
432
+ assert_eq ! (
433
+ cond2. signature( ) ,
434
+ Signature :: new(
435
+ vec![ st, Type :: new_tuple( vec![ usize_t( ) ; 3 ] ) ] ,
436
+ vec![ usize_t( ) , qb_t( ) ]
437
+ )
438
+ ) ;
439
+ }
440
+
441
+ #[ test]
442
+ fn test_tail_loop ( ) {
443
+ let tv0 = Type :: new_var_use ( 0 , TypeBound :: Copyable ) ;
444
+ let tail_loop = TailLoop {
445
+ just_inputs : vec ! [ qb_t( ) , tv0. clone( ) ] . into ( ) ,
446
+ just_outputs : vec ! [ tv0. clone( ) , qb_t( ) ] . into ( ) ,
447
+ rest : vec ! [ tv0. clone( ) ] . into ( ) ,
448
+ extension_delta : ExtensionSet :: type_var ( 1 ) ,
449
+ } ;
450
+ let tail2 = tail_loop. substitute ( & Substitution :: new (
451
+ & [
452
+ usize_t ( ) . into ( ) ,
453
+ TypeArg :: Extensions {
454
+ es : PRELUDE_ID . into ( ) ,
455
+ } ,
456
+ ] ,
457
+ & PRELUDE_REGISTRY ,
458
+ ) ) ;
459
+ assert_eq ! (
460
+ tail2. signature( ) ,
461
+ Signature :: new(
462
+ vec![ qb_t( ) , usize_t( ) , usize_t( ) ] ,
463
+ vec![ usize_t( ) , qb_t( ) , usize_t( ) ]
464
+ )
465
+ . with_extension_delta( PRELUDE_ID )
466
+ ) ;
467
+ }
468
+ }
0 commit comments