@@ -170,15 +170,9 @@ pub(crate) fn transform(
170170
171171 // Covers all functions in the ast
172172 for submodule in ast. submodules . iter_mut ( ) . filter ( |submodule| submodule. is_contract ) {
173- let storage_defined = check_for_storage_definition ( & submodule. contents ) ;
174-
175- if transform_module ( & mut submodule. contents , storage_defined) {
176- match check_for_aztec_dependency ( crate_id, context) {
177- Ok ( ( ) ) => include_relevant_imports ( & mut submodule. contents ) ,
178- Err ( file_id) => {
179- return Err ( ( DefCollectorErrorKind :: AztecNotFound { } , file_id) ) ;
180- }
181- }
173+ if transform_module ( & mut submodule. contents , crate_id, context) ? {
174+ check_for_aztec_dependency ( crate_id, context) ?;
175+ include_relevant_imports ( & mut submodule. contents ) ;
182176 }
183177 }
184178 Ok ( ast)
@@ -209,19 +203,59 @@ fn include_relevant_imports(ast: &mut SortedModule) {
209203}
210204
211205/// Creates an error alerting the user that they have not downloaded the Aztec-noir library
212- fn check_for_aztec_dependency ( crate_id : & CrateId , context : & Context ) -> Result < ( ) , FileId > {
206+ fn check_for_aztec_dependency (
207+ crate_id : & CrateId ,
208+ context : & Context ,
209+ ) -> Result < ( ) , ( DefCollectorErrorKind , FileId ) > {
213210 let crate_graph = & context. crate_graph [ crate_id] ;
214211 let has_aztec_dependency = crate_graph. dependencies . iter ( ) . any ( |dep| dep. as_name ( ) == "aztec" ) ;
215212 if has_aztec_dependency {
216213 Ok ( ( ) )
217214 } else {
218- Err ( crate_graph. root_file_id )
215+ Err ( ( DefCollectorErrorKind :: AztecNotFound { } , crate_graph. root_file_id ) )
219216 }
220217}
221218
222219// Check to see if the user has defined a storage struct
223220fn check_for_storage_definition ( module : & SortedModule ) -> bool {
224- module. types . iter ( ) . any ( |function| function. name . 0 . contents == "Storage" )
221+ module. types . iter ( ) . any ( |r#struct| r#struct. name . 0 . contents == "Storage" )
222+ }
223+
224+ // Check if "compute_note_hash_and_nullifier(Field,Field,Field,[Field; N]) -> [Field; 4]" is defined
225+ fn check_for_compute_note_hash_and_nullifier_definition ( module : & SortedModule ) -> bool {
226+ module. functions . iter ( ) . any ( |func| {
227+ func. def . name . 0 . contents == "compute_note_hash_and_nullifier"
228+ && func. def . parameters . len ( ) == 4
229+ && func. def . parameters [ 0 ] . 1 . typ == UnresolvedTypeData :: FieldElement
230+ && func. def . parameters [ 1 ] . 1 . typ == UnresolvedTypeData :: FieldElement
231+ && func. def . parameters [ 2 ] . 1 . typ == UnresolvedTypeData :: FieldElement
232+ // checks if the 4th parameter is an array and the Box<UnresolvedType> in
233+ // Array(Option<UnresolvedTypeExpression>, Box<UnresolvedType>) contains only fields
234+ && match & func. def . parameters [ 3 ] . 1 . typ {
235+ UnresolvedTypeData :: Array ( _, inner_type) => {
236+ match inner_type. typ {
237+ UnresolvedTypeData :: FieldElement => true ,
238+ _ => false ,
239+ }
240+ } ,
241+ _ => false ,
242+ }
243+ // We check the return type the same way as we did the 4th parameter
244+ && match & func. def . return_type {
245+ FunctionReturnType :: Default ( _) => false ,
246+ FunctionReturnType :: Ty ( unresolved_type) => {
247+ match & unresolved_type. typ {
248+ UnresolvedTypeData :: Array ( _, inner_type) => {
249+ match inner_type. typ {
250+ UnresolvedTypeData :: FieldElement => true ,
251+ _ => false ,
252+ }
253+ } ,
254+ _ => false ,
255+ }
256+ }
257+ }
258+ } )
225259}
226260
227261/// Checks if an attribute is a custom attribute with a specific name
@@ -236,9 +270,26 @@ fn is_custom_attribute(attr: &SecondaryAttribute, attribute_name: &str) -> bool
236270/// Determines if ast nodes are annotated with aztec attributes.
237271/// For annotated functions it calls the `transform` function which will perform the required transformations.
238272/// Returns true if an annotated node is found, false otherwise
239- fn transform_module ( module : & mut SortedModule , storage_defined : bool ) -> bool {
273+ fn transform_module (
274+ module : & mut SortedModule ,
275+ crate_id : & CrateId ,
276+ context : & Context ,
277+ ) -> Result < bool , ( DefCollectorErrorKind , FileId ) > {
240278 let mut has_transformed_module = false ;
241279
280+ // Check for a user defined storage struct
281+ let storage_defined = check_for_storage_definition ( & module) ;
282+
283+ if storage_defined && check_for_compute_note_hash_and_nullifier_definition ( & module) {
284+ let crate_graph = & context. crate_graph [ crate_id] ;
285+ return Err ( (
286+ DefCollectorErrorKind :: AztecComputeNoteHashAndNullifierNotFound {
287+ span : Span :: default ( ) , // Add a default span so we know which contract file the error originates from
288+ } ,
289+ crate_graph. root_file_id ,
290+ ) ) ;
291+ }
292+
242293 for structure in module. types . iter ( ) {
243294 if structure. attributes . iter ( ) . any ( |attr| matches ! ( attr, SecondaryAttribute :: Event ) ) {
244295 module. impls . push ( generate_selector_impl ( structure) ) ;
@@ -262,7 +313,7 @@ fn transform_module(module: &mut SortedModule, storage_defined: bool) -> bool {
262313 has_transformed_module = true ;
263314 }
264315 }
265- has_transformed_module
316+ Ok ( has_transformed_module)
266317}
267318
268319/// If it does, it will insert the following things:
0 commit comments