@@ -17,7 +17,7 @@ mod bytes;
1717mod parse;
1818mod serialize;
1919
20- use crate :: { ArrayType , Identifier , LiteralType } ;
20+ use crate :: { ArrayType , Identifier , LiteralType , Locator , ProgramID } ;
2121use snarkvm_console_network:: prelude:: * ;
2222
2323/// A `PlaintextType` defines the type parameter for a literal, struct, or array.
@@ -26,14 +26,49 @@ pub enum PlaintextType<N: Network> {
2626 /// A literal type contains its type name.
2727 /// The format of the type is `<type_name>`.
2828 Literal ( LiteralType ) ,
29- /// An struct type contains its identifier.
29+ /// A struct type contains its identifier.
3030 /// The format of the type is `<identifier>`.
3131 Struct ( Identifier < N > ) ,
32+ /// An external struct type contains its locator.
33+ /// The format of the type is `<program_id>/<identifier>`.
34+ ExternalStruct ( Locator < N > ) ,
3235 /// An array type contains its element type and length.
3336 /// The format of the type is `[<element_type>; <length>]`.
3437 Array ( ArrayType < N > ) ,
3538}
3639
40+ impl < N : Network > PlaintextType < N > {
41+ /// Are the two types equivalent for the purposes of static checking?
42+ ///
43+ /// Since struct types are compared by structure, we can't determine equality
44+ /// by only looking at their names.
45+ pub fn equal_or_structs ( & self , rhs : & Self ) -> bool {
46+ use PlaintextType :: * ;
47+
48+ match ( self , rhs) {
49+ ( ExternalStruct ( ..) | Struct ( ..) , ExternalStruct ( ..) | Struct ( ..) ) => true ,
50+ ( Literal ( lit0) , Literal ( lit1) ) => lit0 == lit1,
51+ ( Array ( array0) , Array ( array1) ) => {
52+ array0. length ( ) == array1. length ( )
53+ && array0. base_element_type ( ) . equal_or_structs ( array1. base_element_type ( ) )
54+ }
55+ _ => false ,
56+ }
57+ }
58+
59+ // Make unqualified structs into external ones with the given `id`.
60+ pub fn qualify ( self , id : ProgramID < N > ) -> Self {
61+ match self {
62+ PlaintextType :: ExternalStruct ( ..) | PlaintextType :: Literal ( ..) => self ,
63+ PlaintextType :: Struct ( name) => PlaintextType :: ExternalStruct ( Locator :: new ( id, name) ) ,
64+ PlaintextType :: Array ( array_type) => {
65+ let element_type = array_type. next_element_type ( ) . clone ( ) . qualify ( id) ;
66+ PlaintextType :: Array ( ArrayType :: new ( element_type, vec ! [ * array_type. length( ) ] ) . unwrap ( ) )
67+ }
68+ }
69+ }
70+ }
71+
3772impl < N : Network > From < LiteralType > for PlaintextType < N > {
3873 /// Initializes a plaintext type from a literal type.
3974 fn from ( literal : LiteralType ) -> Self {
@@ -48,6 +83,13 @@ impl<N: Network> From<Identifier<N>> for PlaintextType<N> {
4883 }
4984}
5085
86+ impl < N : Network > From < Locator < N > > for PlaintextType < N > {
87+ /// Initializes a plaintext type from an external struct type.
88+ fn from ( locator : Locator < N > ) -> Self {
89+ PlaintextType :: ExternalStruct ( locator)
90+ }
91+ }
92+
5193impl < N : Network > From < ArrayType < N > > for PlaintextType < N > {
5294 /// Initializes a plaintext type from an array type.
5395 fn from ( array : ArrayType < N > ) -> Self {
0 commit comments