@@ -57,7 +57,7 @@ impl AbiContext<'_> {
5757 AbiStrContext {
5858 program_name : self . program . namespace . current_package_name ( ) . to_string ( ) ,
5959 abi_with_callpaths : self . abi_with_callpaths ,
60- abi_with_fully_specified_types : false ,
60+ abi_with_fully_specified_types : self . experimental . abi_type_aliases ,
6161 abi_root_type_without_generic_type_parameters : true ,
6262 abi_type_aliases : self . experimental . abi_type_aliases ,
6363 }
@@ -68,13 +68,31 @@ impl AbiContext<'_> {
6868pub struct TypeCacheKey ( u64 ) ;
6969
7070impl TypeCacheKey {
71- fn from_type_id ( engines : & Engines , type_id : TypeId ) -> Self {
71+ fn from_type_id ( engines : & Engines , abi_type_aliases_enabled : bool , type_id : TypeId ) -> Self {
7272 let type_engine = engines. te ( ) ;
7373 let type_info = & * type_engine. get ( type_id) ;
74- Self :: from_type_info ( type_info, engines)
74+ Self :: from_type_info ( type_info, engines, abi_type_aliases_enabled )
7575 }
7676
77- fn from_type_info ( type_info : & TypeInfo , engines : & Engines ) -> Self {
77+ fn from_type_info (
78+ type_info : & TypeInfo ,
79+ engines : & Engines ,
80+ abi_type_aliases_enabled : bool ,
81+ ) -> Self {
82+ if abi_type_aliases_enabled {
83+ if let TypeInfo :: Alias { name, ty } = type_info {
84+ let mut hasher = DefaultHasher :: new ( ) ;
85+ name. hash ( & mut hasher) ;
86+
87+ let target_type_id = engines. te ( ) . get_unaliased_type_id ( ty. type_id ) ;
88+ let target_key =
89+ TypeCacheKey :: from_type_id ( engines, abi_type_aliases_enabled, target_type_id) ;
90+ target_key. 0 . hash ( & mut hasher) ;
91+
92+ return TypeCacheKey ( hasher. finish ( ) ) ;
93+ }
94+ }
95+
7896 let mut hasher = DefaultHasher :: new ( ) ;
7997 type_info. hash ( & mut hasher, engines) ;
8098 TypeCacheKey ( hasher. finish ( ) )
@@ -481,6 +499,7 @@ fn standardize_json_abi_types(json_abi_program: &mut program_abi::ProgramABI) {
481499 d. type_field == decl. type_field
482500 && decl. components . is_none ( )
483501 && decl. type_parameters . is_none ( )
502+ && decl. alias_of . is_none ( )
484503 } ) {
485504 old_to_new_id. insert (
486505 decl. metadata_type_id . clone ( ) ,
@@ -492,6 +511,7 @@ fn standardize_json_abi_types(json_abi_program: &mut program_abi::ProgramABI) {
492511 d. type_field == decl. type_field
493512 && d. components == decl. components
494513 && d. type_parameters == decl. type_parameters
514+ && d. alias_of == decl. alias_of
495515 } ) {
496516 old_to_new_id. insert (
497517 decl. metadata_type_id . clone ( ) ,
@@ -603,6 +623,14 @@ fn update_json_type_metadata_declaration(
603623 update_json_type_application ( component, old_to_new_id) ;
604624 }
605625 }
626+
627+ if let Some ( alias_of) = & mut type_declaration. alias_of {
628+ if let Some ( fuel_abi_types:: abi:: program:: TypeId :: Metadata ( new_id) ) =
629+ old_to_new_id. get ( alias_of)
630+ {
631+ * alias_of = new_id. clone ( ) ;
632+ }
633+ }
606634}
607635
608636/// Updates the metadata type IDs used in a `program_abi::TypeConcreteDeclaration` given a HashMap from
@@ -629,7 +657,8 @@ fn generate_concrete_type_declaration(
629657 type_id : TypeId ,
630658 resolved_type_id : TypeId ,
631659) -> Result < ConcreteTypeId , ErrorEmitted > {
632- let cache_key = TypeCacheKey :: from_type_id ( engines, resolved_type_id) ;
660+ let cache_key =
661+ TypeCacheKey :: from_type_id ( engines, ctx. experimental . abi_type_aliases , resolved_type_id) ;
633662 if ctx. type_cache_enabled {
634663 if let Some ( cached_decl) = ctx. concrete_declaration_cache . get ( & cache_key) {
635664 return Ok ( cached_decl. concrete_type_id . clone ( ) ) ;
@@ -653,6 +682,7 @@ fn generate_concrete_type_declaration(
653682
654683 let metadata_type_id = if type_metadata_decl. type_parameters . is_some ( )
655684 || type_metadata_decl. components . is_some ( )
685+ || type_metadata_decl. alias_of . is_some ( )
656686 {
657687 Some ( type_metadata_decl. metadata_type_id . clone ( ) )
658688 } else {
@@ -704,13 +734,39 @@ fn generate_type_metadata_declaration(
704734 resolved_type_id : TypeId ,
705735 metadata_types_to_add : & mut Vec < program_abi:: TypeMetadataDeclaration > ,
706736) -> Result < program_abi:: TypeMetadataDeclaration , ErrorEmitted > {
707- let cache_key = TypeCacheKey :: from_type_id ( engines, resolved_type_id) ;
737+ let cache_key =
738+ TypeCacheKey :: from_type_id ( engines, ctx. experimental . abi_type_aliases , resolved_type_id) ;
708739 if ctx. type_cache_enabled {
709740 if let Some ( cached_decl) = ctx. metadata_declaration_cache . get ( & cache_key) {
710741 return Ok ( cached_decl. clone ( ) ) ;
711742 }
712743 }
713744
745+ let mut alias_metadata_types_to_add = Vec :: < program_abi:: TypeMetadataDeclaration > :: new ( ) ;
746+
747+ let type_engine = engines. te ( ) ;
748+ let alias_of_metadata_decl = if ctx. experimental . abi_type_aliases {
749+ match & * type_engine. get ( resolved_type_id) {
750+ TypeInfo :: Alias { ty, .. } => {
751+ let dealiased_ty = fully_dealias_type_id ( engines, ty. type_id ) ;
752+ let dealiased_metadata_decl = generate_type_metadata_declaration (
753+ handler,
754+ ctx,
755+ engines,
756+ metadata_types,
757+ concrete_types,
758+ dealiased_ty,
759+ dealiased_ty,
760+ & mut alias_metadata_types_to_add,
761+ ) ?;
762+ Some ( dealiased_metadata_decl)
763+ }
764+ _ => None ,
765+ }
766+ } else {
767+ None
768+ } ;
769+
714770 let mut new_metadata_types_to_add = Vec :: < program_abi:: TypeMetadataDeclaration > :: new ( ) ;
715771
716772 let components = type_id. get_abi_type_components (
@@ -735,22 +791,87 @@ fn generate_type_metadata_declaration(
735791 let type_field =
736792 type_id. get_abi_type_str ( handler, & ctx. to_str_context ( ) , engines, resolved_type_id) ?;
737793
794+ let alias_of = alias_of_metadata_decl
795+ . as_ref ( )
796+ . map ( |decl| decl. metadata_type_id . clone ( ) ) ;
797+
738798 let type_metadata_decl = program_abi:: TypeMetadataDeclaration {
739799 metadata_type_id : MetadataTypeId ( type_id. index ( ) ) ,
740800 type_field,
741801 components,
742802 type_parameters,
743- alias_of : None ,
803+ alias_of,
744804 } ;
745805
746806 ctx. metadata_declaration_cache
747807 . insert ( cache_key, type_metadata_decl. clone ( ) ) ;
748808 metadata_types_to_add. push ( type_metadata_decl. clone ( ) ) ;
749809 metadata_types_to_add. extend ( new_metadata_types_to_add) ;
810+ metadata_types_to_add. extend ( alias_metadata_types_to_add) ;
750811
751812 Ok ( type_metadata_decl)
752813}
753814
815+ fn fully_dealias_type_id ( engines : & Engines , type_id : TypeId ) -> TypeId {
816+ fn inner ( engines : & Engines , type_id : TypeId , visited : & mut HashSet < TypeId > ) -> TypeId {
817+ if !visited. insert ( type_id) {
818+ return type_id;
819+ }
820+
821+ let type_engine = engines. te ( ) ;
822+ match & * type_engine. get ( type_id) {
823+ TypeInfo :: Alias { ty, .. } => inner ( engines, ty. type_id , visited) ,
824+ TypeInfo :: Tuple ( fields) => type_engine. insert_tuple (
825+ engines,
826+ fields
827+ . iter ( )
828+ . map ( |field| {
829+ let mut field_clone = field. clone ( ) ;
830+ let dealiased = inner ( engines, field_clone. type_id , visited) ;
831+ field_clone. type_id = dealiased;
832+ field_clone. initial_type_id = dealiased;
833+ field_clone
834+ } )
835+ . collect ( ) ,
836+ ) ,
837+ TypeInfo :: Array ( elem_ty, length) => {
838+ let mut elem_clone = elem_ty. clone ( ) ;
839+ let dealiased = inner ( engines, elem_clone. type_id , visited) ;
840+ elem_clone. type_id = dealiased;
841+ elem_clone. initial_type_id = dealiased;
842+ type_engine. insert_array ( engines, elem_clone, length. clone ( ) )
843+ }
844+ TypeInfo :: Slice ( elem_ty) => {
845+ let mut elem_clone = elem_ty. clone ( ) ;
846+ let dealiased = inner ( engines, elem_clone. type_id , visited) ;
847+ elem_clone. type_id = dealiased;
848+ elem_clone. initial_type_id = dealiased;
849+ type_engine. insert_slice ( engines, elem_clone)
850+ }
851+ TypeInfo :: Ptr ( elem_ty) => {
852+ let mut elem_clone = elem_ty. clone ( ) ;
853+ let dealiased = inner ( engines, elem_clone. type_id , visited) ;
854+ elem_clone. type_id = dealiased;
855+ elem_clone. initial_type_id = dealiased;
856+ type_engine. insert_ptr ( engines, elem_clone)
857+ }
858+ TypeInfo :: Ref {
859+ to_mutable_value,
860+ referenced_type,
861+ } => {
862+ let mut referenced_clone = referenced_type. clone ( ) ;
863+ let dealiased = inner ( engines, referenced_clone. type_id , visited) ;
864+ referenced_clone. type_id = dealiased;
865+ referenced_clone. initial_type_id = dealiased;
866+ type_engine. insert_ref ( engines, * to_mutable_value, referenced_clone)
867+ }
868+ _ => type_id,
869+ }
870+ }
871+
872+ inner ( engines, type_id, & mut HashSet :: new ( ) )
873+ }
874+
754875fn generate_logged_types (
755876 handler : & Handler ,
756877 ctx : & mut AbiContext ,
@@ -1294,16 +1415,20 @@ impl TypeId {
12941415 }
12951416 }
12961417 TypeInfo :: Alias { .. } => {
1297- if let TypeInfo :: Alias { ty, .. } = & * type_engine. get ( resolved_type_id) {
1298- ty. initial_type_id . get_abi_type_components (
1299- handler,
1300- ctx,
1301- engines,
1302- metadata_types,
1303- concrete_types,
1304- ty. type_id ,
1305- metadata_types_to_add,
1306- ) ?
1418+ if ctx. experimental . abi_type_aliases {
1419+ if let TypeInfo :: Alias { ty, .. } = & * type_engine. get ( resolved_type_id) {
1420+ ty. initial_type_id . get_abi_type_components (
1421+ handler,
1422+ ctx,
1423+ engines,
1424+ metadata_types,
1425+ concrete_types,
1426+ ty. type_id ,
1427+ metadata_types_to_add,
1428+ ) ?
1429+ } else {
1430+ None
1431+ }
13071432 } else {
13081433 None
13091434 }
@@ -1680,7 +1805,11 @@ impl GenericTypeParameter {
16801805 concrete_types : & mut Vec < program_abi:: TypeConcreteDeclaration > ,
16811806 metadata_types_to_add : & mut Vec < program_abi:: TypeMetadataDeclaration > ,
16821807 ) -> Result < MetadataTypeId , ErrorEmitted > {
1683- let cache_key = TypeCacheKey :: from_type_id ( engines, self . initial_type_id ) ;
1808+ let cache_key = TypeCacheKey :: from_type_id (
1809+ engines,
1810+ ctx. experimental . abi_type_aliases ,
1811+ self . initial_type_id ,
1812+ ) ;
16841813 if ctx. type_cache_enabled {
16851814 if let Some ( cached) = ctx. metadata_declaration_cache . get ( & cache_key) {
16861815 return Ok ( cached. metadata_type_id . clone ( ) ) ;
0 commit comments