@@ -13,7 +13,7 @@ mod variables;
1313pub use codegen:: InstructionBuilder ;
1414pub use modules:: { ModuleCache , compile_type_import} ;
1515pub use pattern:: MatchCertainty ;
16- pub use typing:: { TupleAccessor , TypeAliasDef , union_types} ;
16+ pub use typing:: { TupleAccessor , TypeAliasDef , resolve_type_alias_for_display , union_types} ;
1717
1818use crate :: {
1919 ast,
@@ -319,8 +319,14 @@ impl<'a> Compiler<'a> {
319319 ast:: Type :: Tuple ( tuple) => {
320320 // Validate partial types have all named fields
321321 if tuple. is_partial {
322- let has_unnamed = tuple. fields . iter ( ) . any ( |f| f. name . is_none ( ) ) ;
323- let has_named = tuple. fields . iter ( ) . any ( |f| f. name . is_some ( ) ) ;
322+ let has_unnamed = tuple
323+ . fields
324+ . iter ( )
325+ . any ( |f| matches ! ( f, ast:: FieldType :: Field { name: None , .. } ) ) ;
326+ let has_named = tuple
327+ . fields
328+ . iter ( )
329+ . any ( |f| matches ! ( f, ast:: FieldType :: Field { name: Some ( _) , .. } ) ) ;
324330
325331 if has_unnamed && has_named {
326332 return Err ( Error :: TypeUnresolved (
@@ -330,7 +336,9 @@ impl<'a> Compiler<'a> {
330336 }
331337 // Recursively validate field types
332338 for field in & tuple. fields {
333- Self :: validate_type_ast ( & field. type_def ) ?;
339+ if let ast:: FieldType :: Field { type_def, .. } = field {
340+ Self :: validate_type_ast ( type_def) ?;
341+ }
334342 }
335343 Ok ( ( ) )
336344 }
@@ -399,7 +407,7 @@ impl<'a> Compiler<'a> {
399407
400408 fn compile_tuple (
401409 & mut self ,
402- tuple_name : Option < String > ,
410+ tuple_name : ast :: TupleName ,
403411 fields : Vec < ast:: TupleField > ,
404412 value_type : Option < Type > ,
405413 ) -> Result < Type , Error > {
@@ -409,57 +417,38 @@ impl<'a> Compiler<'a> {
409417 let contains_spread = Self :: tuple_contains_spread ( & fields) ;
410418
411419 if contains_spread {
412- // Special handling for identifier[..., fields] and ~[..., fields] syntax:
413- // If tuple name matches a spread identifier, use the source type's name
414- let resolved_tuple_name = if let Some ( ref name) = tuple_name {
415- // Check if any spread field references this name
416- let has_matching_spread = fields. iter ( ) . any ( |f| {
417- matches ! (
418- & f. value,
419- ast:: FieldValue :: Spread ( Some ( id) ) if id == name
420- )
421- } ) ;
422-
423- if has_matching_spread {
424- if name == "~" {
420+ // Resolve tuple name based on the TupleName variant
421+ let resolved_tuple_name = match tuple_name {
422+ ast:: TupleName :: Literal ( name) => Some ( name) ,
423+ ast:: TupleName :: None => None ,
424+ ast:: TupleName :: Identifier ( id) => {
425+ if id == "~" {
425426 // Ripple spread: ~[..., fields]
426427 // Get the ripple type from value_type (the piped value)
427- if let Some ( ref ripple_type ) = value_type {
428+ value_type . as_ref ( ) . and_then ( |ripple_type| {
428429 if let Type :: Tuple ( type_id) = ripple_type {
429- if let Some ( type_info) = self . program . lookup_type ( type_id) {
430- type_info. name . clone ( )
431- } else {
432- None
433- }
430+ self . program
431+ . lookup_type ( type_id)
432+ . and_then ( |type_info| type_info. name . clone ( ) )
434433 } else {
435434 None
436435 }
437- } else {
438- None
439- }
436+ } )
440437 } else {
441438 // Identifier spread: identifier[..., fields]
442439 // Look up the variable's type
443- if let Some ( ( var_type, _) ) = self . lookup_variable ( & self . scopes , name, & [ ] ) {
444- // If it's a tuple type, use its name
445- if let Type :: Tuple ( type_id) = var_type {
446- if let Some ( type_info) = self . program . lookup_type ( & type_id) {
447- type_info. name . clone ( )
440+ self . lookup_variable ( & self . scopes , & id, & [ ] )
441+ . and_then ( |( var_type, _) | {
442+ if let Type :: Tuple ( type_id) = var_type {
443+ self . program
444+ . lookup_type ( & type_id)
445+ . and_then ( |type_info| type_info. name . clone ( ) )
448446 } else {
449- tuple_name
447+ None
450448 }
451- } else {
452- tuple_name
453- }
454- } else {
455- tuple_name
456- }
449+ } )
457450 }
458- } else {
459- tuple_name
460451 }
461- } else {
462- None
463452 } ;
464453
465454 // Use specialized compilation for tuples with spreads
@@ -507,7 +496,16 @@ impl<'a> Compiler<'a> {
507496 }
508497
509498 // Register the tuple type and emit instruction
510- let type_id = self . program . register_type ( tuple_name, field_types) ;
499+ let resolved_name = match tuple_name {
500+ ast:: TupleName :: Literal ( name) => Some ( name) ,
501+ ast:: TupleName :: None => None ,
502+ ast:: TupleName :: Identifier ( _) => {
503+ // Parser enforces that identifier syntax requires spreads,
504+ // so this path only executes when there are spreads (handled above)
505+ unreachable ! ( "TupleName::Identifier without spreads should be rejected by parser" )
506+ }
507+ } ;
508+ let type_id = self . program . register_type ( resolved_name, field_types) ;
511509 self . codegen . add_instruction ( Instruction :: Tuple ( type_id) ) ;
512510
513511 // If this tuple established a ripple context, clean up
@@ -647,7 +645,11 @@ impl<'a> Compiler<'a> {
647645
648646 if let Some ( ast:: Type :: Tuple ( tuple_type) ) = & function. parameter_type {
649647 for field in & tuple_type. fields {
650- if let Some ( field_name) = & field. name {
648+ if let ast:: FieldType :: Field {
649+ name : Some ( field_name) ,
650+ ..
651+ } = field
652+ {
651653 function_params. insert ( field_name. clone ( ) ) ;
652654 }
653655 }
@@ -792,10 +794,14 @@ impl<'a> Compiler<'a> {
792794 let mut parameter_fields = HashMap :: new ( ) ;
793795 if let Some ( ast:: Type :: Tuple ( tuple_type) ) = & function. parameter_type {
794796 for ( field_index, field) in tuple_type. fields . iter ( ) . enumerate ( ) {
795- if let Some ( field_name) = & field. name {
797+ if let ast:: FieldType :: Field {
798+ name : Some ( field_name) ,
799+ type_def,
800+ } = field
801+ {
796802 let field_type = typing:: resolve_ast_type (
797803 & self . type_aliases ,
798- field . type_def . clone ( ) ,
804+ type_def. clone ( ) ,
799805 & mut self . program ,
800806 ) ?;
801807 parameter_fields. insert ( field_name. clone ( ) , ( field_index, field_type) ) ;
0 commit comments