diff --git a/crates/nargo/src/cli/check_cmd.rs b/crates/nargo/src/cli/check_cmd.rs index 61aa17d7db7..8fd4573ef22 100644 --- a/crates/nargo/src/cli/check_cmd.rs +++ b/crates/nargo/src/cli/check_cmd.rs @@ -2,7 +2,7 @@ use crate::{errors::CliError, resolver::Resolver}; use acvm::ProofSystemCompiler; use clap::Args; use iter_extended::btree_map; -use noirc_abi::{Abi, AbiParameter, AbiType}; +use noirc_abi::{AbiParameter, AbiType, MAIN_RETURN_NAME}; use std::{ collections::BTreeMap, path::{Path, PathBuf}, @@ -37,7 +37,7 @@ fn check_from_path>(p: P, allow_warnings: bool) -> Result<(), Cli } // XXX: We can have a --overwrite flag to determine if you want to overwrite the Prover/Verifier.toml files - if let Some(abi) = driver.compute_abi() { + if let Some((parameters, return_type)) = driver.compute_function_signature() { // XXX: The root config should return an enum to determine if we are looking for .json or .toml // For now it is hard-coded to be toml. // @@ -49,12 +49,15 @@ fn check_from_path>(p: P, allow_warnings: bool) -> Result<(), Cli // If they are not available, then create them and // populate them based on the ABI if !path_to_prover_input.exists() { - let toml = toml::to_string(&build_empty_map(abi.clone())).unwrap(); + let toml = + toml::to_string(&build_placeholder_input_map(parameters.clone(), None)).unwrap(); write_to_file(toml.as_bytes(), &path_to_prover_input); } if !path_to_verifier_input.exists() { - let public_abi = abi.public_abi(); - let toml = toml::to_string(&build_empty_map(public_abi)).unwrap(); + let public_inputs = parameters.into_iter().filter(|param| param.is_public()).collect(); + + let toml = + toml::to_string(&build_placeholder_input_map(public_inputs, return_type)).unwrap(); write_to_file(toml.as_bytes(), &path_to_verifier_input); } } else { @@ -63,11 +66,26 @@ fn check_from_path>(p: P, allow_warnings: bool) -> Result<(), Cli Ok(()) } -fn build_empty_map(abi: Abi) -> BTreeMap { - btree_map(abi.parameters, |AbiParameter { name, typ, .. }| { - let default_value = if matches!(typ, AbiType::Array { .. }) { "[]" } else { "" }; - (name, default_value) - }) +fn build_placeholder_input_map( + parameters: Vec, + return_type: Option, +) -> BTreeMap { + let default_value = |typ: AbiType| { + if matches!(typ, AbiType::Array { .. }) { + "[]" + } else { + "" + } + }; + + let mut map = + btree_map(parameters, |AbiParameter { name, typ, .. }| (name, default_value(typ))); + + if let Some(typ) = return_type { + map.insert(MAIN_RETURN_NAME.to_owned(), default_value(typ)); + } + + map } #[cfg(test)] diff --git a/crates/noirc_abi/src/lib.rs b/crates/noirc_abi/src/lib.rs index 6d34d9a55e3..1a5293b160c 100644 --- a/crates/noirc_abi/src/lib.rs +++ b/crates/noirc_abi/src/lib.rs @@ -24,6 +24,9 @@ pub type InputMap = BTreeMap; /// A map from the witnesses in a constraint system to the field element values pub type WitnessMap = BTreeMap; +/// A tuple of the arguments to a function along with its return value. +pub type FunctionSignature = (Vec, Option); + pub const MAIN_RETURN_NAME: &str = "return"; #[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)] diff --git a/crates/noirc_driver/src/lib.rs b/crates/noirc_driver/src/lib.rs index a034128307e..d898a0ae1c7 100644 --- a/crates/noirc_driver/src/lib.rs +++ b/crates/noirc_driver/src/lib.rs @@ -4,7 +4,7 @@ use acvm::Language; use fm::FileType; -use noirc_abi::Abi; +use noirc_abi::FunctionSignature; use noirc_errors::{reporter, ReportedError}; use noirc_evaluator::create_circuit; use noirc_frontend::graph::{CrateId, CrateName, CrateType, LOCAL_CRATE}; @@ -129,15 +129,14 @@ impl Driver { reporter::finish_report(error_count) } - pub fn compute_abi(&self) -> Option { + pub fn compute_function_signature(&self) -> Option { let local_crate = self.context.def_map(LOCAL_CRATE).unwrap(); let main_function = local_crate.main_function()?; let func_meta = self.context.def_interner.function_meta(&main_function); - let abi = func_meta.into_abi(&self.context.def_interner); - Some(abi) + Some(func_meta.into_function_signature(&self.context.def_interner)) } pub fn into_compiled_program( diff --git a/crates/noirc_evaluator/src/lib.rs b/crates/noirc_evaluator/src/lib.rs index dc43a3aa89c..d2c988d64d3 100644 --- a/crates/noirc_evaluator/src/lib.rs +++ b/crates/noirc_evaluator/src/lib.rs @@ -63,14 +63,14 @@ pub fn create_circuit( let witness_index = evaluator.current_witness_index(); - let mut abi = program.abi; + let (parameters, return_type) = program.main_function_signature; // TODO: remove return value from `param_witnesses` once we track public outputs // see https://github.com/noir-lang/acvm/pull/56 let mut param_witnesses = evaluator.param_witnesses; let return_witnesses = param_witnesses.remove(MAIN_RETURN_NAME).unwrap_or_default(); - abi.param_witnesses = param_witnesses; - abi.return_witnesses = return_witnesses; + + let abi = Abi { parameters, param_witnesses, return_type, return_witnesses }; let optimized_circuit = acvm::compiler::compile( Circuit { @@ -287,7 +287,7 @@ impl Evaluator { // The new grammar has been conceived, and will be implemented. let main = ir_gen.program.main(); let main_params = std::mem::take(&mut main.parameters); - let abi_params = std::mem::take(&mut ir_gen.program.abi.parameters); + let abi_params = std::mem::take(&mut ir_gen.program.main_function_signature.0); assert_eq!(main_params.len(), abi_params.len()); diff --git a/crates/noirc_frontend/src/hir_def/function.rs b/crates/noirc_frontend/src/hir_def/function.rs index 1f80cd09df8..df87c5d4eec 100644 --- a/crates/noirc_frontend/src/hir_def/function.rs +++ b/crates/noirc_frontend/src/hir_def/function.rs @@ -1,7 +1,5 @@ -use std::collections::BTreeMap; - use iter_extended::vecmap; -use noirc_abi::{Abi, AbiParameter, AbiVisibility}; +use noirc_abi::{AbiParameter, AbiType, AbiVisibility}; use noirc_errors::{Location, Span}; use super::expr::{HirBlockExpression, HirExpression, HirIdent}; @@ -55,20 +53,14 @@ fn get_param_name<'a>(pattern: &HirPattern, interner: &'a NodeInterner) -> Optio pub struct Parameters(pub Vec); impl Parameters { - fn into_abi(self, interner: &NodeInterner) -> Abi { - let parameters = vecmap(self.0, |param| { + fn into_abi_params(self, interner: &NodeInterner) -> Vec { + vecmap(self.0, |param| { let param_name = get_param_name(¶m.0, interner) .expect("Abi for tuple and struct parameters is unimplemented") .to_owned(); let as_abi = param.1.as_abi_type(); AbiParameter { name: param_name, typ: as_abi, visibility: param.2 } - }); - noirc_abi::Abi { - parameters, - param_witnesses: BTreeMap::new(), - return_type: None, - return_witnesses: Vec::new(), - } + }) } pub fn span(&self) -> Span { @@ -147,15 +139,18 @@ impl FuncMeta { } } - pub fn into_abi(self, interner: &NodeInterner) -> Abi { - let return_type = self.return_type().clone(); - let mut abi = self.parameters.into_abi(interner); - abi.return_type = match return_type { + pub fn into_function_signature( + self, + interner: &NodeInterner, + ) -> (Vec, Option) { + let return_type = match self.return_type() { Type::Unit => None, - _ => Some(return_type.as_abi_type()), + typ => Some(typ.as_abi_type()), }; - abi + let params = self.parameters.into_abi_params(interner); + + (params, return_type) } /// Gives the (uninstantiated) return type of this function. diff --git a/crates/noirc_frontend/src/monomorphization/ast.rs b/crates/noirc_frontend/src/monomorphization/ast.rs index bcd6c744ff5..add01cbb2d2 100644 --- a/crates/noirc_frontend/src/monomorphization/ast.rs +++ b/crates/noirc_frontend/src/monomorphization/ast.rs @@ -1,6 +1,6 @@ use acvm::FieldElement; use iter_extended::vecmap; -use noirc_abi::Abi; +use noirc_abi::FunctionSignature; use noirc_errors::Location; use crate::{BinaryOpKind, Signedness}; @@ -185,12 +185,12 @@ impl Type { #[derive(Debug, Clone)] pub struct Program { pub functions: Vec, - pub abi: Abi, + pub main_function_signature: FunctionSignature, } impl Program { - pub fn new(functions: Vec, abi: Abi) -> Program { - Program { functions, abi } + pub fn new(functions: Vec, main_function_signature: FunctionSignature) -> Program { + Program { functions, main_function_signature } } pub fn main(&mut self) -> &mut Function { diff --git a/crates/noirc_frontend/src/monomorphization/mod.rs b/crates/noirc_frontend/src/monomorphization/mod.rs index 43ab1a31dbb..29fccff155f 100644 --- a/crates/noirc_frontend/src/monomorphization/mod.rs +++ b/crates/noirc_frontend/src/monomorphization/mod.rs @@ -1,6 +1,6 @@ use acvm::FieldElement; use iter_extended::{btree_map, vecmap}; -use noirc_abi::Abi; +use noirc_abi::FunctionSignature; use std::collections::{BTreeMap, HashMap, VecDeque}; use crate::{ @@ -40,7 +40,7 @@ type HirType = crate::Type; pub fn monomorphize(main: node_interner::FuncId, interner: &NodeInterner) -> Program { let mut monomorphizer = Monomorphizer::new(interner); - let abi = monomorphizer.compile_main(main); + let function_sig = monomorphizer.compile_main(main); while !monomorphizer.queue.is_empty() { let (next_fn_id, new_id, bindings) = monomorphizer.queue.pop_front().unwrap(); @@ -52,7 +52,7 @@ pub fn monomorphize(main: node_interner::FuncId, interner: &NodeInterner) -> Pro } let functions = vecmap(monomorphizer.finished_functions, |(_, f)| f); - Program::new(functions, abi) + Program::new(functions, function_sig) } impl<'interner> Monomorphizer<'interner> { @@ -129,13 +129,13 @@ impl<'interner> Monomorphizer<'interner> { self.globals.entry(id).or_default().insert(typ, new_id); } - fn compile_main(&mut self, main_id: node_interner::FuncId) -> Abi { + fn compile_main(&mut self, main_id: node_interner::FuncId) -> FunctionSignature { let new_main_id = self.next_function_id(); assert_eq!(new_main_id, Program::main_id()); self.function(main_id, new_main_id); let main_meta = self.interner.function_meta(&main_id); - main_meta.into_abi(self.interner) + main_meta.into_function_signature(self.interner) } fn function(&mut self, f: node_interner::FuncId, id: FuncId) {