@@ -21,6 +21,57 @@ pub const BN254_FP_SERIALIZED_SIZE: u32 = 32;
2121pub const BN254_G1_SERIALIZED_SIZE : u32 = BN254_FP_SERIALIZED_SIZE * 2 ; // 64
2222pub const BN254_G2_SERIALIZED_SIZE : u32 = BN254_G1_SERIALIZED_SIZE * 2 ; // 128
2323
24+ /// Returns true if `name` matches a built-in Soroban type that is
25+ /// recognized by `map_type`. Types with these names cannot be used as
26+ /// `#[contracttype]` names because `map_type` would silently classify them
27+ /// as built-in types instead of user-defined types in the contract spec.
28+ pub fn is_reserved_type_name ( name : & str ) -> bool {
29+ matches ! (
30+ name,
31+ // Non-generic built-in types
32+ "Val"
33+ | "u64"
34+ | "i64"
35+ | "u32"
36+ | "i32"
37+ | "u128"
38+ | "i128"
39+ | "U256"
40+ | "I256"
41+ | "bool"
42+ | "Symbol"
43+ | "String"
44+ | "Error"
45+ | "Bytes"
46+ | "Address"
47+ | "MuxedAddress"
48+ | "Timepoint"
49+ | "Duration"
50+ // BLS12-381 types (unprefixed)
51+ | "Fp"
52+ | "Fp2"
53+ | "G1Affine"
54+ | "G2Affine"
55+ | "Fr"
56+ // BLS12-381 types (prefixed)
57+ | "Bls12381Fp"
58+ | "Bls12381Fp2"
59+ | "Bls12381G1Affine"
60+ | "Bls12381G2Affine"
61+ // BN254 types
62+ | "Bn254Fp"
63+ | "Bn254G1Affine"
64+ | "Bn254G2Affine"
65+ // Generic built-in types
66+ | "Result"
67+ | "Option"
68+ | "Vec"
69+ | "Map"
70+ | "BytesN"
71+ | "Hash"
72+ )
73+ }
74+
2475#[ allow( clippy:: too_many_lines) ]
2576pub fn map_type ( t : & Type , allow_ref : bool , allow_hash : bool ) -> Result < ScSpecTypeDef , Error > {
2677 match t {
@@ -299,4 +350,59 @@ mod test {
299350 } ) )
300351 ) ;
301352 }
353+
354+ #[ test]
355+ fn test_is_reserved_type_name ( ) {
356+ // Non-generic built-in types
357+ assert ! ( is_reserved_type_name( "Val" ) ) ;
358+ assert ! ( is_reserved_type_name( "u64" ) ) ;
359+ assert ! ( is_reserved_type_name( "i64" ) ) ;
360+ assert ! ( is_reserved_type_name( "u32" ) ) ;
361+ assert ! ( is_reserved_type_name( "i32" ) ) ;
362+ assert ! ( is_reserved_type_name( "u128" ) ) ;
363+ assert ! ( is_reserved_type_name( "i128" ) ) ;
364+ assert ! ( is_reserved_type_name( "U256" ) ) ;
365+ assert ! ( is_reserved_type_name( "I256" ) ) ;
366+ assert ! ( is_reserved_type_name( "bool" ) ) ;
367+ assert ! ( is_reserved_type_name( "Symbol" ) ) ;
368+ assert ! ( is_reserved_type_name( "String" ) ) ;
369+ assert ! ( is_reserved_type_name( "Error" ) ) ;
370+ assert ! ( is_reserved_type_name( "Bytes" ) ) ;
371+ assert ! ( is_reserved_type_name( "Address" ) ) ;
372+ assert ! ( is_reserved_type_name( "MuxedAddress" ) ) ;
373+ assert ! ( is_reserved_type_name( "Timepoint" ) ) ;
374+ assert ! ( is_reserved_type_name( "Duration" ) ) ;
375+
376+ // BLS12-381 types (unprefixed)
377+ assert ! ( is_reserved_type_name( "Fp" ) ) ;
378+ assert ! ( is_reserved_type_name( "Fp2" ) ) ;
379+ assert ! ( is_reserved_type_name( "G1Affine" ) ) ;
380+ assert ! ( is_reserved_type_name( "G2Affine" ) ) ;
381+ assert ! ( is_reserved_type_name( "Fr" ) ) ;
382+
383+ // BLS12-381 types (prefixed)
384+ assert ! ( is_reserved_type_name( "Bls12381Fp" ) ) ;
385+ assert ! ( is_reserved_type_name( "Bls12381Fp2" ) ) ;
386+ assert ! ( is_reserved_type_name( "Bls12381G1Affine" ) ) ;
387+ assert ! ( is_reserved_type_name( "Bls12381G2Affine" ) ) ;
388+
389+ // BN254 types
390+ assert ! ( is_reserved_type_name( "Bn254Fp" ) ) ;
391+ assert ! ( is_reserved_type_name( "Bn254G1Affine" ) ) ;
392+ assert ! ( is_reserved_type_name( "Bn254G2Affine" ) ) ;
393+
394+ // Generic built-in types
395+ assert ! ( is_reserved_type_name( "Result" ) ) ;
396+ assert ! ( is_reserved_type_name( "Option" ) ) ;
397+ assert ! ( is_reserved_type_name( "Vec" ) ) ;
398+ assert ! ( is_reserved_type_name( "Map" ) ) ;
399+ assert ! ( is_reserved_type_name( "BytesN" ) ) ;
400+ assert ! ( is_reserved_type_name( "Hash" ) ) ;
401+
402+ // Non-reserved names
403+ assert ! ( !is_reserved_type_name( "MyStruct" ) ) ;
404+ assert ! ( !is_reserved_type_name( "Token" ) ) ;
405+ assert ! ( !is_reserved_type_name( "MyAddress" ) ) ;
406+ assert ! ( !is_reserved_type_name( "address" ) ) ;
407+ }
302408}
0 commit comments