@@ -189,6 +189,36 @@ enum TypeRootFilter {
189
189
TraitType ( String ) ,
190
190
}
191
191
192
+ #[ derive( Clone , Hash , Eq , PartialEq , Debug ) ]
193
+ enum TypeFilter {
194
+ Unknown ,
195
+ Never ,
196
+ Placeholder ,
197
+ TypeParam ( usize ) ,
198
+ StringSlice ,
199
+ StringArray ( usize ) ,
200
+ U8 ,
201
+ U16 ,
202
+ U32 ,
203
+ U64 ,
204
+ U256 ,
205
+ Bool ,
206
+ Custom ( String ) ,
207
+ B256 ,
208
+ Contract ,
209
+ ErrorRecovery ,
210
+ Tuple ( usize , Vec < Box < TypeFilter > > ) ,
211
+ Enum ( ParsedDeclId < EnumDeclaration > , Vec < Box < TypeFilter > > ) ,
212
+ Struct ( ParsedDeclId < StructDeclaration > , Vec < Box < TypeFilter > > ) ,
213
+ ContractCaller ( String ) ,
214
+ Array ( usize , Box < TypeFilter > ) ,
215
+ RawUntypedPtr ,
216
+ RawUntypedSlice ,
217
+ Ptr ( Box < TypeFilter > ) ,
218
+ Slice ( Box < TypeFilter > ) ,
219
+ TraitType ( String ) ,
220
+ }
221
+
192
222
/// Map holding trait implementations for types.
193
223
///
194
224
/// Note: "impl self" blocks are considered traits and are stored in the
@@ -197,7 +227,7 @@ enum TypeRootFilter {
197
227
pub ( crate ) struct TraitMap {
198
228
trait_impls : TraitImpls ,
199
229
satisfied_cache : im:: HashSet < u64 > ,
200
- insert_for_type_cache : im:: HashMap < TypeRootFilter , im:: Vector < TypeId > > ,
230
+ insert_for_type_cache : im:: HashMap < TypeFilter , im:: Vector < TypeId > > ,
201
231
}
202
232
203
233
pub ( crate ) enum IsImplSelf {
@@ -541,7 +571,7 @@ impl TraitMap {
541
571
let trait_map = TraitMap {
542
572
trait_impls,
543
573
satisfied_cache : im:: HashSet :: default ( ) ,
544
- insert_for_type_cache : im:: HashMap :: < TypeRootFilter , im:: Vector < TypeId > > :: new ( ) ,
574
+ insert_for_type_cache : im:: HashMap :: < TypeFilter , im:: Vector < TypeId > > :: new ( ) ,
545
575
} ;
546
576
547
577
self . extend ( trait_map, engines) ;
@@ -639,7 +669,7 @@ impl TraitMap {
639
669
type_id : TypeId ,
640
670
code_block_first_pass : CodeBlockFirstPass ,
641
671
) {
642
- let root_filter = TraitMap :: get_type_root_filter ( engines, type_id) ;
672
+ let root_filter = TraitMap :: get_type_filter ( engines, type_id) ;
643
673
if let Some ( values) = self . insert_for_type_cache . get_mut ( & root_filter) {
644
674
let unify_checker = UnifyCheck :: non_dynamic_equality ( engines) . with_unify_ref_mut ( false ) ;
645
675
if values. iter ( ) . any ( |v| unify_checker. check ( type_id, * v) ) {
@@ -1725,4 +1755,88 @@ impl TraitMap {
1725
1755
} => Self :: get_type_root_filter ( engines, referenced_type. type_id ) ,
1726
1756
}
1727
1757
}
1758
+
1759
+ // This is used by the trait map to filter the entries into a HashMap with the return type string as key.
1760
+ fn get_type_filter ( engines : & Engines , type_id : TypeId ) -> TypeFilter {
1761
+ use TypeInfo :: * ;
1762
+ match & * engines. te ( ) . get ( type_id) {
1763
+ Unknown => TypeFilter :: Unknown ,
1764
+ Never => TypeFilter :: Never ,
1765
+ UnknownGeneric { .. } | Placeholder ( _) => TypeFilter :: Placeholder ,
1766
+ TypeParam ( n) => TypeFilter :: TypeParam ( * n) ,
1767
+ StringSlice => TypeFilter :: StringSlice ,
1768
+ StringArray ( x) => TypeFilter :: StringArray ( x. val ( ) ) ,
1769
+ UnsignedInteger ( x) => match x {
1770
+ IntegerBits :: Eight => TypeFilter :: U8 ,
1771
+ IntegerBits :: Sixteen => TypeFilter :: U16 ,
1772
+ IntegerBits :: ThirtyTwo => TypeFilter :: U32 ,
1773
+ IntegerBits :: SixtyFour => TypeFilter :: U64 ,
1774
+ IntegerBits :: V256 => TypeFilter :: U256 ,
1775
+ } ,
1776
+ Boolean => TypeFilter :: Bool ,
1777
+ Custom {
1778
+ qualified_call_path : call_path,
1779
+ ..
1780
+ } => TypeFilter :: Custom ( call_path. call_path . suffix . to_string ( ) ) ,
1781
+ B256 => TypeFilter :: B256 ,
1782
+ Numeric => TypeFilter :: U64 , // u64 is the default
1783
+ Contract => TypeFilter :: Contract ,
1784
+ ErrorRecovery ( _) => TypeFilter :: ErrorRecovery ,
1785
+ Tuple ( fields) => TypeFilter :: Tuple (
1786
+ fields. len ( ) ,
1787
+ fields
1788
+ . iter ( )
1789
+ . map ( |f| Box :: new ( Self :: get_type_filter ( engines, f. type_id ) ) )
1790
+ . collect :: < Vec < _ > > ( ) ,
1791
+ ) ,
1792
+ UntypedEnum ( _) => unreachable ! ( ) ,
1793
+ UntypedStruct ( _) => unreachable ! ( ) ,
1794
+ Enum ( decl_id) => {
1795
+ // TODO Remove unwrap once #6475 is fixed
1796
+ TypeFilter :: Enum (
1797
+ engines. de ( ) . get_parsed_decl_id ( decl_id) . unwrap ( ) ,
1798
+ engines
1799
+ . de ( )
1800
+ . get_enum ( decl_id)
1801
+ . type_parameters
1802
+ . iter ( )
1803
+ . map ( |f| Box :: new ( Self :: get_type_filter ( engines, f. type_id ) ) )
1804
+ . collect :: < Vec < _ > > ( ) ,
1805
+ )
1806
+ }
1807
+ Struct ( decl_id) => {
1808
+ // TODO Remove unwrap once #6475 is fixed
1809
+ TypeFilter :: Struct (
1810
+ engines. de ( ) . get_parsed_decl_id ( decl_id) . unwrap ( ) ,
1811
+ engines
1812
+ . de ( )
1813
+ . get_struct ( decl_id)
1814
+ . type_parameters
1815
+ . iter ( )
1816
+ . map ( |f| Box :: new ( Self :: get_type_filter ( engines, f. type_id ) ) )
1817
+ . collect :: < Vec < _ > > ( ) ,
1818
+ )
1819
+ }
1820
+ ContractCaller { abi_name, .. } => TypeFilter :: ContractCaller ( abi_name. to_string ( ) ) ,
1821
+ Array ( type_argument, length) => TypeFilter :: Array (
1822
+ length. val ( ) ,
1823
+ Box :: new ( Self :: get_type_filter ( engines, type_argument. type_id ) ) ,
1824
+ ) ,
1825
+ RawUntypedPtr => TypeFilter :: RawUntypedPtr ,
1826
+ RawUntypedSlice => TypeFilter :: RawUntypedSlice ,
1827
+ Ptr ( type_argument) => TypeFilter :: Ptr ( Box :: new ( Self :: get_type_filter (
1828
+ engines,
1829
+ type_argument. type_id ,
1830
+ ) ) ) ,
1831
+ Slice ( type_argument) => TypeFilter :: Slice ( Box :: new ( Self :: get_type_filter (
1832
+ engines,
1833
+ type_argument. type_id ,
1834
+ ) ) ) ,
1835
+ Alias { ty, .. } => Self :: get_type_filter ( engines, ty. type_id ) ,
1836
+ TraitType { name, .. } => TypeFilter :: TraitType ( name. to_string ( ) ) ,
1837
+ Ref {
1838
+ referenced_type, ..
1839
+ } => Self :: get_type_filter ( engines, referenced_type. type_id ) ,
1840
+ }
1841
+ }
1728
1842
}
0 commit comments