diff --git a/aztec_macros/src/lib.rs b/aztec_macros/src/lib.rs index 24f0f5a71b6..a0ab4e79760 100644 --- a/aztec_macros/src/lib.rs +++ b/aztec_macros/src/lib.rs @@ -31,10 +31,15 @@ impl MacroProcessor for AztecMacro { } } +const FUNCTION_TREE_HEIGHT: u32 = 5; +const MAX_CONTRACT_FUNCTIONS: usize = 2_usize.pow(FUNCTION_TREE_HEIGHT); + #[derive(Debug, Clone)] pub enum AztecMacroError { AztecNotFound, AztecComputeNoteHashAndNullifierNotFound { span: Span }, + AztecContractHasTooManyFunctions { span: Span }, + AztecContractConstructorMissing { span: Span }, } impl From for MacroError { @@ -50,6 +55,16 @@ impl From for MacroError { secondary_message: None, span: Some(span), }, + AztecMacroError::AztecContractHasTooManyFunctions { span } => MacroError { + primary_message: format!("Contract can only have a maximum of {} functions", MAX_CONTRACT_FUNCTIONS), + secondary_message: None, + span: Some(span), + }, + AztecMacroError::AztecContractConstructorMissing { span } => MacroError { + primary_message: "Contract must have a constructor function".to_owned(), + secondary_message: None, + span: Some(span), + }, } } } @@ -340,6 +355,28 @@ fn transform_module( has_transformed_module = true; } } + + if has_transformed_module { + // We only want to run these checks if the macro processor has found the module to be an Aztec contract. + + if module.functions.len() > MAX_CONTRACT_FUNCTIONS { + let crate_graph = &context.crate_graph[crate_id]; + return Err(( + AztecMacroError::AztecContractHasTooManyFunctions { span: Span::default() }.into(), + crate_graph.root_file_id, + )); + } + + let constructor_defined = module.functions.iter().any(|func| func.name() == "constructor"); + if !constructor_defined { + let crate_graph = &context.crate_graph[crate_id]; + return Err(( + AztecMacroError::AztecContractConstructorMissing { span: Span::default() }.into(), + crate_graph.root_file_id, + )); + } + } + Ok(has_transformed_module) }