From c96ae48c62c4b0c60a882130bc4e4386653deb7e Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Fri, 20 Oct 2023 15:24:41 +0100 Subject: [PATCH 1/7] chore: add backend interface definition to convert proof/vk to fields (#3203) --- tooling/backend_interface/src/cli/mod.rs | 4 ++ .../src/cli/proof_as_fields.rs | 38 ++++++++++++ .../backend_interface/src/cli/vk_as_fields.rs | 39 ++++++++++++ tooling/backend_interface/src/proof_system.rs | 62 +++++++++++++++---- tooling/bb_abstraction_leaks/src/lib.rs | 12 ++-- 5 files changed, 137 insertions(+), 18 deletions(-) create mode 100644 tooling/backend_interface/src/cli/proof_as_fields.rs create mode 100644 tooling/backend_interface/src/cli/vk_as_fields.rs diff --git a/tooling/backend_interface/src/cli/mod.rs b/tooling/backend_interface/src/cli/mod.rs index d1eebb1ba8e..3ea65f28103 100644 --- a/tooling/backend_interface/src/cli/mod.rs +++ b/tooling/backend_interface/src/cli/mod.rs @@ -3,17 +3,21 @@ mod contract; mod gates; mod info; +mod proof_as_fields; mod prove; mod verify; mod version; +mod vk_as_fields; mod write_vk; pub(crate) use contract::ContractCommand; pub(crate) use gates::GatesCommand; pub(crate) use info::InfoCommand; +pub(crate) use proof_as_fields::ProofAsFieldsCommand; pub(crate) use prove::ProveCommand; pub(crate) use verify::VerifyCommand; pub(crate) use version::VersionCommand; +pub(crate) use vk_as_fields::VkAsFieldsCommand; pub(crate) use write_vk::WriteVkCommand; #[test] diff --git a/tooling/backend_interface/src/cli/proof_as_fields.rs b/tooling/backend_interface/src/cli/proof_as_fields.rs new file mode 100644 index 00000000000..7eb1c1ef35c --- /dev/null +++ b/tooling/backend_interface/src/cli/proof_as_fields.rs @@ -0,0 +1,38 @@ +use std::path::{Path, PathBuf}; + +use acvm::FieldElement; + +use crate::BackendError; + +use super::string_from_stderr; + +/// `ProofAsFieldsCommand` will call the barretenberg binary +/// to split a proof into a representation as [`FieldElement`]s. +pub(crate) struct ProofAsFieldsCommand { + pub(crate) proof_path: PathBuf, + pub(crate) vk_path: PathBuf, +} + +impl ProofAsFieldsCommand { + pub(crate) fn run(self, binary_path: &Path) -> Result, BackendError> { + let mut command = std::process::Command::new(binary_path); + + command + .arg("proof_as_fields") + .arg("-p") + .arg(self.proof_path) + .arg("-k") + .arg(self.vk_path) + .arg("-o") + .arg("-"); + + let output = command.output()?; + if output.status.success() { + let string_output = String::from_utf8(output.stdout).unwrap(); + serde_json::from_str(&string_output) + .map_err(|err| BackendError::CommandFailed(err.to_string())) + } else { + Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) + } + } +} diff --git a/tooling/backend_interface/src/cli/vk_as_fields.rs b/tooling/backend_interface/src/cli/vk_as_fields.rs new file mode 100644 index 00000000000..1b0212241c4 --- /dev/null +++ b/tooling/backend_interface/src/cli/vk_as_fields.rs @@ -0,0 +1,39 @@ +use std::path::{Path, PathBuf}; + +use acvm::FieldElement; + +use crate::BackendError; + +use super::string_from_stderr; + +/// VkAsFieldsCommand will call the barretenberg binary +/// to split a verification key into a representation as [`FieldElement`]s. +/// +/// The hash of the verification key will also be returned. +pub(crate) struct VkAsFieldsCommand { + pub(crate) vk_path: PathBuf, +} + +impl VkAsFieldsCommand { + pub(crate) fn run( + self, + binary_path: &Path, + ) -> Result<(FieldElement, Vec), BackendError> { + let mut command = std::process::Command::new(binary_path); + + command.arg("vk_as_fields").arg("-k").arg(self.vk_path).arg("-o").arg("-"); + + let output = command.output()?; + if output.status.success() { + let string_output = String::from_utf8(output.stdout).unwrap(); + let mut fields: Vec = serde_json::from_str(&string_output) + .map_err(|err| BackendError::CommandFailed(err.to_string()))?; + + // The first element of this vector is the hash of the verification key, we want to split that off. + let hash = fields.remove(0); + Ok((hash, fields)) + } else { + Err(BackendError::CommandFailed(string_from_stderr(&output.stderr))) + } + } +} diff --git a/tooling/backend_interface/src/proof_system.rs b/tooling/backend_interface/src/proof_system.rs index 7d6e7d51888..c4fc6e743e5 100644 --- a/tooling/backend_interface/src/proof_system.rs +++ b/tooling/backend_interface/src/proof_system.rs @@ -7,7 +7,10 @@ use acvm::FieldElement; use acvm::Language; use tempfile::tempdir; -use crate::cli::{GatesCommand, InfoCommand, ProveCommand, VerifyCommand, WriteVkCommand}; +use crate::cli::{ + GatesCommand, InfoCommand, ProofAsFieldsCommand, ProveCommand, VerifyCommand, + VkAsFieldsCommand, WriteVkCommand, +}; use crate::{Backend, BackendError, BackendOpcodeSupport}; impl Backend { @@ -86,17 +89,9 @@ impl Backend { let temp_directory = tempdir().expect("could not create a temporary directory"); let temp_directory = temp_directory.path().to_path_buf(); - // Unlike when proving, we omit any unassigned witnesses. - // Witness values should be ordered by their index but we skip over any indices without an assignment. - let flattened_public_inputs: Vec = - public_inputs.into_iter().map(|(_, el)| el).collect(); - - let proof_with_public_inputs = bb_abstraction_leaks::prepend_public_inputs( - proof.to_vec(), - flattened_public_inputs.to_vec(), - ); - // Create a temporary file for the proof + let proof_with_public_inputs = + bb_abstraction_leaks::prepend_public_inputs(proof.to_vec(), public_inputs); let proof_path = temp_directory.join("proof").with_extension("proof"); write_to_file(&proof_with_public_inputs, &proof_path); @@ -119,6 +114,51 @@ impl Backend { VerifyCommand { crs_path: self.crs_directory(), is_recursive, proof_path, vk_path } .run(binary_path) } + + pub fn get_intermediate_proof_artifacts( + &self, + circuit: &Circuit, + proof: &[u8], + public_inputs: WitnessMap, + ) -> Result<(Vec, FieldElement, Vec), BackendError> { + let binary_path = self.assert_binary_exists()?; + self.assert_correct_version()?; + + let temp_directory = tempdir().expect("could not create a temporary directory"); + let temp_directory = temp_directory.path().to_path_buf(); + + // Create a temporary file for the circuit + // + let bytecode_path = temp_directory.join("circuit").with_extension("bytecode"); + let serialized_circuit = serialize_circuit(circuit); + write_to_file(&serialized_circuit, &bytecode_path); + + // Create the verification key and write it to the specified path + let vk_path = temp_directory.join("vk"); + + WriteVkCommand { + crs_path: self.crs_directory(), + bytecode_path, + vk_path_output: vk_path.clone(), + } + .run(binary_path)?; + + // Create a temporary file for the proof + + let proof_with_public_inputs = + bb_abstraction_leaks::prepend_public_inputs(proof.to_vec(), public_inputs); + let proof_path = temp_directory.join("proof").with_extension("proof"); + write_to_file(&proof_with_public_inputs, &proof_path); + + // Now ready to generate intermediate artifacts. + + let proof_as_fields = + ProofAsFieldsCommand { proof_path, vk_path: vk_path.clone() }.run(binary_path)?; + + let (vk_hash, vk_as_fields) = VkAsFieldsCommand { vk_path }.run(binary_path)?; + + Ok((proof_as_fields, vk_hash, vk_as_fields)) + } } pub(super) fn write_to_file(bytes: &[u8], path: &Path) -> String { diff --git a/tooling/bb_abstraction_leaks/src/lib.rs b/tooling/bb_abstraction_leaks/src/lib.rs index e0fdc467c53..fec53809ad4 100644 --- a/tooling/bb_abstraction_leaks/src/lib.rs +++ b/tooling/bb_abstraction_leaks/src/lib.rs @@ -1,7 +1,7 @@ #![warn(unused_crate_dependencies, unused_extern_crates)] #![warn(unreachable_pub)] -use acvm::FieldElement; +use acvm::{acir::native_types::WitnessMap, FieldElement}; pub const ACVM_BACKEND_BARRETENBERG: &str = "acvm-backend-barretenberg"; pub const BB_DOWNLOAD_URL: &str = env!("BB_BINARY_URL"); @@ -23,13 +23,11 @@ pub fn remove_public_inputs(num_pub_inputs: usize, proof: &[u8]) -> Vec { } /// Prepends a set of public inputs to a proof. -pub fn prepend_public_inputs(proof: Vec, public_inputs: Vec) -> Vec { - if public_inputs.is_empty() { - return proof; - } - +pub fn prepend_public_inputs(proof: Vec, public_inputs: WitnessMap) -> Vec { + // We omit any unassigned witnesses. + // Witness values should be ordered by their index but we skip over any indices without an assignment. let public_inputs_bytes = - public_inputs.into_iter().flat_map(|assignment| assignment.to_be_bytes()); + public_inputs.into_iter().flat_map(|(_, assignment)| assignment.to_be_bytes()); public_inputs_bytes.chain(proof).collect() } From 989e80d4ea62e68cfab69a1cd16d481cbccc6c02 Mon Sep 17 00:00:00 2001 From: jfecher Date: Fri, 20 Oct 2023 15:48:01 -0500 Subject: [PATCH 2/7] fix: Add compiler error message for invalid input types (#3220) --- .../noirc_frontend/src/hir/def_map/mod.rs | 6 +- .../src/hir/resolution/errors.rs | 5 + .../src/hir/resolution/resolver.rs | 94 +++++++++++++++++++ compiler/noirc_frontend/src/hir_def/types.rs | 40 ++++++++ compiler/noirc_frontend/src/lexer/token.rs | 7 ++ 5 files changed, 149 insertions(+), 3 deletions(-) diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 006e00d2d07..345e5447bf5 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -173,9 +173,9 @@ impl CrateDefMap { .value_definitions() .filter_map(|id| { id.as_function().map(|function_id| { - let attributes = interner.function_attributes(&function_id); - let is_entry_point = !attributes.has_contract_library_method() - && !attributes.is_test_function(); + let is_entry_point = interner + .function_attributes(&function_id) + .is_contract_entry_point(); ContractFunctionMeta { function_id, is_entry_point } }) }) diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index 80a0b557465..afdf65e5c5c 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -78,6 +78,8 @@ pub enum ResolverError { InvalidClosureEnvironment { typ: Type, span: Span }, #[error("{name} is private and not visible from the current module")] PrivateFunctionCalled { name: String, span: Span }, + #[error("Only sized types may be used in the entry point to a program")] + InvalidTypeForEntryPoint { span: Span }, } impl ResolverError { @@ -294,6 +296,9 @@ impl From for Diagnostic { ResolverError::PrivateFunctionCalled { span, name } => Diagnostic::simple_warning( format!("{name} is private and not visible from the current module"), format!("{name} is private"), span), + ResolverError::InvalidTypeForEntryPoint { span } => Diagnostic::simple_error( + "Only sized types may be used in the entry point to a program".to_string(), + "Slices, references, or any type containing them may not be used in main or a contract function".to_string(), span), } } } diff --git a/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/compiler/noirc_frontend/src/hir/resolution/resolver.rs index ca30b31e78d..a4a85d85929 100644 --- a/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -736,6 +736,10 @@ impl<'a> Resolver<'a> { }); } + if self.is_entry_point_function(func) { + self.verify_type_valid_for_program_input(&typ); + } + let pattern = self.resolve_pattern(pattern, DefinitionKind::Local(None)); let typ = self.resolve_type_inner(typ, &mut generics); @@ -810,6 +814,14 @@ impl<'a> Resolver<'a> { } } + fn is_entry_point_function(&self, func: &NoirFunction) -> bool { + if self.in_contract() { + func.attributes().is_contract_entry_point() + } else { + func.name() == MAIN_FUNCTION + } + } + /// True if the `distinct` keyword is allowed on a function's return type fn distinct_allowed(&self, func: &NoirFunction) -> bool { if self.in_contract() { @@ -1627,6 +1639,88 @@ impl<'a> Resolver<'a> { } HirLiteral::FmtStr(str, fmt_str_idents) } + + /// Only sized types are valid to be used as main's parameters or the parameters to a contract + /// function. If the given type is not sized (e.g. contains a slice or NamedGeneric type), an + /// error is issued. + fn verify_type_valid_for_program_input(&mut self, typ: &UnresolvedType) { + match &typ.typ { + UnresolvedTypeData::FieldElement + | UnresolvedTypeData::Integer(_, _) + | UnresolvedTypeData::Bool + | UnresolvedTypeData::Unit + | UnresolvedTypeData::Error => (), + + UnresolvedTypeData::MutableReference(_) + | UnresolvedTypeData::Function(_, _, _) + | UnresolvedTypeData::FormatString(_, _) + | UnresolvedTypeData::TraitAsType(..) + | UnresolvedTypeData::Unspecified => { + let span = typ.span.expect("Function parameters should always have spans"); + self.push_err(ResolverError::InvalidTypeForEntryPoint { span }); + } + + UnresolvedTypeData::Array(length, element) => { + if let Some(length) = length { + self.verify_type_expression_valid_for_program_input(length); + } else { + let span = typ.span.expect("Function parameters should always have spans"); + self.push_err(ResolverError::InvalidTypeForEntryPoint { span }); + } + self.verify_type_valid_for_program_input(element); + } + UnresolvedTypeData::Expression(expression) => { + self.verify_type_expression_valid_for_program_input(expression); + } + UnresolvedTypeData::String(length) => { + if let Some(length) = length { + self.verify_type_expression_valid_for_program_input(length); + } else { + let span = typ.span.expect("Function parameters should always have spans"); + self.push_err(ResolverError::InvalidTypeForEntryPoint { span }); + } + } + UnresolvedTypeData::Named(path, generics) => { + // Since the type is named, we need to resolve it to see what it actually refers to + // in order to check whether it is valid. Since resolving it may lead to a + // resolution error, we have to truncate our error count to the previous count just + // in case. This is to ensure resolution errors are not issued twice when this type + // is later resolved properly. + let error_count = self.errors.len(); + let resolved = self.resolve_named_type(path.clone(), generics.clone(), &mut vec![]); + self.errors.truncate(error_count); + + if !resolved.is_valid_for_program_input() { + let span = typ.span.expect("Function parameters should always have spans"); + self.push_err(ResolverError::InvalidTypeForEntryPoint { span }); + } + } + UnresolvedTypeData::Tuple(elements) => { + for element in elements { + self.verify_type_valid_for_program_input(element); + } + } + } + } + + fn verify_type_expression_valid_for_program_input(&mut self, expr: &UnresolvedTypeExpression) { + match expr { + UnresolvedTypeExpression::Constant(_, _) => (), + UnresolvedTypeExpression::Variable(path) => { + let error_count = self.errors.len(); + let resolved = self.resolve_named_type(path.clone(), vec![], &mut vec![]); + self.errors.truncate(error_count); + + if !resolved.is_valid_for_program_input() { + self.push_err(ResolverError::InvalidTypeForEntryPoint { span: path.span() }); + } + } + UnresolvedTypeExpression::BinaryOperation(lhs, _, rhs, _) => { + self.verify_type_expression_valid_for_program_input(lhs); + self.verify_type_expression_valid_for_program_input(rhs); + } + } + } } /// Gives an error if a user tries to create a mutable reference diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index 1f7baa0afaf..110334f331e 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -520,6 +520,46 @@ impl Type { } } } + + /// True if this type can be used as a parameter to `main` or a contract function. + /// This is only false for unsized types like slices or slices that do not make sense + /// as a program input such as named generics or mutable references. + /// + /// This function should match the same check done in `create_value_from_type` in acir_gen. + /// If this function does not catch a case where a type should be valid, it will later lead to a + /// panic in that function instead of a user-facing compiler error message. + pub(crate) fn is_valid_for_program_input(&self) -> bool { + match self { + // Type::Error is allowed as usual since it indicates an error was already issued and + // we don't need to issue further errors about this likely unresolved type + Type::FieldElement + | Type::Integer(_, _) + | Type::Bool + | Type::Unit + | Type::Constant(_) + | Type::Error => true, + + Type::FmtString(_, _) + | Type::TypeVariable(_, _) + | Type::NamedGeneric(_, _) + | Type::Function(_, _, _) + | Type::MutableReference(_) + | Type::Forall(_, _) + | Type::TraitAsType(..) + | Type::NotConstant => false, + + Type::Array(length, element) => { + length.is_valid_for_program_input() && element.is_valid_for_program_input() + } + Type::String(length) => length.is_valid_for_program_input(), + Type::Tuple(elements) => elements.iter().all(|elem| elem.is_valid_for_program_input()), + Type::Struct(definition, generics) => definition + .borrow() + .get_fields(generics) + .into_iter() + .all(|(_, field)| field.is_valid_for_program_input()), + } + } } impl std::fmt::Display for Type { diff --git a/compiler/noirc_frontend/src/lexer/token.rs b/compiler/noirc_frontend/src/lexer/token.rs index c91d1610f48..fe3e9476318 100644 --- a/compiler/noirc_frontend/src/lexer/token.rs +++ b/compiler/noirc_frontend/src/lexer/token.rs @@ -398,6 +398,13 @@ impl Attributes { matches!(self.function, Some(FunctionAttribute::Test(_))) } + /// True if these attributes mean the given function is an entry point function if it was + /// defined within a contract. Note that this does not check if the function is actually part + /// of a contract. + pub fn is_contract_entry_point(&self) -> bool { + !self.has_contract_library_method() && !self.is_test_function() + } + /// Returns note if a deprecated secondary attribute is found pub fn get_deprecated_note(&self) -> Option> { self.secondary.iter().find_map(|attr| match attr { From 86704bad3af19dd03634cbec0d697ff8159ed683 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Fri, 20 Oct 2023 23:06:26 +0100 Subject: [PATCH 3/7] chore: Release Noir(0.17.0) (#2967) --- .release-please-manifest.json | 4 +- CHANGELOG.md | 82 +++++++++++++++++++ Cargo.lock | 52 ++++++------ Cargo.toml | 2 +- acvm-repo/CHANGELOG.md | 33 ++++++++ acvm-repo/acir/Cargo.toml | 2 +- acvm-repo/acir_field/Cargo.toml | 2 +- acvm-repo/acvm/Cargo.toml | 2 +- acvm-repo/acvm_js/Cargo.toml | 2 +- acvm-repo/acvm_js/package.json | 2 +- .../barretenberg_blackbox_solver/Cargo.toml | 2 +- acvm-repo/blackbox_solver/Cargo.toml | 2 +- acvm-repo/brillig/Cargo.toml | 2 +- acvm-repo/brillig_vm/Cargo.toml | 2 +- acvm-repo/stdlib/Cargo.toml | 2 +- compiler/source-resolver/package.json | 2 +- compiler/wasm/package.json | 2 +- flake.nix | 2 +- tooling/noir_js/package.json | 2 +- .../noir_js_backend_barretenberg/package.json | 2 +- tooling/noir_js_types/package.json | 2 +- tooling/noirc_abi_wasm/package.json | 2 +- 22 files changed, 161 insertions(+), 46 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index d085bb9234a..55950a42d1e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,4 +1,4 @@ { - ".": "0.16.0", - "acvm-repo": "0.28.0" + ".": "0.17.0", + "acvm-repo": "0.29.0" } \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index a56f9490edb..5fce9e43321 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,87 @@ # Changelog +## [0.17.0](https://github.com/noir-lang/noir/compare/v0.16.0...v0.17.0) (2023-10-20) + + +### ⚠ BREAKING CHANGES + +* Pass ACIR to ACVM by reference rather than passing ownership ([#2872](https://github.com/noir-lang/noir/issues/2872)) +* Make for loops a statement ([#2975](https://github.com/noir-lang/noir/issues/2975)) +* **traits:** trait functions with a default implementation must not be followed by a semicolon ([#2987](https://github.com/noir-lang/noir/issues/2987)) +* **wasm:** improve and simplify wasm compiler interface ([#2976](https://github.com/noir-lang/noir/issues/2976)) +* **wasm:** update wasm artifacts to match cli artifacts ([#2973](https://github.com/noir-lang/noir/issues/2973)) + +### Features + +* **acir:** Set dynamic array values ([#3054](https://github.com/noir-lang/noir/issues/3054)) ([e871866](https://github.com/noir-lang/noir/commit/e871866d2203f0f0f49f3b273d99d385b950b65f)) +* **acvm:** Separate ACVM optimizations and transformations ([#2979](https://github.com/noir-lang/noir/issues/2979)) ([5865d1a](https://github.com/noir-lang/noir/commit/5865d1a1bca16e1853663c71f893ff81fa3f7185)) +* Add `destroy` method to `Noir` ([#3105](https://github.com/noir-lang/noir/issues/3105)) ([7e40274](https://github.com/noir-lang/noir/commit/7e402744a7d64ffcac6db026cec1631230204f0f)) +* Add `execute` method to `Noir` class ([#3081](https://github.com/noir-lang/noir/issues/3081)) ([17bdd7e](https://github.com/noir-lang/noir/commit/17bdd7e3909f0ddd195e5cb7095cd0d30758ed43)) +* Add ACIR serializer C++ codegen ([#2961](https://github.com/noir-lang/noir/issues/2961)) ([7556982](https://github.com/noir-lang/noir/commit/7556982dbebe25eaa17240abbe270b771b55de45)) +* Add an options object to `BarretenbergBackend` constructor ([#3105](https://github.com/noir-lang/noir/issues/3105)) ([7e40274](https://github.com/noir-lang/noir/commit/7e402744a7d64ffcac6db026cec1631230204f0f)) +* Add aztec selectors for event structs ([#2983](https://github.com/noir-lang/noir/issues/2983)) ([982380e](https://github.com/noir-lang/noir/commit/982380e54bb4d696688522c540f1234734ae2e80)) +* Add conditional compilation of methods based on the underlying field being used ([#3045](https://github.com/noir-lang/noir/issues/3045)) ([2e008e2](https://github.com/noir-lang/noir/commit/2e008e2438795bbc41b0641e830378b76bf2e194)) +* Add experimental REPL-based debugger ([#2995](https://github.com/noir-lang/noir/issues/2995)) ([281c696](https://github.com/noir-lang/noir/commit/281c696da61c64b42b9525b8756ffc195f70d775)) +* Add JS types for ABI and input maps ([#3023](https://github.com/noir-lang/noir/issues/3023)) ([599e7a1](https://github.com/noir-lang/noir/commit/599e7a1d6bae5d93273e9ef1265024eac909660d)) +* **debugger:** Highlight current src code loc ([#3174](https://github.com/noir-lang/noir/issues/3174)) ([6b87582](https://github.com/noir-lang/noir/commit/6b87582dfe872ad6c248cf9995d76b0ef1580625)) +* Format infix expressions ([#3001](https://github.com/noir-lang/noir/issues/3001)) ([7926ada](https://github.com/noir-lang/noir/commit/7926ada88ed08ac9d874604834533d900fbb16b0)) +* **formatter:** Add formatter support for array literals ([#3061](https://github.com/noir-lang/noir/issues/3061)) ([a535321](https://github.com/noir-lang/noir/commit/a5353217a1f49b83daf11d5fa55e0bcccebf0271)) +* Implement automatic dereferencing for index expressions ([#3082](https://github.com/noir-lang/noir/issues/3082)) ([8221bfd](https://github.com/noir-lang/noir/commit/8221bfd2ffde7d1dbf71a72d95257acf76ecca74)) +* Implement automatic dereferencing for indexing lvalues ([#3083](https://github.com/noir-lang/noir/issues/3083)) ([6e2b70a](https://github.com/noir-lang/noir/commit/6e2b70ae90b686158957ea29ef1b2a5f0ed38e5f)) +* Implement impl specialization ([#3087](https://github.com/noir-lang/noir/issues/3087)) ([44716fa](https://github.com/noir-lang/noir/commit/44716fae0bae0f78ceee76f7231af49c4abeace1)) +* **lsp:** Add "info" codelens ([#2982](https://github.com/noir-lang/noir/issues/2982)) ([80770d9](https://github.com/noir-lang/noir/commit/80770d9fae7c42e69a62cf01babfc69449600ac5)) +* Nargo test runtime callstacks and assert messages without string matching ([#2953](https://github.com/noir-lang/noir/issues/2953)) ([1b6a4e6](https://github.com/noir-lang/noir/commit/1b6a4e6021929c23a1bca5dff02c004422cc71f8)) +* Old docs issues ([#3195](https://github.com/noir-lang/noir/issues/3195)) ([26746c5](https://github.com/noir-lang/noir/commit/26746c59e12a60f3869a5b885b05926c94f01215)) +* Optimize euclidean division acir-gen ([#3121](https://github.com/noir-lang/noir/issues/3121)) ([2c175c0](https://github.com/noir-lang/noir/commit/2c175c0d886eea390ef97ada1c2a5b0e1bef15e8)) +* Pass ACIR to ACVM by reference rather than passing ownership ([#2872](https://github.com/noir-lang/noir/issues/2872)) ([b3a9c34](https://github.com/noir-lang/noir/commit/b3a9c343993ce3207de62106bda6cb2b2ef3de50)) +* Pass brillig bytecode to VM by reference ([#3030](https://github.com/noir-lang/noir/issues/3030)) ([4ee290b](https://github.com/noir-lang/noir/commit/4ee290b8b6f75bc1974a5750248570eeca8d244e)) +* Prevent unnecessary witness creation in euclidean division ([#2980](https://github.com/noir-lang/noir/issues/2980)) ([c6f660e](https://github.com/noir-lang/noir/commit/c6f660e86d40a106930483f1d6161814e3c0de10)) +* Provide formatting subcommand ([#2640](https://github.com/noir-lang/noir/issues/2640)) ([a38b15f](https://github.com/noir-lang/noir/commit/a38b15f5d8e69faff125d363f2fd1f2f90ae6830)) +* Publish aztec build of noir_wasm ([#3049](https://github.com/noir-lang/noir/issues/3049)) ([3b51f4d](https://github.com/noir-lang/noir/commit/3b51f4df7e808233f6987baec93f4b5de7e5b304)) +* Remove unnecessary truncation of boolean multiplication ([#3122](https://github.com/noir-lang/noir/issues/3122)) ([39dbcf1](https://github.com/noir-lang/noir/commit/39dbcf1ab80d2bb472d08db4de15d4e0c1f2eb52)) +* Return compilation errors from noir_wasm ([#3091](https://github.com/noir-lang/noir/issues/3091)) ([55f63c9](https://github.com/noir-lang/noir/commit/55f63c935cec62fbba63eed421812a4372c1aa4d)) +* Reuse witnesses which have been assigned constant values during ACIR gen ([#3137](https://github.com/noir-lang/noir/issues/3137)) ([9eb43e2](https://github.com/noir-lang/noir/commit/9eb43e2a4665397295e74a593f73d19fa9fa5d27)) +* Save Brillig execution state in ACVM ([#3026](https://github.com/noir-lang/noir/issues/3026)) ([88682da](https://github.com/noir-lang/noir/commit/88682da87ffc9e26da5c9e4b5a4d8e62a6ee43c6)) +* Solve `fixed_base_scalar_mul` black box functions in rust ([#3153](https://github.com/noir-lang/noir/issues/3153)) ([1c1afbc](https://github.com/noir-lang/noir/commit/1c1afbcddf0b5fdb39f00ad28ae90caf699d1265)) +* **traits:** Add impl Trait as function return type [#2397](https://github.com/noir-lang/noir/issues/2397) ([#3176](https://github.com/noir-lang/noir/issues/3176)) ([4cb2024](https://github.com/noir-lang/noir/commit/4cb20244abba0abc49be0376611979a786563565)) +* **traits:** Add trait impl for buildin types ([#2964](https://github.com/noir-lang/noir/issues/2964)) ([2c87b27](https://github.com/noir-lang/noir/commit/2c87b273dfdf033dd8c79b78f006a0e9813559d7)) +* **traits:** Added checks for duplicated trait associated items (types, consts, functions) ([#2927](https://github.com/noir-lang/noir/issues/2927)) ([d49492c](https://github.com/noir-lang/noir/commit/d49492cd80d04ee6acc01247b06b088deefcd0c6)) +* **traits:** Allow multiple traits to share the same associated function name and to be implemented for the same type ([#3126](https://github.com/noir-lang/noir/issues/3126)) ([004f8dd](https://github.com/noir-lang/noir/commit/004f8dd733cb23da4ed57b160f6b86d53bc0b5f1)) +* **traits:** Improve support for traits static method resolution ([#2958](https://github.com/noir-lang/noir/issues/2958)) ([0d0d8f7](https://github.com/noir-lang/noir/commit/0d0d8f7d2b401eb6b534dbb175dfd4b26d2a5f7d)) +* **wasm:** Improve and simplify wasm compiler interface ([#2976](https://github.com/noir-lang/noir/issues/2976)) ([1b5124b](https://github.com/noir-lang/noir/commit/1b5124bc74f7ac5360db04b34d1b7b2284061fd3)) +* **wasm:** Update wasm artifacts to match cli artifacts ([#2973](https://github.com/noir-lang/noir/issues/2973)) ([ce16c0b](https://github.com/noir-lang/noir/commit/ce16c0b14565cfe1bc2c9f09ae71643d2657440b)) + + +### Bug Fixes + +* ACIR optimizer should update assertion messages ([#3010](https://github.com/noir-lang/noir/issues/3010)) ([758b6b6](https://github.com/noir-lang/noir/commit/758b6b62918907c1a39f3090a77419003551745e)) +* Add `pub` modifier to grumpkin functions ([#3036](https://github.com/noir-lang/noir/issues/3036)) ([f8990d7](https://github.com/noir-lang/noir/commit/f8990d75b948ce0a6968db659370f7ece7f5db08)) +* Add compiler error message for invalid input types ([#3220](https://github.com/noir-lang/noir/issues/3220)) ([989e80d](https://github.com/noir-lang/noir/commit/989e80d4ea62e68cfab69a1cd16d481cbccc6c02)) +* Allow constructors in parentheses in `if` conditions and `for` ranges ([#3219](https://github.com/noir-lang/noir/issues/3219)) ([ad192d1](https://github.com/noir-lang/noir/commit/ad192d1b7492f6ecd5fc98bb88201d6c442dc052)) +* Allow two `TypeVariable::Constant(N)` to unify even if their constants are not equal ([#3225](https://github.com/noir-lang/noir/issues/3225)) ([cc4ca4b](https://github.com/noir-lang/noir/commit/cc4ca4bb5f4fed5f531a2040501fcc6ed53a9ab4)) +* Change non-constant argument errors from `to_be_radix` from ICE to proper error ([#3048](https://github.com/noir-lang/noir/issues/3048)) ([19ce286](https://github.com/noir-lang/noir/commit/19ce28638fe3ea42ab4984cb99e3898cd17fa8d9)) +* Check for overflow with hexadecimal inputs ([#3004](https://github.com/noir-lang/noir/issues/3004)) ([db1e736](https://github.com/noir-lang/noir/commit/db1e736240c0b74f6f59504db5a50de1c749d395)) +* Complete debug metadata ([#3228](https://github.com/noir-lang/noir/issues/3228)) ([2f6509d](https://github.com/noir-lang/noir/commit/2f6509d2acdee5014d65efaca9e6a9e0df3ca160)) +* Determinism of fallback transformer ([#3100](https://github.com/noir-lang/noir/issues/3100)) ([12daad1](https://github.com/noir-lang/noir/commit/12daad19c902caf5ee9e2eb4b6847bde5a924353)) +* Disable modulo for fields ([#3009](https://github.com/noir-lang/noir/issues/3009)) ([7e68976](https://github.com/noir-lang/noir/commit/7e689768f4af1188e01a1a300a0d2fa152cea504)) +* Disallow returning constant values ([#2978](https://github.com/noir-lang/noir/issues/2978)) ([79c2e88](https://github.com/noir-lang/noir/commit/79c2e88ebefe71ebc0fe457347570df31b24ac36)) +* Do not perform dead instruction elimination on mod,div unless rhs is constant ([#3141](https://github.com/noir-lang/noir/issues/3141)) ([af3d771](https://github.com/noir-lang/noir/commit/af3d77182054845303fa59de92d783453079a048)) +* **docs:** Update `editUrl` path for docusaurus ([#3184](https://github.com/noir-lang/noir/issues/3184)) ([4646a93](https://github.com/noir-lang/noir/commit/4646a93f5e95604b5710353764b2c4295efaef6b)) +* Download expected `bb` version if installed backend has version mismatch ([#3150](https://github.com/noir-lang/noir/issues/3150)) ([3f03435](https://github.com/noir-lang/noir/commit/3f03435552fe75b5c7a49bfc8d63d06573381220)) +* Fix aztec library after nargo fmt ([#3014](https://github.com/noir-lang/noir/issues/3014)) ([f43083c](https://github.com/noir-lang/noir/commit/f43083c744ff13aefa4d294a090c9445a9b70aac)) +* Fix method `program_counter`, change method signature ([#3012](https://github.com/noir-lang/noir/issues/3012)) ([5ea522b](https://github.com/noir-lang/noir/commit/5ea522b840ca0f6f90d02ca00f0de32f515d450f)) +* Fix panic when using repeated arrays which define variables ([#3221](https://github.com/noir-lang/noir/issues/3221)) ([c4faf3a](https://github.com/noir-lang/noir/commit/c4faf3a0a40eea1ee02e11dfe08b48c6b4438bbf)) +* Include .nr and .sol files in builds ([#3039](https://github.com/noir-lang/noir/issues/3039)) ([ae8d0e9](https://github.com/noir-lang/noir/commit/ae8d0e9013f26b52e8f0bdc9f84866ffec50872d)) +* Make for loops a statement ([#2975](https://github.com/noir-lang/noir/issues/2975)) ([0e266eb](https://github.com/noir-lang/noir/commit/0e266ebc7328866b0b10554e37c9d9012a7b501c)) +* Minor problems with `aztec` publishing ([#3095](https://github.com/noir-lang/noir/issues/3095)) ([0fc8f20](https://github.com/noir-lang/noir/commit/0fc8f20b8b87d033d27ce18db039399c17f81837)) +* Parse parenthesized lvalues ([#3058](https://github.com/noir-lang/noir/issues/3058)) ([50ca58c](https://github.com/noir-lang/noir/commit/50ca58c7b133f8b21091dfd304379429284b0d60)) +* Prevent duplicated assert message transformation ([#3038](https://github.com/noir-lang/noir/issues/3038)) ([082a6d0](https://github.com/noir-lang/noir/commit/082a6d02dad67a25692bed15c340a16a848a320e)) +* Prevent mutating immutable bindings to mutable types ([#3075](https://github.com/noir-lang/noir/issues/3075)) ([d5ee20e](https://github.com/noir-lang/noir/commit/d5ee20ea43ccf1130f7d34231562f13e98ea636b)) +* Return error rather than panicking on unreadable circuits ([#3179](https://github.com/noir-lang/noir/issues/3179)) ([d4f61d3](https://github.com/noir-lang/noir/commit/d4f61d3d51d515e40a5fd02d35315889f841bf53)) +* **traits:** Trait functions with a default implementation must not be followed by a semicolon ([#2987](https://github.com/noir-lang/noir/issues/2987)) ([a3593c0](https://github.com/noir-lang/noir/commit/a3593c042163d89bd012b7f901f3b18446209e82)) +* Transform hir before type checks ([#2994](https://github.com/noir-lang/noir/issues/2994)) ([a29b568](https://github.com/noir-lang/noir/commit/a29b568295e40e19dd354bbe47e31f922e08d8c9)) +* Update link to recursion example ([#3224](https://github.com/noir-lang/noir/issues/3224)) ([10eae15](https://github.com/noir-lang/noir/commit/10eae15c6992442876e184c7d2bd36a34f639ea1)) + ## [0.16.0](https://github.com/noir-lang/noir/compare/v0.15.0...v0.16.0) (2023-10-03) diff --git a/Cargo.lock b/Cargo.lock index 5601dbae53d..c9c60fc62ed 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4,7 +4,7 @@ version = 3 [[package]] name = "acir" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acir_field", "bincode", @@ -22,7 +22,7 @@ dependencies = [ [[package]] name = "acir_field" -version = "0.28.0" +version = "0.29.0" dependencies = [ "ark-bls12-381", "ark-bn254", @@ -36,7 +36,7 @@ dependencies = [ [[package]] name = "acvm" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -53,7 +53,7 @@ dependencies = [ [[package]] name = "acvm_blackbox_solver" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acir", "blake2", @@ -66,7 +66,7 @@ dependencies = [ [[package]] name = "acvm_js" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acvm", "barretenberg_blackbox_solver", @@ -87,7 +87,7 @@ dependencies = [ [[package]] name = "acvm_stdlib" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acir", ] @@ -217,7 +217,7 @@ checksum = "a4668cab20f66d8d020e1fbc0ebe47217433c1b6c8f2040faf858554e394ace6" [[package]] name = "arena" -version = "0.16.0" +version = "0.17.0" dependencies = [ "generational-arena", ] @@ -449,7 +449,7 @@ dependencies = [ [[package]] name = "barretenberg_blackbox_solver" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -573,7 +573,7 @@ dependencies = [ [[package]] name = "brillig" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acir_field", "serde", @@ -581,7 +581,7 @@ dependencies = [ [[package]] name = "brillig_vm" -version = "0.28.0" +version = "0.29.0" dependencies = [ "acir", "acvm_blackbox_solver", @@ -1611,7 +1611,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.16.0" +version = "0.17.0" dependencies = [ "codespan-reporting", "iter-extended", @@ -2192,7 +2192,7 @@ dependencies = [ [[package]] name = "iter-extended" -version = "0.16.0" +version = "0.17.0" [[package]] name = "itertools" @@ -2411,7 +2411,7 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "nargo" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "base64", @@ -2431,7 +2431,7 @@ dependencies = [ [[package]] name = "nargo_cli" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "assert_cmd", @@ -2479,7 +2479,7 @@ dependencies = [ [[package]] name = "nargo_fmt" -version = "0.16.0" +version = "0.17.0" dependencies = [ "bytecount", "noirc_frontend", @@ -2491,7 +2491,7 @@ dependencies = [ [[package]] name = "nargo_toml" -version = "0.16.0" +version = "0.17.0" dependencies = [ "dirs", "fm", @@ -2539,7 +2539,7 @@ dependencies = [ [[package]] name = "noir_debugger" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "easy-repl", @@ -2551,7 +2551,7 @@ dependencies = [ [[package]] name = "noir_lsp" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "async-lsp", @@ -2573,7 +2573,7 @@ dependencies = [ [[package]] name = "noir_wasm" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "build-data", @@ -2595,7 +2595,7 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "iter-extended", @@ -2612,7 +2612,7 @@ dependencies = [ [[package]] name = "noirc_abi_wasm" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "build-data", @@ -2629,7 +2629,7 @@ dependencies = [ [[package]] name = "noirc_driver" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "base64", @@ -2645,7 +2645,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "chumsky", @@ -2658,7 +2658,7 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "fxhash", @@ -2673,7 +2673,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "arena", @@ -2694,7 +2694,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.16.0" +version = "0.17.0" dependencies = [ "acvm", "iter-extended", diff --git a/Cargo.toml b/Cargo.toml index b0bb24ddb03..e80de516e72 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ resolver = "2" [workspace.package] # x-release-please-start-version -version = "0.16.0" +version = "0.17.0" # x-release-please-end authors = ["The Noir Team "] edition = "2021" diff --git a/acvm-repo/CHANGELOG.md b/acvm-repo/CHANGELOG.md index 60bdba65a38..fd3ad6223e0 100644 --- a/acvm-repo/CHANGELOG.md +++ b/acvm-repo/CHANGELOG.md @@ -5,6 +5,39 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [0.29.0](https://github.com/noir-lang/noir/compare/v0.28.0...v0.29.0) (2023-10-20) + + +### ⚠ BREAKING CHANGES + +* Pass ACIR to ACVM by reference rather than passing ownership ([#2872](https://github.com/noir-lang/noir/issues/2872)) +* **wasm:** improve and simplify wasm compiler interface ([#2976](https://github.com/noir-lang/noir/issues/2976)) +* Maintain shape of foreign call arguments ([#2935](https://github.com/noir-lang/noir/issues/2935)) + +### Features + +* **acvm_js:** Export black box solver functions ([#2812](https://github.com/noir-lang/noir/issues/2812)) ([da8a98e](https://github.com/noir-lang/noir/commit/da8a98ed312fe69cb0bdb8f9d0a70ee7a981398f)) +* **acvm:** Separate ACVM optimizations and transformations ([#2979](https://github.com/noir-lang/noir/issues/2979)) ([5865d1a](https://github.com/noir-lang/noir/commit/5865d1a1bca16e1853663c71f893ff81fa3f7185)) +* Add ACIR serializer C++ codegen ([#2961](https://github.com/noir-lang/noir/issues/2961)) ([7556982](https://github.com/noir-lang/noir/commit/7556982dbebe25eaa17240abbe270b771b55de45)) +* Add conditional compilation of methods based on the underlying field being used ([#3045](https://github.com/noir-lang/noir/issues/3045)) ([2e008e2](https://github.com/noir-lang/noir/commit/2e008e2438795bbc41b0641e830378b76bf2e194)) +* Maintain shape of foreign call arguments ([#2935](https://github.com/noir-lang/noir/issues/2935)) ([f7869e6](https://github.com/noir-lang/noir/commit/f7869e6fb492b617e776e538ac4babfa56261d26)) +* Pass ACIR to ACVM by reference rather than passing ownership ([#2872](https://github.com/noir-lang/noir/issues/2872)) ([b3a9c34](https://github.com/noir-lang/noir/commit/b3a9c343993ce3207de62106bda6cb2b2ef3de50)) +* Pass brillig bytecode to VM by reference ([#3030](https://github.com/noir-lang/noir/issues/3030)) ([4ee290b](https://github.com/noir-lang/noir/commit/4ee290b8b6f75bc1974a5750248570eeca8d244e)) +* Save Brillig execution state in ACVM ([#3026](https://github.com/noir-lang/noir/issues/3026)) ([88682da](https://github.com/noir-lang/noir/commit/88682da87ffc9e26da5c9e4b5a4d8e62a6ee43c6)) +* Solve `fixed_base_scalar_mul` black box functions in rust ([#3153](https://github.com/noir-lang/noir/issues/3153)) ([1c1afbc](https://github.com/noir-lang/noir/commit/1c1afbcddf0b5fdb39f00ad28ae90caf699d1265)) +* **wasm:** Improve and simplify wasm compiler interface ([#2976](https://github.com/noir-lang/noir/issues/2976)) ([1b5124b](https://github.com/noir-lang/noir/commit/1b5124bc74f7ac5360db04b34d1b7b2284061fd3)) + + +### Bug Fixes + +* ACIR optimizer should update assertion messages ([#3010](https://github.com/noir-lang/noir/issues/3010)) ([758b6b6](https://github.com/noir-lang/noir/commit/758b6b62918907c1a39f3090a77419003551745e)) +* **acvm:** Return false rather than panicking on invalid ECDSA signatures ([#2783](https://github.com/noir-lang/noir/issues/2783)) ([155abc0](https://github.com/noir-lang/noir/commit/155abc0d99fff41c79163c16bf297d41e5dff0fa)) +* Determinism of fallback transformer ([#3100](https://github.com/noir-lang/noir/issues/3100)) ([12daad1](https://github.com/noir-lang/noir/commit/12daad19c902caf5ee9e2eb4b6847bde5a924353)) +* Fix method `program_counter`, change method signature ([#3012](https://github.com/noir-lang/noir/issues/3012)) ([5ea522b](https://github.com/noir-lang/noir/commit/5ea522b840ca0f6f90d02ca00f0de32f515d450f)) +* Minor problems with `aztec` publishing ([#3095](https://github.com/noir-lang/noir/issues/3095)) ([0fc8f20](https://github.com/noir-lang/noir/commit/0fc8f20b8b87d033d27ce18db039399c17f81837)) +* Prevent duplicated assert message transformation ([#3038](https://github.com/noir-lang/noir/issues/3038)) ([082a6d0](https://github.com/noir-lang/noir/commit/082a6d02dad67a25692bed15c340a16a848a320e)) +* Return error rather than panicking on unreadable circuits ([#3179](https://github.com/noir-lang/noir/issues/3179)) ([d4f61d3](https://github.com/noir-lang/noir/commit/d4f61d3d51d515e40a5fd02d35315889f841bf53)) + ## [0.28.0](https://github.com/noir-lang/noir/compare/v0.27.4...v0.28.0) (2023-10-03) diff --git a/acvm-repo/acir/Cargo.toml b/acvm-repo/acir/Cargo.toml index 087a0f26335..90d2c743a79 100644 --- a/acvm-repo/acir/Cargo.toml +++ b/acvm-repo/acir/Cargo.toml @@ -2,7 +2,7 @@ name = "acir" description = "ACIR is the IR that the VM processes, it is analogous to LLVM IR" # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acir_field/Cargo.toml b/acvm-repo/acir_field/Cargo.toml index 10027519d6d..a81e16b18a2 100644 --- a/acvm-repo/acir_field/Cargo.toml +++ b/acvm-repo/acir_field/Cargo.toml @@ -2,7 +2,7 @@ name = "acir_field" description = "The field implementation being used by ACIR." # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm/Cargo.toml b/acvm-repo/acvm/Cargo.toml index f51bb627fd9..21029e90464 100644 --- a/acvm-repo/acvm/Cargo.toml +++ b/acvm-repo/acvm/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm" description = "The virtual machine that processes ACIR given a backend/proof system." # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm_js/Cargo.toml b/acvm-repo/acvm_js/Cargo.toml index f977eb5234f..18ed39e046e 100644 --- a/acvm-repo/acvm_js/Cargo.toml +++ b/acvm-repo/acvm_js/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_js" description = "Typescript wrapper around the ACVM allowing execution of ACIR code" # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/acvm_js/package.json b/acvm-repo/acvm_js/package.json index 6c20627400c..b8f7642566d 100644 --- a/acvm-repo/acvm_js/package.json +++ b/acvm-repo/acvm_js/package.json @@ -1,6 +1,6 @@ { "name": "@noir-lang/acvm_js", - "version": "0.28.0", + "version": "0.29.0", "repository": { "type": "git", "url": "https://github.com/noir-lang/acvm.git" diff --git a/acvm-repo/barretenberg_blackbox_solver/Cargo.toml b/acvm-repo/barretenberg_blackbox_solver/Cargo.toml index 97e58c2804b..1a1431c0e42 100644 --- a/acvm-repo/barretenberg_blackbox_solver/Cargo.toml +++ b/acvm-repo/barretenberg_blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "barretenberg_blackbox_solver" description = "A wrapper around a barretenberg WASM binary to execute black box functions for which there is no rust implementation" # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/blackbox_solver/Cargo.toml b/acvm-repo/blackbox_solver/Cargo.toml index f0295456977..3c240b21fee 100644 --- a/acvm-repo/blackbox_solver/Cargo.toml +++ b/acvm-repo/blackbox_solver/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_blackbox_solver" description = "A solver for the blackbox functions found in ACIR and Brillig" # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/brillig/Cargo.toml b/acvm-repo/brillig/Cargo.toml index c0f230ba55b..2709d71662c 100644 --- a/acvm-repo/brillig/Cargo.toml +++ b/acvm-repo/brillig/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig" description = "Brillig is the bytecode ACIR uses for non-determinism." # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/brillig_vm/Cargo.toml b/acvm-repo/brillig_vm/Cargo.toml index 46d29935685..95a89b7275d 100644 --- a/acvm-repo/brillig_vm/Cargo.toml +++ b/acvm-repo/brillig_vm/Cargo.toml @@ -2,7 +2,7 @@ name = "brillig_vm" description = "The virtual machine that processes Brillig bytecode, used to introduce non-determinism to the ACVM" # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/acvm-repo/stdlib/Cargo.toml b/acvm-repo/stdlib/Cargo.toml index e675e7b284c..96e11a5aaf2 100644 --- a/acvm-repo/stdlib/Cargo.toml +++ b/acvm-repo/stdlib/Cargo.toml @@ -2,7 +2,7 @@ name = "acvm_stdlib" description = "The ACVM standard library." # x-release-please-start-version -version = "0.28.0" +version = "0.29.0" # x-release-please-end authors.workspace = true edition.workspace = true diff --git a/compiler/source-resolver/package.json b/compiler/source-resolver/package.json index 7f9530324b6..8fa2763c2e9 100644 --- a/compiler/source-resolver/package.json +++ b/compiler/source-resolver/package.json @@ -1,6 +1,6 @@ { "name": "@noir-lang/source-resolver", - "version": "0.16.0", + "version": "0.17.0", "license": "MIT", "main": "./lib-node/index_node.js", "types": "./types/index_node.d.ts", diff --git a/compiler/wasm/package.json b/compiler/wasm/package.json index 5dbc79f4c55..808a9f93caa 100644 --- a/compiler/wasm/package.json +++ b/compiler/wasm/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.16.0", + "version": "0.17.0", "license": "(MIT OR Apache-2.0)", "main": "./nodejs/noir_wasm.js", "types": "./web/noir_wasm.d.ts", diff --git a/flake.nix b/flake.nix index dc3b4881203..efe64734b60 100644 --- a/flake.nix +++ b/flake.nix @@ -73,7 +73,7 @@ # Configuration shared between builds config = { # x-release-please-start-version - version = "0.16.0"; + version = "0.17.0"; # x-release-please-end src = pkgs.lib.cleanSourceWith { diff --git a/tooling/noir_js/package.json b/tooling/noir_js/package.json index 3f17a1a44b2..8c11349f410 100644 --- a/tooling/noir_js/package.json +++ b/tooling/noir_js/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.16.0", + "version": "0.17.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js_backend_barretenberg/package.json b/tooling/noir_js_backend_barretenberg/package.json index afc0a75d19e..ae56c5dd507 100644 --- a/tooling/noir_js_backend_barretenberg/package.json +++ b/tooling/noir_js_backend_barretenberg/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.7.10", + "version": "0.17.0", "packageManager": "yarn@3.5.1", "license": "(MIT OR Apache-2.0)", "type": "module", diff --git a/tooling/noir_js_types/package.json b/tooling/noir_js_types/package.json index 547a6f9faf4..fb0f806140e 100644 --- a/tooling/noir_js_types/package.json +++ b/tooling/noir_js_types/package.json @@ -4,7 +4,7 @@ "The Noir Team " ], "packageManager": "yarn@3.5.1", - "version": "0.16.0", + "version": "0.17.0", "license": "(MIT OR Apache-2.0)", "files": [ "lib", diff --git a/tooling/noirc_abi_wasm/package.json b/tooling/noirc_abi_wasm/package.json index 7dc2858cd57..338251253cb 100644 --- a/tooling/noirc_abi_wasm/package.json +++ b/tooling/noirc_abi_wasm/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.16.0", + "version": "0.17.0", "license": "(MIT OR Apache-2.0)", "files": [ "nodejs", From 7de37c6935571c2865eca7ce11da0038ff735b2f Mon Sep 17 00:00:00 2001 From: kek kek kek Date: Sat, 21 Oct 2023 05:59:04 -0700 Subject: [PATCH 4/7] chore: format array and index expressions (#3223) --- tooling/nargo_fmt/src/config.rs | 3 + tooling/nargo_fmt/src/utils.rs | 38 +++- tooling/nargo_fmt/src/visitor.rs | 19 +- tooling/nargo_fmt/src/visitor/expr.rs | 179 ++++++++++++++----- tooling/nargo_fmt/src/visitor/stmt.rs | 7 + tooling/nargo_fmt/tests/expected/array.nr | 23 +++ tooling/nargo_fmt/tests/expected/call.nr | 12 +- tooling/nargo_fmt/tests/expected/index.nr | 4 + tooling/nargo_fmt/tests/expected/let.nr | 17 ++ tooling/nargo_fmt/tests/expected/literals.nr | 2 + tooling/nargo_fmt/tests/expected/struct.nr | 4 +- tooling/nargo_fmt/tests/expected/tuple.nr | 37 ++-- tooling/nargo_fmt/tests/input/array.nr | 39 ++++ tooling/nargo_fmt/tests/input/index.nr | 5 + tooling/nargo_fmt/tests/input/let.nr | 15 ++ tooling/nargo_fmt/tests/input/literals.nr | 2 + 16 files changed, 321 insertions(+), 85 deletions(-) create mode 100644 tooling/nargo_fmt/tests/expected/array.nr create mode 100644 tooling/nargo_fmt/tests/expected/let.nr create mode 100644 tooling/nargo_fmt/tests/input/array.nr create mode 100644 tooling/nargo_fmt/tests/input/let.nr diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 7cb80a9f04d..1514937caff 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -42,8 +42,11 @@ macro_rules! config { } config! { + max_width: usize, 100, "Maximum width of each line"; tab_spaces: usize, 4, "Number of spaces per tab"; remove_nested_parens: bool, true, "Remove nested parens"; + short_array_element_width_threshold: usize, 10, "Width threshold for an array element to be considered short"; + array_width: usize, 60, "Maximum width of an array literal before falling back to vertical formatting"; } impl Config { diff --git a/tooling/nargo_fmt/src/utils.rs b/tooling/nargo_fmt/src/utils.rs index a1aeadee523..4bea21be939 100644 --- a/tooling/nargo_fmt/src/utils.rs +++ b/tooling/nargo_fmt/src/utils.rs @@ -31,11 +31,21 @@ pub(crate) fn comments(source: &str) -> impl Iterator + '_ { #[derive(Debug)] pub(crate) struct Expr { pub(crate) leading: String, - pub(crate) expr: String, + pub(crate) value: String, pub(crate) trailing: String, pub(crate) different_line: bool, } +impl Expr { + pub(crate) fn total_width(&self) -> usize { + comment_len(&self.leading) + self.value.chars().count() + comment_len(&self.trailing) + } + + pub(crate) fn is_multiline(&self) -> bool { + self.leading.contains('\n') || self.trailing.contains('\n') + } +} + pub(crate) struct Exprs<'me> { pub(crate) visitor: &'me FmtVisitor<'me>, pub(crate) elements: std::iter::Peekable>, @@ -71,17 +81,17 @@ impl Iterator for Exprs<'_> { let is_last = self.elements.peek().is_none(); let next_start = self.elements.peek().map_or(self.end_position, |expr| expr.span.start()); - let (leading, newlines) = self.leading(start, end); + let (leading, different_line) = self.leading(start, end); let expr = self.visitor.format_expr(element); let trailing = self.trailing(element_span.end(), next_start, is_last); - Expr { leading, expr, trailing, different_line: newlines }.into() + Expr { leading, value: expr, trailing, different_line }.into() } } impl<'me> Exprs<'me> { pub(crate) fn leading(&mut self, start: u32, end: u32) -> (String, bool) { - let mut newlines = false; + let mut different_line = false; let leading = slice!(self.visitor, start, end); let leading_trimmed = slice!(self.visitor, start, end).trim(); @@ -94,13 +104,13 @@ impl<'me> Exprs<'me> { let comment_end = leading_trimmed.rfind(|c| c == '/').unwrap(); if leading[comment_end..].contains('\n') { - newlines = true; + different_line = true; } } else if starts_with_single_line_comment || starts_with_block_comment { - newlines = true; + different_line = true; }; - (leading_trimmed.to_string(), newlines) + (leading_trimmed.to_string(), different_line) } pub(crate) fn trailing(&mut self, start: u32, end: u32, is_last: bool) -> String { @@ -177,3 +187,17 @@ pub(crate) fn find_comment_end(slice: &str, is_last: bool) -> usize { 0 } } + +fn comment_len(comment: &str) -> usize { + match comment { + "" => 0, + _ => { + let len = comment.trim().len(); + if len > 0 { + len + 6 + } else { + len + } + } + } +} diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index e2a20053a3f..f357fb2f12b 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -33,6 +33,13 @@ impl<'me> FmtVisitor<'me> { } } + fn shape(&self) -> Shape { + Shape { + width: self.config.max_width.saturating_sub(self.indent.width()), + indent: self.indent, + } + } + pub(crate) fn fork(&self) -> Self { Self { buffer: String::new(), @@ -151,12 +158,16 @@ impl<'me> FmtVisitor<'me> { } } -#[derive(Clone, Copy)] +#[derive(Clone, Copy, Debug)] struct Indent { block_indent: usize, } impl Indent { + fn width(&self) -> usize { + self.block_indent + } + fn block_indent(&mut self, config: &Config) { self.block_indent += config.tab_spaces; } @@ -174,3 +185,9 @@ impl Indent { " ".repeat(self.block_indent) } } + +#[derive(Clone, Copy, Debug)] +struct Shape { + width: usize, + indent: Indent, +} diff --git a/tooling/nargo_fmt/src/visitor/expr.rs b/tooling/nargo_fmt/src/visitor/expr.rs index 6c56d96e7a6..8d996276a10 100644 --- a/tooling/nargo_fmt/src/visitor/expr.rs +++ b/tooling/nargo_fmt/src/visitor/expr.rs @@ -5,8 +5,11 @@ use noirc_frontend::{ ExpressionKind, Literal, Statement, UnaryOp, }; -use super::{FmtVisitor, Indent}; -use crate::utils::{self, Expr, FindToken}; +use super::{FmtVisitor, Shape}; +use crate::{ + utils::{self, Expr, FindToken}, + Config, +}; impl FmtVisitor<'_> { pub(crate) fn visit_expr(&mut self, expr: Expression) { @@ -56,7 +59,8 @@ impl FmtVisitor<'_> { } ExpressionKind::Call(call_expr) => { let span = call_expr.func.span.end()..span.end(); - let span = normalized_parenthesized_span(slice!(self, span.start, span.end), span); + let span = + skip_useless_tokens(Token::LeftParen, slice!(self, span.start, span.end), span); let callee = self.format_expr(*call_expr.func); let args = format_parens(self.fork(), false, call_expr.arguments, span); @@ -65,7 +69,8 @@ impl FmtVisitor<'_> { } ExpressionKind::MethodCall(method_call_expr) => { let span = method_call_expr.method_name.span().end()..span.end(); - let span = normalized_parenthesized_span(slice!(self, span.start, span.end), span); + let span = + skip_useless_tokens(Token::LeftParen, slice!(self, span.start, span.end), span); let object = self.format_expr(method_call_expr.object); let method = method_call_expr.method_name.to_string(); @@ -78,10 +83,18 @@ impl FmtVisitor<'_> { format!("{}.{}", lhs_str, member_access_expr.rhs) } ExpressionKind::Index(index_expr) => { - let formatted_collection = - self.format_expr(index_expr.collection).trim_end().to_string(); - let formatted_index = self.format_expr(index_expr.index); - format!("{}[{}]", formatted_collection, formatted_index) + let span = index_expr.collection.span.end()..span.end(); + + let span = skip_useless_tokens( + Token::LeftBracket, + slice!(self, span.start, span.end), + span, + ); + + let collection = self.format_expr(index_expr.collection); + let index = format_brackets(self.fork(), false, vec![index_expr.index], span); + + format!("{collection}{index}") } ExpressionKind::Tuple(exprs) => { format_parens(self.fork(), exprs.len() == 1, exprs, span) @@ -91,13 +104,13 @@ impl FmtVisitor<'_> { slice!(self, span.start(), span.end()).to_string() } Literal::Array(ArrayLiteral::Repeated { repeated_element, length }) => { - format!("[{}; {length}]", self.format_expr(*repeated_element)) + let repeated = self.format_expr(*repeated_element); + let length = self.format_expr(*length); + + format!("[{repeated}; {length}]") } - // TODO: Handle line breaks when array gets too long. Literal::Array(ArrayLiteral::Standard(exprs)) => { - let contents: Vec = - exprs.into_iter().map(|expr| self.format_expr(expr)).collect(); - format!("[{}]", contents.join(", ")) + format_brackets(self.fork(), false, exprs, span) } Literal::Unit => "()".to_string(), }, @@ -224,58 +237,103 @@ impl FmtVisitor<'_> { } } -fn format_parens( +fn format_expr_seq( + prefix: &str, + sufix: &str, mut visitor: FmtVisitor, trailing_comma: bool, exprs: Vec, span: Span, + limit: Option, ) -> String { visitor.indent.block_indent(visitor.config); - let nested_indent = visitor.indent; + let nested_indent = visitor.shape(); let exprs: Vec<_> = utils::Exprs::new(&visitor, span, exprs).collect(); - let (exprs, force_one_line) = format_exprs(trailing_comma, exprs, nested_indent); + let exprs = format_exprs(visitor.config, trailing_comma, exprs, nested_indent, limit); visitor.indent.block_unindent(visitor.config); - wrap_exprs(exprs, nested_indent, visitor.indent, force_one_line) + wrap_exprs(prefix, sufix, exprs, nested_indent, visitor.shape()) } -fn format_exprs(trailing_comma: bool, exprs: Vec, indent: Indent) -> (String, bool) { - let mut result = String::new(); +fn format_brackets( + visitor: FmtVisitor, + trailing_comma: bool, + exprs: Vec, + span: Span, +) -> String { + let array_width = visitor.config.array_width; + format_expr_seq("[", "]", visitor, trailing_comma, exprs, span, array_width.into()) +} + +fn format_parens( + visitor: FmtVisitor, + trailing_comma: bool, + exprs: Vec, + span: Span, +) -> String { + format_expr_seq("(", ")", visitor, trailing_comma, exprs, span, None) +} - let mut force_one_line = true; - let indent_str = indent.to_string(); +fn format_exprs( + config: &Config, + trailing_comma: bool, + exprs: Vec, + shape: Shape, + limit: Option, +) -> String { + let mut result = String::new(); + let indent_str = shape.indent.to_string(); - let tactic = Tactic::of(&exprs); + let tactic = Tactic::of(&exprs, config.short_array_element_width_threshold, limit); let mut exprs = exprs.into_iter().enumerate().peekable(); + let mut line_len = 0; + let mut prev_expr_trailing_comment = false; while let Some((index, expr)) = exprs.next() { let is_first = index == 0; let separate = exprs.peek().is_some() || trailing_comma; + let separate_len = usize::from(separate); match tactic { - Tactic::Vertical if !is_first && !expr.expr.is_empty() && !result.is_empty() => { + Tactic::Vertical if !is_first && !expr.value.is_empty() && !result.is_empty() => { result.push('\n'); result.push_str(&indent_str); } Tactic::Horizontal if !is_first => { result.push(' '); } + Tactic::Mixed => { + let total_width = expr.total_width() + separate_len; + + if line_len > 0 && line_len + 1 + total_width > shape.width + || prev_expr_trailing_comment + { + result.push('\n'); + result.push_str(&indent_str); + line_len = 0; + } else if line_len > 0 { + result.push(' '); + line_len += 1; + } + + line_len += total_width; + } _ => {} } result.push_str(&expr.leading); if expr.different_line { - force_one_line = false; result.push('\n'); result.push_str(&indent_str); + line_len = expr.value.chars().count(); } else if !expr.leading.is_empty() { result.push(' '); } - result.push_str(&expr.expr); + result.push_str(&expr.value); if tactic == Tactic::Horizontal { result.push_str(&expr.trailing); @@ -285,48 +343,83 @@ fn format_exprs(trailing_comma: bool, exprs: Vec, indent: Indent) -> (Stri result.push(','); } - if tactic == Tactic::Vertical { - if !expr.different_line { + if tactic != Tactic::Horizontal { + prev_expr_trailing_comment = !expr.trailing.is_empty(); + + if !expr.different_line && !expr.trailing.is_empty() { result.push(' '); } + result.push_str(&expr.trailing); } } - (result, force_one_line) + result } fn wrap_exprs( + prefix: &str, + sufix: &str, exprs: String, - nested_indent: Indent, - indent: Indent, - force_one_line: bool, + nested_shape: Shape, + shape: Shape, ) -> String { - if force_one_line && !exprs.contains('\n') { - format!("({exprs})") + let first_line_width = exprs.lines().next().map_or(0, |line| line.chars().count()); + + if first_line_width <= shape.width { + let allow_trailing_newline = exprs + .lines() + .last() + .unwrap_or_default() + .find_token_with(|token| matches!(token, Token::LineComment(_, _))) + .is_some(); + + let trailing_newline = if allow_trailing_newline { + shape.indent.to_string_with_newline() + } else { + String::new() + }; + + format!("{prefix}{exprs}{trailing_newline}{sufix}") } else { - let nested_indent_str = "\n".to_string() + &nested_indent.to_string(); - let indent_str = "\n".to_string() + &indent.to_string(); + let nested_indent_str = nested_shape.indent.to_string_with_newline(); + let indent_str = shape.indent.to_string(); - format!("({nested_indent_str}{exprs}{indent_str})") + format!("{prefix}{nested_indent_str}{exprs}{indent_str}{sufix}") } } -#[derive(PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq, Clone, Copy)] enum Tactic { Vertical, Horizontal, + Mixed, } impl Tactic { - fn of(exprs: &[Expr]) -> Self { - if exprs.iter().any(|item| { + fn of(exprs: &[Expr], max_width: usize, limit: Option) -> Self { + let mut tactic = if exprs.iter().any(|item| { has_single_line_comment(&item.leading) || has_single_line_comment(&item.trailing) }) { Tactic::Vertical } else { Tactic::Horizontal + }; + + if tactic == Tactic::Vertical && no_long_exprs(exprs, max_width) { + tactic = Tactic::Mixed; } + + if let Some(limit) = limit { + let total_width: usize = exprs.iter().map(|expr| expr.total_width()).sum(); + if total_width <= limit && !exprs.iter().any(|expr| expr.is_multiline()) { + tactic = Tactic::Horizontal; + } else { + tactic = Tactic::Mixed; + } + } + + tactic } } @@ -334,8 +427,12 @@ fn has_single_line_comment(slice: &str) -> bool { slice.trim_start().starts_with("//") } -fn normalized_parenthesized_span(slice: &str, mut span: Range) -> Span { - let offset = slice.find_token(Token::LeftParen).expect("parenthesized expression"); +fn skip_useless_tokens(token: Token, slice: &str, mut span: Range) -> Span { + let offset = slice.find_token(token).unwrap(); span.start += offset; span.into() } + +fn no_long_exprs(exprs: &[Expr], max_width: usize) -> bool { + exprs.iter().all(|expr| expr.value.len() <= max_width) +} diff --git a/tooling/nargo_fmt/src/visitor/stmt.rs b/tooling/nargo_fmt/src/visitor/stmt.rs index 973167fd19a..d7a43db1e00 100644 --- a/tooling/nargo_fmt/src/visitor/stmt.rs +++ b/tooling/nargo_fmt/src/visitor/stmt.rs @@ -9,6 +9,13 @@ impl super::FmtVisitor<'_> { self.visit_expr(expr); self.push_str(";"); } + StatementKind::Let(let_stmt) => { + let let_str = + slice!(self, span.start(), let_stmt.expression.span.start()).trim_end(); + let expr_str = self.format_expr(let_stmt.expression); + + self.push_rewrite(format!("{let_str} {expr_str};"), span); + } StatementKind::Error => unreachable!(), _ => self.format_missing(span.end()), } diff --git a/tooling/nargo_fmt/tests/expected/array.nr b/tooling/nargo_fmt/tests/expected/array.nr new file mode 100644 index 00000000000..c0ffa30a85e --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/array.nr @@ -0,0 +1,23 @@ +fn big_array() { + [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, + 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, + 10000000000000000, 100000000000000000, 1000000000000000000, 10000000000000000000, + 100000000000000000000, 1000000000000000000000, 10000000000000000000000, + 100000000000000000000000, 1000000000000000000000000]; + + [1, 10]; + + [// hello! + 1, 10]; + + [// hello! + 1, // asd + 10]; + + [// hello! + 1, // asd + 10// asdasd + ]; + + [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18]]]; +} diff --git a/tooling/nargo_fmt/tests/expected/call.nr b/tooling/nargo_fmt/tests/expected/call.nr index eeb2e386bc8..8a104b6d5e0 100644 --- a/tooling/nargo_fmt/tests/expected/call.nr +++ b/tooling/nargo_fmt/tests/expected/call.nr @@ -1,23 +1,19 @@ fn foo() { my_function(10, some_value, another_func(20, 30)); - outer_function( - some_function(), // Original inner function call + outer_function(some_function(), // Original inner function call another_function() // Original inner function call ); - outer_function( - some_function(), // Original inner function call + outer_function(some_function(), // Original inner function call another_function() // Original inner function call ); - my_function( - // Comment + my_function(// Comment some_value, /* Multiline Comment */ - another_func(20, 30) - ); + another_func(20, 30)); my_function(some_function(10, "arg1", another_function()), another_func(20, some_function(), 30)); diff --git a/tooling/nargo_fmt/tests/expected/index.nr b/tooling/nargo_fmt/tests/expected/index.nr index 79430e5c0e6..54f2ed2cf39 100644 --- a/tooling/nargo_fmt/tests/expected/index.nr +++ b/tooling/nargo_fmt/tests/expected/index.nr @@ -2,4 +2,8 @@ fn foo() { let arr = [10, 20, 30, 40]; arr[2]; arr[2]; + arr[/*test*/ 2]; + arr[2/*test*/]; + arr[// test + 2]; } diff --git a/tooling/nargo_fmt/tests/expected/let.nr b/tooling/nargo_fmt/tests/expected/let.nr new file mode 100644 index 00000000000..261982cf3e1 --- /dev/null +++ b/tooling/nargo_fmt/tests/expected/let.nr @@ -0,0 +1,17 @@ +fn let_() { + let fn_call = my_function(some_function(10, "arg1", another_function()), another_func(20, some_function(), 30)); + let array = [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18]]]; + + let padded_sha256_hash: [u8; 259] = [// Padded hash + 209, 50, 135, 178, 4, 155, 190, 229, 228, 111, 61, 174, 8, 49, 48, 116, 90, 226, 77, 7, 111, + 27, 19, 113, 154, 48, 138, 136, 138, 15, 230, 132, 32, 4, 0, 5, 1, 2, 4, 3, 101, 1, 72, 134, + 96, 9, 6, 13, 48, 49, 48, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, + // Rest is padded with 0s until max bytes + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0]; +} diff --git a/tooling/nargo_fmt/tests/expected/literals.nr b/tooling/nargo_fmt/tests/expected/literals.nr index 4dc47bf7e2e..abe14c14965 100644 --- a/tooling/nargo_fmt/tests/expected/literals.nr +++ b/tooling/nargo_fmt/tests/expected/literals.nr @@ -5,6 +5,8 @@ fn main() { [0xff; 5]; + [0 as u8; MAX_BYTES]; + true; "hello world"; diff --git a/tooling/nargo_fmt/tests/expected/struct.nr b/tooling/nargo_fmt/tests/expected/struct.nr index 5e3530e8364..f662e5757a5 100644 --- a/tooling/nargo_fmt/tests/expected/struct.nr +++ b/tooling/nargo_fmt/tests/expected/struct.nr @@ -53,7 +53,7 @@ fn get_dog() -> Animal { } fn main(x: Field, y: Field) { - let first = Foo::default(x,y); + let first = Foo::default(x, y); let p = Pair { first, second: 1 }; assert(p.bar() == x); @@ -61,7 +61,7 @@ fn main(x: Field, y: Field) { assert(p.first.array[0] != p.first.array[1]); // Nested structs - let (struct_from_tuple, a_bool) = test_struct_in_tuple(true,x,y); + let (struct_from_tuple, a_bool) = test_struct_in_tuple(true, x, y); assert(struct_from_tuple.my_bool == true); assert(a_bool == true); assert(struct_from_tuple.my_int == 5); diff --git a/tooling/nargo_fmt/tests/expected/tuple.nr b/tooling/nargo_fmt/tests/expected/tuple.nr index 71f67c9f14f..b190a5f7c55 100644 --- a/tooling/nargo_fmt/tests/expected/tuple.nr +++ b/tooling/nargo_fmt/tests/expected/tuple.nr @@ -1,9 +1,7 @@ fn main() { (1,); - ( - // hello - 1, - ); + (// hello + 1,); (/*hello*/ 1,); (1/*hello*/,); (1,); @@ -16,32 +14,19 @@ fn main() { (1/*test*/,); - ( - // - 1, - ); + (// + 1,); - ( - // 1 - 1, - // 2, - 2 - ); + (// 1 + 1, // 2, + 2); (/*1*/ 1, /*2*/ 2); // FIXME: - ( - ( - ( - //2 - 1, - ), - ), - ); - ( - /*a*/ + (((//2 + 1,),),); + (/*a*/ 1/*b*/, -/*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/ - ); +/*c*/ 2/*d*/, /*c*/ 2/*d*/, /*e*/ 3/*f*/); } diff --git a/tooling/nargo_fmt/tests/input/array.nr b/tooling/nargo_fmt/tests/input/array.nr new file mode 100644 index 00000000000..73651ef76bd --- /dev/null +++ b/tooling/nargo_fmt/tests/input/array.nr @@ -0,0 +1,39 @@ +fn big_array() { + [ + 1,10,100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, 10000000000000000, 100000000000000000, 1000000000000000000, + 10000000000000000000, + 100000000000000000000, + 1000000000000000000000, + 10000000000000000000000, + 100000000000000000000000, + 1000000000000000000000000, + ]; + + [ + 1, + 10, + ]; + + [ +// hello! +1, +10, + ]; + + [ +// hello! +1, +// asd +10, + ]; + + [ +// hello! +1, +// asd +10, +// asdasd + ]; + + [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18]]]; +} diff --git a/tooling/nargo_fmt/tests/input/index.nr b/tooling/nargo_fmt/tests/input/index.nr index e1c6fed02c1..7d10e897b8d 100644 --- a/tooling/nargo_fmt/tests/input/index.nr +++ b/tooling/nargo_fmt/tests/input/index.nr @@ -2,4 +2,9 @@ fn foo() { let arr = [10, 20, 30, 40]; arr [2]; arr [2]; + arr [/*test*/2]; + arr [2/*test*/]; + arr [ + // test + 2]; } \ No newline at end of file diff --git a/tooling/nargo_fmt/tests/input/let.nr b/tooling/nargo_fmt/tests/input/let.nr new file mode 100644 index 00000000000..d73a6450a33 --- /dev/null +++ b/tooling/nargo_fmt/tests/input/let.nr @@ -0,0 +1,15 @@ +fn let_() { + let fn_call = my_function(some_function( 10, "arg1", another_function() ),another_func (20, some_function() , 30 )); + let array = [[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]], [[13, 14, 15], [16, 17, 18]]]; + + let padded_sha256_hash: [u8; 259] = [ + // Padded hash + 209, 50, 135, 178, 4, 155, 190, 229, 228, 111, 61, 174, 8, 49, 48, 116, 90, 226, 77, 7, 111, 27, 19, 113, 154, 48, 138, 136, 138, 15, 230, 132, 32, 4, 0, 5, 1, 2, 4, 3, 101, 1, 72, 134, 96, 9, 6, 13, 48, 49, + 48, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 1, 0, + // Rest is padded with 0s until max bytes + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ]; +} diff --git a/tooling/nargo_fmt/tests/input/literals.nr b/tooling/nargo_fmt/tests/input/literals.nr index ec7659ac66f..3490c1e7d0d 100644 --- a/tooling/nargo_fmt/tests/input/literals.nr +++ b/tooling/nargo_fmt/tests/input/literals.nr @@ -7,6 +7,8 @@ fn main() { [0xff;5]; + [0 as u8; MAX_BYTES]; + true; "hello world"; From c82c43fa3fd9490a9c18ad1507405d39b99bc89b Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 23 Oct 2023 12:36:47 +0100 Subject: [PATCH 5/7] chore: move empty circuits to `compile_success_empty` (#3247) --- .../conditional_regression_547/target/acir.gz | Bin 39 -> 0 bytes .../target/witness.gz | Bin 45 -> 0 bytes .../conditional_regression_579/target/acir.gz | Bin 24 -> 0 bytes .../target/witness.gz | Bin 23 -> 0 bytes .../target/acir.gz | Bin 24 -> 0 bytes .../target/witness.gz | Bin 23 -> 0 bytes .../acir_artifacts/main_return/target/acir.gz | Bin 40 -> 0 bytes .../main_return/target/witness.gz | Bin 46 -> 0 bytes .../references_aliasing/target/acir.gz | Bin 24 -> 0 bytes .../references_aliasing/target/witness.gz | Bin 23 -> 0 bytes .../simple_array_param/target/acir.gz | Bin 42 -> 0 bytes .../simple_array_param/target/witness.gz | Bin 49 -> 0 bytes .../target/acir.gz | Bin 24 -> 0 bytes .../target/witness.gz | Bin 23 -> 0 bytes .../trait_as_return_type/target/acir.gz | Bin 0 -> 46 bytes .../target/witness.gz | Bin .../target/acir.gz | Bin 24 -> 0 bytes .../target/witness.gz | Bin 23 -> 0 bytes .../target/acir.gz | Bin 38 -> 0 bytes .../trait_function_calls/target/acir.gz | Bin 24 -> 0 bytes .../trait_function_calls/target/witness.gz | Bin 23 -> 0 bytes .../trait_multi_module_test/target/acir.gz | Bin 24 -> 0 bytes .../trait_multi_module_test/target/witness.gz | Bin 23 -> 0 bytes .../target/acir.gz | Bin 38 -> 0 bytes .../target/witness.gz | Bin 46 -> 0 bytes .../acir_artifacts/trait_self/target/acir.gz | Bin 24 -> 0 bytes .../trait_self/target/witness.gz | Bin 23 -> 0 bytes .../trait_where_clause/target/acir.gz | Bin 24 -> 0 bytes .../trait_where_clause/target/witness.gz | Bin 23 -> 0 bytes .../conditional_regression_547/Nargo.toml | 0 .../conditional_regression_547/Prover.toml | 0 .../conditional_regression_547/src/main.nr | 0 .../conditional_regression_579/Nargo.toml | 0 .../conditional_regression_579/Prover.toml | 0 .../conditional_regression_579/src/main.nr | 0 .../conditional_regression_to_bits/Nargo.toml | 0 .../Prover.toml | 0 .../src/main.nr | 0 .../main_return/Nargo.toml | 0 .../main_return/Prover.toml | 0 .../main_return/src/main.nr | 0 .../references_aliasing/src/main.nr | 27 +++++++++++++--- .../simple_array_param/Nargo.toml | 0 .../simple_array_param/Prover.toml | 0 .../simple_array_param/src/main.nr | 0 .../Nargo.toml | 0 .../Prover.toml | 0 .../src/main.nr | 0 .../Nargo.toml | 0 .../Prover.toml | 0 .../src/main.nr | 0 .../trait_default_implementation/Nargo.toml | 0 .../trait_default_implementation/Prover.toml | 0 .../trait_default_implementation/src/main.nr | 0 .../trait_function_calls/Nargo.toml | 0 .../trait_function_calls}/Prover.toml | 0 .../trait_function_calls/src/main.nr | 0 .../trait_multi_module_test/Nargo.toml | 0 .../trait_multi_module_test}/Prover.toml | 0 .../trait_multi_module_test/src/main.nr | 0 .../trait_multi_module_test/src/module1.nr | 0 .../trait_multi_module_test/src/module2.nr | 0 .../trait_multi_module_test/src/module3.nr | 0 .../trait_multi_module_test/src/module4.nr | 0 .../trait_multi_module_test/src/module5.nr | 0 .../trait_multi_module_test/src/module6.nr | 0 .../trait_override_implementation/Nargo.toml | 0 .../trait_override_implementation/Prover.toml | 0 .../trait_override_implementation/src/main.nr | 0 .../trait_self/Nargo.toml | 0 .../trait_self/src/main.nr | 0 .../trait_self/trait_self/Nargo.toml | 0 .../trait_self/trait_self/src/main.nr | 0 .../trait_where_clause/Nargo.toml | 0 .../trait_where_clause/src/main.nr | 0 .../trait_where_clause/src/the_trait.nr | 0 .../references_aliasing/Nargo.toml | 7 ----- .../references_aliasing/src/main.nr | 29 ------------------ .../trait_multi_module_test/Prover.toml | 0 79 files changed, 23 insertions(+), 40 deletions(-) delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/conditional_regression_579/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/conditional_regression_579/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/conditional_regression_to_bits/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/conditional_regression_to_bits/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/main_return/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/main_return/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/references_aliasing/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/references_aliasing/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_allowed_item_name_matches/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_allowed_item_name_matches/target/witness.gz create mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_as_return_type/target/acir.gz rename tooling/nargo_cli/tests/acir_artifacts/{trait_default_implementation => trait_as_return_type}/target/witness.gz (100%) delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_associated_member_names_clashes/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_associated_member_names_clashes/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_default_implementation/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_function_calls/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_function_calls/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_multi_module_test/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_multi_module_test/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_override_implementation/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_override_implementation/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_self/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_self/target/witness.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_where_clause/target/acir.gz delete mode 100644 tooling/nargo_cli/tests/acir_artifacts/trait_where_clause/target/witness.gz rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_547/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_547/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_547/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_579/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_579/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_579/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_to_bits/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_to_bits/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/conditional_regression_to_bits/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/main_return/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/main_return/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/main_return/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/simple_array_param/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/simple_array_param/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/simple_array_param/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_allowed_item_name_matches/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success/references_aliasing => compile_success_empty/trait_allowed_item_name_matches}/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_allowed_item_name_matches/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_associated_member_names_clashes/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success/trait_allowed_item_name_matches => compile_success_empty/trait_associated_member_names_clashes}/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_associated_member_names_clashes/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_default_implementation/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_default_implementation/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_default_implementation/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_function_calls/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success/trait_associated_member_names_clashes => compile_success_empty/trait_function_calls}/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_function_calls/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success/trait_function_calls => compile_success_empty/trait_multi_module_test}/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/src/module1.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/src/module2.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/src/module3.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/src/module4.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/src/module5.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_multi_module_test/src/module6.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_override_implementation/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_override_implementation/Prover.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_override_implementation/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_self/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_self/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_self/trait_self/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_self/trait_self/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_where_clause/Nargo.toml (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_where_clause/src/main.nr (100%) rename tooling/nargo_cli/tests/{execution_success => compile_success_empty}/trait_where_clause/src/the_trait.nr (100%) delete mode 100644 tooling/nargo_cli/tests/execution_success/references_aliasing/Nargo.toml delete mode 100644 tooling/nargo_cli/tests/execution_success/references_aliasing/src/main.nr delete mode 100644 tooling/nargo_cli/tests/execution_success/trait_multi_module_test/Prover.toml diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_547/target/acir.gz deleted file mode 100644 index 090578ca4e3da83386c1be71ed2b91b72b1de1ce..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 39 pcmb2|=3oGW|D`7maspXR2kz9roaeYe{^5y7d0~~pyID*36@Gu>`nUTHW-%61!jqLpWhAYnJKj#Ruwpb7XR0IGwrw*(D diff --git a/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_579/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/conditional_regression_579/target/acir.gz deleted file mode 100644 index 2639a2e0809384eac56475a35d011104cd4b4686..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24 acmb2|=3oGW|H%moatsVIX)4V+Kmhh)Q@ef)6 diff --git a/tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/simple_array_param/target/witness.gz deleted file mode 100644 index a8e277ea7959fc5fcbdad4fcdfabfc566b551e19..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 49 zcmb2|=3oE;rvGbuHgYmBa2(zu{*wJ){nVzv3wT+KSU*0od?VEO{wnwXPnod`fC>St C5))Yf diff --git a/tooling/nargo_cli/tests/acir_artifacts/trait_allowed_item_name_matches/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/trait_allowed_item_name_matches/target/acir.gz deleted file mode 100644 index 2639a2e0809384eac56475a35d011104cd4b4686..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24 acmb2|=3oGW|H%moatsVIX)4V+Kmh~&V6Et^^NuVX*=x7IUCwsy>$G(aKxF`J_7RT& literal 0 HcmV?d00001 diff --git a/tooling/nargo_cli/tests/acir_artifacts/trait_default_implementation/target/witness.gz b/tooling/nargo_cli/tests/acir_artifacts/trait_as_return_type/target/witness.gz similarity index 100% rename from tooling/nargo_cli/tests/acir_artifacts/trait_default_implementation/target/witness.gz rename to tooling/nargo_cli/tests/acir_artifacts/trait_as_return_type/target/witness.gz diff --git a/tooling/nargo_cli/tests/acir_artifacts/trait_associated_member_names_clashes/target/acir.gz b/tooling/nargo_cli/tests/acir_artifacts/trait_associated_member_names_clashes/target/acir.gz deleted file mode 100644 index 2639a2e0809384eac56475a35d011104cd4b4686..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 24 acmb2|=3oGW|H%moatsVIX)4V+Kmh Date: Mon, 23 Oct 2023 04:38:01 -0700 Subject: [PATCH 6/7] chore: add constructor formatter (#3243) --- tooling/nargo_fmt/src/config.rs | 2 +- tooling/nargo_fmt/src/lib.rs | 3 +- tooling/nargo_fmt/src/utils.rs | 74 +++++-- tooling/nargo_fmt/src/visitor.rs | 30 +-- tooling/nargo_fmt/src/visitor/expr.rs | 225 ++++++++++++++------- tooling/nargo_fmt/src/visitor/item.rs | 2 +- tooling/nargo_fmt/src/visitor/stmt.rs | 2 +- tooling/nargo_fmt/tests/expected/array.nr | 30 ++- tooling/nargo_fmt/tests/expected/expr.nr | 4 + tooling/nargo_fmt/tests/expected/let.nr | 34 ++++ tooling/nargo_fmt/tests/expected/struct.nr | 6 +- tooling/nargo_fmt/tests/input/expr.nr | 5 + tooling/nargo_fmt/tests/input/let.nr | 12 ++ 13 files changed, 312 insertions(+), 117 deletions(-) diff --git a/tooling/nargo_fmt/src/config.rs b/tooling/nargo_fmt/src/config.rs index 1514937caff..aaa5cbac3d0 100644 --- a/tooling/nargo_fmt/src/config.rs +++ b/tooling/nargo_fmt/src/config.rs @@ -46,7 +46,7 @@ config! { tab_spaces: usize, 4, "Number of spaces per tab"; remove_nested_parens: bool, true, "Remove nested parens"; short_array_element_width_threshold: usize, 10, "Width threshold for an array element to be considered short"; - array_width: usize, 60, "Maximum width of an array literal before falling back to vertical formatting"; + array_width: usize, 100, "Maximum width of an array literal before falling back to vertical formatting"; } impl Config { diff --git a/tooling/nargo_fmt/src/lib.rs b/tooling/nargo_fmt/src/lib.rs index 887e71be735..3e8ee570c09 100644 --- a/tooling/nargo_fmt/src/lib.rs +++ b/tooling/nargo_fmt/src/lib.rs @@ -20,9 +20,8 @@ /// in both placement and content during the formatting process. mod config; pub mod errors; -#[macro_use] -mod visitor; mod utils; +mod visitor; use noirc_frontend::ParsedModule; use visitor::FmtVisitor; diff --git a/tooling/nargo_fmt/src/utils.rs b/tooling/nargo_fmt/src/utils.rs index 4bea21be939..d1c642b87d2 100644 --- a/tooling/nargo_fmt/src/utils.rs +++ b/tooling/nargo_fmt/src/utils.rs @@ -2,7 +2,7 @@ use crate::visitor::FmtVisitor; use noirc_frontend::hir::resolution::errors::Span; use noirc_frontend::lexer::Lexer; use noirc_frontend::token::Token; -use noirc_frontend::Expression; +use noirc_frontend::{Expression, Ident}; pub(crate) fn recover_comment_removed(original: &str, new: String) -> String { if changed_comment_content(original, &new) { @@ -46,19 +46,15 @@ impl Expr { } } -pub(crate) struct Exprs<'me> { +pub(crate) struct Exprs<'me, T> { pub(crate) visitor: &'me FmtVisitor<'me>, - pub(crate) elements: std::iter::Peekable>, + pub(crate) elements: std::iter::Peekable>, pub(crate) last_position: u32, pub(crate) end_position: u32, } -impl<'me> Exprs<'me> { - pub(crate) fn new( - visitor: &'me FmtVisitor<'me>, - span: Span, - elements: Vec, - ) -> Self { +impl<'me, T: Item> Exprs<'me, T> { + pub(crate) fn new(visitor: &'me FmtVisitor<'me>, span: Span, elements: Vec) -> Self { Self { visitor, last_position: span.start() + 1, /*(*/ @@ -68,33 +64,33 @@ impl<'me> Exprs<'me> { } } -impl Iterator for Exprs<'_> { +impl Iterator for Exprs<'_, T> { type Item = Expr; fn next(&mut self) -> Option { let element = self.elements.next()?; - let element_span = element.span; + let element_span = element.span(); let start = self.last_position; let end = element_span.start(); let is_last = self.elements.peek().is_none(); - let next_start = self.elements.peek().map_or(self.end_position, |expr| expr.span.start()); + let next_start = self.elements.peek().map_or(self.end_position, |expr| expr.start()); let (leading, different_line) = self.leading(start, end); - let expr = self.visitor.format_expr(element); + let expr = element.format(self.visitor); let trailing = self.trailing(element_span.end(), next_start, is_last); Expr { leading, value: expr, trailing, different_line }.into() } } -impl<'me> Exprs<'me> { +impl<'me, T> Exprs<'me, T> { pub(crate) fn leading(&mut self, start: u32, end: u32) -> (String, bool) { let mut different_line = false; - let leading = slice!(self.visitor, start, end); - let leading_trimmed = slice!(self.visitor, start, end).trim(); + let leading = self.visitor.slice(start..end); + let leading_trimmed = leading.trim(); let starts_with_block_comment = leading_trimmed.starts_with("/*"); let ends_with_block_comment = leading_trimmed.ends_with("*/"); @@ -114,7 +110,7 @@ impl<'me> Exprs<'me> { } pub(crate) fn trailing(&mut self, start: u32, end: u32, is_last: bool) -> String { - let slice = slice!(self.visitor, start, end); + let slice = self.visitor.slice(start..end); let comment_end = find_comment_end(slice, is_last); let trailing = slice[..comment_end].trim_matches(',').trim(); self.last_position = start + (comment_end as u32); @@ -201,3 +197,47 @@ fn comment_len(comment: &str) -> usize { } } } + +pub(crate) trait Item { + fn span(&self) -> Span; + + fn format(self, visitor: &FmtVisitor) -> String; + + fn start(&self) -> u32 { + self.span().start() + } + + fn end(&self) -> u32 { + self.span().end() + } +} + +impl Item for Expression { + fn span(&self) -> Span { + self.span + } + + fn format(self, visitor: &FmtVisitor) -> String { + visitor.format_expr(self) + } +} + +impl Item for (Ident, Expression) { + fn span(&self) -> Span { + let (name, value) = self; + (name.span().start()..value.span.end()).into() + } + + fn format(self, visitor: &FmtVisitor) -> String { + let (name, expr) = self; + + let name = name.0.contents; + let expr = visitor.format_expr(expr); + + if name == expr { + name + } else { + format!("{name}: {expr}") + } + } +} diff --git a/tooling/nargo_fmt/src/visitor.rs b/tooling/nargo_fmt/src/visitor.rs index f357fb2f12b..32e41cb34db 100644 --- a/tooling/nargo_fmt/src/visitor.rs +++ b/tooling/nargo_fmt/src/visitor.rs @@ -1,18 +1,10 @@ -/// A macro to create a slice from a given data source, helping to avoid borrow checker errors. -#[macro_export] -macro_rules! slice { - ($this:expr, $start:expr, $end:expr) => { - &$this.source[$start as usize..$end as usize] - }; -} - mod expr; mod item; mod stmt; -use noirc_frontend::hir::resolution::errors::Span; +use noirc_frontend::{hir::resolution::errors::Span, token::Token}; -use crate::config::Config; +use crate::{config::Config, utils::FindToken}; pub(crate) struct FmtVisitor<'me> { config: &'me Config, @@ -33,6 +25,20 @@ impl<'me> FmtVisitor<'me> { } } + pub(crate) fn slice(&self, span: impl Into) -> &'me str { + let span = span.into(); + &self.source[span.start() as usize..span.end() as usize] + } + + fn span_before(&self, span: impl Into, token: Token) -> Span { + let span = span.into(); + + let slice = self.slice(span); + let offset = slice.find_token(token).unwrap(); + + (span.start() + offset..span.end()).into() + } + fn shape(&self) -> Shape { Shape { width: self.config.max_width.saturating_sub(self.indent.width()), @@ -110,7 +116,7 @@ impl<'me> FmtVisitor<'me> { return; } - let slice = slice!(self, start, end); + let slice = self.slice(start..end); self.last_position = end; if slice.trim().is_empty() && !self.at_start() { @@ -147,7 +153,7 @@ impl<'me> FmtVisitor<'me> { } pub(crate) fn format_comment(&self, span: Span) -> String { - let slice = slice!(self, span.start(), span.end()).trim(); + let slice = self.slice(span).trim(); let pos = slice.find('/'); if !slice.is_empty() && pos.is_some() { diff --git a/tooling/nargo_fmt/src/visitor/expr.rs b/tooling/nargo_fmt/src/visitor/expr.rs index 8d996276a10..89674f3f17a 100644 --- a/tooling/nargo_fmt/src/visitor/expr.rs +++ b/tooling/nargo_fmt/src/visitor/expr.rs @@ -1,13 +1,11 @@ -use std::ops::Range; - use noirc_frontend::{ - hir::resolution::errors::Span, token::Token, ArrayLiteral, BlockExpression, Expression, - ExpressionKind, Literal, Statement, UnaryOp, + hir::resolution::errors::Span, token::Token, ArrayLiteral, BlockExpression, + ConstructorExpression, Expression, ExpressionKind, Literal, Statement, UnaryOp, }; use super::{FmtVisitor, Shape}; use crate::{ - utils::{self, Expr, FindToken}, + utils::{self, Expr, FindToken, Item}, Config, }; @@ -16,8 +14,7 @@ impl FmtVisitor<'_> { let span = expr.span; let rewrite = self.format_expr(expr); - let rewrite = - utils::recover_comment_removed(slice!(self, span.start(), span.end()), rewrite); + let rewrite = utils::recover_comment_removed(self.slice(span), rewrite); self.push_rewrite(rewrite, span); self.last_position = span.end(); @@ -58,23 +55,23 @@ impl FmtVisitor<'_> { ) } ExpressionKind::Call(call_expr) => { - let span = call_expr.func.span.end()..span.end(); - let span = - skip_useless_tokens(Token::LeftParen, slice!(self, span.start, span.end), span); + let args_span = + self.span_before(call_expr.func.span.end()..span.end(), Token::LeftParen); let callee = self.format_expr(*call_expr.func); - let args = format_parens(self.fork(), false, call_expr.arguments, span); + let args = format_parens(self.fork(), false, call_expr.arguments, args_span); format!("{callee}{args}") } ExpressionKind::MethodCall(method_call_expr) => { - let span = method_call_expr.method_name.span().end()..span.end(); - let span = - skip_useless_tokens(Token::LeftParen, slice!(self, span.start, span.end), span); + let args_span = self.span_before( + method_call_expr.method_name.span().end()..span.end(), + Token::LeftParen, + ); let object = self.format_expr(method_call_expr.object); let method = method_call_expr.method_name.to_string(); - let args = format_parens(self.fork(), false, method_call_expr.arguments, span); + let args = format_parens(self.fork(), false, method_call_expr.arguments, args_span); format!("{object}.{method}{args}") } @@ -83,16 +80,11 @@ impl FmtVisitor<'_> { format!("{}.{}", lhs_str, member_access_expr.rhs) } ExpressionKind::Index(index_expr) => { - let span = index_expr.collection.span.end()..span.end(); - - let span = skip_useless_tokens( - Token::LeftBracket, - slice!(self, span.start, span.end), - span, - ); + let index_span = self + .span_before(index_expr.collection.span.end()..span.end(), Token::LeftBracket); let collection = self.format_expr(index_expr.collection); - let index = format_brackets(self.fork(), false, vec![index_expr.index], span); + let index = format_brackets(self.fork(), false, vec![index_expr.index], index_span); format!("{collection}{index}") } @@ -101,7 +93,7 @@ impl FmtVisitor<'_> { } ExpressionKind::Literal(literal) => match literal { Literal::Integer(_) | Literal::Bool(_) | Literal::Str(_) | Literal::FmtStr(_) => { - slice!(self, span.start(), span.end()).to_string() + self.slice(span).to_string() } Literal::Array(ArrayLiteral::Repeated { repeated_element, length }) => { let repeated = self.format_expr(*repeated_element); @@ -172,11 +164,56 @@ impl FmtVisitor<'_> { result } } + ExpressionKind::Constructor(constructor) => { + let type_name = self.slice(constructor.type_name.span()); + let fields_span = self + .span_before(constructor.type_name.span().end()..span.end(), Token::LeftBrace); + + self.format_struct_lit(type_name, fields_span, *constructor) + } // TODO: - _expr => slice!(self, span.start(), span.end()).to_string(), + _expr => self.slice(span).to_string(), } } + fn format_struct_lit( + &self, + type_name: &str, + fields_span: Span, + constructor: ConstructorExpression, + ) -> String { + let fields = { + let mut visitor = self.fork(); + + visitor.indent.block_indent(visitor.config); + + let nested_indent = visitor.shape(); + let exprs: Vec<_> = + utils::Exprs::new(&visitor, fields_span, constructor.fields).collect(); + let exprs = format_exprs( + visitor.config, + Tactic::HorizontalVertical, + false, + exprs, + nested_indent, + ); + + visitor.indent.block_unindent(visitor.config); + + if exprs.contains('\n') { + format!( + "{}{exprs}{}", + nested_indent.indent.to_string_with_newline(), + visitor.shape().indent.to_string_with_newline() + ) + } else { + format!(" {exprs} ") + } + }; + + format!("{type_name} {{{fields}}}") + } + pub(crate) fn visit_block( &mut self, block: BlockExpression, @@ -197,7 +234,7 @@ impl FmtVisitor<'_> { this.visit_stmts(block.0); }); - let slice = slice!(self, self.last_position, block_span.end() - 1).trim_end(); + let slice = self.slice(self.last_position..block_span.end() - 1).trim_end(); self.push_str(slice); self.last_position = block_span.end(); @@ -211,7 +248,7 @@ impl FmtVisitor<'_> { fn trim_spaces_after_opening_brace(&mut self, block: &[Statement]) { if let Some(first_stmt) = block.first() { - let slice = slice!(self, self.last_position, first_stmt.span.start()); + let slice = self.slice(self.last_position..first_stmt.span.start()); let len = slice.chars().take_while(|ch| ch.is_whitespace()).collect::().rfind('\n'); self.last_position += len.unwrap_or(0) as u32; @@ -219,7 +256,7 @@ impl FmtVisitor<'_> { } fn visit_empty_block(&mut self, block_span: Span, should_indent: bool) { - let slice = slice!(self, block_span.start(), block_span.end()); + let slice = self.slice(block_span); let comment_str = slice[1..slice.len() - 1].trim(); let block_str = if comment_str.is_empty() { "{}".to_string() @@ -237,24 +274,24 @@ impl FmtVisitor<'_> { } } -fn format_expr_seq( +fn format_expr_seq( prefix: &str, - sufix: &str, + suffix: &str, mut visitor: FmtVisitor, trailing_comma: bool, - exprs: Vec, + exprs: Vec, span: Span, - limit: Option, + tactic: Tactic, ) -> String { visitor.indent.block_indent(visitor.config); let nested_indent = visitor.shape(); let exprs: Vec<_> = utils::Exprs::new(&visitor, span, exprs).collect(); - let exprs = format_exprs(visitor.config, trailing_comma, exprs, nested_indent, limit); + let exprs = format_exprs(visitor.config, tactic, trailing_comma, exprs, nested_indent); visitor.indent.block_unindent(visitor.config); - wrap_exprs(prefix, sufix, exprs, nested_indent, visitor.shape()) + wrap_exprs(prefix, suffix, exprs, nested_indent, visitor.shape()) } fn format_brackets( @@ -264,7 +301,15 @@ fn format_brackets( span: Span, ) -> String { let array_width = visitor.config.array_width; - format_expr_seq("[", "]", visitor, trailing_comma, exprs, span, array_width.into()) + format_expr_seq( + "[", + "]", + visitor, + trailing_comma, + exprs, + span, + Tactic::LimitedHorizontalVertical(array_width), + ) } fn format_parens( @@ -273,20 +318,20 @@ fn format_parens( exprs: Vec, span: Span, ) -> String { - format_expr_seq("(", ")", visitor, trailing_comma, exprs, span, None) + format_expr_seq("(", ")", visitor, trailing_comma, exprs, span, Tactic::Horizontal) } fn format_exprs( config: &Config, + tactic: Tactic, trailing_comma: bool, exprs: Vec, shape: Shape, - limit: Option, ) -> String { let mut result = String::new(); let indent_str = shape.indent.to_string(); - let tactic = Tactic::of(&exprs, config.short_array_element_width_threshold, limit); + let tactic = tactic.definitive(&exprs, config.short_array_element_width_threshold); let mut exprs = exprs.into_iter().enumerate().peekable(); let mut line_len = 0; let mut prev_expr_trailing_comment = false; @@ -297,14 +342,16 @@ fn format_exprs( let separate_len = usize::from(separate); match tactic { - Tactic::Vertical if !is_first && !expr.value.is_empty() && !result.is_empty() => { + DefinitiveTactic::Vertical + if !is_first && !expr.value.is_empty() && !result.is_empty() => + { result.push('\n'); result.push_str(&indent_str); } - Tactic::Horizontal if !is_first => { + DefinitiveTactic::Horizontal if !is_first => { result.push(' '); } - Tactic::Mixed => { + DefinitiveTactic::Mixed => { let total_width = expr.total_width() + separate_len; if line_len > 0 && line_len + 1 + total_width > shape.width @@ -335,7 +382,7 @@ fn format_exprs( result.push_str(&expr.value); - if tactic == Tactic::Horizontal { + if tactic == DefinitiveTactic::Horizontal { result.push_str(&expr.trailing); } @@ -343,7 +390,7 @@ fn format_exprs( result.push(','); } - if tactic != Tactic::Horizontal { + if tactic != DefinitiveTactic::Horizontal { prev_expr_trailing_comment = !expr.trailing.is_empty(); if !expr.different_line && !expr.trailing.is_empty() { @@ -359,7 +406,7 @@ fn format_exprs( fn wrap_exprs( prefix: &str, - sufix: &str, + suffix: &str, exprs: String, nested_shape: Shape, shape: Shape, @@ -380,46 +427,84 @@ fn wrap_exprs( String::new() }; - format!("{prefix}{exprs}{trailing_newline}{sufix}") + format!("{prefix}{exprs}{trailing_newline}{suffix}") } else { let nested_indent_str = nested_shape.indent.to_string_with_newline(); - let indent_str = shape.indent.to_string(); + let indent_str = shape.indent.to_string_with_newline(); - format!("{prefix}{nested_indent_str}{exprs}{indent_str}{sufix}") + format!("{prefix}{nested_indent_str}{exprs}{indent_str}{suffix}") } } -#[derive(Debug, PartialEq, Eq, Clone, Copy)] +#[derive(PartialEq, Eq)] enum Tactic { - Vertical, Horizontal, + HorizontalVertical, + LimitedHorizontalVertical(usize), Mixed, } impl Tactic { - fn of(exprs: &[Expr], max_width: usize, limit: Option) -> Self { - let mut tactic = if exprs.iter().any(|item| { - has_single_line_comment(&item.leading) || has_single_line_comment(&item.trailing) - }) { - Tactic::Vertical - } else { - Tactic::Horizontal + fn definitive( + self, + exprs: &[Expr], + short_array_element_width_threshold: usize, + ) -> DefinitiveTactic { + let tactic = || { + let has_single_line_comment = exprs.iter().any(|item| { + has_single_line_comment(&item.leading) || has_single_line_comment(&item.trailing) + }); + + let limit = match self { + _ if has_single_line_comment => return DefinitiveTactic::Vertical, + + Tactic::Horizontal => return DefinitiveTactic::Horizontal, + Tactic::LimitedHorizontalVertical(limit) => limit, + Tactic::HorizontalVertical | Tactic::Mixed => 100, + }; + + let (sep_count, total_width): (usize, usize) = exprs + .iter() + .map(|expr| expr.total_width()) + .fold((0, 0), |(sep_count, total_width), width| { + (sep_count + 1, total_width + width) + }); + + let total_sep_len = sep_count.saturating_sub(1); + let real_total = total_width + total_sep_len; + + if real_total <= limit && !exprs.iter().any(|expr| expr.is_multiline()) { + DefinitiveTactic::Horizontal + } else if self == Tactic::Mixed { + DefinitiveTactic::Mixed + } else { + DefinitiveTactic::Vertical + } }; - if tactic == Tactic::Vertical && no_long_exprs(exprs, max_width) { - tactic = Tactic::Mixed; - } + tactic().reduce(exprs, short_array_element_width_threshold) + } +} - if let Some(limit) = limit { - let total_width: usize = exprs.iter().map(|expr| expr.total_width()).sum(); - if total_width <= limit && !exprs.iter().any(|expr| expr.is_multiline()) { - tactic = Tactic::Horizontal; - } else { - tactic = Tactic::Mixed; +#[derive(Debug, PartialEq, Eq, Clone, Copy)] +enum DefinitiveTactic { + Vertical, + Horizontal, + Mixed, +} + +impl DefinitiveTactic { + fn reduce(self, exprs: &[Expr], short_array_element_width_threshold: usize) -> Self { + match self { + DefinitiveTactic::Vertical + if no_long_exprs(exprs, short_array_element_width_threshold) => + { + DefinitiveTactic::Mixed + } + DefinitiveTactic::Vertical | DefinitiveTactic::Horizontal | DefinitiveTactic::Mixed => { + self } } - - tactic } } @@ -427,12 +512,6 @@ fn has_single_line_comment(slice: &str) -> bool { slice.trim_start().starts_with("//") } -fn skip_useless_tokens(token: Token, slice: &str, mut span: Range) -> Span { - let offset = slice.find_token(token).unwrap(); - span.start += offset; - span.into() -} - fn no_long_exprs(exprs: &[Expr], max_width: usize) -> bool { exprs.iter().all(|expr| expr.value.len() <= max_width) } diff --git a/tooling/nargo_fmt/src/visitor/item.rs b/tooling/nargo_fmt/src/visitor/item.rs index 1e32ab22747..09031082fa3 100644 --- a/tooling/nargo_fmt/src/visitor/item.rs +++ b/tooling/nargo_fmt/src/visitor/item.rs @@ -5,7 +5,7 @@ use noirc_frontend::{ impl super::FmtVisitor<'_> { fn format_fn_before_block(&self, func: NoirFunction, start: u32) -> (String, bool) { - let slice = slice!(self, start, func.span().start()); + let slice = self.slice(start..func.span().start()); let force_brace_newline = slice.contains("//"); (slice.trim_end().to_string(), force_brace_newline) } diff --git a/tooling/nargo_fmt/src/visitor/stmt.rs b/tooling/nargo_fmt/src/visitor/stmt.rs index d7a43db1e00..724f6bc7156 100644 --- a/tooling/nargo_fmt/src/visitor/stmt.rs +++ b/tooling/nargo_fmt/src/visitor/stmt.rs @@ -11,7 +11,7 @@ impl super::FmtVisitor<'_> { } StatementKind::Let(let_stmt) => { let let_str = - slice!(self, span.start(), let_stmt.expression.span.start()).trim_end(); + self.slice(span.start()..let_stmt.expression.span.start()).trim_end(); let expr_str = self.format_expr(let_stmt.expression); self.push_rewrite(format!("{let_str} {expr_str};"), span); diff --git a/tooling/nargo_fmt/tests/expected/array.nr b/tooling/nargo_fmt/tests/expected/array.nr index c0ffa30a85e..fdf81d3595c 100644 --- a/tooling/nargo_fmt/tests/expected/array.nr +++ b/tooling/nargo_fmt/tests/expected/array.nr @@ -1,9 +1,29 @@ fn big_array() { - [1, 10, 100, 1000, 10000, 100000, 1000000, 10000000, 100000000, 1000000000, 10000000000, - 100000000000, 1000000000000, 10000000000000, 100000000000000, 1000000000000000, - 10000000000000000, 100000000000000000, 1000000000000000000, 10000000000000000000, - 100000000000000000000, 1000000000000000000000, 10000000000000000000000, - 100000000000000000000000, 1000000000000000000000000]; + [1, + 10, + 100, + 1000, + 10000, + 100000, + 1000000, + 10000000, + 100000000, + 1000000000, + 10000000000, + 100000000000, + 1000000000000, + 10000000000000, + 100000000000000, + 1000000000000000, + 10000000000000000, + 100000000000000000, + 1000000000000000000, + 10000000000000000000, + 100000000000000000000, + 1000000000000000000000, + 10000000000000000000000, + 100000000000000000000000, + 1000000000000000000000000]; [1, 10]; diff --git a/tooling/nargo_fmt/tests/expected/expr.nr b/tooling/nargo_fmt/tests/expected/expr.nr index c4fd1633bdb..6c95b6925ef 100644 --- a/tooling/nargo_fmt/tests/expected/expr.nr +++ b/tooling/nargo_fmt/tests/expected/expr.nr @@ -90,3 +90,7 @@ fn parenthesized() { x as Field ) } + +fn constructor() { + Point { x: 5, y: 10 }; +} diff --git a/tooling/nargo_fmt/tests/expected/let.nr b/tooling/nargo_fmt/tests/expected/let.nr index 261982cf3e1..c53f43c7e65 100644 --- a/tooling/nargo_fmt/tests/expected/let.nr +++ b/tooling/nargo_fmt/tests/expected/let.nr @@ -14,4 +14,38 @@ fn let_() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]; + + let a = BigUint56 { + limbs: [ + 1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 + ] + }; + + let person = Person { + first_name: "John", + last_name: "Doe", + home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345" } + }; + + let person = Person { + first_name: "John", + last_name: "Doe", + home_address: Address { + street: "123 Main St", + city: "Exampleville", + zip_code: "12345", + master: Person { + first_name: "John", + last_name: "Doe", + home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345" } + } + } + }; + + let expr = Expr { + // A boolean literal (true, false). + kind: ExprKind::Bool(true) + }; + + let expr = Expr { /*A boolean literal (true, false).*/ kind: ExprKind::Bool(true) }; } diff --git a/tooling/nargo_fmt/tests/expected/struct.nr b/tooling/nargo_fmt/tests/expected/struct.nr index f662e5757a5..6734dec68a6 100644 --- a/tooling/nargo_fmt/tests/expected/struct.nr +++ b/tooling/nargo_fmt/tests/expected/struct.nr @@ -34,11 +34,7 @@ struct MyStruct { my_nest: Nested, } fn test_struct_in_tuple(a_bool : bool,x:Field, y:Field) -> (MyStruct, bool) { - let my_struct = MyStruct { - my_bool: a_bool, - my_int: 5, - my_nest: Nested{a:x,b:y}, - }; + let my_struct = MyStruct { my_bool: a_bool, my_int: 5, my_nest: Nested { a: x, b: y } }; (my_struct, a_bool) } diff --git a/tooling/nargo_fmt/tests/input/expr.nr b/tooling/nargo_fmt/tests/input/expr.nr index 0baef877169..ff2ac1e10a2 100644 --- a/tooling/nargo_fmt/tests/input/expr.nr +++ b/tooling/nargo_fmt/tests/input/expr.nr @@ -99,3 +99,8 @@ fn parenthesized() { x as Field ) } + +fn constructor() { + Point{x :5, + y: 10 }; +} \ No newline at end of file diff --git a/tooling/nargo_fmt/tests/input/let.nr b/tooling/nargo_fmt/tests/input/let.nr index d73a6450a33..c603d44a4ad 100644 --- a/tooling/nargo_fmt/tests/input/let.nr +++ b/tooling/nargo_fmt/tests/input/let.nr @@ -12,4 +12,16 @@ fn let_() { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]; + + let a = BigUint56 {limbs:[1, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]}; + + let person = Person { first_name: "John", last_name: "Doe", home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345" } }; + + let person = Person { first_name: "John", last_name: "Doe", home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345", master: Person { first_name: "John", last_name: "Doe", home_address: Address { street: "123 Main St", city: "Exampleville", zip_code: "12345" } } } }; + + let expr = Expr {// A boolean literal (true, false). +kind: ExprKind::Bool(true), + }; + + let expr = Expr {/*A boolean literal (true, false).*/kind: ExprKind::Bool(true),}; } From 7e963e34a18bcb58ae7f1922c727418c5edbb22b Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Mon, 23 Oct 2023 15:08:54 +0100 Subject: [PATCH 7/7] chore(ci): Generate circuit benchmark summaries on PRs (#3250) --- .github/workflows/gates_report.yml | 90 +++++++++++++++++++++++++ .gitignore | 3 + Cargo.lock | 20 ++---- cspell.json | 1 + tooling/nargo_cli/Cargo.toml | 2 +- tooling/nargo_cli/tests/gates_report.sh | 36 ++++++++++ 6 files changed, 135 insertions(+), 17 deletions(-) create mode 100644 .github/workflows/gates_report.yml create mode 100755 tooling/nargo_cli/tests/gates_report.sh diff --git a/.github/workflows/gates_report.yml b/.github/workflows/gates_report.yml new file mode 100644 index 00000000000..e2d6bdd56b7 --- /dev/null +++ b/.github/workflows/gates_report.yml @@ -0,0 +1,90 @@ +name: Report gates diff + +on: + push: + branches: + - master + pull_request: + +jobs: + build-nargo: + runs-on: ubuntu-latest + strategy: + matrix: + target: [x86_64-unknown-linux-gnu] + + steps: + - name: Checkout Noir repo + uses: actions/checkout@v4 + + - name: Setup toolchain + uses: dtolnay/rust-toolchain@1.66.0 + + - uses: Swatinem/rust-cache@v2 + with: + key: ${{ matrix.target }} + cache-on-failure: true + save-if: ${{ github.event_name != 'merge_group' }} + + - name: Build Nargo + run: cargo build --package nargo_cli --release + + - name: Package artifacts + run: | + mkdir dist + cp ./target/release/nargo ./dist/nargo + 7z a -ttar -so -an ./dist/* | 7z a -si ./nargo-x86_64-unknown-linux-gnu.tar.gz + + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: nargo + path: ./dist/* + retention-days: 3 + + + compare_gas_reports: + needs: [build-nargo] + runs-on: ubuntu-latest + permissions: + pull-requests: write + + steps: + - uses: actions/checkout@v3 + with: + submodules: recursive + + - name: Download nargo binary + uses: actions/download-artifact@v3 + with: + name: nargo + path: ./nargo + + - name: Set nargo on PATH + run: | + nargo_binary="${{ github.workspace }}/nargo/nargo" + chmod +x $nargo_binary + echo "$(dirname $nargo_binary)" >> $GITHUB_PATH + export PATH="$PATH:$(dirname $nargo_binary)" + nargo -V + + - name: Generate gates report + working-directory: ./tooling/nargo_cli/tests + run: | + ./gates_report.sh + mv gates_report.json ../../../gates_report.json + + - name: Compare gates reports + id: gates_diff + uses: TomAFrench/noir-gates-diff@e7cf131b7e7f044c01615f93f0b855f65ddc02d4 + with: + report: gates_report.json + summaryQuantile: 0.9 # only display the 10% most significant circuit size diffs in the summary (defaults to 20%) + + - name: Add gates diff to sticky comment + if: github.event_name == 'pull_request' || github.event_name == 'pull_request_target' + uses: marocchino/sticky-pull-request-comment@v2 + with: + # delete the comment in case changes no longer impact circuit sizes + delete: ${{ !steps.gates_diff.outputs.markdown }} + message: ${{ steps.gates_diff.outputs.markdown }} diff --git a/.gitignore b/.gitignore index 94e8f1a8db0..169353af2b6 100644 --- a/.gitignore +++ b/.gitignore @@ -40,6 +40,9 @@ result !tooling/nargo_cli/tests/acir_artifacts/*/target !tooling/nargo_cli/tests/acir_artifacts/*/target/witness.gz !compiler/wasm/noir-script/target + +gates_report.json + # Github Actions scratch space # This gives a location to download artifacts into the repository in CI without making git dirty. libbarretenberg-wasm32 diff --git a/Cargo.lock b/Cargo.lock index c9c60fc62ed..8fb282dda98 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1116,16 +1116,6 @@ dependencies = [ "itertools", ] -[[package]] -name = "crossbeam-channel" -version = "0.5.8" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a33c2bf77f2df06183c3aa30d1e96c0695a313d4f9c453cc3762a6db39f99200" -dependencies = [ - "cfg-if", - "crossbeam-utils", -] - [[package]] name = "crossbeam-deque" version = "0.8.3" @@ -3187,9 +3177,9 @@ dependencies = [ [[package]] name = "rayon" -version = "1.7.0" +version = "1.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d2df5196e37bcc87abebc0053e20787d73847bb33134a69841207dd0a47f03b" +checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" dependencies = [ "either", "rayon-core", @@ -3197,14 +3187,12 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.11.0" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b8f95bd6966f5c87776639160a66bd8ab9895d9d4ab01ddba9fc60661aebe8d" +checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" dependencies = [ - "crossbeam-channel", "crossbeam-deque", "crossbeam-utils", - "num_cpus", ] [[package]] diff --git a/cspell.json b/cspell.json index ac7953e0653..4df858ffcfa 100644 --- a/cspell.json +++ b/cspell.json @@ -88,6 +88,7 @@ "prettytable", "printstd", "pseudocode", + "quantile", "rustc", "rustup", "schnorr", diff --git a/tooling/nargo_cli/Cargo.toml b/tooling/nargo_cli/Cargo.toml index cb824b41428..a1440dc2ecb 100644 --- a/tooling/nargo_cli/Cargo.toml +++ b/tooling/nargo_cli/Cargo.toml @@ -37,7 +37,7 @@ toml.workspace = true serde.workspace = true serde_json.workspace = true prettytable-rs = "0.10" -rayon = "1.7.0" +rayon = "1.8.0" thiserror.workspace = true tower.workspace = true async-lsp = { version = "0.0.5", default-features = false, features = [ diff --git a/tooling/nargo_cli/tests/gates_report.sh b/tooling/nargo_cli/tests/gates_report.sh new file mode 100755 index 00000000000..e06e6812e9d --- /dev/null +++ b/tooling/nargo_cli/tests/gates_report.sh @@ -0,0 +1,36 @@ +#!/bin/bash +set -e + +# These tests are incompatible with gas reporting +excluded_dirs=("workspace" "workspace_default_member") + +# These tests cause failures in CI with a stack overflow for some reason. +ci_excluded_dirs=("eddsa") + +current_dir=$(pwd) +base_path="$current_dir/execution_success" +test_dirs=$(ls $base_path) + +# We generate a Noir workspace which contains all of the test cases +# This allows us to generate a gates report using `nargo info` for all of them at once. + +echo "[workspace]" > Nargo.toml +echo "members = [" >> Nargo.toml + +for dir in $test_dirs; do + if [[ " ${excluded_dirs[@]} " =~ " ${dir} " ]]; then + continue + fi + + if [[ ${CI-false} = "true" ]] && [[ " ${ci_excluded_dirs[@]} " =~ " ${dir} " ]]; then + continue + fi + + echo " \"execution_success/$dir\"," >> Nargo.toml +done + +echo "]" >> Nargo.toml + +nargo info --json > gates_report.json + +rm Nargo.toml