@@ -25,13 +25,14 @@ use crate::{
2525 types:: {
2626 CustomType , FuncTypeBase , MaybeRV , PolyFuncType , PolyFuncTypeBase , RowVariable , Signature ,
2727 Term , Type , TypeArg , TypeBase , TypeBound , TypeEnum , TypeName , TypeRow ,
28- type_param:: TypeParam , type_row:: TypeRowBase ,
28+ type_param:: { SeqPart , TypeParam } ,
29+ type_row:: TypeRowBase ,
2930 } ,
3031} ;
3132use fxhash:: FxHashMap ;
3233use hugr_model:: v0 as model;
3334use hugr_model:: v0:: table;
34- use itertools:: Either ;
35+ use itertools:: { Either , Itertools } ;
3536use smol_str:: { SmolStr , ToSmolStr } ;
3637use thiserror:: Error ;
3738
@@ -1255,14 +1256,10 @@ impl<'a> Context<'a> {
12551256 if let Some ( [ item_types] ) = self . match_symbol ( term_id, model:: CORE_TUPLE_TYPE ) ? {
12561257 // At present `hugr-model` has no way to express that the item
12571258 // types of a tuple must be copyable. Therefore we import it as `Any`.
1258- let item_types = ( || {
1259- self . import_closed_list ( item_types) ?
1260- . into_iter ( )
1261- . map ( |param| self . import_term ( param) )
1262- . collect :: < Result < _ , _ > > ( )
1263- } ) ( )
1264- . map_err ( |err| error_context ! ( err, "item types of tuple type" ) ) ?;
1265- return Ok ( TypeParam :: TupleType ( item_types) ) ;
1259+ let item_types = self
1260+ . import_term ( item_types)
1261+ . map_err ( |err| error_context ! ( err, "item types of tuple type" ) ) ?;
1262+ return Ok ( TypeParam :: new_tuple_type ( item_types) ) ;
12661263 }
12671264
12681265 match self . get_term ( term_id) ? {
@@ -1277,28 +1274,24 @@ impl<'a> Context<'a> {
12771274 Ok ( Term :: new_var_use ( var. 1 as _ , decl) )
12781275 }
12791276
1280- table:: Term :: List { .. } => {
1281- let elems = ( || {
1282- self . import_closed_list ( term_id) ?
1283- . iter ( )
1284- . map ( |item| self . import_term ( * item) )
1285- . collect :: < Result < _ , _ > > ( )
1286- } ) ( )
1287- . map_err ( |err| error_context ! ( err, "list items" ) ) ?;
1288-
1289- Ok ( Term :: List ( elems) )
1277+ table:: Term :: List ( parts) => {
1278+ // PERFORMANCE: Can we do this without the additional allocation?
1279+ let parts: Vec < _ > = parts
1280+ . iter ( )
1281+ . map ( |part| self . import_seq_part ( part) )
1282+ . collect :: < Result < _ , _ > > ( )
1283+ . map_err ( |err| error_context ! ( err, "list parts" ) ) ?;
1284+ Ok ( TypeArg :: new_list_from_parts ( parts) )
12901285 }
12911286
1292- table:: Term :: Tuple { .. } => {
1293- let elems = ( || {
1294- self . import_closed_list ( term_id) ?
1295- . iter ( )
1296- . map ( |item| self . import_term ( * item) )
1297- . collect :: < Result < _ , _ > > ( )
1298- } ) ( )
1299- . map_err ( |err| error_context ! ( err, "tuple items" ) ) ?;
1300-
1301- Ok ( Term :: Tuple ( elems) )
1287+ table:: Term :: Tuple ( parts) => {
1288+ // PERFORMANCE: Can we do this without the additional allocation?
1289+ let parts: Vec < _ > = parts
1290+ . iter ( )
1291+ . map ( |part| self . import_seq_part ( part) )
1292+ . try_collect ( )
1293+ . map_err ( |err| error_context ! ( err, "tuple parts" ) ) ?;
1294+ Ok ( TypeArg :: new_tuple_from_parts ( parts) )
13021295 }
13031296
13041297 table:: Term :: Literal ( model:: Literal :: Str ( value) ) => {
@@ -1322,6 +1315,16 @@ impl<'a> Context<'a> {
13221315 . map_err ( |err| error_context ! ( err, "term {}" , term_id) )
13231316 }
13241317
1318+ fn import_seq_part (
1319+ & mut self ,
1320+ seq_part : & ' a table:: SeqPart ,
1321+ ) -> Result < SeqPart < TypeArg > , ImportError > {
1322+ Ok ( match seq_part {
1323+ table:: SeqPart :: Item ( term_id) => SeqPart :: Item ( self . import_term ( * term_id) ?) ,
1324+ table:: SeqPart :: Splice ( term_id) => SeqPart :: Splice ( self . import_term ( * term_id) ?) ,
1325+ } )
1326+ }
1327+
13251328 /// Import a `Type` from a term that represents a runtime type.
13261329 fn import_type < RV : MaybeRV > (
13271330 & mut self ,
0 commit comments