diff --git a/.noir-sync-commit b/.noir-sync-commit index 75ca521fbe6..c7d7dc99a11 100644 --- a/.noir-sync-commit +++ b/.noir-sync-commit @@ -1 +1 @@ -8aad2e45acbe08afc3902db95a83324f822c35eb +d4c68066ab35ce1c52510cf0c038fb627a0677c3 diff --git a/avm-transpiler/src/utils.rs b/avm-transpiler/src/utils.rs index 97667a386c0..af0bc6bc9cc 100644 --- a/avm-transpiler/src/utils.rs +++ b/avm-transpiler/src/utils.rs @@ -15,16 +15,17 @@ pub fn extract_brillig_from_acir_program(program: &Program) -> &[BrilligOpcode] assert_eq!( program.functions.len(), 1, - "An AVM program should have only a single ACIR function flagged as 'BrilligCall'" + "An AVM program should have only a single ACIR function with a 'BrilligCall'" ); - let opcodes = &program.functions[0].opcodes; + let main_function = &program.functions[0]; + let opcodes = &main_function.opcodes; assert_eq!( opcodes.len(), 1, - "An AVM program should have only a single ACIR function flagged as 'BrilligCall'" + "An AVM program should only have a single `BrilligCall`" ); match opcodes[0] { - Opcode::BrilligCall { .. } => {} + Opcode::BrilligCall { id, .. } => assert_eq!(id, 0, "The ID of the `BrilligCall` must be 0 as we have a single `Brillig` function"), _ => panic!("Tried to extract a Brillig program from its ACIR wrapper opcode, but the opcode doesn't contain Brillig!"), } assert_eq!( diff --git a/barretenberg/acir_tests/run_acir_tests.sh b/barretenberg/acir_tests/run_acir_tests.sh index 88189a43438..e75f8fb1a6b 100755 --- a/barretenberg/acir_tests/run_acir_tests.sh +++ b/barretenberg/acir_tests/run_acir_tests.sh @@ -35,7 +35,7 @@ export BIN CRS_PATH VERBOSE BRANCH cd acir_tests # Convert them to array -SKIP_ARRAY=(diamond_deps_0 workspace workspace_default_member) +SKIP_ARRAY=(diamond_deps_0 workspace workspace_default_member witness_compression) function test() { cd $1 diff --git a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr index da0b4587bb6..ec83e8cc964 100644 --- a/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr +++ b/noir-projects/noir-contracts/contracts/docs_example_contract/src/main.nr @@ -306,7 +306,7 @@ contract DocsExample { b: Field // The actual return type of our circuit is the PrivateCircuitPublicInputs struct, this will be the // input to our kernel! // docs:start:context-example-return - ) -> distinct pub PrivateCircuitPublicInputs { + ) -> pub PrivateCircuitPublicInputs { // docs:end:context-example-return // ************************************************************ // The hasher is a structure used to generate a hash of the circuits inputs. diff --git a/noir-projects/noir-protocol-circuits/crates/parity-base/src/main.nr b/noir-projects/noir-protocol-circuits/crates/parity-base/src/main.nr index 7c2f15d6f76..8dbc300f0f3 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-base/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-base/src/main.nr @@ -1,6 +1,6 @@ use dep::parity_lib::{BaseParityInputs, ParityPublicInputs}; #[recursive] -fn main(inputs: BaseParityInputs) -> distinct pub ParityPublicInputs { +fn main(inputs: BaseParityInputs) -> pub ParityPublicInputs { inputs.base_parity_circuit() } diff --git a/noir-projects/noir-protocol-circuits/crates/parity-root/src/main.nr b/noir-projects/noir-protocol-circuits/crates/parity-root/src/main.nr index b7bae47e468..6f704d260f0 100644 --- a/noir-projects/noir-protocol-circuits/crates/parity-root/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/parity-root/src/main.nr @@ -1,6 +1,6 @@ use dep::parity_lib::{RootParityInputs, ParityPublicInputs}; #[recursive] -fn main(inputs: RootParityInputs) -> distinct pub ParityPublicInputs { +fn main(inputs: RootParityInputs) -> pub ParityPublicInputs { inputs.root_parity_circuit() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr index a152eb992f1..2d0470155e5 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInitCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; -unconstrained fn main(input: PrivateKernelInitCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { +unconstrained fn main(input: PrivateKernelInitCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_initial() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr index 7c89bdaaa97..635b9da54d9 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-init/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInitCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; -fn main(input: PrivateKernelInitCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { +fn main(input: PrivateKernelInitCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_initial() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr index 5d067c6bdb1..f3494a35038 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInnerCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; -unconstrained fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { +unconstrained fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_inner() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr index d4a0f8bd28d..861d229580c 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-inner/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelInnerCircuitPrivateInputs; use dep::types::PrivateKernelCircuitPublicInputs; -fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> distinct pub PrivateKernelCircuitPublicInputs { +fn main(input: PrivateKernelInnerCircuitPrivateInputs) -> pub PrivateKernelCircuitPublicInputs { input.native_private_kernel_circuit_inner() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr index 3e8cb913733..bedd642aeaa 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelTailCircuitPrivateInputs; use dep::types::KernelCircuitPublicInputs; -unconstrained fn main(input: PrivateKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { +unconstrained fn main(input: PrivateKernelTailCircuitPrivateInputs) -> pub KernelCircuitPublicInputs { input.native_private_kernel_circuit_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr index d3acd17bfed..6c20fcfdeb0 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelTailToPublicCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -unconstrained fn main(input: PrivateKernelTailToPublicCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +unconstrained fn main(input: PrivateKernelTailToPublicCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr index 8c9ecbe1591..85050fa143b 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail-to-public/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelTailToPublicCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -fn main(input: PrivateKernelTailToPublicCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +fn main(input: PrivateKernelTailToPublicCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.execute() } diff --git a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr index 35bb9ea802c..681eaacb72d 100644 --- a/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/private-kernel-tail/src/main.nr @@ -1,6 +1,6 @@ use dep::private_kernel_lib::PrivateKernelTailCircuitPrivateInputs; use dep::types::KernelCircuitPublicInputs; -fn main(input: PrivateKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { +fn main(input: PrivateKernelTailCircuitPrivateInputs) -> pub KernelCircuitPublicInputs { input.native_private_kernel_circuit_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic-simulated/src/main.nr index a41c1710e87..eaf2169e3a1 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelAppLogicCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -unconstrained fn main(input: PublicKernelAppLogicCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +unconstrained fn main(input: PublicKernelAppLogicCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.public_kernel_app_logic() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic/src/main.nr index d7c39940cc3..fc4185f03b3 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-app-logic/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelAppLogicCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -fn main(input: PublicKernelAppLogicCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +fn main(input: PublicKernelAppLogicCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.public_kernel_app_logic() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-setup-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-setup-simulated/src/main.nr index 6e9782b95ed..35f53631a04 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-setup-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-setup-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelSetupCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -unconstrained fn main(input: PublicKernelSetupCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +unconstrained fn main(input: PublicKernelSetupCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.public_kernel_setup() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-setup/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-setup/src/main.nr index f5cc57d5cc6..da84636684b 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-setup/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-setup/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelSetupCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -fn main(input: PublicKernelSetupCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +fn main(input: PublicKernelSetupCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.public_kernel_setup() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr index b82c9aa6362..bd928276f4c 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelTailCircuitPrivateInputs; use dep::types::KernelCircuitPublicInputs; -unconstrained fn main(input: PublicKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { +unconstrained fn main(input: PublicKernelTailCircuitPrivateInputs) -> pub KernelCircuitPublicInputs { input.public_kernel_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr index a294f728943..8b6ba443c87 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-tail/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelTailCircuitPrivateInputs; use dep::types::KernelCircuitPublicInputs; -fn main(input: PublicKernelTailCircuitPrivateInputs) -> distinct pub KernelCircuitPublicInputs { +fn main(input: PublicKernelTailCircuitPrivateInputs) -> pub KernelCircuitPublicInputs { input.public_kernel_tail() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown-simulated/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown-simulated/src/main.nr index f37b6755f92..55e9d441348 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown-simulated/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown-simulated/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelTeardownCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -unconstrained fn main(input: PublicKernelTeardownCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +unconstrained fn main(input: PublicKernelTeardownCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.public_kernel_teardown() } diff --git a/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown/src/main.nr b/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown/src/main.nr index 2b21ec6847d..4e347630044 100644 --- a/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown/src/main.nr +++ b/noir-projects/noir-protocol-circuits/crates/public-kernel-teardown/src/main.nr @@ -1,6 +1,6 @@ use dep::public_kernel_lib::PublicKernelTeardownCircuitPrivateInputs; use dep::types::PublicKernelCircuitPublicInputs; -fn main(input: PublicKernelTeardownCircuitPrivateInputs) -> distinct pub PublicKernelCircuitPublicInputs { +fn main(input: PublicKernelTeardownCircuitPrivateInputs) -> pub PublicKernelCircuitPublicInputs { input.public_kernel_teardown() } diff --git a/noir/noir-repo/.github/workflows/docs-pr.yml b/noir/noir-repo/.github/workflows/docs-pr.yml index 945ed555639..9cb6775bfb7 100644 --- a/noir/noir-repo/.github/workflows/docs-pr.yml +++ b/noir/noir-repo/.github/workflows/docs-pr.yml @@ -79,6 +79,8 @@ jobs: run: yarn workspace docs version::stables - name: Build docs + env: + MATOMO_ENV: staging # not really a secret, it will show in the footer anyway run: yarn workspaces foreach -Rpt --from docs run build - name: Upload artifact diff --git a/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml b/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml index c13b0815d94..ccd431ea879 100644 --- a/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml +++ b/noir/noir-repo/.github/workflows/test-rust-workspace-msrv.yml @@ -88,7 +88,8 @@ jobs: - name: Run tests run: | cargo nextest run --archive-file nextest-archive.tar.zst \ - --partition count:${{ matrix.partition }}/4 + --partition count:${{ matrix.partition }}/4 \ + --no-fail-fast # This is a job which depends on all test jobs and reports the overall status. # This allows us to add/remove test jobs without having to update the required workflows. diff --git a/noir/noir-repo/.github/workflows/test-rust-workspace.yml b/noir/noir-repo/.github/workflows/test-rust-workspace.yml index cf35950fa3e..1f3ee5e2268 100644 --- a/noir/noir-repo/.github/workflows/test-rust-workspace.yml +++ b/noir/noir-repo/.github/workflows/test-rust-workspace.yml @@ -75,7 +75,8 @@ jobs: - name: Run tests run: | cargo nextest run --archive-file nextest-archive.tar.zst \ - --partition count:${{ matrix.partition }}/4 + --partition count:${{ matrix.partition }}/4 \ + --no-fail-fast # This is a job which depends on all test jobs and reports the overall status. # This allows us to add/remove test jobs without having to update the required workflows. diff --git a/noir/noir-repo/aztec_macros/src/transforms/functions.rs b/noir/noir-repo/aztec_macros/src/transforms/functions.rs index 24cad05b866..b5803d8ac9e 100644 --- a/noir/noir-repo/aztec_macros/src/transforms/functions.rs +++ b/noir/noir-repo/aztec_macros/src/transforms/functions.rs @@ -2,7 +2,7 @@ use convert_case::{Case, Casing}; use noirc_errors::Span; use noirc_frontend::ast; use noirc_frontend::ast::{ - BlockExpression, ConstrainKind, ConstrainStatement, Distinctness, Expression, ExpressionKind, + BlockExpression, ConstrainKind, ConstrainStatement, Expression, ExpressionKind, ForLoopStatement, ForRange, FunctionReturnType, Ident, Literal, NoirFunction, NoirStruct, Param, PathKind, Pattern, Signedness, Statement, StatementKind, UnresolvedType, UnresolvedTypeData, Visibility, @@ -104,13 +104,8 @@ pub fn transform_function( func.def.return_visibility = Visibility::Public; } - // Distinct return types are only required for private functions // Public functions should have unconstrained auto-inferred - match ty { - "Private" => func.def.return_distinctness = Distinctness::Distinct, - "Public" | "Avm" => func.def.is_unconstrained = true, - _ => (), - } + func.def.is_unconstrained = matches!(ty, "Public" | "Avm"); Ok(()) } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs index 7a7ee24a670..7f945f19784 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs @@ -49,8 +49,6 @@ pub(crate) fn optimize_into_acir( force_brillig_output: bool, print_timings: bool, ) -> Result { - let abi_distinctness = program.return_distinctness; - let ssa_gen_span = span!(Level::TRACE, "ssa_generation"); let ssa_gen_span_guard = ssa_gen_span.enter(); let ssa = SsaBuilder::new(program, print_passes, force_brillig_output, print_timings)? @@ -67,6 +65,9 @@ pub(crate) fn optimize_into_acir( .run_pass(Ssa::remove_bit_shifts, "After Removing Bit Shifts:") // Run mem2reg once more with the flattened CFG to catch any remaining loads/stores .run_pass(Ssa::mem2reg, "After Mem2Reg:") + // Run the inlining pass again to handle functions with `InlineType::NoPredicates`. + // Before flattening is run, we treat functions marked with the `InlineType::NoPredicates` as an entry point. + .run_pass(Ssa::inline_functions_with_no_predicates, "After Inlining:") .run_pass(Ssa::fold_constants, "After Constant Folding:") .run_pass(Ssa::remove_enable_side_effects, "After EnableSideEffects removal:") .run_pass(Ssa::fold_constants_using_constraints, "After Constraint Folding:") @@ -78,7 +79,7 @@ pub(crate) fn optimize_into_acir( drop(ssa_gen_span_guard); - time("SSA to ACIR", print_timings, || ssa.into_acir(&brillig, abi_distinctness)) + time("SSA to ACIR", print_timings, || ssa.into_acir(&brillig)) } // Helper to time SSA passes diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index c5e4e88862f..ff94cd6757e 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -42,7 +42,6 @@ use acvm::{ use fxhash::FxHashMap as HashMap; use im::Vector; use iter_extended::{try_vecmap, vecmap}; -use noirc_frontend::ast::Distinctness; #[derive(Default)] struct SharedContext { @@ -282,11 +281,7 @@ pub(crate) type Artifacts = impl Ssa { #[tracing::instrument(level = "trace", skip_all)] - pub(crate) fn into_acir( - self, - brillig: &Brillig, - abi_distinctness: Distinctness, - ) -> Result { + pub(crate) fn into_acir(self, brillig: &Brillig) -> Result { let mut acirs = Vec::new(); // TODO: can we parallelise this? let mut shared_context = SharedContext::default(); @@ -333,34 +328,38 @@ impl Ssa { bytecode: brillig.byte_code, }); - // TODO: check whether doing this for a single circuit's return witnesses is correct. - // We probably need it for all foldable circuits, as any circuit being folded is essentially an entry point. However, I do not know how that - // plays a part when we potentially want not inlined functions normally as part of the compiler. - // Also at the moment we specify Distinctness as part of the ABI exclusively rather than the function itself - // so this will need to be updated. - let main_func_acir = &mut acirs[0]; - match abi_distinctness { - Distinctness::Distinct => { - // Create a witness for each return witness we have - // to guarantee that the return witnesses are distinct - let distinct_return_witness: Vec<_> = main_func_acir - .return_witnesses - .clone() - .into_iter() - .map(|return_witness| { - main_func_acir - .create_witness_for_expression(&Expression::from(return_witness)) - }) - .collect(); - - main_func_acir.return_witnesses = distinct_return_witness; + let runtime_types = self.functions.values().map(|function| function.runtime()); + for (acir, runtime_type) in acirs.iter_mut().zip(runtime_types) { + if matches!(runtime_type, RuntimeType::Acir(_)) { + generate_distinct_return_witnesses(acir); } - Distinctness::DuplicationAllowed => {} } + Ok((acirs, brillig, self.error_selector_to_type)) } } +fn generate_distinct_return_witnesses(acir: &mut GeneratedAcir) { + // Create a witness for each return witness we have to guarantee that the return witnesses match the standard + // layout for serializing those types as if they were being passed as inputs. + // + // This is required for recursion as otherwise in situations where we cannot make use of the program's ABI + // (e.g. for `std::verify_proof` or the solidity verifier), we need extra knowledge about the program we're + // working with rather than following the standard ABI encoding rules. + // + // TODO: We're being conservative here by generating a new witness for every expression. + // This means that we're likely to get a number of constraints which are just renumbering witnesses. + // This can be tackled by: + // - Tracking the last assigned public input witness and only renumbering a witness if it is below this value. + // - Modifying existing constraints to rearrange their outputs so they are suitable + // - See: https://github.com/noir-lang/noir/pull/4467 + let distinct_return_witness = vecmap(acir.return_witnesses.clone(), |return_witness| { + acir.create_witness_for_expression(&Expression::from(return_witness)) + }); + + acir.return_witnesses = distinct_return_witness; +} + impl<'a> Context<'a> { fn new(shared_context: &'a mut SharedContext) -> Context<'a> { let mut acir_context = AcirContext::default(); @@ -394,7 +393,10 @@ impl<'a> Context<'a> { panic!("ACIR function should have been inlined earlier if not marked otherwise"); } } - InlineType::Fold | InlineType::Never => {} + InlineType::NoPredicates => { + panic!("All ACIR functions marked with #[no_predicates] should be inlined before ACIR gen. This is an SSA exclusive codegen attribute"); + } + InlineType::Fold => {} } // We only want to convert entry point functions. This being `main` and those marked with `InlineType::Fold` Ok(Some(self.convert_acir_main(function, ssa, brillig)?)) @@ -2672,10 +2674,14 @@ mod test { basic_call_with_outputs_assert(InlineType::Fold); call_output_as_next_call_input(InlineType::Fold); basic_nested_call(InlineType::Fold); + } - call_output_as_next_call_input(InlineType::Never); - basic_nested_call(InlineType::Never); - basic_call_with_outputs_assert(InlineType::Never); + #[test] + #[should_panic] + fn basic_calls_no_predicates() { + basic_call_with_outputs_assert(InlineType::NoPredicates); + call_output_as_next_call_input(InlineType::NoPredicates); + basic_nested_call(InlineType::NoPredicates); } #[test] @@ -2717,7 +2723,7 @@ mod test { let ssa = builder.finish(); let (acir_functions, _, _) = ssa - .into_acir(&Brillig::default(), noirc_frontend::ast::Distinctness::Distinct) + .into_acir(&Brillig::default()) .expect("Should compile manually written SSA into ACIR"); // Expected result: // main f0 @@ -2812,9 +2818,9 @@ mod test { let ssa = builder.finish(); let (acir_functions, _, _) = ssa - .into_acir(&Brillig::default(), noirc_frontend::ast::Distinctness::Distinct) + .into_acir(&Brillig::default()) .expect("Should compile manually written SSA into ACIR"); - // The expected result should look very similar to the abvoe test expect that the input witnesses of the `Call` + // The expected result should look very similar to the above test expect that the input witnesses of the `Call` // opcodes will be different. The changes can discerned from the checks below. let main_acir = &acir_functions[0]; @@ -2902,7 +2908,7 @@ mod test { let ssa = builder.finish(); let (acir_functions, _, _) = ssa - .into_acir(&Brillig::default(), noirc_frontend::ast::Distinctness::Distinct) + .into_acir(&Brillig::default()) .expect("Should compile manually written SSA into ACIR"); assert_eq!(acir_functions.len(), 3, "Should have three ACIR functions"); @@ -2918,9 +2924,10 @@ mod test { let func_with_nested_call_acir = &acir_functions[1]; let func_with_nested_call_opcodes = func_with_nested_call_acir.opcodes(); + assert_eq!( func_with_nested_call_opcodes.len(), - 2, + 3, "Should have an expression and a call to a nested `foo`" ); // Should call foo f2 @@ -3014,9 +3021,8 @@ mod test { let ssa = builder.finish(); let brillig = ssa.to_brillig(false); - let (acir_functions, brillig_functions, _) = ssa - .into_acir(&brillig, noirc_frontend::ast::Distinctness::Distinct) - .expect("Should compile manually written SSA into ACIR"); + let (acir_functions, brillig_functions, _) = + ssa.into_acir(&brillig).expect("Should compile manually written SSA into ACIR"); assert_eq!(acir_functions.len(), 1, "Should only have a `main` ACIR function"); assert_eq!(brillig_functions.len(), 2, "Should only have generated two Brillig functions"); @@ -3072,7 +3078,7 @@ mod test { // The Brillig bytecode we insert for the stdlib is hardcoded so we do not need to provide any // Brillig artifacts to the ACIR gen pass. let (acir_functions, brillig_functions, _) = ssa - .into_acir(&Brillig::default(), noirc_frontend::ast::Distinctness::Distinct) + .into_acir(&Brillig::default()) .expect("Should compile manually written SSA into ACIR"); assert_eq!(acir_functions.len(), 1, "Should only have a `main` ACIR function"); @@ -3143,9 +3149,8 @@ mod test { let brillig = ssa.to_brillig(false); println!("{}", ssa); - let (acir_functions, brillig_functions, _) = ssa - .into_acir(&brillig, noirc_frontend::ast::Distinctness::Distinct) - .expect("Should compile manually written SSA into ACIR"); + let (acir_functions, brillig_functions, _) = + ssa.into_acir(&brillig).expect("Should compile manually written SSA into ACIR"); assert_eq!(acir_functions.len(), 1, "Should only have a `main` ACIR function"); // We expect 3 brillig functions: @@ -3232,9 +3237,8 @@ mod test { let brillig = ssa.to_brillig(false); println!("{}", ssa); - let (acir_functions, brillig_functions, _) = ssa - .into_acir(&brillig, noirc_frontend::ast::Distinctness::Distinct) - .expect("Should compile manually written SSA into ACIR"); + let (acir_functions, brillig_functions, _) = + ssa.into_acir(&brillig).expect("Should compile manually written SSA into ACIR"); assert_eq!(acir_functions.len(), 2, "Should only have two ACIR functions"); // We expect 3 brillig functions: diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs index 057786bf5ec..a49e02b0380 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs @@ -85,6 +85,13 @@ impl Function { self.runtime = runtime; } + pub(crate) fn is_no_predicates(&self) -> bool { + match self.runtime() { + RuntimeType::Acir(inline_type) => matches!(inline_type, InlineType::NoPredicates), + RuntimeType::Brillig => false, + } + } + /// Retrieves the entry block of a function. /// /// A function's entry block contains the instructions diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs index 0b78d47fbb1..bddfb25f26c 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/inlining.rs @@ -36,13 +36,30 @@ impl Ssa { /// changes. This is because if the function's id later becomes known by a later /// pass, we would need to re-run all of inlining anyway to inline it, so we might /// as well save the work for later instead of performing it twice. + /// + /// There are some attributes that allow inlining a function at a different step of codegen. + /// Currently this is just `InlineType::NoPredicates` for which we have a flag indicating + /// whether treating that inline functions. The default is to treat these functions as entry points. #[tracing::instrument(level = "trace", skip(self))] - pub(crate) fn inline_functions(mut self) -> Ssa { - self.functions = btree_map(get_entry_point_functions(&self), |entry_point| { - let new_function = InlineContext::new(&self, entry_point).inline_all(&self); - (entry_point, new_function) - }); + pub(crate) fn inline_functions(self) -> Ssa { + Self::inline_functions_inner(self, true) + } + + // Run the inlining pass where functions marked with `InlineType::NoPredicates` as not entry points + pub(crate) fn inline_functions_with_no_predicates(self) -> Ssa { + Self::inline_functions_inner(self, false) + } + fn inline_functions_inner(mut self, no_predicates_is_entry_point: bool) -> Ssa { + self.functions = btree_map( + get_entry_point_functions(&self, no_predicates_is_entry_point), + |entry_point| { + let new_function = + InlineContext::new(&self, entry_point, no_predicates_is_entry_point) + .inline_all(&self); + (entry_point, new_function) + }, + ); self } } @@ -60,6 +77,8 @@ struct InlineContext { // The FunctionId of the entry point function we're inlining into in the old, unmodified Ssa. entry_point: FunctionId, + + no_predicates_is_entry_point: bool, } /// The per-function inlining context contains information that is only valid for one function. @@ -97,10 +116,19 @@ struct PerFunctionContext<'function> { /// should be left in the final program. /// This is the `main` function, any Acir functions with a [fold inline type][InlineType::Fold], /// and any brillig functions used. -fn get_entry_point_functions(ssa: &Ssa) -> BTreeSet { +fn get_entry_point_functions( + ssa: &Ssa, + no_predicates_is_entry_point: bool, +) -> BTreeSet { let functions = ssa.functions.iter(); let mut entry_points = functions - .filter(|(_, function)| function.runtime().is_entry_point()) + .filter(|(_, function)| { + // If we have not already finished the flattening pass, functions marked + // to not have predicates should be marked as entry points. + let no_predicates_is_entry_point = + no_predicates_is_entry_point && function.is_no_predicates(); + function.runtime().is_entry_point() || no_predicates_is_entry_point + }) .map(|(id, _)| *id) .collect::>(); @@ -114,11 +142,21 @@ impl InlineContext { /// The function being inlined into will always be the main function, although it is /// actually a copy that is created in case the original main is still needed from a function /// that could not be inlined calling it. - fn new(ssa: &Ssa, entry_point: FunctionId) -> InlineContext { + fn new( + ssa: &Ssa, + entry_point: FunctionId, + no_predicates_is_entry_point: bool, + ) -> InlineContext { let source = &ssa.functions[&entry_point]; let mut builder = FunctionBuilder::new(source.name().to_owned(), entry_point); builder.set_runtime(source.runtime()); - Self { builder, recursion_level: 0, entry_point, call_stack: CallStack::new() } + Self { + builder, + recursion_level: 0, + entry_point, + call_stack: CallStack::new(), + no_predicates_is_entry_point, + } } /// Start inlining the entry point function and all functions reachable from it. @@ -351,11 +389,17 @@ impl<'function> PerFunctionContext<'function> { for id in block.instructions() { match &self.source_function.dfg[*id] { Instruction::Call { func, arguments } => match self.get_function(*func) { - Some(function) => { - if ssa.functions[&function].runtime().is_entry_point() { + Some(func_id) => { + let function = &ssa.functions[&func_id]; + // If we have not already finished the flattening pass, functions marked + // to not have predicates should be marked as entry points. + let no_predicates_is_entry_point = + self.context.no_predicates_is_entry_point + && function.is_no_predicates(); + if function.runtime().is_entry_point() || no_predicates_is_entry_point { self.push_instruction(*id); } else { - self.inline_function(ssa, *id, function, arguments); + self.inline_function(ssa, *id, func_id, arguments); } } None => self.push_instruction(*id), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/ast/expression.rs b/noir/noir-repo/compiler/noirc_frontend/src/ast/expression.rs index 5659de46588..59c04218e2e 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/expression.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/expression.rs @@ -2,7 +2,7 @@ use std::borrow::Cow; use std::fmt::Display; use crate::ast::{ - Distinctness, Ident, ItemVisibility, Path, Pattern, Recoverable, Statement, StatementKind, + Ident, ItemVisibility, Path, Pattern, Recoverable, Statement, StatementKind, UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, Visibility, }; use crate::token::{Attributes, Token}; @@ -401,7 +401,6 @@ pub struct FunctionDefinition { pub where_clause: Vec, pub return_type: FunctionReturnType, pub return_visibility: Visibility, - pub return_distinctness: Distinctness, } #[derive(Debug, PartialEq, Eq, Clone)] @@ -698,7 +697,6 @@ impl FunctionDefinition { where_clause: where_clause.to_vec(), return_type: return_type.clone(), return_visibility: Visibility::Private, - return_distinctness: Distinctness::DuplicationAllowed, } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/ast/function.rs b/noir/noir-repo/compiler/noirc_frontend/src/ast/function.rs index 9115178671e..dc426a4642a 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/function.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/function.rs @@ -109,7 +109,7 @@ impl From for NoirFunction { Some(FunctionAttribute::Oracle(_)) => FunctionKind::Oracle, Some(FunctionAttribute::Recursive) => FunctionKind::Recursive, Some(FunctionAttribute::Fold) => FunctionKind::Normal, - Some(FunctionAttribute::Inline(_)) => FunctionKind::Normal, + Some(FunctionAttribute::NoPredicates) => FunctionKind::Normal, None => FunctionKind::Normal, }; diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs index 1727471c34f..fa4ea96316a 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -77,7 +77,7 @@ pub enum ResolverError { #[error("#[recursive] attribute is only allowed on entry points to a program")] MisplacedRecursiveAttribute { ident: Ident }, #[error("#[abi(tag)] attribute is only allowed in contracts")] - AbiAttributeOusideContract { span: Span }, + AbiAttributeOutsideContract { span: Span }, #[error("Usage of the `#[foreign]` or `#[builtin]` function attributes are not allowed outside of the Noir standard library")] LowLevelFunctionOutsideOfStdlib { ident: Ident }, #[error("Dependency cycle found, '{item}' recursively depends on itself: {cycle} ")] @@ -90,8 +90,8 @@ pub enum ResolverError { MutableGlobal { span: Span }, #[error("Self-referential structs are not supported")] SelfReferentialStruct { span: Span }, - #[error("#[inline(tag)] attribute is only allowed on constrained functions")] - InlineAttributeOnUnconstrained { ident: Ident }, + #[error("#[no_predicates] attribute is only allowed on constrained functions")] + NoPredicatesAttributeOnUnconstrained { ident: Ident }, #[error("#[fold] attribute is only allowed on constrained functions")] FoldAttributeOnUnconstrained { ident: Ident }, } @@ -313,7 +313,7 @@ impl<'a> From<&'a ResolverError> for Diagnostic { diag.add_note("The `#[recursive]` attribute specifies to the backend whether it should use a prover which generates proofs that are friendly for recursive verification in another circuit".to_owned()); diag } - ResolverError::AbiAttributeOusideContract { span } => { + ResolverError::AbiAttributeOutsideContract { span } => { Diagnostic::simple_error( "#[abi(tag)] attributes can only be used in contracts".to_string(), "misplaced #[abi(tag)] attribute".to_string(), @@ -362,16 +362,16 @@ impl<'a> From<&'a ResolverError> for Diagnostic { *span, ) }, - ResolverError::InlineAttributeOnUnconstrained { ident } => { + ResolverError::NoPredicatesAttributeOnUnconstrained { ident } => { let name = &ident.0.contents; let mut diag = Diagnostic::simple_error( - format!("misplaced #[inline(tag)] attribute on unconstrained function {name}. Only allowed on constrained functions"), - "misplaced #[inline(tag)] attribute".to_string(), + format!("misplaced #[no_predicates] attribute on unconstrained function {name}. Only allowed on constrained functions"), + "misplaced #[no_predicates] attribute".to_string(), ident.0.span(), ); - diag.add_note("The `#[inline(tag)]` attribute specifies to the compiler whether it should diverge from auto-inlining constrained functions".to_owned()); + diag.add_note("The `#[no_predicates]` attribute specifies to the compiler whether it should diverge from auto-inlining constrained functions".to_owned()); diag } ResolverError::FoldAttributeOnUnconstrained { ident } => { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs index 94db3c977fb..60baaecab59 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/resolver.rs @@ -26,8 +26,8 @@ use std::collections::{BTreeMap, BTreeSet, HashSet}; use std::rc::Rc; use crate::ast::{ - ArrayLiteral, BinaryOpKind, BlockExpression, Distinctness, Expression, ExpressionKind, - ForRange, FunctionDefinition, FunctionKind, FunctionReturnType, Ident, ItemVisibility, LValue, + ArrayLiteral, BinaryOpKind, BlockExpression, Expression, ExpressionKind, ForRange, + FunctionDefinition, FunctionKind, FunctionReturnType, Ident, ItemVisibility, LValue, LetStatement, Literal, NoirFunction, NoirStruct, NoirTypeAlias, Param, Path, PathKind, Pattern, Statement, StatementKind, TraitBound, UnaryOp, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression, Visibility, ERROR_IDENT, @@ -320,7 +320,6 @@ impl<'a> Resolver<'a> { where_clause: where_clause.to_vec(), return_type: return_type.clone(), return_visibility: Visibility::Private, - return_distinctness: Distinctness::DuplicationAllowed, }; let (hir_func, func_meta) = self.intern_function(NoirFunction { kind, def }, func_id); @@ -695,7 +694,7 @@ impl<'a> Resolver<'a> { .iter() .any(|attr| matches!(attr, SecondaryAttribute::Abi(_))) { - self.push_err(ResolverError::AbiAttributeOusideContract { + self.push_err(ResolverError::AbiAttributeOutsideContract { span: struct_type.borrow().name.span(), }); } @@ -1000,11 +999,11 @@ impl<'a> Resolver<'a> { let name_ident = HirIdent::non_trait_method(id, location); let attributes = func.attributes().clone(); - let has_inline_attribute = attributes.is_inline(); + let has_no_predicates_attribute = attributes.is_no_predicates(); let should_fold = attributes.is_foldable(); if !self.inline_attribute_allowed(func) { - if has_inline_attribute { - self.push_err(ResolverError::InlineAttributeOnUnconstrained { + if has_no_predicates_attribute { + self.push_err(ResolverError::NoPredicatesAttributeOnUnconstrained { ident: func.name_ident().clone(), }); } else if should_fold { @@ -1013,10 +1012,10 @@ impl<'a> Resolver<'a> { }); } } - // Both the #[fold] and #[inline(tag)] alter a function's inline type and code generation in similar ways. + // Both the #[fold] and #[no_predicates] alter a function's inline type and code generation in similar ways. // In certain cases such as type checking (for which the following flag will be used) both attributes // indicate we should code generate in the same way. Thus, we unify the attributes into one flag here. - let has_inline_or_fold_attribute = has_inline_attribute || should_fold; + let has_inline_attribute = has_no_predicates_attribute || should_fold; let mut generics = vecmap(&self.generics, |(_, typevar, _)| typevar.clone()); let mut parameters = vec![]; @@ -1069,12 +1068,6 @@ impl<'a> Resolver<'a> { }); } - if !self.distinct_allowed(func) - && func.def.return_distinctness != Distinctness::DuplicationAllowed - { - self.push_err(ResolverError::DistinctNotAllowed { ident: func.name_ident().clone() }); - } - if matches!(attributes.function, Some(FunctionAttribute::Test { .. })) && !parameters.is_empty() { @@ -1107,11 +1100,10 @@ impl<'a> Resolver<'a> { parameters: parameters.into(), return_type: func.def.return_type.clone(), return_visibility: func.def.return_visibility, - return_distinctness: func.def.return_distinctness, has_body: !func.def.body.is_empty(), trait_constraints: self.resolve_trait_constraints(&func.def.where_clause), is_entry_point: self.is_entry_point_function(func), - has_inline_or_fold_attribute, + has_inline_attribute, } } @@ -1136,17 +1128,6 @@ impl<'a> Resolver<'a> { } } - /// True if the `distinct` keyword is allowed on a function's return type - fn distinct_allowed(&self, func: &NoirFunction) -> bool { - if self.in_contract { - // "unconstrained" functions are compiled to brillig and thus duplication of - // witness indices in their abis is not a concern. - !func.def.is_unconstrained - } else { - func.name() == MAIN_FUNCTION - } - } - fn inline_attribute_allowed(&self, func: &NoirFunction) -> bool { // Inline attributes are only relevant for constrained functions // as all unconstrained functions are not inlined @@ -1280,7 +1261,7 @@ impl<'a> Resolver<'a> { && let_stmt.attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Abi(_))) { let span = let_stmt.pattern.span(); - self.push_err(ResolverError::AbiAttributeOusideContract { span }); + self.push_err(ResolverError::AbiAttributeOutsideContract { span }); } if !let_stmt.comptime && matches!(let_stmt.pattern, Pattern::Mutable(..)) { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/traits.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/traits.rs index ccae8c6dd03..3d355fd4447 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/traits.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/traits.rs @@ -124,6 +124,7 @@ fn resolve_trait_methods( let mut resolver = Resolver::new(interner, &path_resolver, def_maps, file); resolver.add_generics(generics); + resolver.add_existing_generics(&unresolved_trait.trait_def.generics, trait_generics); resolver.add_existing_generic("Self", name_span, self_typevar); resolver.set_self_type(Some(self_type.clone())); @@ -207,16 +208,16 @@ fn collect_trait_impl_methods( if overrides.is_empty() { if let Some(default_impl) = &method.default_impl { + // copy 'where' clause from unresolved trait impl + let mut default_impl_clone = default_impl.clone(); + default_impl_clone.def.where_clause.extend(trait_impl.where_clause.clone()); + let func_id = interner.push_empty_fn(); let module = ModuleId { local_id: trait_impl.module_id, krate: crate_id }; let location = Location::new(default_impl.def.span, trait_impl.file_id); interner.push_function(func_id, &default_impl.def, module, location); func_ids_in_trait.insert(func_id); - ordered_methods.push(( - method.default_impl_module_id, - func_id, - *default_impl.clone(), - )); + ordered_methods.push((method.default_impl_module_id, func_id, *default_impl_clone)); } else { let error = DefCollectorErrorKind::TraitMissingMethod { trait_name: interner.get_trait(trait_id).name.clone(), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/type_check/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/type_check/mod.rs index 6235fe3848d..0f8131d6ebb 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/type_check/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/type_check/mod.rs @@ -173,7 +173,7 @@ fn check_if_type_is_valid_for_program_input( ) { let meta = type_checker.interner.function_meta(&func_id); if (meta.is_entry_point && !param.1.is_valid_for_program_input()) - || (meta.has_inline_or_fold_attribute && !param.1.is_valid_non_inlined_function_input()) + || (meta.has_inline_attribute && !param.1.is_valid_non_inlined_function_input()) { let span = param.0.span(); errors.push(TypeCheckError::InvalidTypeForEntryPoint { span }); @@ -433,9 +433,7 @@ pub mod test { use iter_extended::btree_map; use noirc_errors::{Location, Span}; - use crate::ast::{ - BinaryOpKind, Distinctness, FunctionKind, FunctionReturnType, Path, Visibility, - }; + use crate::ast::{BinaryOpKind, FunctionKind, FunctionReturnType, Path, Visibility}; use crate::graph::CrateId; use crate::hir::def_map::{ModuleData, ModuleId}; use crate::hir::resolution::import::{ @@ -539,14 +537,13 @@ pub mod test { ] .into(), return_visibility: Visibility::Private, - return_distinctness: Distinctness::DuplicationAllowed, has_body: true, trait_impl: None, return_type: FunctionReturnType::Default(Span::default()), trait_constraints: Vec::new(), direct_generics: Vec::new(), is_entry_point: true, - has_inline_or_fold_attribute: false, + has_inline_attribute: false, }; interner.push_fn_meta(func_meta, func_id); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs index 57d3038a135..c38dd41fd3d 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs @@ -6,7 +6,7 @@ use std::rc::Rc; use super::expr::{HirBlockExpression, HirExpression, HirIdent}; use super::stmt::HirPattern; use super::traits::TraitConstraint; -use crate::ast::{Distinctness, FunctionKind, FunctionReturnType, Visibility}; +use crate::ast::{FunctionKind, FunctionReturnType, Visibility}; use crate::node_interner::{ExprId, NodeInterner, TraitImplId}; use crate::{Type, TypeVariable}; @@ -99,8 +99,6 @@ pub struct FuncMeta { pub return_visibility: Visibility, - pub return_distinctness: Distinctness, - /// The type of this function. Either a Type::Function /// or a Type::Forall for generic functions. pub typ: Type, @@ -126,8 +124,9 @@ pub struct FuncMeta { pub is_entry_point: bool, /// True if this function is marked with an attribute - /// that indicates it should not be inlined, such as `fold` or `inline(never)` - pub has_inline_or_fold_attribute: bool, + /// that indicates it should be inlined differently than the default (inline everything). + /// For example, such as `fold` (never inlined) or `no_predicates` (inlined after flattening) + pub has_inline_attribute: bool, } impl FuncMeta { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs index 82e17ac3912..ebbc7fc9813 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs @@ -582,8 +582,8 @@ impl Attributes { self.function.as_ref().map_or(false, |func_attribute| func_attribute.is_foldable()) } - pub fn is_inline(&self) -> bool { - self.function.as_ref().map_or(false, |func_attribute| func_attribute.is_inline()) + pub fn is_no_predicates(&self) -> bool { + self.function.as_ref().map_or(false, |func_attribute| func_attribute.is_no_predicates()) } } @@ -645,10 +645,7 @@ impl Attribute { ["test"] => Attribute::Function(FunctionAttribute::Test(TestScope::None)), ["recursive"] => Attribute::Function(FunctionAttribute::Recursive), ["fold"] => Attribute::Function(FunctionAttribute::Fold), - ["inline", tag] => { - validate(tag)?; - Attribute::Function(FunctionAttribute::Inline(tag.to_string())) - } + ["no_predicates"] => Attribute::Function(FunctionAttribute::NoPredicates), ["test", name] => { validate(name)?; let malformed_scope = @@ -701,7 +698,7 @@ pub enum FunctionAttribute { Test(TestScope), Recursive, Fold, - Inline(String), + NoPredicates, } impl FunctionAttribute { @@ -738,8 +735,8 @@ impl FunctionAttribute { /// Check whether we have an `inline` attribute /// Although we also do not want to inline foldable functions, /// we keep the two attributes distinct for clarity. - pub fn is_inline(&self) -> bool { - matches!(self, FunctionAttribute::Inline(_)) + pub fn is_no_predicates(&self) -> bool { + matches!(self, FunctionAttribute::NoPredicates) } } @@ -752,7 +749,7 @@ impl fmt::Display for FunctionAttribute { FunctionAttribute::Oracle(ref k) => write!(f, "#[oracle({k})]"), FunctionAttribute::Recursive => write!(f, "#[recursive]"), FunctionAttribute::Fold => write!(f, "#[fold]"), - FunctionAttribute::Inline(ref k) => write!(f, "#[inline({k})]"), + FunctionAttribute::NoPredicates => write!(f, "#[no_predicates]"), } } } @@ -798,7 +795,7 @@ impl AsRef for FunctionAttribute { FunctionAttribute::Test { .. } => "", FunctionAttribute::Recursive => "", FunctionAttribute::Fold => "", - FunctionAttribute::Inline(string) => string, + FunctionAttribute::NoPredicates => "", } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lib.rs b/noir/noir-repo/compiler/noirc_frontend/src/lib.rs index 6c77e3d0545..958a18ac2fb 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lib.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lib.rs @@ -50,7 +50,7 @@ pub mod macros_api { pub use crate::token::SecondaryAttribute; pub use crate::ast::{ - BlockExpression, CallExpression, CastExpression, Distinctness, Expression, ExpressionKind, + BlockExpression, CallExpression, CastExpression, Expression, ExpressionKind, FunctionReturnType, Ident, IndexExpression, ItemVisibility, LetStatement, Literal, MemberAccessExpression, MethodCallExpression, NoirFunction, Path, PathKind, Pattern, Statement, UnresolvedType, UnresolvedTypeData, Visibility, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs index c01b8c9e909..4bd501c07ba 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/ast.rs @@ -5,14 +5,13 @@ use noirc_errors::{ Location, }; +use super::HirType; use crate::hir_def::function::FunctionSignature; use crate::{ - ast::{BinaryOpKind, Distinctness, IntegerBitSize, Signedness, Visibility}, + ast::{BinaryOpKind, IntegerBitSize, Signedness, Visibility}, token::{Attributes, FunctionAttribute}, }; -use super::HirType; - /// The monomorphized AST is expression-based, all statements are also /// folded into this expression enum. Compared to the HIR, the monomorphized /// AST has several differences: @@ -215,10 +214,13 @@ pub enum InlineType { Inline, /// Functions marked as foldable will not be inlined and compiled separately into ACIR Fold, - /// Similar to `Fold`, these functions will not be inlined and compile separately into ACIR. - /// They are different from `Fold` though as they are expected to be inlined into the program + /// Functions marked to have no predicates will not be inlined in the default inlining pass + /// and will be separately inlined after the flattening pass. + /// They are different from `Fold` as they are expected to be inlined into the program /// entry point before being used in the backend. - Never, + /// This attribute is unsafe and can cause a function whose logic relies on predicates from + /// the flattening pass to fail. + NoPredicates, } impl From<&Attributes> for InlineType { @@ -226,13 +228,7 @@ impl From<&Attributes> for InlineType { attributes.function.as_ref().map_or(InlineType::default(), |func_attribute| { match func_attribute { FunctionAttribute::Fold => InlineType::Fold, - FunctionAttribute::Inline(tag) => { - if tag == "never" { - InlineType::Never - } else { - InlineType::default() - } - } + FunctionAttribute::NoPredicates => InlineType::NoPredicates, _ => InlineType::default(), } }) @@ -244,7 +240,7 @@ impl InlineType { match self { InlineType::Inline => false, InlineType::Fold => true, - InlineType::Never => true, + InlineType::NoPredicates => false, } } } @@ -254,7 +250,7 @@ impl std::fmt::Display for InlineType { match self { InlineType::Inline => write!(f, "inline"), InlineType::Fold => write!(f, "fold"), - InlineType::Never => write!(f, "inline(never)"), + InlineType::NoPredicates => write!(f, "no_predicates"), } } } @@ -307,11 +303,6 @@ pub struct Program { pub functions: Vec, pub function_signatures: Vec, pub main_function_signature: FunctionSignature, - /// Indicates whether witness indices are allowed to reoccur in the ABI of the resulting ACIR. - /// - /// Note: this has no impact on monomorphization, and is simply attached here for ease of - /// forwarding to the next phase. - pub return_distinctness: Distinctness, pub return_location: Option, pub return_visibility: Visibility, /// Indicates to a backend whether a SNARK-friendly prover should be used. @@ -327,7 +318,6 @@ impl Program { functions: Vec, function_signatures: Vec, main_function_signature: FunctionSignature, - return_distinctness: Distinctness, return_location: Option, return_visibility: Visibility, recursive: bool, @@ -339,7 +329,6 @@ impl Program { functions, function_signatures, main_function_signature, - return_distinctness, return_location, return_visibility, recursive, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs index c831e4be245..f918610af2c 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -142,8 +142,7 @@ pub fn monomorphize_debug( .collect(); let functions = vecmap(monomorphizer.finished_functions, |(_, f)| f); - let FuncMeta { return_distinctness, return_visibility, kind, .. } = - monomorphizer.interner.function_meta(&main); + let FuncMeta { return_visibility, kind, .. } = monomorphizer.interner.function_meta(&main); let (debug_variables, debug_functions, debug_types) = monomorphizer.debug_type_tracker.extract_vars_and_types(); @@ -151,7 +150,6 @@ pub fn monomorphize_debug( functions, func_sigs, function_sig, - *return_distinctness, monomorphizer.return_location, *return_visibility, *kind == FunctionKind::Recursive, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs index af3d4caa145..9f9a8200954 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/errors.rs @@ -30,6 +30,8 @@ pub enum ParserErrorReason { TraitImplFunctionModifiers, #[error("comptime keyword is deprecated")] ComptimeDeprecated, + #[error("distinct keyword is deprecated. The `distinct` behavior is now the default.")] + DistinctDeprecated, #[error("{0} are experimental and aren't fully supported yet")] ExperimentalFeature(&'static str), #[error( diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs index 4a85f6cb18f..b627714d2a6 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs @@ -33,10 +33,10 @@ use super::{ }; use super::{spanned, Item, ItemKind}; use crate::ast::{ - BinaryOp, BinaryOpKind, BlockExpression, Distinctness, ForLoopStatement, ForRange, - FunctionReturnType, Ident, IfExpression, InfixExpression, LValue, Literal, ModuleDeclaration, - NoirTypeAlias, Param, Path, Pattern, Recoverable, Statement, TraitBound, TypeImpl, - UnresolvedTraitConstraint, UnresolvedTypeExpression, UseTree, UseTreeKind, Visibility, + BinaryOp, BinaryOpKind, BlockExpression, ForLoopStatement, ForRange, Ident, IfExpression, + InfixExpression, LValue, Literal, ModuleDeclaration, NoirTypeAlias, Param, Path, Pattern, + Recoverable, Statement, TraitBound, TypeImpl, UnresolvedTraitConstraint, + UnresolvedTypeExpression, UseTree, UseTreeKind, Visibility, }; use crate::ast::{ Expression, ExpressionKind, LetStatement, StatementKind, UnresolvedType, UnresolvedTypeData, @@ -296,21 +296,6 @@ fn type_alias_definition() -> impl NoirParser { }) } -fn function_return_type() -> impl NoirParser<((Distinctness, Visibility), FunctionReturnType)> { - just(Token::Arrow) - .ignore_then(optional_distinctness()) - .then(optional_visibility()) - .then(spanned(parse_type())) - .or_not() - .map_with_span(|ret, span| match ret { - Some((head, (ty, _))) => (head, FunctionReturnType::Ty(ty)), - None => ( - (Distinctness::DuplicationAllowed, Visibility::Private), - FunctionReturnType::Default(span), - ), - }) -} - fn self_parameter() -> impl NoirParser { let mut_ref_pattern = just(Token::Ampersand).then_ignore(keyword(Keyword::Mut)); let mut_pattern = keyword(Keyword::Mut); @@ -737,13 +722,6 @@ fn optional_visibility() -> impl NoirParser { }) } -fn optional_distinctness() -> impl NoirParser { - keyword(Keyword::Distinct).or_not().map(|opt| match opt { - Some(_) => Distinctness::Distinct, - None => Distinctness::DuplicationAllowed, - }) -} - fn maybe_comp_time() -> impl NoirParser { keyword(Keyword::Comptime).or_not().validate(|opt, span, emit| { if opt.is_some() { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs index ec4728fba4f..40180a9f9ac 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/function.rs @@ -1,16 +1,19 @@ use super::{ attributes::{attributes, validate_attributes}, - block, fresh_statement, ident, keyword, maybe_comp_time, nothing, optional_distinctness, - optional_visibility, parameter_name_recovery, parameter_recovery, parenthesized, parse_type, - pattern, self_parameter, where_clause, NoirParser, -}; -use crate::ast::{ - Distinctness, FunctionDefinition, FunctionReturnType, Ident, ItemVisibility, NoirFunction, - Param, Visibility, + block, fresh_statement, ident, keyword, maybe_comp_time, nothing, optional_visibility, + parameter_name_recovery, parameter_recovery, parenthesized, parse_type, pattern, + self_parameter, where_clause, NoirParser, }; use crate::parser::labels::ParsingRuleLabel; use crate::parser::spanned; use crate::token::{Keyword, Token}; +use crate::{ + ast::{ + FunctionDefinition, FunctionReturnType, Ident, ItemVisibility, NoirFunction, Param, + Visibility, + }, + parser::{ParserError, ParserErrorReason}, +}; use chumsky::prelude::*; @@ -43,8 +46,7 @@ pub(super) fn function_definition(allow_self: bool) -> impl NoirParser impl NoirParser> { .map(|opt| opt.unwrap_or_default()) } -fn function_return_type() -> impl NoirParser<((Distinctness, Visibility), FunctionReturnType)> { +#[deprecated = "Distinct keyword is now deprecated. Remove this function after the 0.30.0 release"] +fn optional_distinctness() -> impl NoirParser { + keyword(Keyword::Distinct).or_not().validate(|opt, span, emit| { + if opt.is_some() { + emit(ParserError::with_reason(ParserErrorReason::DistinctDeprecated, span)); + } + opt.is_some() + }) +} + +pub(super) fn function_return_type() -> impl NoirParser<(Visibility, FunctionReturnType)> { + #[allow(deprecated)] just(Token::Arrow) .ignore_then(optional_distinctness()) - .then(optional_visibility()) + .ignore_then(optional_visibility()) .then(spanned(parse_type())) .or_not() .map_with_span(|ret, span| match ret { - Some((head, (ty, _))) => (head, FunctionReturnType::Ty(ty)), - None => ( - (Distinctness::DuplicationAllowed, Visibility::Private), - FunctionReturnType::Default(span), - ), + Some((visibility, (ty, _))) => (visibility, FunctionReturnType::Ty(ty)), + None => (Visibility::Private, FunctionReturnType::Default(span)), }) } @@ -174,7 +184,7 @@ mod test { "fn f(f: pub Field, y : Field, z : Field) -> u8 { x + a }", "fn f(f: pub Field, y : T, z : Field) -> u8 { x + a }", "fn func_name(x: [Field], y : [Field;2],y : pub [Field;2], z : pub [u8;5]) {}", - "fn main(x: pub u8, y: pub u8) -> distinct pub [u8; 2] { [x, y] }", + "fn main(x: pub u8, y: pub u8) -> pub [u8; 2] { [x, y] }", "fn f(f: pub Field, y : Field, z : Field) -> u8 { x + a }", "fn f(f: pub Field, y : T, z : Field) -> u8 { x + a }", "fn func_name(f: Field, y : T) where T: SomeTrait {}", @@ -214,6 +224,8 @@ mod test { // A leading plus is not allowed. "fn func_name(f: Field, y : T) where T: + SomeTrait {}", "fn func_name(f: Field, y : T) where T: TraitX + {}", + // `distinct` is deprecated + "fn main(x: pub u8, y: pub u8) -> distinct pub [u8; 2] { [x, y] }", ], ); } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/traits.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/traits.rs index 0507dbdbc71..1aec57c8e41 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/traits.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/traits.rs @@ -1,9 +1,7 @@ use chumsky::prelude::*; -use super::{ - block, expression, fresh_statement, function, function_declaration_parameters, - function_return_type, -}; +use super::function::function_return_type; +use super::{block, expression, fresh_statement, function, function_declaration_parameters}; use crate::ast::{ Expression, ItemVisibility, NoirTrait, NoirTraitImpl, TraitBound, TraitImplItem, TraitItem, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs index cf2d7dbe153..5f99e9e347a 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs @@ -746,6 +746,27 @@ mod test { } } + #[test] + fn test_impl_self_within_default_def() { + let src = " + trait Bar { + fn ok(self) -> Self; + + fn ref_ok(self) -> Self { + self.ok() + } + } + + impl Bar for (T, T) where T: Bar { + fn ok(self) -> Self { + self + } + }"; + let errors = get_program_errors(src); + errors.iter().for_each(|err| println!("{:?}", err)); + assert!(errors.is_empty()); + } + #[test] fn check_trait_as_type_as_fn_parameter() { let src = " @@ -1357,9 +1378,10 @@ fn lambda$f1(mut env$l1: (Field)) -> Field { assert_eq!(get_program_errors(src).len(), 1); } + #[test] fn deny_inline_attribute_on_unconstrained() { let src = r#" - #[inline(never)] + #[no_predicates] unconstrained fn foo(x: Field, y: Field) { assert(x != y); } @@ -1368,7 +1390,9 @@ fn lambda$f1(mut env$l1: (Field)) -> Field { assert_eq!(errors.len(), 1); assert!(matches!( errors[0].0, - CompilationError::ResolverError(ResolverError::InlineAttributeOnUnconstrained { .. }) + CompilationError::ResolverError( + ResolverError::NoPredicatesAttributeOnUnconstrained { .. } + ) )); } diff --git a/noir/noir-repo/docs/docs/noir/concepts/distinct.md b/noir/noir-repo/docs/docs/noir/concepts/distinct.md deleted file mode 100644 index 6c993b8b5e0..00000000000 --- a/noir/noir-repo/docs/docs/noir/concepts/distinct.md +++ /dev/null @@ -1,64 +0,0 @@ ---- -title: Distinct Witnesses -sidebar_position: 11 ---- - -The `distinct` keyword prevents repetitions of witness indices in the program's ABI. This ensures -that the witnesses being returned as public inputs are all unique. - -The `distinct` keyword is only used for return values on program entry points (usually the `main()` -function). - -When using `distinct` and `pub` simultaneously, `distinct` comes first. See the example below. - -You can read more about the problem this solves -[here](https://github.com/noir-lang/noir/issues/1183). - -## Example - -Without the `distinct` keyword, the following program - -```rust -fn main(x : pub Field, y : pub Field) -> pub [Field; 4] { - let a = 1; - let b = 1; - [x + 1, y, a, b] -} -``` - -compiles to - -```json -{ - //... - "abi": { - //... - "param_witnesses": { "x": [1], "y": [2] }, - "return_witnesses": [3, 2, 4, 4] - } -} -``` - -Whereas (with the `distinct` keyword) - -```rust -fn main(x : pub Field, y : pub Field) -> distinct pub [Field; 4] { - let a = 1; - let b = 1; - [x + 1, y, a, b] -} -``` - -compiles to - -```json -{ - //... - "abi": { - //... - "param_witnesses": { "x": [1], "y": [2] }, - //... - "return_witnesses": [3, 4, 5, 6] - } -} -``` diff --git a/noir/noir-repo/docs/docusaurus.config.ts b/noir/noir-repo/docs/docusaurus.config.ts index 49566c5c380..2d5b8941f55 100644 --- a/noir/noir-repo/docs/docusaurus.config.ts +++ b/noir/noir-repo/docs/docusaurus.config.ts @@ -47,7 +47,9 @@ export default { }, ], ], - + customFields: { + MATOMO_ENV: process.env.MATOMO_ENV, + }, themeConfig: { colorMode: { respectPrefersColorScheme: true, diff --git a/noir/noir-repo/docs/package.json b/noir/noir-repo/docs/package.json index f9e95fc02f8..c81d0b7b24f 100644 --- a/noir/noir-repo/docs/package.json +++ b/noir/noir-repo/docs/package.json @@ -4,11 +4,12 @@ "private": true, "scripts": { "preprocess": "yarn workspace @noir-lang/acvm_js build && ./scripts/codegen_nargo_reference.sh && yarn node ./scripts/preprocess/index.js", - "start": "yarn preprocess && docusaurus start", + "start": "yarn preprocess && MATOMO_ENV=dev docusaurus start", "build": "yarn preprocess && docusaurus build", "clean": "rm -rf ./processed-docs ./processed-docs ./build", "version::stables": "ts-node ./scripts/setStable.ts", "serve": "serve build", + "swizzle": "docusaurus swizzle", "version": "yarn version::stables && ./scripts/cut_version.sh" }, "dependencies": { diff --git a/noir/noir-repo/docs/src/components/Matomo/matomo.jsx b/noir/noir-repo/docs/src/components/Matomo/matomo.jsx new file mode 100644 index 00000000000..7ee34fc8e51 --- /dev/null +++ b/noir/noir-repo/docs/src/components/Matomo/matomo.jsx @@ -0,0 +1,133 @@ +import { useEffect, useState } from 'react'; +import useDocusaurusContext from '@docusaurus/useDocusaurusContext'; +import Link from '@docusaurus/Link'; + +function getSiteId(env) { + if (env == 'dev') { + return '3'; + } else if (env == 'staging') { + return '2'; + } else { + return '1'; + } +} +function pushInstruction(name, ...args) { + return window._paq.push([name, ...args]); +} + +export default function useMatomo() { + const { siteConfig } = useDocusaurusContext(); + const [showBanner, setShowBanner] = useState(false); + + const env = siteConfig.customFields.MATOMO_ENV; + const urlBase = 'https://noirlang.matomo.cloud/'; + const trackerUrl = `${urlBase}matomo.php`; + const srcUrl = `${urlBase}matomo.js`; + + window._paq = window._paq || []; + + useEffect(() => { + const storedConsent = localStorage.getItem('matomoConsent'); + if (storedConsent === null) { + setShowBanner(true); + } + }, []); + + useEffect(() => { + pushInstruction('setTrackerUrl', trackerUrl); + pushInstruction('setSiteId', getSiteId(env)); + if (env !== 'prod') { + pushInstruction('setSecureCookie', false); + } + + const doc = document; + const scriptElement = doc.createElement('script'); + const scripts = doc.getElementsByTagName('script')[0]; + + scriptElement.type = 'text/javascript'; + scriptElement.async = true; + scriptElement.defer = true; + scriptElement.src = srcUrl; + + if (scripts && scripts.parentNode) { + scripts.parentNode.insertBefore(scriptElement, scripts); + } + }, []); + + useEffect(() => { + pushInstruction('trackPageView'); + }, [window.location.href]); + + const optIn = () => { + pushInstruction('rememberConsentGiven'); + localStorage.setItem('matomoConsent', true); + setShowBanner(false); + }; + + const optOut = () => { + pushInstruction('forgetConsentGiven'); + localStorage.setItem('matomoConsent', false); + setShowBanner(false); + }; + + const debug = () => { + pushInstruction(function () { + console.log(this.getRememberedConsent()); + console.log(localStorage.getItem('matomoConsent')); + }); + }; + + const reset = () => { + pushInstruction('forgetConsentGiven'); + localStorage.clear('matomoConsent'); + }; + + if (!showBanner && env === 'dev') { + return ( +
+
+

Debugging analytics

+
+ + +
+
+
+ ); + } else if (!showBanner) { + return null; + } + + return ( +
+
+

+ We value your privacy and we only collect statistics and essential cookies. If you'd like to help us improve + our websites, you can allow cookies for tracking page views, time on site, and other analytics. +
+
+ + Find out how we use cookies and how you can change your settings. + +

+
+ + + {env === 'dev' && ( + + )} +
+
+
+ ); +} diff --git a/noir/noir-repo/docs/src/css/custom.css b/noir/noir-repo/docs/src/css/custom.css index b08766fbc3b..fb6be87b519 100644 --- a/noir/noir-repo/docs/src/css/custom.css +++ b/noir/noir-repo/docs/src/css/custom.css @@ -214,3 +214,31 @@ input#docsearch-input { background-color: transparent; } + +#optout-form { + position: sticky; + bottom: 10px; + flex-direction: column; + display: flex; + max-width: 800px; + margin: 0 auto; + background-color: var(--ifm-breadcrumb-color-active); +} + + + +.homepage_footer { + text-align: center; + margin-bottom: 1rem; + padding: 1.5rem 2rem; + display: flex; + flex-direction: column; + border: 1px solid #BEC2C3; + border-radius: 12px; +} + +.homepage_cta_footer_container { + display: flex; + justify-content: center; +} + diff --git a/noir/noir-repo/docs/src/pages/index.jsx b/noir/noir-repo/docs/src/pages/index.jsx index b372871e7b4..c7de44b300d 100644 --- a/noir/noir-repo/docs/src/pages/index.jsx +++ b/noir/noir-repo/docs/src/pages/index.jsx @@ -1,9 +1,8 @@ -import React, { lazy, Suspense } from 'react'; +import React from 'react'; import Layout from '@theme/Layout'; import Link from '@docusaurus/Link'; import headerPic from '@site/static/img/homepage_header_pic.png'; -import { BeatLoader } from 'react-spinners'; export default function Landing() { return ( diff --git a/noir/noir-repo/docs/src/theme/Root.js b/noir/noir-repo/docs/src/theme/Root.js new file mode 100644 index 00000000000..68c1e529db3 --- /dev/null +++ b/noir/noir-repo/docs/src/theme/Root.js @@ -0,0 +1,22 @@ +import React from 'react'; +import useMatomo from '@site/src/components/Matomo/matomo'; +import BrowserOnly from '@docusaurus/BrowserOnly'; +import useIsBrowser from '@docusaurus/useIsBrowser'; + +function OptOutForm() { + const banner = useMatomo(); + + return <>{banner}; +} + +export default function Root({ children }) { + const useIsBrowserValue = useIsBrowser(); + if (!useIsBrowserValue) return <>{children}; + + return ( + <> + {children} + {() => } + + ); +} diff --git a/noir/noir-repo/docs/versioned_docs/version-v0.28.0/tutorials/noirjs_app.md b/noir/noir-repo/docs/versioned_docs/version-v0.28.0/tutorials/noirjs_app.md index 3dd9fe7d2b0..6446e0b2a76 100644 --- a/noir/noir-repo/docs/versioned_docs/version-v0.28.0/tutorials/noirjs_app.md +++ b/noir/noir-repo/docs/versioned_docs/version-v0.28.0/tutorials/noirjs_app.md @@ -24,7 +24,7 @@ Before we start, we want to make sure we have Node and Nargo installed. We start by opening a terminal and executing `node --version`. If we don't get an output like `v20.10.0`, that means node is not installed. Let's do that by following the handy [nvm guide](https://github.com/nvm-sh/nvm?tab=readme-ov-file#install--update-script). -As for `Nargo`, we can follow the [Nargo guide](../getting_started/installation/index.md) to install it. If you're lazy, just paste this on a terminal and run `noirup`: +As for `Nargo`, we can follow the the [Nargo guide](../getting_started/installation/index.md) to install it. If you're lazy, just paste this on a terminal and run `noirup`: ```sh curl -L https://raw.githubusercontent.com/noir-lang/noirup/main/install | bash diff --git a/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/Nargo.toml b/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/Nargo.toml new file mode 100644 index 00000000000..5894e457dd8 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "impl_from_where_impl" +type = "bin" +authors = [""] +compiler_version = ">=0.27.0" + +[dependencies] diff --git a/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/src/main.nr new file mode 100644 index 00000000000..3cec46bdfcd --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/impl_from_where_impl/src/main.nr @@ -0,0 +1,15 @@ +trait Bar { + fn ok(self) -> Self; + + fn ref_ok(self) -> Self { + self.ok() + } +} + +impl Bar for (T, T) where T: Bar { + fn ok(self) -> Self { + self + } +} + +fn main() {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_547/Nargo.toml b/noir/noir-repo/test_programs/execution_success/conditional_regression_547/Nargo.toml similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/conditional_regression_547/Nargo.toml rename to noir/noir-repo/test_programs/execution_success/conditional_regression_547/Nargo.toml diff --git a/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_547/Prover.toml b/noir/noir-repo/test_programs/execution_success/conditional_regression_547/Prover.toml similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/conditional_regression_547/Prover.toml rename to noir/noir-repo/test_programs/execution_success/conditional_regression_547/Prover.toml diff --git a/noir/noir-repo/test_programs/compile_success_empty/conditional_regression_547/src/main.nr b/noir/noir-repo/test_programs/execution_success/conditional_regression_547/src/main.nr similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/conditional_regression_547/src/main.nr rename to noir/noir-repo/test_programs/execution_success/conditional_regression_547/src/main.nr diff --git a/noir/noir-repo/test_programs/execution_success/distinct_keyword/Nargo.toml b/noir/noir-repo/test_programs/execution_success/distinct_keyword/Nargo.toml deleted file mode 100644 index 3f1b1386ba7..00000000000 --- a/noir/noir-repo/test_programs/execution_success/distinct_keyword/Nargo.toml +++ /dev/null @@ -1,6 +0,0 @@ -[package] -name = "distinct_keyword" -type = "bin" -authors = [""] - -[dependencies] diff --git a/noir/noir-repo/test_programs/execution_success/distinct_keyword/Prover.toml b/noir/noir-repo/test_programs/execution_success/distinct_keyword/Prover.toml deleted file mode 100644 index 07890234a19..00000000000 --- a/noir/noir-repo/test_programs/execution_success/distinct_keyword/Prover.toml +++ /dev/null @@ -1 +0,0 @@ -x = "3" diff --git a/noir/noir-repo/test_programs/execution_success/distinct_keyword/src/main.nr b/noir/noir-repo/test_programs/execution_success/distinct_keyword/src/main.nr deleted file mode 100644 index 8e9b5c008ed..00000000000 --- a/noir/noir-repo/test_programs/execution_success/distinct_keyword/src/main.nr +++ /dev/null @@ -1,4 +0,0 @@ -// Example that uses the distinct keyword -fn main(x: pub Field) -> distinct pub [Field; 2] { - [x + 1, x] -} diff --git a/noir/noir-repo/test_programs/execution_success/fold_distinct_return/Nargo.toml b/noir/noir-repo/test_programs/execution_success/fold_distinct_return/Nargo.toml new file mode 100644 index 00000000000..f18edb7e49d --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_distinct_return/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_distinct_return" +type = "bin" +authors = [""] +compiler_version = ">=0.28.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/fold_distinct_return/Prover.toml b/noir/noir-repo/test_programs/execution_success/fold_distinct_return/Prover.toml new file mode 100644 index 00000000000..f28f2f8cc48 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_distinct_return/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "10" diff --git a/noir/noir-repo/test_programs/execution_success/fold_distinct_return/src/main.nr b/noir/noir-repo/test_programs/execution_success/fold_distinct_return/src/main.nr new file mode 100644 index 00000000000..b0843a02b80 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_distinct_return/src/main.nr @@ -0,0 +1,10 @@ +fn main(x: u32, y: pub u32) { + let new_field = new_field_in_array([x, y, 3]); + assert(new_field[0] == 25); +} + +#[fold] +fn new_field_in_array(mut input: [u32; 3]) -> [u32; 3] { + input[0] = input[0] + 20; + input +} diff --git a/noir/noir-repo/test_programs/execution_success/fold_fibonacci/Nargo.toml b/noir/noir-repo/test_programs/execution_success/fold_fibonacci/Nargo.toml new file mode 100644 index 00000000000..6d8214689b0 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_fibonacci/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "fold_fibonacci" +type = "bin" +authors = [""] +compiler_version = ">=0.28.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/fold_fibonacci/Prover.toml b/noir/noir-repo/test_programs/execution_success/fold_fibonacci/Prover.toml new file mode 100644 index 00000000000..3a627b9188b --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_fibonacci/Prover.toml @@ -0,0 +1 @@ +x = "10" diff --git a/noir/noir-repo/test_programs/execution_success/fold_fibonacci/src/main.nr b/noir/noir-repo/test_programs/execution_success/fold_fibonacci/src/main.nr new file mode 100644 index 00000000000..e150a586086 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/fold_fibonacci/src/main.nr @@ -0,0 +1,12 @@ +fn main(x: u32) { + assert(fibonacci(x) == 55); +} + +#[fold] +fn fibonacci(x: u32) -> u32 { + if x <= 1 { + x + } else { + fibonacci(x - 1) + fibonacci(x - 2) + } +} diff --git a/noir/noir-repo/test_programs/compile_success_empty/main_return/Nargo.toml b/noir/noir-repo/test_programs/execution_success/main_return/Nargo.toml similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/main_return/Nargo.toml rename to noir/noir-repo/test_programs/execution_success/main_return/Nargo.toml diff --git a/noir/noir-repo/test_programs/compile_success_empty/main_return/Prover.toml b/noir/noir-repo/test_programs/execution_success/main_return/Prover.toml similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/main_return/Prover.toml rename to noir/noir-repo/test_programs/execution_success/main_return/Prover.toml diff --git a/noir/noir-repo/test_programs/compile_success_empty/main_return/src/main.nr b/noir/noir-repo/test_programs/execution_success/main_return/src/main.nr similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/main_return/src/main.nr rename to noir/noir-repo/test_programs/execution_success/main_return/src/main.nr diff --git a/noir/noir-repo/test_programs/execution_success/no_predicates_basic/Nargo.toml b/noir/noir-repo/test_programs/execution_success/no_predicates_basic/Nargo.toml new file mode 100644 index 00000000000..bcefd550fb0 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/no_predicates_basic/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "no_predicates_basic" +type = "bin" +authors = [""] +compiler_version = ">=0.27.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/no_predicates_basic/Prover.toml b/noir/noir-repo/test_programs/execution_success/no_predicates_basic/Prover.toml new file mode 100644 index 00000000000..f28f2f8cc48 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/no_predicates_basic/Prover.toml @@ -0,0 +1,2 @@ +x = "5" +y = "10" diff --git a/noir/noir-repo/test_programs/execution_success/no_predicates_basic/src/main.nr b/noir/noir-repo/test_programs/execution_success/no_predicates_basic/src/main.nr new file mode 100644 index 00000000000..d6037c2ab26 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/no_predicates_basic/src/main.nr @@ -0,0 +1,8 @@ +fn main(x: Field, y: pub Field) { + basic_check(x, y); +} + +#[no_predicates] +fn basic_check(x: Field, y: Field) { + assert(x != y); +} diff --git a/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/Nargo.toml b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/Nargo.toml new file mode 100644 index 00000000000..1ce13c24287 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "no_predicates_numeric_generic_poseidon" +type = "bin" +authors = [""] +compiler_version = ">=0.28.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/Prover.toml b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/Prover.toml new file mode 100644 index 00000000000..00e821cf89d --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/Prover.toml @@ -0,0 +1,2 @@ +enable = [true, false] +to_hash = [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]] diff --git a/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/src/main.nr b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/src/main.nr new file mode 100644 index 00000000000..dcb5e6bc5ca --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/no_predicates_numeric_generic_poseidon/src/main.nr @@ -0,0 +1,33 @@ +use dep::std::hash::{pedersen_hash_with_separator, poseidon2::Poseidon2}; + +global NUM_HASHES = 2; +global HASH_LENGTH = 10; + +#[no_predicates] +pub fn poseidon_hash(inputs: [Field; N]) -> Field { + Poseidon2::hash(inputs, inputs.len()) +} + +fn main( + to_hash: [[Field; HASH_LENGTH]; NUM_HASHES], + enable: [bool; NUM_HASHES] +) -> pub [Field; NUM_HASHES + 1] { + let mut result = [0; NUM_HASHES + 1]; + for i in 0..NUM_HASHES { + let enable = enable[i]; + let to_hash = to_hash[i]; + if enable { + result[i] = poseidon_hash(to_hash); + } + } + + // We want to make sure that the function marked with `#[no_predicates]` with a numeric generic + // is monomorphized correctly. + let mut double_preimage = [0; 20]; + for i in 0..HASH_LENGTH * 2 { + double_preimage[i] = to_hash[0][i % HASH_LENGTH]; + } + result[NUM_HASHES] = poseidon_hash(double_preimage); + + result +} diff --git a/noir/noir-repo/test_programs/compile_success_empty/simple_array_param/Nargo.toml b/noir/noir-repo/test_programs/execution_success/simple_array_param/Nargo.toml similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/simple_array_param/Nargo.toml rename to noir/noir-repo/test_programs/execution_success/simple_array_param/Nargo.toml diff --git a/noir/noir-repo/test_programs/compile_success_empty/simple_array_param/Prover.toml b/noir/noir-repo/test_programs/execution_success/simple_array_param/Prover.toml similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/simple_array_param/Prover.toml rename to noir/noir-repo/test_programs/execution_success/simple_array_param/Prover.toml diff --git a/noir/noir-repo/test_programs/compile_success_empty/simple_array_param/src/main.nr b/noir/noir-repo/test_programs/execution_success/simple_array_param/src/main.nr similarity index 100% rename from noir/noir-repo/test_programs/compile_success_empty/simple_array_param/src/main.nr rename to noir/noir-repo/test_programs/execution_success/simple_array_param/src/main.nr diff --git a/noir/noir-repo/tooling/debugger/ignored-tests.txt b/noir/noir-repo/tooling/debugger/ignored-tests.txt index 5e6ce18be54..cbef395e65c 100644 --- a/noir/noir-repo/tooling/debugger/ignored-tests.txt +++ b/noir/noir-repo/tooling/debugger/ignored-tests.txt @@ -17,5 +17,8 @@ fold_basic_nested_call fold_call_witness_condition fold_after_inlined_calls fold_numeric_generic_poseidon -inline_never_basic +no_predicates_basic +no_predicates_numeric_generic_poseidon regression_4709 +fold_distinct_return +fold_fibonacci diff --git a/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs b/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs index 82cfefba632..a5d042dc71e 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs @@ -6,7 +6,7 @@ use crate::{ }, visitor::expr::{format_seq, NewlineMode}, }; -use noirc_frontend::ast::{Distinctness, NoirFunction, Visibility}; +use noirc_frontend::ast::{NoirFunction, Visibility}; use noirc_frontend::{ hir::resolution::errors::Span, parser::{Item, ItemKind}, @@ -118,10 +118,6 @@ impl super::FmtVisitor<'_> { if let Some(span) = return_type_span { result.push_str(" -> "); - if let Distinctness::Distinct = func.def.return_distinctness { - result.push_str("distinct "); - } - let visibility = match func.def.return_visibility { Visibility::Public => "pub", Visibility::DataBus => "return_data", diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr index 0088dba6a8f..3d231cd3f7f 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/fn.nr @@ -36,7 +36,7 @@ fn apply_binary_field_op( registers: &mut Registers ) -> bool {} -fn main() -> distinct pub [Field; 2] {} +fn main() -> pub [Field; 2] {} fn ret_normal_lambda1() -> ((fn() -> Field)) {} diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/input/fn.nr b/noir/noir-repo/tooling/nargo_fmt/tests/input/fn.nr index 26ff5933802..1c6d201fa39 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/input/fn.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/input/fn.nr @@ -23,7 +23,7 @@ fn main(tape: [Field; TAPE_LEN], initial_registers: [Field; REGISTER_COUNT], ini fn apply_binary_field_op(lhs: RegisterIndex, rhs: RegisterIndex, result: RegisterIndex, op: u8, registers: &mut Registers) -> bool {} -fn main() -> distinct pub [Field;2] {} +fn main() -> pub [Field;2] {} fn ret_normal_lambda1() -> ((fn() -> Field)) {} diff --git a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts index 0bef2150bae..b003195c393 100644 --- a/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts +++ b/yarn-project/end-to-end/src/e2e_blacklist_token_contract/minting.test.ts @@ -14,7 +14,7 @@ describe('e2e_blacklist_token_contract mint', () => { await t.setup(); // Have to destructure again to ensure we have latest refs. ({ asset, tokenSim, wallets, blacklisted } = t); - }); + }, 200_000); afterAll(async () => { await t.teardown(); diff --git a/yarn-project/end-to-end/src/e2e_ordering.test.ts b/yarn-project/end-to-end/src/e2e_ordering.test.ts index 66a37afe6e2..0f777d7ea2f 100644 --- a/yarn-project/end-to-end/src/e2e_ordering.test.ts +++ b/yarn-project/end-to-end/src/e2e_ordering.test.ts @@ -29,7 +29,7 @@ describe('e2e_ordering', () => { beforeEach(async () => { ({ teardown, pxe, wallet } = await setup()); - }); + }, 200_000); afterEach(() => teardown());