From 4c01c562f307cfcbab6abbdb162e3d9ca21b12ad Mon Sep 17 00:00:00 2001 From: AztecBot Date: Tue, 9 Jul 2024 12:43:07 +0000 Subject: [PATCH] [1 changes] fix: prevent `no_predicates` from removing predicates in calling function (https://github.com/noir-lang/noir/pull/5452) feat: lsp rename/find-all-references for globals (https://github.com/noir-lang/noir/pull/5415) feat: remove redundant `EnableSideEffects` instructions (https://github.com/noir-lang/noir/pull/5440) --- .noir-sync-commit | 2 +- .../workflows/mirror-external_libs.yml | 8 + .../acvm-repo/acvm/src/pwg/brillig.rs | 108 +++++++------ noir/noir-repo/acvm-repo/acvm_js/build.sh | 2 +- .../compiler/noirc_evaluator/src/ssa.rs | 1 + .../check_for_underconstrained_values.rs | 0 .../noirc_evaluator/src/ssa/checks/mod.rs | 1 + .../noirc_evaluator/src/ssa/opt/inlining.rs | 57 +++++-- .../noirc_evaluator/src/ssa/opt/mod.rs | 1 - .../src/ssa/opt/remove_enable_side_effects.rs | 100 +++++++++++- .../noirc_frontend/src/ast/statement.rs | 7 + .../src/elaborator/expressions.rs | 3 +- .../noirc_frontend/src/elaborator/mod.rs | 152 +++++++++--------- .../noirc_frontend/src/elaborator/patterns.rs | 8 +- .../noirc_frontend/src/elaborator/scope.rs | 5 +- .../noirc_frontend/src/elaborator/types.rs | 46 ++++-- .../noirc_frontend/src/hir/comptime/errors.rs | 8 + .../src/hir/comptime/interpreter.rs | 2 +- .../noirc_frontend/src/hir/comptime/value.rs | 7 +- .../src/hir/def_collector/dc_crate.rs | 28 ++-- .../src/hir/def_collector/dc_mod.rs | 8 +- .../compiler/noirc_frontend/src/locations.rs | 69 +++++--- .../src/monomorphization/mod.rs | 28 ++-- .../noirc_frontend/src/node_interner.rs | 32 +--- .../compiler/noirc_frontend/src/parser/mod.rs | 2 +- .../noirc_frontend/src/parser/parser.rs | 15 +- .../docs/noir/concepts/data_types/slices.mdx | 70 +++++++- .../docs/docs/noir/standard_library/traits.md | 30 ++++ noir/noir-repo/noir_stdlib/src/append.nr | 35 ++++ noir/noir-repo/noir_stdlib/src/lib.nr | 1 + noir/noir-repo/noir_stdlib/src/slice.nr | 29 ++++ .../slice_join/Nargo.toml | 7 + .../slice_join/src/main.nr | 16 ++ .../Nargo.toml | 7 + .../src/main.nr | 14 ++ .../regression_5435/Nargo.toml | 7 + .../regression_5435/Prover.toml | 2 + .../regression_5435/src/main.nr | 18 +++ .../verify_honk_proof/Prover.toml | 4 - .../verify_honk_proof/src/main.nr | 21 --- .../tooling/lsp/src/requests/references.rs | 2 +- .../tooling/lsp/src/requests/rename.rs | 94 ++++++++--- .../test_programs/rename_function/src/main.nr | 6 + .../test_programs/rename_global}/Nargo.toml | 2 +- .../test_programs/rename_global/src/main.nr | 22 +++ .../test_programs/rename_struct/src/main.nr | 6 + .../rename_type_alias/Nargo.toml | 6 + .../rename_type_alias/src/main.nr | 24 +++ noir/noir-repo/tooling/nargo_cli/build.rs | 3 +- .../noir_js_backend_barretenberg/package.json | 2 +- .../src/backend.ts | 46 +++--- .../noir-repo/tooling/noirc_abi_wasm/build.sh | 2 +- noir/noir-repo/yarn.lock | 13 +- 53 files changed, 847 insertions(+), 342 deletions(-) create mode 100644 noir/noir-repo/.github/workflows/mirror-external_libs.yml rename noir/noir-repo/compiler/noirc_evaluator/src/ssa/{opt => checks}/check_for_underconstrained_values.rs (100%) create mode 100644 noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/mod.rs create mode 100644 noir/noir-repo/noir_stdlib/src/append.nr create mode 100644 noir/noir-repo/test_programs/compile_success_empty/slice_join/Nargo.toml create mode 100644 noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr create mode 100644 noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/Nargo.toml create mode 100644 noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/src/main.nr create mode 100644 noir/noir-repo/test_programs/execution_success/regression_5435/Nargo.toml create mode 100644 noir/noir-repo/test_programs/execution_success/regression_5435/Prover.toml create mode 100644 noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr delete mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml delete mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr rename noir/noir-repo/{test_programs/execution_success/verify_honk_proof => tooling/lsp/test_programs/rename_global}/Nargo.toml (66%) create mode 100644 noir/noir-repo/tooling/lsp/test_programs/rename_global/src/main.nr create mode 100644 noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/Nargo.toml create mode 100644 noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/src/main.nr diff --git a/.noir-sync-commit b/.noir-sync-commit index b396ec10e9d..1d316606dc4 100644 --- a/.noir-sync-commit +++ b/.noir-sync-commit @@ -1 +1 @@ -30c50f52a6d58163e39006b73f4eb5003afc239b +66244b6e5b505f692c7e9a41bdc061c77fd1284d diff --git a/noir/noir-repo/.github/workflows/mirror-external_libs.yml b/noir/noir-repo/.github/workflows/mirror-external_libs.yml new file mode 100644 index 00000000000..e577ac0ed92 --- /dev/null +++ b/noir/noir-repo/.github/workflows/mirror-external_libs.yml @@ -0,0 +1,8 @@ +name: Mirror Repositories +on: + workflow_dispatch: {} +jobs: + lint: + runs-on: ubuntu-latest + steps: + - run: echo Dummy workflow TODO \ No newline at end of file diff --git a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs index 3a639df044a..91dedac8e35 100644 --- a/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs +++ b/noir/noir-repo/acvm-repo/acvm/src/pwg/brillig.rs @@ -162,63 +162,27 @@ impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { VMStatus::Finished { .. } => Ok(BrilligSolverStatus::Finished), VMStatus::InProgress => Ok(BrilligSolverStatus::InProgress), VMStatus::Failure { reason, call_stack } => { + let call_stack = call_stack + .iter() + .map(|brillig_index| OpcodeLocation::Brillig { + acir_index: self.acir_index, + brillig_index: *brillig_index, + }) + .collect(); let payload = match reason { FailureReason::RuntimeError { message } => { Some(ResolvedAssertionPayload::String(message)) } FailureReason::Trap { revert_data_offset, revert_data_size } => { - // Since noir can only revert with strings currently, we can parse return data as a string - if revert_data_size == 0 { - None - } else { - let memory = self.vm.get_memory(); - let mut revert_values_iter = memory - [revert_data_offset..(revert_data_offset + revert_data_size)] - .iter(); - let error_selector = ErrorSelector::new( - revert_values_iter - .next() - .expect("Incorrect revert data size") - .try_into() - .expect("Error selector is not u64"), - ); - - match error_selector { - STRING_ERROR_SELECTOR => { - // If the error selector is 0, it means the error is a string - let string = revert_values_iter - .map(|memory_value| { - let as_u8: u8 = memory_value - .try_into() - .expect("String item is not u8"); - as_u8 as char - }) - .collect(); - Some(ResolvedAssertionPayload::String(string)) - } - _ => { - // If the error selector is not 0, it means the error is a custom error - Some(ResolvedAssertionPayload::Raw(RawAssertionPayload { - selector: error_selector, - data: revert_values_iter - .map(|value| value.to_field()) - .collect(), - })) - } - } - } + extract_failure_payload_from_memory( + self.vm.get_memory(), + revert_data_offset, + revert_data_size, + ) } }; - Err(OpcodeResolutionError::BrilligFunctionFailed { - payload, - call_stack: call_stack - .iter() - .map(|brillig_index| OpcodeLocation::Brillig { - acir_index: self.acir_index, - brillig_index: *brillig_index, - }) - .collect(), - }) + + Err(OpcodeResolutionError::BrilligFunctionFailed { payload, call_stack }) } VMStatus::ForeignCallWait { function, inputs } => { Ok(BrilligSolverStatus::ForeignCallWait(ForeignCallWaitInfo { function, inputs })) @@ -283,6 +247,50 @@ impl<'b, B: BlackBoxFunctionSolver, F: AcirField> BrilligSolver<'b, F, B> { } } +/// Extracts a `ResolvedAssertionPayload` from a block of memory of a Brillig VM instance. +/// +/// Returns `None` if the amount of memory requested is zero. +fn extract_failure_payload_from_memory( + memory: &[MemoryValue], + revert_data_offset: usize, + revert_data_size: usize, +) -> Option> { + // Since noir can only revert with strings currently, we can parse return data as a string + if revert_data_size == 0 { + None + } else { + let mut revert_values_iter = + memory[revert_data_offset..(revert_data_offset + revert_data_size)].iter(); + let error_selector = ErrorSelector::new( + revert_values_iter + .next() + .expect("Incorrect revert data size") + .try_into() + .expect("Error selector is not u64"), + ); + + match error_selector { + STRING_ERROR_SELECTOR => { + // If the error selector is 0, it means the error is a string + let string = revert_values_iter + .map(|memory_value| { + let as_u8: u8 = memory_value.try_into().expect("String item is not u8"); + as_u8 as char + }) + .collect(); + Some(ResolvedAssertionPayload::String(string)) + } + _ => { + // If the error selector is not 0, it means the error is a custom error + Some(ResolvedAssertionPayload::Raw(RawAssertionPayload { + selector: error_selector, + data: revert_values_iter.map(|value| value.to_field()).collect(), + })) + } + } + } +} + /// Encapsulates a request from a Brillig VM process that encounters a [foreign call opcode][acir::brillig_vm::Opcode::ForeignCall] /// where the result of the foreign call has not yet been provided. /// diff --git a/noir/noir-repo/acvm-repo/acvm_js/build.sh b/noir/noir-repo/acvm-repo/acvm_js/build.sh index c07d2d8a4c1..16fb26e55db 100755 --- a/noir/noir-repo/acvm-repo/acvm_js/build.sh +++ b/noir/noir-repo/acvm-repo/acvm_js/build.sh @@ -25,7 +25,7 @@ function run_if_available { require_command jq require_command cargo require_command wasm-bindgen -#require_command wasm-opt +require_command wasm-opt self_path=$(dirname "$(readlink -f "$0")") pname=$(cargo read-manifest | jq -r '.name') diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs index e1182f17bcd..820374df9c1 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs @@ -36,6 +36,7 @@ use self::{ }; mod acir_gen; +mod checks; pub(super) mod function_builder; pub mod ir; mod opt; diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/check_for_underconstrained_values.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs similarity index 100% rename from noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/check_for_underconstrained_values.rs rename to noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/mod.rs new file mode 100644 index 00000000000..4f1831e5bb0 --- /dev/null +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/mod.rs @@ -0,0 +1 @@ +mod check_for_underconstrained_values; 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 7dda0ac7787..09802713363 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 @@ -45,23 +45,23 @@ impl Ssa { /// This step should run after runtime separation, since it relies on the runtime of the called functions being final. #[tracing::instrument(level = "trace", skip(self))] pub(crate) fn inline_functions(self) -> Ssa { - Self::inline_functions_inner(self, true) + Self::inline_functions_inner(self, false) } // 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) + Self::inline_functions_inner(self, true) } - fn inline_functions_inner(mut self, no_predicates_is_entry_point: bool) -> Ssa { + fn inline_functions_inner(mut self, inline_no_predicates_functions: bool) -> Ssa { let recursive_functions = find_all_recursive_functions(&self); self.functions = btree_map( - get_functions_to_inline_into(&self, no_predicates_is_entry_point), + get_functions_to_inline_into(&self, inline_no_predicates_functions), |entry_point| { let new_function = InlineContext::new( &self, entry_point, - no_predicates_is_entry_point, + inline_no_predicates_functions, recursive_functions.clone(), ) .inline_all(&self); @@ -86,7 +86,13 @@ 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, + /// Whether the inlining pass should inline any functions marked with [`InlineType::NoPredicates`] + /// or whether these should be preserved as entrypoint functions. + /// + /// This is done as we delay inlining of functions with the attribute `#[no_predicates]` until after + /// the control flow graph has been flattened. + inline_no_predicates_functions: bool, + // We keep track of the recursive functions in the SSA to avoid inlining them in a brillig context. recursive_functions: BTreeSet, } @@ -179,7 +185,7 @@ fn find_all_recursive_functions(ssa: &Ssa) -> BTreeSet { /// - Any Acir functions with a [fold inline type][InlineType::Fold], fn get_functions_to_inline_into( ssa: &Ssa, - no_predicates_is_entry_point: bool, + inline_no_predicates_functions: bool, ) -> BTreeSet { let mut brillig_entry_points = BTreeSet::default(); let mut acir_entry_points = BTreeSet::default(); @@ -190,10 +196,9 @@ fn get_functions_to_inline_into( } // 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(); - if function.runtime().is_entry_point() || no_predicates_is_entry_point { + // to not have predicates should be preserved. + let preserve_function = !inline_no_predicates_functions && function.is_no_predicates(); + if function.runtime().is_entry_point() || preserve_function { acir_entry_points.insert(*func_id); } @@ -228,7 +233,7 @@ impl InlineContext { fn new( ssa: &Ssa, entry_point: FunctionId, - no_predicates_is_entry_point: bool, + inline_no_predicates_functions: bool, recursive_functions: BTreeSet, ) -> InlineContext { let source = &ssa.functions[&entry_point]; @@ -239,7 +244,7 @@ impl InlineContext { recursion_level: 0, entry_point, call_stack: CallStack::new(), - no_predicates_is_entry_point, + inline_no_predicates_functions, recursive_functions, } } @@ -470,6 +475,8 @@ impl<'function> PerFunctionContext<'function> { /// Inline each instruction in the given block into the function being inlined into. /// This may recurse if it finds another function to inline if a call instruction is within this block. fn inline_block_instructions(&mut self, ssa: &Ssa, block_id: BasicBlockId) { + let mut side_effects_enabled: Option = None; + let block = &self.source_function.dfg[block_id]; for id in block.instructions() { match &self.source_function.dfg[*id] { @@ -477,12 +484,28 @@ impl<'function> PerFunctionContext<'function> { Some(func_id) => { if self.should_inline_call(ssa, func_id) { self.inline_function(ssa, *id, func_id, arguments); + + // This is only relevant during handling functions with `InlineType::NoPredicates` as these + // can pollute the function they're being inlined into with `Instruction::EnabledSideEffects`, + // resulting in predicates not being applied properly. + // + // Note that this doesn't cover the case in which there exists an `Instruction::EnabledSideEffects` + // within the function being inlined whilst the source function has not encountered one yet. + // In practice this isn't an issue as the last `Instruction::EnabledSideEffects` in the + // function being inlined will be to turn off predicates rather than to create one. + if let Some(condition) = side_effects_enabled { + self.context.builder.insert_enable_side_effects_if(condition); + } } else { self.push_instruction(*id); } } None => self.push_instruction(*id), }, + Instruction::EnableSideEffects { condition } => { + side_effects_enabled = Some(self.translate_value(*condition)); + self.push_instruction(*id); + } _ => self.push_instruction(*id), } } @@ -495,10 +518,10 @@ impl<'function> PerFunctionContext<'function> { // If the called function is acir, we inline if it's not an entry point // 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(); - !inline_type.is_entry_point() && !no_predicates_is_entry_point + // to not have predicates should be preserved. + let preserve_function = + !self.context.inline_no_predicates_functions && function.is_no_predicates(); + !inline_type.is_entry_point() && !preserve_function } else { // If the called function is brillig, we inline only if it's into brillig and the function is not recursive ssa.functions[&self.context.entry_point].runtime() == RuntimeType::Brillig diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs index 56484ced290..4e5fa262696 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mod.rs @@ -7,7 +7,6 @@ mod array_set; mod as_slice_length; mod assert_constant; mod bubble_up_constrains; -mod check_for_underconstrained_values; mod constant_folding; mod defunctionalize; mod die; diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs index f9a3c9a55eb..1584b848564 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/remove_enable_side_effects.rs @@ -18,6 +18,7 @@ use crate::ssa::{ dfg::DataFlowGraph, function::Function, instruction::{BinaryOp, Instruction, Intrinsic}, + types::Type, value::Value, }, ssa_gen::Ssa, @@ -62,6 +63,7 @@ impl Context { ) { let instructions = function.dfg[block].take_instructions(); + let mut active_condition = function.dfg.make_constant(FieldElement::one(), Type::bool()); let mut last_side_effects_enabled_instruction = None; let mut new_instructions = Vec::with_capacity(instructions.len()); @@ -72,19 +74,26 @@ impl Context { // instructions with side effects then we can drop the instruction we're holding and // continue with the new `Instruction::EnableSideEffects`. if let Instruction::EnableSideEffects { condition } = instruction { + // If this instruction isn't changing the currently active condition then we can ignore it. + if active_condition == *condition { + continue; + } + // If we're seeing an `enable_side_effects u1 1` then we want to insert it immediately. // This is because we want to maximize the effect it will have. - if function + let condition_is_one = function .dfg .get_numeric_constant(*condition) - .map_or(false, |condition| condition.is_one()) - { + .map_or(false, |condition| condition.is_one()); + if condition_is_one { new_instructions.push(instruction_id); last_side_effects_enabled_instruction = None; + active_condition = *condition; continue; } last_side_effects_enabled_instruction = Some(instruction_id); + active_condition = *condition; continue; } @@ -172,3 +181,88 @@ impl Context { } } } + +#[cfg(test)] +mod test { + + use crate::ssa::{ + function_builder::FunctionBuilder, + ir::{ + instruction::{BinaryOp, Instruction}, + map::Id, + types::Type, + }, + }; + + #[test] + fn remove_chains_of_same_condition() { + // acir(inline) fn main f0 { + // b0(v0: Field): + // enable_side_effects u1 1 + // v4 = mul v0, Field 2 + // enable_side_effects u1 1 + // v5 = mul v0, Field 2 + // enable_side_effects u1 1 + // v6 = mul v0, Field 2 + // enable_side_effects u1 1 + // v7 = mul v0, Field 2 + // enable_side_effects u1 1 + // (no terminator instruction) + // } + // + // After constructing this IR, we run constant folding which should replace the second cast + // with a reference to the results to the first. This then allows us to optimize away + // the constrain instruction as both inputs are known to be equal. + // + // The first cast instruction is retained and will be removed in the dead instruction elimination pass. + let main_id = Id::test_new(0); + + // Compiling main + let mut builder = FunctionBuilder::new("main".into(), main_id); + let v0 = builder.add_parameter(Type::field()); + + let two = builder.numeric_constant(2u128, Type::field()); + + let one = builder.numeric_constant(1u128, Type::bool()); + + builder.insert_enable_side_effects_if(one); + builder.insert_binary(v0, BinaryOp::Mul, two); + builder.insert_enable_side_effects_if(one); + builder.insert_binary(v0, BinaryOp::Mul, two); + builder.insert_enable_side_effects_if(one); + builder.insert_binary(v0, BinaryOp::Mul, two); + builder.insert_enable_side_effects_if(one); + builder.insert_binary(v0, BinaryOp::Mul, two); + builder.insert_enable_side_effects_if(one); + + let ssa = builder.finish(); + + println!("{ssa}"); + + let main = ssa.main(); + let instructions = main.dfg[main.entry_block()].instructions(); + assert_eq!(instructions.len(), 9); + + // Expected output: + // + // acir(inline) fn main f0 { + // b0(v0: Field): + // v3 = mul v0, Field 2 + // v4 = mul v0, Field 2 + // v5 = mul v0, Field 2 + // v6 = mul v0, Field 2 + // (no terminator instruction) + // } + let ssa = ssa.remove_enable_side_effects(); + + println!("{ssa}"); + + let main = ssa.main(); + let instructions = main.dfg[main.entry_block()].instructions(); + + assert_eq!(instructions.len(), 4); + for instruction in instructions.iter().take(4) { + assert_eq!(&main.dfg[*instruction], &Instruction::binary(BinaryOp::Mul, v0, two)); + } + } +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs b/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs index 48e34ad7fc9..3e6a140ff93 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs @@ -10,6 +10,7 @@ use super::{ BlockExpression, Expression, ExpressionKind, IndexExpression, MemberAccessExpression, MethodCallExpression, UnresolvedType, }; +use crate::hir::resolution::resolver::SELF_TYPE_NAME; use crate::lexer::token::SpannedToken; use crate::macros_api::SecondaryAttribute; use crate::parser::{ParserError, ParserErrorReason}; @@ -165,6 +166,12 @@ impl StatementKind { #[derive(Eq, Debug, Clone)] pub struct Ident(pub Spanned); +impl Ident { + pub fn is_self_type_name(&self) -> bool { + self.0.contents == SELF_TYPE_NAME + } +} + impl PartialEq for Ident { fn eq(&self, other: &Ident) -> bool { self.0.contents == other.0.contents diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/expressions.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/expressions.rs index e013cf7b4f1..5c3866816a6 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -403,6 +403,7 @@ impl<'context> Elaborator<'context> { constructor: ConstructorExpression, ) -> (HirExpression, Type) { let span = constructor.type_name.span(); + let is_self_type = constructor.type_name.last_segment().is_self_type_name(); let (r#type, struct_generics) = if let Some(struct_id) = constructor.struct_type { let typ = self.interner.get_struct(struct_id); @@ -433,7 +434,7 @@ impl<'context> Elaborator<'context> { }); let referenced = ReferenceId::Struct(struct_type.borrow().id); - let reference = ReferenceId::Variable(Location::new(span, self.file)); + let reference = ReferenceId::Variable(Location::new(span, self.file), is_self_type); self.interner.add_reference(referenced, reference); (expr, Type::Struct(struct_type, generics)) diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs index 2065657c864..7d436c01ebe 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs @@ -1288,11 +1288,11 @@ impl<'context> Elaborator<'context> { .map_err(|error| error.into_compilation_error_pair())?; if value != Value::Unit { - let item = value - .into_top_level_item(location) + let items = value + .into_top_level_items(location) .map_err(|error| error.into_compilation_error_pair())?; - self.add_item(item, generated_items, location); + self.add_items(items, generated_items, location); } Ok(()) @@ -1350,6 +1350,8 @@ impl<'context> Elaborator<'context> { self.elaborate_comptime_global(global_id); } + self.interner.add_definition_location(ReferenceId::Global(global_id)); + self.local_module = old_module; self.file = old_file; self.current_item = old_item; @@ -1449,11 +1451,13 @@ impl<'context> Elaborator<'context> { self.generics.clear(); if let Some(trait_id) = trait_id { + let trait_name = trait_impl.trait_path.last_segment(); + let referenced = ReferenceId::Trait(trait_id); - let reference = ReferenceId::Variable(Location::new( - trait_impl.trait_path.last_segment().span(), - trait_impl.file_id, - )); + let reference = ReferenceId::Variable( + Location::new(trait_name.span(), trait_impl.file_id), + trait_name.is_self_type_name(), + ); self.interner.add_reference(referenced, reference); } } @@ -1542,79 +1546,81 @@ impl<'context> Elaborator<'context> { (comptime, items) } - fn add_item( + fn add_items( &mut self, - item: TopLevelStatement, + items: Vec, generated_items: &mut CollectedItems, location: Location, ) { - match item { - TopLevelStatement::Function(function) => { - let id = self.interner.push_empty_fn(); - let module = self.module_id(); - self.interner.push_function(id, &function.def, module, location); - let functions = vec![(self.local_module, id, function)]; - generated_items.functions.push(UnresolvedFunctions { - file_id: self.file, - functions, - trait_id: None, - self_type: None, - }); - } - TopLevelStatement::TraitImpl(mut trait_impl) => { - let methods = dc_mod::collect_trait_impl_functions( - self.interner, - &mut trait_impl, - self.crate_id, - self.file, - self.local_module, - ); + for item in items { + match item { + TopLevelStatement::Function(function) => { + let id = self.interner.push_empty_fn(); + let module = self.module_id(); + self.interner.push_function(id, &function.def, module, location); + let functions = vec![(self.local_module, id, function)]; + generated_items.functions.push(UnresolvedFunctions { + file_id: self.file, + functions, + trait_id: None, + self_type: None, + }); + } + TopLevelStatement::TraitImpl(mut trait_impl) => { + let methods = dc_mod::collect_trait_impl_functions( + self.interner, + &mut trait_impl, + self.crate_id, + self.file, + self.local_module, + ); - generated_items.trait_impls.push(UnresolvedTraitImpl { - file_id: self.file, - module_id: self.local_module, - trait_generics: trait_impl.trait_generics, - trait_path: trait_impl.trait_name, - object_type: trait_impl.object_type, - methods, - generics: trait_impl.impl_generics, - where_clause: trait_impl.where_clause, - - // These last fields are filled in later - trait_id: None, - impl_id: None, - resolved_object_type: None, - resolved_generics: Vec::new(), - resolved_trait_generics: Vec::new(), - }); - } - TopLevelStatement::Global(global) => { - let (global, error) = dc_mod::collect_global( - self.interner, - self.def_maps.get_mut(&self.crate_id).unwrap(), - global, - self.file, - self.local_module, - ); + generated_items.trait_impls.push(UnresolvedTraitImpl { + file_id: self.file, + module_id: self.local_module, + trait_generics: trait_impl.trait_generics, + trait_path: trait_impl.trait_name, + object_type: trait_impl.object_type, + methods, + generics: trait_impl.impl_generics, + where_clause: trait_impl.where_clause, + + // These last fields are filled in later + trait_id: None, + impl_id: None, + resolved_object_type: None, + resolved_generics: Vec::new(), + resolved_trait_generics: Vec::new(), + }); + } + TopLevelStatement::Global(global) => { + let (global, error) = dc_mod::collect_global( + self.interner, + self.def_maps.get_mut(&self.crate_id).unwrap(), + global, + self.file, + self.local_module, + ); - generated_items.globals.push(global); - if let Some(error) = error { - self.errors.push(error); + generated_items.globals.push(global); + if let Some(error) = error { + self.errors.push(error); + } + } + // Assume that an error has already been issued + TopLevelStatement::Error => (), + + TopLevelStatement::Module(_) + | TopLevelStatement::Import(_) + | TopLevelStatement::Struct(_) + | TopLevelStatement::Trait(_) + | TopLevelStatement::Impl(_) + | TopLevelStatement::TypeAlias(_) + | TopLevelStatement::SubModule(_) => { + let item = item.to_string(); + let error = InterpreterError::UnsupportedTopLevelItemUnquote { item, location }; + self.errors.push(error.into_compilation_error_pair()); } - } - // Assume that an error has already been issued - TopLevelStatement::Error => (), - - TopLevelStatement::Module(_) - | TopLevelStatement::Import(_) - | TopLevelStatement::Struct(_) - | TopLevelStatement::Trait(_) - | TopLevelStatement::Impl(_) - | TopLevelStatement::TypeAlias(_) - | TopLevelStatement::SubModule(_) => { - let item = item.to_string(); - let error = InterpreterError::UnsupportedTopLevelItemUnquote { item, location }; - self.errors.push(error.into_compilation_error_pair()); } } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/patterns.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/patterns.rs index e3c854d615d..81fffb522bf 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -159,6 +159,7 @@ impl<'context> Elaborator<'context> { new_definitions: &mut Vec, ) -> HirPattern { let name_span = name.last_segment().span(); + let is_self_type = name.last_segment().is_self_type_name(); let error_identifier = |this: &mut Self| { // Must create a name here to return a HirPattern::Identifier. Allowing @@ -200,7 +201,7 @@ impl<'context> Elaborator<'context> { ); let referenced = ReferenceId::Struct(struct_type.borrow().id); - let reference = ReferenceId::Variable(Location::new(name_span, self.file)); + let reference = ReferenceId::Variable(Location::new(name_span, self.file), is_self_type); self.interner.add_reference(referenced, reference); HirPattern::Struct(expected_type, fields, location) @@ -437,6 +438,7 @@ impl<'context> Elaborator<'context> { // Otherwise, then it is referring to an Identifier // This lookup allows support of such statements: let x = foo::bar::SOME_GLOBAL + 10; // If the expression is a singular indent, we search the resolver's current scope as normal. + let is_self_type_name = path.last_segment().is_self_type_name(); let (hir_ident, var_scope_index) = self.get_ident_from_path(path); if hir_ident.id != DefinitionId::dummy_id() { @@ -446,7 +448,7 @@ impl<'context> Elaborator<'context> { self.interner.add_function_dependency(current_item, func_id); } - let variable = ReferenceId::Variable(hir_ident.location); + let variable = ReferenceId::Variable(hir_ident.location, is_self_type_name); let function = ReferenceId::Function(func_id); self.interner.add_reference(function, variable); } @@ -458,7 +460,7 @@ impl<'context> Elaborator<'context> { self.interner.add_global_dependency(current_item, global_id); } - let variable = ReferenceId::Variable(hir_ident.location); + let variable = ReferenceId::Variable(hir_ident.location, is_self_type_name); let global = ReferenceId::Global(global_id); self.interner.add_reference(global, variable); } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs index b253e272982..6c556e000d5 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/scope.rs @@ -53,7 +53,10 @@ impl<'context> Elaborator<'context> { resolver.resolve(self.def_maps, path.clone(), &mut Some(&mut references))?; for (referenced, ident) in references.iter().zip(path.segments) { - let reference = ReferenceId::Variable(Location::new(ident.span(), self.file)); + let reference = ReferenceId::Variable( + Location::new(ident.span(), self.file), + ident.is_self_type_name(), + ); self.interner.add_reference(*referenced, reference); } } else { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/types.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/types.rs index b6212abb4a2..83810b141fb 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/types.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/types.rs @@ -58,6 +58,12 @@ impl<'context> Elaborator<'context> { use crate::ast::UnresolvedTypeData::*; let span = typ.span; + let (is_self_type_name, is_synthetic) = if let Named(ref named_path, _, synthetic) = typ.typ + { + (named_path.last_segment().is_self_type_name(), synthetic) + } else { + (false, false) + }; let resolved_type = match typ.typ { FieldElement => Type::FieldElement, @@ -147,17 +153,33 @@ impl<'context> Elaborator<'context> { Resolved(id) => self.interner.get_quoted_type(id).clone(), }; - if let Type::Struct(ref struct_type, _) = resolved_type { - if let Some(unresolved_span) = typ.span { - // Record the location of the type reference - self.interner.push_type_ref_location( - resolved_type.clone(), - Location::new(unresolved_span, self.file), - ); + if let Some(unresolved_span) = typ.span { + match resolved_type { + Type::Struct(ref struct_type, _) => { + // Record the location of the type reference + self.interner.push_type_ref_location( + resolved_type.clone(), + Location::new(unresolved_span, self.file), + ); - let referenced = ReferenceId::Struct(struct_type.borrow().id); - let reference = ReferenceId::Variable(Location::new(unresolved_span, self.file)); - self.interner.add_reference(referenced, reference); + if !is_synthetic { + let referenced = ReferenceId::Struct(struct_type.borrow().id); + let reference = ReferenceId::Variable( + Location::new(unresolved_span, self.file), + is_self_type_name, + ); + self.interner.add_reference(referenced, reference); + } + } + Type::Alias(ref alias_type, _) => { + let referenced = ReferenceId::Alias(alias_type.borrow().id); + let reference = ReferenceId::Variable( + Location::new(unresolved_span, self.file), + is_self_type_name, + ); + self.interner.add_reference(referenced, reference); + } + _ => (), } } @@ -347,6 +369,10 @@ impl<'context> Elaborator<'context> { self.interner.add_global_dependency(current_item, id); } + let referenced = ReferenceId::Global(id); + let reference = ReferenceId::Variable(Location::new(path.span(), self.file), false); + self.interner.add_reference(referenced, reference); + Some(Type::Constant(self.eval_global_as_array_length(id, path))) } _ => None, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs index 09b9d6ba3a5..25ff50085fe 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -50,6 +50,7 @@ pub enum InterpreterError { NonComptimeFnCallInSameCrate { function: String, location: Location }, NoImpl { location: Location }, NoMatchingImplFound { error: NoMatchingImplFoundError, file: FileId }, + ImplMethodTypeMismatch { expected: Type, actual: Type, location: Location }, Unimplemented { item: String, location: Location }, @@ -114,6 +115,7 @@ impl InterpreterError { | InterpreterError::NonComptimeFnCallInSameCrate { location, .. } | InterpreterError::Unimplemented { location, .. } | InterpreterError::NoImpl { location, .. } + | InterpreterError::ImplMethodTypeMismatch { location, .. } | InterpreterError::BreakNotInLoop { location, .. } | InterpreterError::ContinueNotInLoop { location, .. } => *location, InterpreterError::FailedToParseMacro { error, file, .. } => { @@ -344,6 +346,12 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let msg = "No impl found due to prior type error".into(); CustomDiagnostic::simple_error(msg, String::new(), location.span) } + InterpreterError::ImplMethodTypeMismatch { expected, actual, location } => { + let msg = format!( + "Impl method type {actual} does not unify with trait method type {expected}" + ); + CustomDiagnostic::simple_error(msg, String::new(), location.span) + } InterpreterError::NoMatchingImplFound { error, .. } => error.into(), InterpreterError::Break => unreachable!("Uncaught InterpreterError::Break"), InterpreterError::Continue => unreachable!("Uncaught InterpreterError::Continue"), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 959163d2d61..605a35780ed 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -74,7 +74,7 @@ impl<'a> Interpreter<'a> { let trait_method = self.interner.get_trait_method_id(function); perform_instantiation_bindings(&instantiation_bindings); - let impl_bindings = perform_impl_bindings(self.interner, trait_method, function); + let impl_bindings = perform_impl_bindings(self.interner, trait_method, function, location)?; let result = self.call_function_inner(function, arguments, location); undo_instantiation_bindings(impl_bindings); undo_instantiation_bindings(instantiation_bindings); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/value.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/value.rs index adb13c4bfbc..9e15b73324f 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/value.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/value.rs @@ -326,9 +326,12 @@ impl Value { } } - pub(crate) fn into_top_level_item(self, location: Location) -> IResult { + pub(crate) fn into_top_level_items( + self, + location: Location, + ) -> IResult> { match self { - Value::Code(tokens) => parse_tokens(tokens, parser::top_level_item(), location.file), + Value::Code(tokens) => parse_tokens(tokens, parser::top_level_items(), location.file), value => Err(InterpreterError::CannotInlineMacro { value, location }), } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index cbe9f3eb7fe..390f6528592 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -343,7 +343,8 @@ impl DefCollector { let file_id = current_def_map.file_id(module_id); for (referenced, ident) in references.iter().zip(&collected_import.path.segments) { - let reference = ReferenceId::Variable(Location::new(ident.span(), file_id)); + let reference = + ReferenceId::Variable(Location::new(ident.span(), file_id), false); context.def_interner.add_reference(*referenced, reference); } @@ -510,21 +511,18 @@ fn add_import_reference( return; } - match def_id { - crate::macros_api::ModuleDefId::FunctionId(func_id) => { - let variable = ReferenceId::Variable(Location::new(name.span(), file_id)); - interner.add_reference(ReferenceId::Function(func_id), variable); + let referenced = match def_id { + crate::macros_api::ModuleDefId::ModuleId(module_id) => ReferenceId::Module(module_id), + crate::macros_api::ModuleDefId::FunctionId(func_id) => ReferenceId::Function(func_id), + crate::macros_api::ModuleDefId::TypeId(struct_id) => ReferenceId::Struct(struct_id), + crate::macros_api::ModuleDefId::TraitId(trait_id) => ReferenceId::Trait(trait_id), + crate::macros_api::ModuleDefId::TypeAliasId(type_alias_id) => { + ReferenceId::Alias(type_alias_id) } - crate::macros_api::ModuleDefId::TypeId(struct_id) => { - let variable = ReferenceId::Variable(Location::new(name.span(), file_id)); - interner.add_reference(ReferenceId::Struct(struct_id), variable); - } - crate::macros_api::ModuleDefId::TraitId(trait_id) => { - let variable = ReferenceId::Variable(Location::new(name.span(), file_id)); - interner.add_reference(ReferenceId::Trait(trait_id), variable); - } - _ => (), - } + crate::macros_api::ModuleDefId::GlobalId(global_id) => ReferenceId::Global(global_id), + }; + let reference = ReferenceId::Variable(Location::new(name.span(), file_id), false); + interner.add_reference(referenced, reference); } fn inject_prelude( diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 138a37f4174..483b061998e 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -268,7 +268,6 @@ impl<'a> ModCollector<'a> { let mut definition_errors = vec![]; for struct_definition in types { let name = struct_definition.name.clone(); - let name_location = Location::new(name.span(), self.file_id); let unresolved = UnresolvedStruct { file_id: self.file_id, @@ -319,7 +318,6 @@ impl<'a> ModCollector<'a> { // And store the TypeId -> StructType mapping somewhere it is reachable self.def_collector.items.types.insert(id, unresolved); - context.def_interner.add_struct_location(id, name_location); context.def_interner.add_definition_location(ReferenceId::Struct(id)); } definition_errors @@ -366,6 +364,8 @@ impl<'a> ModCollector<'a> { } self.def_collector.items.type_aliases.insert(type_alias_id, unresolved); + + context.def_interner.add_definition_location(ReferenceId::Alias(type_alias_id)); } errors } @@ -381,7 +381,6 @@ impl<'a> ModCollector<'a> { let mut errors: Vec<(CompilationError, FileId)> = vec![]; for trait_definition in traits { let name = trait_definition.name.clone(); - let name_location = Location::new(name.span(), self.file_id); // Create the corresponding module for the trait namespace let trait_id = match self.push_child_module( @@ -533,7 +532,6 @@ impl<'a> ModCollector<'a> { }; context.def_interner.push_empty_trait(trait_id, &unresolved, resolved_generics); - context.def_interner.add_trait_location(trait_id, name_location); context.def_interner.add_definition_location(ReferenceId::Trait(trait_id)); self.def_collector.items.traits.insert(trait_id, unresolved); @@ -652,7 +650,7 @@ impl<'a> ModCollector<'a> { Ok(child_mod_id) => { // Track that the "foo" in `mod foo;` points to the module "foo" let referenced = ReferenceId::Module(child_mod_id); - let reference = ReferenceId::Variable(location); + let reference = ReferenceId::Variable(location, false); context.def_interner.add_reference(referenced, reference); errors.extend(collect_defs( diff --git a/noir/noir-repo/compiler/noirc_frontend/src/locations.rs b/noir/noir-repo/compiler/noirc_frontend/src/locations.rs index c142d10319b..dae7edb21e6 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/locations.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/locations.rs @@ -33,11 +33,22 @@ impl NodeInterner { match reference { ReferenceId::Module(id) => self.module_location(&id), ReferenceId::Function(id) => self.function_modifiers(&id).name_location, - ReferenceId::Struct(id) => self.struct_location(&id), - ReferenceId::Trait(id) => self.trait_location(&id), + ReferenceId::Struct(id) => { + let struct_type = self.get_struct(id); + let struct_type = struct_type.borrow(); + Location::new(struct_type.name.span(), struct_type.location.file) + } + ReferenceId::Trait(id) => { + let trait_type = self.get_trait(id); + Location::new(trait_type.name.span(), trait_type.location.file) + } ReferenceId::Global(id) => self.get_global(id).location, - ReferenceId::Alias(id) => self.get_type_alias(id).borrow().location, - ReferenceId::Variable(location) => location, + ReferenceId::Alias(id) => { + let alias_type = self.get_type_alias(id); + let alias_type = alias_type.borrow(); + Location::new(alias_type.name.span(), alias_type.location.file) + } + ReferenceId::Variable(location, _) => location, } } @@ -83,47 +94,57 @@ impl NodeInterner { .map(|node_index| self.reference_location(self.reference_graph[node_index])) } - // Is the given location known to this interner? - pub fn is_location_known(&self, location: Location) -> bool { - self.location_indices.get_node_from_location(location).is_some() + // Returns the `ReferenceId` that exists at a given location, if any. + pub fn reference_at_location(&self, location: Location) -> Option { + self.location_indices.get_node_from_location(location)?; + + let node_index = self.location_indices.get_node_from_location(location)?; + Some(self.reference_graph[node_index]) } // Starting at the given location, find the node referenced by it. Then, gather // all locations that reference that node, and return all of them - // (the references and optionally the reference node if `include_reference` is true). + // (the references and optionally the referenced node if `include_referencedd` is true). + // If `include_self_type_name` is true, references where "Self" is written are returned, + // otherwise they are not. // Returns `None` if the location is not known to this interner. pub fn find_all_references( &self, location: Location, - include_reference: bool, + include_referenced: bool, + include_self_type_name: bool, ) -> Option> { let node_index = self.location_indices.get_node_from_location(location)?; let reference_node = self.reference_graph[node_index]; - let found_locations: Vec = match reference_node { - ReferenceId::Alias(_) | ReferenceId::Global(_) | ReferenceId::Module(_) => todo!(), - ReferenceId::Function(_) | ReferenceId::Struct(_) | ReferenceId::Trait(_) => { - self.find_all_references_for_index(node_index, include_reference) - } - - ReferenceId::Variable(_) => { - let referenced_node_index = self.referenced_index(node_index)?; - self.find_all_references_for_index(referenced_node_index, include_reference) - } + let referenced_node_index = if let ReferenceId::Variable(_, _) = reference_node { + self.referenced_index(node_index)? + } else { + node_index }; + + let found_locations = self.find_all_references_for_index( + referenced_node_index, + include_referenced, + include_self_type_name, + ); + Some(found_locations) } // Given a referenced node index, find all references to it and return their locations, optionally together - // with the reference node's location if `include_reference` is true. + // with the reference node's location if `include_referenced` is true. + // If `include_self_type_name` is true, references where "Self" is written are returned, + // otherwise they are not. fn find_all_references_for_index( &self, referenced_node_index: PetGraphIndex, - include_reference: bool, + include_referenced: bool, + include_self_type_name: bool, ) -> Vec { let id = self.reference_graph[referenced_node_index]; let mut edit_locations = Vec::new(); - if include_reference { + if include_referenced && (include_self_type_name || !id.is_self_type_name()) { edit_locations.push(self.reference_location(id)); } @@ -131,7 +152,9 @@ impl NodeInterner { .neighbors_directed(referenced_node_index, petgraph::Direction::Incoming) .for_each(|reference_node_index| { let id = self.reference_graph[reference_node_index]; - edit_locations.push(self.reference_location(id)); + if include_self_type_name || !id.is_self_type_name() { + edit_locations.push(self.reference_location(id)); + } }); edit_locations } 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 1f057e4f544..fabfc74b901 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -72,7 +72,7 @@ struct Monomorphizer<'interner> { /// Queue of functions to monomorphize next each item in the queue is a tuple of: /// (old_id, new_monomorphized_id, any type bindings to apply, the trait method if old_id is from a trait impl) - queue: VecDeque<(node_interner::FuncId, FuncId, TypeBindings, Option)>, + queue: VecDeque<(node_interner::FuncId, FuncId, TypeBindings, Option, Location)>, /// When a function finishes being monomorphized, the monomorphized ast::Function is /// stored here along with its FuncId. @@ -124,11 +124,15 @@ pub fn monomorphize_debug( let function_sig = monomorphizer.compile_main(main)?; while !monomorphizer.queue.is_empty() { - let (next_fn_id, new_id, bindings, trait_method) = monomorphizer.queue.pop_front().unwrap(); + let (next_fn_id, new_id, bindings, trait_method, location) = + monomorphizer.queue.pop_front().unwrap(); monomorphizer.locals.clear(); perform_instantiation_bindings(&bindings); - let impl_bindings = perform_impl_bindings(monomorphizer.interner, trait_method, next_fn_id); + let interner = &monomorphizer.interner; + let impl_bindings = perform_impl_bindings(interner, trait_method, next_fn_id, location) + .map_err(MonomorphizationError::InterpreterError)?; + monomorphizer.function(next_fn_id, new_id)?; undo_instantiation_bindings(impl_bindings); undo_instantiation_bindings(bindings); @@ -1275,9 +1279,10 @@ impl<'interner> Monomorphizer<'interner> { let new_id = self.next_function_id(); self.define_function(id, function_type.clone(), turbofish_generics, new_id); + let location = self.interner.expr_location(&expr_id); let bindings = self.interner.get_instantiation_bindings(expr_id); let bindings = self.follow_bindings(bindings); - self.queue.push_back((id, new_id, bindings, trait_method)); + self.queue.push_back((id, new_id, bindings, trait_method, location)); new_id } @@ -1747,7 +1752,8 @@ pub fn perform_impl_bindings( interner: &NodeInterner, trait_method: Option, impl_method: node_interner::FuncId, -) -> TypeBindings { + location: Location, +) -> Result { let mut bindings = TypeBindings::new(); if let Some(trait_method) = trait_method { @@ -1767,14 +1773,18 @@ pub fn perform_impl_bindings( let type_bindings = generics.iter().map(replace_type_variable).collect(); let impl_method_type = impl_method_type.force_substitute(&type_bindings); - trait_method_type.try_unify(&impl_method_type, &mut bindings).unwrap_or_else(|_| { - unreachable!("Impl method type {} does not unify with trait method type {} during monomorphization", impl_method_type, trait_method_type) - }); + trait_method_type.try_unify(&impl_method_type, &mut bindings).map_err(|_| { + InterpreterError::ImplMethodTypeMismatch { + expected: trait_method_type.clone(), + actual: impl_method_type, + location, + } + })?; perform_instantiation_bindings(&bindings); } - bindings + Ok(bindings) } pub fn resolve_trait_method( diff --git a/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs b/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs index 76a67e3977c..1618058a9f0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs @@ -68,12 +68,6 @@ pub struct NodeInterner { // The location of each module module_locations: HashMap, - // The location of each struct name - struct_name_locations: HashMap, - - // The location of each trait name - trait_name_locations: HashMap, - /// This graph tracks dependencies between different global definitions. /// This is used to ensure the absence of dependency cycles for globals and types. dependency_graph: DiGraph, @@ -251,7 +245,13 @@ pub enum ReferenceId { Global(GlobalId), Function(FuncId), Alias(TypeAliasId), - Variable(Location), + Variable(Location, bool /* is Self */), +} + +impl ReferenceId { + pub fn is_self_type_name(&self) -> bool { + matches!(self, Self::Variable(_, true)) + } } /// A trait implementation is either a normal implementation that is present in the source @@ -547,8 +547,6 @@ impl Default for NodeInterner { function_modifiers: HashMap::new(), function_modules: HashMap::new(), module_locations: HashMap::new(), - struct_name_locations: HashMap::new(), - trait_name_locations: HashMap::new(), func_id_to_trait: HashMap::new(), dependency_graph: petgraph::graph::DiGraph::new(), dependency_graph_indices: HashMap::new(), @@ -980,22 +978,6 @@ impl NodeInterner { &self.struct_attributes[struct_id] } - pub fn add_struct_location(&mut self, struct_id: StructId, location: Location) { - self.struct_name_locations.insert(struct_id, location); - } - - pub fn struct_location(&self, struct_id: &StructId) -> Location { - self.struct_name_locations[struct_id] - } - - pub fn add_trait_location(&mut self, trait_id: TraitId, location: Location) { - self.trait_name_locations.insert(trait_id, location); - } - - pub fn trait_location(&self, trait_id: &TraitId) -> Location { - self.trait_name_locations[trait_id] - } - pub fn add_module_location(&mut self, module_id: ModuleId, location: Location) { self.module_locations.insert(module_id, location); } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs index d7a282dbfc7..c4aa0654ecd 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs @@ -22,7 +22,7 @@ use chumsky::primitive::Container; pub use errors::ParserError; pub use errors::ParserErrorReason; use noirc_errors::Span; -pub use parser::{expression, parse_program, top_level_item}; +pub use parser::{expression, parse_program, top_level_items}; #[derive(Debug, Clone)] pub enum TopLevelStatement { 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 afeee889ede..de9095aaff2 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs @@ -192,8 +192,8 @@ fn module() -> impl NoirParser { } /// This parser is used for parsing top level statements in macros -pub fn top_level_item() -> impl NoirParser { - top_level_statement(module()) +pub fn top_level_items() -> impl NoirParser> { + top_level_statement(module()).repeated() } /// top_level_statement: function_definition @@ -1117,16 +1117,11 @@ where } fn quote() -> impl NoirParser { - token_kind(TokenKind::Quote).validate(|token, span, emit| { - let tokens = match token { + token_kind(TokenKind::Quote).map(|token| { + ExpressionKind::Quote(match token { Token::Quote(tokens) => tokens, _ => unreachable!("token_kind(Quote) should guarantee parsing only a quote token"), - }; - emit(ParserError::with_reason( - ParserErrorReason::ExperimentalFeature("quoted expressions"), - span, - )); - ExpressionKind::Quote(tokens) + }) }) } diff --git a/noir/noir-repo/docs/docs/noir/concepts/data_types/slices.mdx b/noir/noir-repo/docs/docs/noir/concepts/data_types/slices.mdx index d619117b799..95da2030843 100644 --- a/noir/noir-repo/docs/docs/noir/concepts/data_types/slices.mdx +++ b/noir/noir-repo/docs/docs/noir/concepts/data_types/slices.mdx @@ -197,7 +197,7 @@ fn main() { Applies a function to each element of the slice, returning a new slice containing the mapped elements. ```rust -fn map(self, f: fn(T) -> U) -> [U] +fn map(self, f: fn[Env](T) -> U) -> [U] ``` example @@ -213,7 +213,7 @@ Applies a function to each element of the slice, returning the final accumulated parameter is the initial value. ```rust -fn fold(self, mut accumulator: U, f: fn(U, T) -> U) -> U +fn fold(self, mut accumulator: U, f: fn[Env](U, T) -> U) -> U ``` This is a left fold, so the given function will be applied to the accumulator and first element of @@ -247,7 +247,7 @@ fn main() { Same as fold, but uses the first element as the starting element. ```rust -fn reduce(self, f: fn(T, T) -> T) -> T +fn reduce(self, f: fn[Env](T, T) -> T) -> T ``` example: @@ -260,12 +260,72 @@ fn main() { } ``` +### filter + +Returns a new slice containing only elements for which the given predicate returns true. + +```rust +fn filter(self, f: fn[Env](T) -> bool) -> Self +``` + +example: + +```rust +fn main() { + let slice = &[1, 2, 3, 4, 5]; + let odds = slice.filter(|x| x % 2 == 1); + assert_eq(odds, &[1, 3, 5]); +} +``` + +### join + +Flatten each element in the slice into one value, separated by `separator`. + +Note that although slices implement `Append`, `join` cannot be used on slice +elements since nested slices are prohibited. + +```rust +fn join(self, separator: T) -> T where T: Append +``` + +example: + +```rust +struct Accumulator { + total: Field, +} + +// "Append" two accumulators by adding them +impl Append for Accumulator { + fn empty() -> Self { + Self { total: 0 } + } + + fn append(self, other: Self) -> Self { + Self { total: self.total + other.total } + } +} + +fn main() { + let slice = &[1, 2, 3, 4, 5].map(|total| Accumulator { total }); + + let result = slice.join(Accumulator::empty()); + assert_eq(result, Accumulator { total: 15 }); + + // We can use a non-empty separator to insert additional elements to sum: + let separator = Accumulator { total: 10 }; + let result = slice.join(separator); + assert_eq(result, Accumulator { total: 55 }); +} +``` + ### all Returns true if all the elements satisfy the given predicate ```rust -fn all(self, predicate: fn(T) -> bool) -> bool +fn all(self, predicate: fn[Env](T) -> bool) -> bool ``` example: @@ -283,7 +343,7 @@ fn main() { Returns true if any of the elements satisfy the given predicate ```rust -fn any(self, predicate: fn(T) -> bool) -> bool +fn any(self, predicate: fn[Env](T) -> bool) -> bool ``` example: diff --git a/noir/noir-repo/docs/docs/noir/standard_library/traits.md b/noir/noir-repo/docs/docs/noir/standard_library/traits.md index 96a7b8e2f22..e6f6f80ff03 100644 --- a/noir/noir-repo/docs/docs/noir/standard_library/traits.md +++ b/noir/noir-repo/docs/docs/noir/standard_library/traits.md @@ -51,6 +51,7 @@ For primitive integer types, the return value of `default` is `0`. Container types such as arrays are filled with default values of their element type, except slices whose length is unknown and thus defaulted to zero. +--- ## `std::convert` @@ -85,6 +86,7 @@ For this reason, implementing `From` on a type will automatically generate a mat `Into` is most useful when passing function arguments where the types don't quite match up with what the function expects. In this case, the compiler has enough type information to perform the necessary conversion by just appending `.into()` onto the arguments in question. +--- ## `std::cmp` @@ -178,6 +180,8 @@ impl Ord for (A, B, C, D, E) where A: Ord, B: Ord, C: Ord, D: Ord, E: Ord { .. } ``` +--- + ## `std::ops` ### `std::ops::Add`, `std::ops::Sub`, `std::ops::Mul`, and `std::ops::Div` @@ -301,3 +305,29 @@ impl Shl for u16 { fn shl(self, other: u16) -> u16 { self << other } } impl Shl for u32 { fn shl(self, other: u32) -> u32 { self << other } } impl Shl for u64 { fn shl(self, other: u64) -> u64 { self << other } } ``` + +--- + +## `std::append` + +### `std::append::Append` + +`Append` can abstract over types that can be appended to - usually container types: + +#include_code append-trait noir_stdlib/src/append.nr rust + +`Append` requires two methods: + +- `empty`: Constructs an empty value of `Self`. +- `append`: Append two values together, returning the result. + +Additionally, it is expected that for any implementation: + +- `T::empty().append(x) == x` +- `x.append(T::empty()) == x` + +Implementations: +```rust +impl Append for [T] +impl Append for Quoted +``` diff --git a/noir/noir-repo/noir_stdlib/src/append.nr b/noir/noir-repo/noir_stdlib/src/append.nr new file mode 100644 index 00000000000..4577ae199b8 --- /dev/null +++ b/noir/noir-repo/noir_stdlib/src/append.nr @@ -0,0 +1,35 @@ +// Appends two values together, returning the result. +// +// An alternate name for this trait is `Monoid` if that is familiar. +// If not, it can be ignored. +// +// It is expected that for any implementation: +// - `T::empty().append(x) == x` +// - `x.append(T::empty()) == x` +// docs:start:append-trait +trait Append { + fn empty() -> Self; + fn append(self, other: Self) -> Self; +} +// docs:end:append-trait + +impl Append for [T] { + fn empty() -> Self { + &[] + } + + fn append(self, other: Self) -> Self { + // Slices have an existing append function which this will resolve to. + self.append(other) + } +} + +impl Append for Quoted { + fn empty() -> Self { + quote {} + } + + fn append(self, other: Self) -> Self { + quote { $self $other } + } +} diff --git a/noir/noir-repo/noir_stdlib/src/lib.nr b/noir/noir-repo/noir_stdlib/src/lib.nr index 65da7e6e9ab..ac53941e752 100644 --- a/noir/noir-repo/noir_stdlib/src/lib.nr +++ b/noir/noir-repo/noir_stdlib/src/lib.nr @@ -27,6 +27,7 @@ mod uint128; mod bigint; mod runtime; mod meta; +mod append; // Oracle calls are required to be wrapped in an unconstrained function // Thus, the only argument to the `println` oracle is expected to always be an ident diff --git a/noir/noir-repo/noir_stdlib/src/slice.nr b/noir/noir-repo/noir_stdlib/src/slice.nr index 1a40abcf704..8d3f395f080 100644 --- a/noir/noir-repo/noir_stdlib/src/slice.nr +++ b/noir/noir-repo/noir_stdlib/src/slice.nr @@ -1,3 +1,5 @@ +use crate::append::Append; + impl [T] { #[builtin(array_len)] pub fn len(self) -> u32 {} @@ -85,6 +87,33 @@ impl [T] { accumulator } + // Returns a new slice containing only elements for which the given predicate + // returns true. + pub fn filter(self, predicate: fn[Env](T) -> bool) -> Self { + let mut ret = &[]; + for elem in self { + if predicate(elem) { + ret = ret.push_back(elem); + } + } + ret + } + + // Flatten each element in the slice into one value, separated by `separator`. + pub fn join(self, separator: T) -> T where T: Append { + let mut ret = T::empty(); + + if self.len() != 0 { + ret = self[0]; + + for i in 1..self.len() { + ret = ret.append(separator).append(self[i]); + } + } + + ret + } + // Returns true if all elements in the slice satisfy the predicate pub fn all(self, predicate: fn[Env](T) -> bool) -> bool { let mut ret = true; diff --git a/noir/noir-repo/test_programs/compile_success_empty/slice_join/Nargo.toml b/noir/noir-repo/test_programs/compile_success_empty/slice_join/Nargo.toml new file mode 100644 index 00000000000..44be002efb4 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/slice_join/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "slice_join" +type = "bin" +authors = [""] +compiler_version = ">=0.31.0" + +[dependencies] \ No newline at end of file diff --git a/noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr new file mode 100644 index 00000000000..217000694b0 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/slice_join/src/main.nr @@ -0,0 +1,16 @@ +use std::append::Append; + +fn main() { + let slice = &[1, 2, 3, 4, 5]; + + let odds = slice.filter(|x| x % 2 == 1); + assert_eq(odds, &[1, 3, 5]); + + let odds_and_evens = append_three(odds, &[100], &[2, 4]); + assert_eq(odds_and_evens, &[1, 3, 5, 100, 2, 4]); +} + +fn append_three(one: T, two: T, three: T) -> T where T: Append { + // The `T::empty()`s here should do nothing + T::empty().append(one).append(two).append(three).append(T::empty()) +} diff --git a/noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/Nargo.toml b/noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/Nargo.toml new file mode 100644 index 00000000000..63f15f2b349 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unquote_multiple_items_from_annotation" +type = "bin" +authors = [""] +compiler_version = ">=0.31.0" + +[dependencies] diff --git a/noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/src/main.nr new file mode 100644 index 00000000000..04f07f038e5 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/unquote_multiple_items_from_annotation/src/main.nr @@ -0,0 +1,14 @@ +#[foo] +struct Foo {} + +fn main() { + assert_eq(ONE, 1); + assert_eq(TWO, 2); +} + +comptime fn foo(_: StructDefinition) -> Quoted { + quote { + global ONE = 1; + global TWO = 2; + } +} diff --git a/noir/noir-repo/test_programs/execution_success/regression_5435/Nargo.toml b/noir/noir-repo/test_programs/execution_success/regression_5435/Nargo.toml new file mode 100644 index 00000000000..6affc423b7a --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/regression_5435/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "regression_5435" +type = "bin" +authors = [""] +compiler_version = ">=0.31.0" + +[dependencies] diff --git a/noir/noir-repo/test_programs/execution_success/regression_5435/Prover.toml b/noir/noir-repo/test_programs/execution_success/regression_5435/Prover.toml new file mode 100644 index 00000000000..f3e2bbe32e7 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/regression_5435/Prover.toml @@ -0,0 +1,2 @@ +input = "0" +enable = false diff --git a/noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr b/noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr new file mode 100644 index 00000000000..65f13c5b201 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/regression_5435/src/main.nr @@ -0,0 +1,18 @@ +fn main(input: Field, enable: bool) { + if enable { + let hash = no_predicate_function(input); + // `EnableSideEffects` instruction from above instruction leaks out and removes the predicate from this call, + // resulting in execution failure. + fail(hash); + } +} + +#[no_predicates] +fn no_predicate_function(enable: Field) -> Field { + // if-statement ensures that an `EnableSideEffects` instruction is emitted. + if enable == 0 { 1 } else { 0 } +} + +unconstrained fn fail(_: Field) { + assert(false); +} diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml deleted file mode 100644 index 921b69e100a..00000000000 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml +++ /dev/null @@ -1,4 +0,0 @@ -key_hash = "0x096129b1c6e108252fc5c829c4cc9b7e8f0d1fd9f29c2532b563d6396645e08f" -proof = ["0x0000000000000000000000000000000000000000000000000000000000000020","0x0000000000000000000000000000000000000000000000000000000000000011","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000042ab5d6d1986846cf","0x00000000000000000000000000000000000000000000000b75c020998797da78","0x0000000000000000000000000000000000000000000000005a107acb64952eca","0x000000000000000000000000000000000000000000000000000031e97a575e9d","0x00000000000000000000000000000000000000000000000b5666547acf8bd5a4","0x00000000000000000000000000000000000000000000000c410db10a01750aeb","0x00000000000000000000000000000000000000000000000d722669117f9758a4","0x000000000000000000000000000000000000000000000000000178cbf4206471","0x000000000000000000000000000000000000000000000000e91b8a11e7842c38","0x000000000000000000000000000000000000000000000007fd51009034b3357f","0x000000000000000000000000000000000000000000000009889939f81e9c7402","0x0000000000000000000000000000000000000000000000000000f94656a2ca48","0x000000000000000000000000000000000000000000000006fb128b46c1ddb67f","0x0000000000000000000000000000000000000000000000093fe27776f50224bd","0x000000000000000000000000000000000000000000000004a0c80c0da527a081","0x0000000000000000000000000000000000000000000000000001b52c2020d746","0x0000000000000000000000000000005a9bae947e1e91af9e4033d8d6aa6ed632","0x000000000000000000000000000000000025e485e013446d4ac7981c88ba6ecc","0x000000000000000000000000000000ff1e0496e30ab24a63b32b2d1120b76e62","0x00000000000000000000000000000000001afe0a8a685d7cd85d1010e55d9d7c","0x000000000000000000000000000000b0804efd6573805f991458295f510a2004","0x00000000000000000000000000000000000c81a178016e2fe18605022d5a8b0e","0x000000000000000000000000000000eba51e76eb1cfff60a53a0092a3c3dea47","0x000000000000000000000000000000000022e7466247b533282f5936ac4e6c15","0x00000000000000000000000000000071b1d76edf770edff98f00ff4deec264cd","0x00000000000000000000000000000000001e48128e68794d8861fcbb2986a383","0x000000000000000000000000000000d3a2af4915ae6d86b097adc377fafda2d4","0x000000000000000000000000000000000006359de9ca452dab3a4f1f8d9c9d98","0x0000000000000000000000000000000d9d719a8b9f020ad3642d60fe704e696f","0x00000000000000000000000000000000000ddfdbbdefc4ac1580ed38e12cfa49","0x0000000000000000000000000000008289fe9754ce48cd01b7be96a861b5e157","0x00000000000000000000000000000000000ff3e0896bdea021253b3d360fa678","0x0000000000000000000000000000000d9d719a8b9f020ad3642d60fe704e696f","0x00000000000000000000000000000000000ddfdbbdefc4ac1580ed38e12cfa49","0x0000000000000000000000000000008289fe9754ce48cd01b7be96a861b5e157","0x00000000000000000000000000000000000ff3e0896bdea021253b3d360fa678","0x000000000000000000000000000000f968b227a358a305607f3efc933823d288","0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08","0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f","0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1","0x0000000000000000000000000000005b739ed2075f2b046062b8fc6a2d1e9863","0x00000000000000000000000000000000001285cd1030d338c0e1603b4da2c838","0x00000000000000000000000000000027447d6c281eb38b2b937af4a516d60c04","0x000000000000000000000000000000000019bc3d980465fbb4a656a74296fc58","0x000000000000000000000000000000b484788ace8f7df86dd5e325d2e9b12599","0x00000000000000000000000000000000000a2ca0d10eb7b767114ae230b728d3","0x000000000000000000000000000000c6dfc7092f16f95795e437664498b88d53","0x0000000000000000000000000000000000131067b4e4d95a4f6f8cf5c9b5450a","0x0f413f22eec51f2a02800e0cafaeec1d92d744fbbaef213c687b9edabd6985f5","0x21230f4ff26c80ffb5d037a9d1d26c3f955ca34cbeca4f54db6656b932967a0c","0x0521f877fe35535767f99597cc50effbd283dcae6812ee0a7620d796ccbfd642","0x202b01350a9cc5c20ec0f3eaada338c0a3b793811bd539418ffa3cc4302615e2","0x2d1214d9b0d41058ad4a172d9c0aecc5bdabe95e687c3465050c6b5396509be4","0x1113b344a151b0af091cb28d728b752ebb4865da6cd7ee68471b961ca5cf69b9","0x2aa66d0954bb83e17bd5c9928d3aa7a7df75d741d409f7c15ba596804ba643fb","0x2e26bc7a530771ef7a95d5360d537e41cf94d8a0942764ff09881c107f91a106","0x0f14f32b921bb63ad1df00adab7c82af58ea8aa7f353f14b281208d8c5fab504","0x13429515c0c53b6502bbcdf545defb3cb69a986c9263e070fcbb397391aae1a3","0x1f21cac5e2f262afc1006a21454cc6bcb018c44e53ad8ab61cebbac99e539176","0x2a9886a6ddc8a61b097c668cd362fc8acdee8dde74f7b1af192c3e060bb2948f","0x2d718181e408ead2e9bcd30a84ad1fccbaf8d48ab6d1820bad4933d284b503c4","0x2634c1aafc902f14508f34d3d7e9d485f42d1a4c95b5a1ef73711ed0d3c68d77","0x092ede9777e6472ce5ffd8c963d466006189e960e2c591d338dc8d4af1a057fb","0x1cba45b17fd24f1cb1b4ab7b83eee741f6c77ba70a497dc4de259eceb7d5ea26","0x246e887c7bf2e17f919b2393b6e9b00b33e8822d862544a775aac05cb7bff710","0x04c3f539fe8689971948afcb437f1ecbd444a5bddaca1c8a450348dcd8480047","0x20c6a423ae4fd58e8951aa378d02d77baf90508ceb48856db2319d70938b186e","0x1bcf8786b554b3316d8ebdbc9d006a4e5d4865aad512ffd404b7f83550d3d030","0x09ab038260518f0970564afcd6bf22e2abf6b1fa5e12a327bbf195b6ca5edd78","0x1024e32554746f89c195286ba6ccfc9765e5d14bbe8064bc6fdf22d16ec6b495","0x17706656f8dbd7e47bb257a6428f0cb7278ea02fa9e6ce431d7bcc9133fba9c7","0x25a3e8a33c15ef2a4dd16313a6049bf1d468b4cdc141f238f2d51a1e8e1c22b3","0x1198863f08006edb27aee23164fb117a4ddec1bf1ed89807aa907e5cd24bf068","0x1862b4856b5b4d4a064f873e221703e4e2cd1ebfca1337dedca56485c38ed5a0","0x062214af1ea6dd6bf8895b92d394571c43970b6f967e1c794624d96071b25ad3","0x1e5be9428ddcf1f9b0cbafc28101e792ec5cf73852b0cd0b84fbff71b4490e09","0x2d4189bea5b1e30f63c64bd26df82f18bcaf885ec8887b54634b2557869ce87f","0x0f2e5d9a908850e9d44925e17d8b12d1adb1ed029799c9b5858598504242bbc0","0x3050dc85746a57931d99f3f35e77c2ba561fba0baa018b79ff1fd544026833ae","0x2a591a32437e5e0b875a137fd868bd1b6dbc003ff1b661f26e00627cc7c5cf47","0x27946841e1670ad9c65717016d0cedf524724217236e81b9fd0a264a36ebfb0e","0x0fc396e9d19d6e68e289602e292ee345542d0d28bf6de34fa62cc577cbdfb1df","0x08e7433a07a44c0c9c4dd4b273a2685bbd1a91fd5cf2b43409458fab42a23e1b","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000000","0x12bd9bfb029c3503a5c6deea87b0a0f11bb9f7ea584af2d48f3e48d7e09247ae","0x2ccc4810748c0a82dfc0f063d0b8c7999ffe9474653080e6ef92b3cb7a428784","0x08eb574d7fecadadb508c8bd35fdad06b99110609d679763c2e3645229b1b95a","0x0f1a65e747c8021ed7c454a4be1e89b1bce66ead9ed980fa98a7a050eafe98a1","0x1c8ff9e36684ec71614dee4c17859b06c742089f6029d3694a16e00dac9b57f1","0x0303101a8ba712aeca4da85b767ab8d3ecf489ec7d746f8ee20041717cc000e9","0x0aaf64c65e7088e5596108c9601467911fea809ca6540d79af77e6e66e36cd99","0x17caf164ce74ea7edfb1390e07763d2197797ec26661b92cde18a98d61d2fddc","0x18cb055c7ad6d01437725bb457681d81f3ecadc4f35d838a3c13daf25a44456a","0x2d78602b8bbcd32b36a99a6e2d248e7fe044ef1b50813133370412f9ef5299f0","0x2b139276ea86d426a115479e4154f72a6bd83a6253bf13e9670dc6b4664378f0","0x127c7837b384902c39a104036c09546728571c46c8166b1b9b13b3a615ebb781","0x05faa4816f83cf0189a482ad943c94b9ec6474002f2b327f8698763ad0ea0985","0x2f90359cc30ee693fb3aced96523cf7aebd152c22329eee56a398d9a4ac0628e","0x0a71beaf17a59c5a238f04c1f203848d87502c5057a78c13f0cfb0f9876e7714","0x2696c1e6d089556adaeb95c8a5e3065b00a393a38c2d69e9bd6ce8cdc49d87da","0x1f3d165a7dc6564a036e451eb9cb7f1e1cb1e6d29daa75e3f135ea3e58a79ccd","0x1473a660819bdd838d56122b72b32b267211e9f1103239480ec50fa85c9e1035","0x0a8ccaeb22451f391b3fc3467c8e6e900270a7afb7b510e8acf5a4f06f1c0888","0x03b3080afc0658cc87e307758cebc171921f43eca159b9dedf7f72aa8dd926bd","0x2dd7d6663fa0e1755dfafac352c361fcd64c7f4d53627e3646870ac169cc4a07","0x1ec54b883f5f35ccad0e75695af20790d9860104095bab34c9bf01628dd40cb9","0x193dff50f83c241f7a9e087a29ce72ecf3f6d8563593f786dcd04c32bcfd4ced","0x135122c0dae26cda8ca1c09de8225064ad86d10423ab0aaa53b481aa4626e1d6","0x08d5a56cbfab5aeed56d3cdd7fb6b30fc26b0c1a5b63fccd7fa44c53ba6fd35a","0x0d12f126dfa2daad3726d00ca339284cc22e36c6d81bb7a4b95c6f9598b60e7c","0x2e8b24bbdf2fd839d3c7cae1f0eeb96bfcfaeef30b27476f2fafcb17da78cd5e","0x2364acfe0cea39b7f749c5f303b99504977357925f810f684c60f35d16315211","0x06ca062eb70b8c51cfac35345e7b6b51f33a8ec9ebe204fb9b4911200bf508b7","0x266c0aa1ccb97186815bf69084f600d06ddd934e59a38dfe602ee5d6b9487f22","0x1d817537a49c6d0e3b4b65c6665334b91d7593142e60065048be9e55ceb5e7ab","0x05e9b7256a368df053c691952b59e9327a7c12ed322bbd6f72c669b9b9c26d49","0x05e9b7256a368df053c691952b59e9327a7c12ed322bbd6f72c669b9b9c26d49","0x25b77026673a1e613e50df0e88fb510973739d5f9064bd364079a9f884209632","0x25c9bc7a3f6aae3d43ff68b5614b34b5eaceff37157b37347995d231784ac1fd","0x085f69baef22680ae15f4801ef4361ebe9c7fc24a94b5bc2527dce8fb705439e","0x0d7c6b9ce31bfc32238a205455baf5ffe99cd30eb0f7bb5b504e1d4501e01382","0x1001a8cc4bc1221c814fba0eddcf3c40619b133373640c600de5bed0a0a05b10","0x20f5894be90e52977cb70f4f4cbd5101693db0360848939750db7e91109d54b6","0x22c09cb26db43f0599408b4daed0f4f496c66424e6affa41c14387d8e0af851b","0x24e5f41357798432426a9549d71e8cc681eaebacbe87f6e3bf38e85de5aa2f3d","0x06eb90100c736fbf2b87432d7821ecdc0b365024739bc36363d48b905973f5b9","0x000000000000000000000000000000ece6d09ed58e9f5661c01140b10558a8c2","0x000000000000000000000000000000000012b6e4f37adcb34b8e88ff8b6eebce","0x000000000000000000000000000000b226a2bb93593fa1fab19a44767828a3f5","0x00000000000000000000000000000000002b5b518342030543092e1428a7e33c","0x00000000000000000000000000000022ba33857034a0574c216eb3c1ddff3025","0x00000000000000000000000000000000001918e58df857985a7cf9eae7802165","0x00000000000000000000000000000045c2d840b96fb6106cc14dcad89dd5f675","0x00000000000000000000000000000000000afdfac1e3a1febdd0208867d44f98","0x00000000000000000000000000000042ebed6c5ec45d794f119aef24c192af0f","0x00000000000000000000000000000000002d05ef250900bbcc5751bbeb210d6a","0x00000000000000000000000000000060d604bdda48eecc90ed065bd9770e1323","0x00000000000000000000000000000000001fed91c63d0041660c1cbc84c2ffbb","0x00000000000000000000000000000054196b549cde36092e8184c7f4f7d878de","0x00000000000000000000000000000000000153f26a01294329922b492485cc31","0x00000000000000000000000000000056ebea579d10dbb440f0222931df2c0059","0x00000000000000000000000000000000000d2cbc61ce5b7cdd7fce398da4637b","0x000000000000000000000000000000e2b9512360b9797d96675d8a2fd2f7aa5d","0x000000000000000000000000000000000025742905f105ff895f74e7c3daa34a","0x000000000000000000000000000000a2dd7df55db59bd41b83518d4403fbc382","0x00000000000000000000000000000000002c1d9c3cbb9371d4cc4e9f900b9a46","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000000000bcf12ae40c9425c3e67654b84181f90502","0x00000000000000000000000000000000000b6d3faa8a71ff6ef1aa887b7307cf","0x0000000000000000000000000000001f6f719acc23b8f84808c0275d61cfb456","0x0000000000000000000000000000000000296030933ed0c134457ae71c393dfe","0x000000000000000000000000000000ebe1a57cdd7d3d763289b40ef5ed9a7ae0","0x000000000000000000000000000000000010f30483e7df51fca2316d3367603c","0x0000000000000000000000000000000149b7b283ab18060618c8e051864c03cd","0x00000000000000000000000000000000001ef7763235a3a25e241a5f06704dc3"] -public_inputs = ["0x0000000000000000000000000000000000000000000000000000000000000003"] -verification_key = ["0x0000000000000000000000000000000000000000000000000000000000000020","0x0000000000000000000000000000000000000000000000000000000000000011","0x0000000000000000000000000000000000000000000000000000000000000001","0x00000000000000000000000000000060e430ad1c23bfcf3514323aae3f206e84","0x00000000000000000000000000000000001b5c3ff4c2458d8f481b1c068f27ae","0x000000000000000000000000000000bb510ab2112def34980e4fc6998ad9dd16","0x00000000000000000000000000000000000576e7c105b43e061e13cb877fefe1","0x000000000000000000000000000000ced074785d11857b065d8199e6669a601c","0x00000000000000000000000000000000000053b48a4098c1c0ae268f273952f7","0x000000000000000000000000000000d1d4b26e941db8168cee8f6de548ae0fd8","0x00000000000000000000000000000000001a9adf5a6dadc3d948bb61dfd63f4c","0x0000000000000000000000000000009ce1faac6f8de6ebb18f1db17372c82ad5","0x00000000000000000000000000000000002002681bb417184b2df070a16a3858","0x000000000000000000000000000000161baa651a8092e0e84725594de5aba511","0x00000000000000000000000000000000000be0064399c2a1efff9eb0cdcb2223","0x0000000000000000000000000000008673be6fd1bdbe980a29d8c1ded54381e7","0x000000000000000000000000000000000008a5158a7d9648cf1d234524c9fa0c","0x0000000000000000000000000000002b4fce6e4b1c72062b296d49bca2aa4130","0x00000000000000000000000000000000002e45a9eff4b6769e55fb710cded44f","0x00000000000000000000000000000072b85bf733758b76bcf97333efb85a23e3","0x000000000000000000000000000000000017da0ea508994fc82862715e4b5592","0x00000000000000000000000000000094fa74695cf058dba8ff35aec95456c6c3","0x0000000000000000000000000000000000211acddb851061c24b8f159e832bd1","0x000000000000000000000000000000303b5e5c531384b9a792e11702ad3bcab0","0x00000000000000000000000000000000000d336dff51a60b8833d5d7f6d4314c","0x0000000000000000000000000000009f825dde88092070747180d581c342444a","0x0000000000000000000000000000000000237fbd6511a03cca8cac01b555fe01","0x0000000000000000000000000000007c313205159495df6d8de292079a4844ff","0x000000000000000000000000000000000018facdfc468530dd45e8f7a1d38ce9","0x0000000000000000000000000000000d1ce33446fc3dc4ab40ca38d92dac74e1","0x00000000000000000000000000000000000852d8e3e0e8f4435af3e94222688b","0x0000000000000000000000000000006c04ee19ec1dfec87ed47d6d04aa158de2","0x000000000000000000000000000000000013240f97a584b45184c8ec31319b5f","0x000000000000000000000000000000cefb5d240b07ceb4be26ea429b6dc9d9e0","0x00000000000000000000000000000000002dad22022121d689f57fb38ca21349","0x000000000000000000000000000000c9f189f2a91aeb664ce376d8b157ba98f8","0x00000000000000000000000000000000002531a51ad54f124d58094b219818d2","0x000000000000000000000000000000ef1e6db71809307f677677e62b4163f556","0x0000000000000000000000000000000000272da4396fb2a7ee0638b9140e523d","0x0000000000000000000000000000002e54c0244a7732c87bc4712a76dd8c83fb","0x000000000000000000000000000000000007db77b3e04b7eba9643da57cbbe4d","0x000000000000000000000000000000e0dfe1ddd7f74ae0d636c910c3e85830d8","0x00000000000000000000000000000000000466fa9b57ec4664abd1505b490862","0x0000000000000000000000000000009ee55ae8a32fe5384c79907067cc27192e","0x00000000000000000000000000000000000799d0e465cec07ecb5238c854e830","0x0000000000000000000000000000001d5910ad361e76e1c241247a823733c39f","0x00000000000000000000000000000000002b03f2ccf7507564da2e6678bef8fe","0x000000000000000000000000000000231147211b3c75e1f47d150e4bbd2fb22e","0x00000000000000000000000000000000000d19ee104a10d3c701cfd87473cbbe","0x0000000000000000000000000000006705f3f382637d00f698e2c5c94ed05ae9","0x00000000000000000000000000000000000b9c792da28bb60601dd7ce4b74e68","0x000000000000000000000000000000ac5acc8cc21e4ddb225c510670f80c80b3","0x00000000000000000000000000000000002da9d3fa57343e6998aba19429b9fa","0x0000000000000000000000000000004bacbf54b7c17a560df0af18b6d0d527be","0x00000000000000000000000000000000000faea33aeca2025b22c288964b21eb","0x000000000000000000000000000000492e756298d68d6e95de096055cc0336c3","0x00000000000000000000000000000000001a12a12f004859e5a3675c7315121b","0x000000000000000000000000000000893d521d512f30e6d32afbbc0cecd8ee00","0x00000000000000000000000000000000001674b3c1ef12c6da690631e0d86c04","0x000000000000000000000000000000aa6cb02a52e7a613873d4ac9b411349945","0x00000000000000000000000000000000001ecb1fe9c493add46751f9940f73e1","0x00000000000000000000000000000045b3d362ca82cba69fb2b9c733a5b8c351","0x000000000000000000000000000000000019a683586af466e331945b732d2f8c","0x000000000000000000000000000000fc79b052dfdfe67c0ecfc06b4267ffd694","0x00000000000000000000000000000000001336a70c396393038d5e9913744ac2","0x0000000000000000000000000000005450d29af1e9438e91cd33ddeb2548226e","0x000000000000000000000000000000000000993a602891cfd0e6f6ecf7404933","0x000000000000000000000000000000498efddab90a32e9b2db729ed6e9b40192","0x00000000000000000000000000000000002425efebe9628c63ca6fc28bdb5901","0x000000000000000000000000000000d8488157f875a21ab5f93f1c2b641f3de9","0x0000000000000000000000000000000000290f95ada3936604dc4b14df7504e3","0x0000000000000000000000000000005d6902187f3ed60dcce06fca211b40329a","0x00000000000000000000000000000000002b5870a6ba0b20aaa0178e5adfbc36","0x000000000000000000000000000000e5c2519171fa0e548fc3c4966ffc1ce570","0x00000000000000000000000000000000001cb8d8f4793b7debbdc429389dbf2d","0x000000000000000000000000000000a3ee22dd60456277b86c32a18982dcb185","0x00000000000000000000000000000000002493c99a3d068b03f8f2b8d28b57ce","0x000000000000000000000000000000f6c3731486320082c20ec71bbdc92196c1","0x00000000000000000000000000000000001ded39c4c8366469843cd63f09ecac","0x000000000000000000000000000000494997477ab161763e46601d95844837ef","0x00000000000000000000000000000000002e0cddbc5712d79b59cb3b41ebbcdd","0x000000000000000000000000000000426db4c64531d350750df62dbbc41a1bd9","0x0000000000000000000000000000000000303126892f664d8d505964d14315ec","0x00000000000000000000000000000076a6b2c6040c0c62bd59acfe3e3e125672","0x000000000000000000000000000000000000874a5ad262eecc6b565e0b085074","0x000000000000000000000000000000ef082fb517183c9c6841c2b8ef2ca1df04","0x0000000000000000000000000000000000127b2a745a1b74968c3edc18982b9b","0x000000000000000000000000000000c9efd4f8c3d56e1eb23d789a8f710d5be6","0x000000000000000000000000000000000015a18748490ff4c2b1871081954e86","0x000000000000000000000000000000a0011ef987dc016ab110eacd554a1d8bbf","0x00000000000000000000000000000000002097c84955059442a95df075833071","0x000000000000000000000000000000d38e9426ad3085b68b00a93c17897c2877","0x00000000000000000000000000000000002aecd48089890ea0798eb952c66824","0x00000000000000000000000000000078d8a9ce405ce559f441f2e71477ff3ddb","0x00000000000000000000000000000000001216bdb2f0d961bb8a7a23331d2150","0x0000000000000000000000000000000000000000000000000000000000000001","0x0000000000000000000000000000000000000000000000000000000000000000","0x0000000000000000000000000000000000000000000000000000000000000002","0x0000000000000000000000000000000000000000000000000000000000000000","0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb","0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56","0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc","0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4"] diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr deleted file mode 100644 index ecfd18f3837..00000000000 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr +++ /dev/null @@ -1,21 +0,0 @@ - -// This circuit aggregates a single Honk proof from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 409; -fn main( - verification_key: [Field; 103], - // This is the proof without public inputs attached. - // - // This means: the size of this does not change with the number of public inputs. - proof: [Field; SIZE_OF_PROOF_IF_LOGN_IS_28], - public_inputs: pub [Field; 1], - // This is currently not public. It is fine given that the vk is a part of the circuit definition. - // I believe we want to eventually make it public too though. - key_hash: Field -) { - std::verify_proof( - verification_key.as_slice(), - proof.as_slice(), - public_inputs.as_slice(), - key_hash - ); -} diff --git a/noir/noir-repo/tooling/lsp/src/requests/references.rs b/noir/noir-repo/tooling/lsp/src/requests/references.rs index d35ec4a86d8..f8c23632936 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/references.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/references.rs @@ -13,7 +13,7 @@ pub(crate) fn on_references_request( ) -> impl Future>, ResponseError>> { let result = process_request(state, params.text_document_position, |location, interner, files| { - interner.find_all_references(location, params.context.include_declaration).map( + interner.find_all_references(location, params.context.include_declaration, true).map( |locations| { locations .iter() diff --git a/noir/noir-repo/tooling/lsp/src/requests/rename.rs b/noir/noir-repo/tooling/lsp/src/requests/rename.rs index 67853c12b81..24d15f91c79 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/rename.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/rename.rs @@ -7,6 +7,7 @@ use async_lsp::ResponseError; use lsp_types::{ PrepareRenameResponse, RenameParams, TextDocumentPositionParams, TextEdit, Url, WorkspaceEdit, }; +use noirc_frontend::node_interner::ReferenceId; use crate::LspState; @@ -17,7 +18,13 @@ pub(crate) fn on_prepare_rename_request( params: TextDocumentPositionParams, ) -> impl Future, ResponseError>> { let result = process_request(state, params, |location, interner, _| { - let rename_possible = interner.is_location_known(location); + let reference_id = interner.reference_at_location(location); + let rename_possible = match reference_id { + // Rename shouldn't be possible when triggered on top of "Self" + Some(ReferenceId::Variable(_, true /* is self type name */)) => false, + Some(_) => true, + None => false, + }; Some(PrepareRenameResponse::DefaultBehavior { default_behavior: rename_possible }) }); future::ready(result) @@ -29,29 +36,30 @@ pub(crate) fn on_rename_request( ) -> impl Future, ResponseError>> { let result = process_request(state, params.text_document_position, |location, interner, files| { - let rename_changes = interner.find_all_references(location, true).map(|locations| { - let rs = locations.iter().fold( - HashMap::new(), - |mut acc: HashMap>, location| { - let file_id = location.file; - let span = location.span; - - let Some(lsp_location) = to_lsp_location(files, file_id, span) else { - return acc; - }; - - let edit = TextEdit { - range: lsp_location.range, - new_text: params.new_name.clone(), - }; - - acc.entry(lsp_location.uri).or_default().push(edit); - - acc - }, - ); - rs - }); + let rename_changes = + interner.find_all_references(location, true, false).map(|locations| { + let rs = locations.iter().fold( + HashMap::new(), + |mut acc: HashMap>, location| { + let file_id = location.file; + let span = location.span; + + let Some(lsp_location) = to_lsp_location(files, file_id, span) else { + return acc; + }; + + let edit = TextEdit { + range: lsp_location.range, + new_text: params.new_name.clone(), + }; + + acc.entry(lsp_location.uri).or_default().push(edit); + + acc + }, + ); + rs + }); let response = WorkspaceEdit { changes: rename_changes, @@ -103,12 +111,19 @@ mod rename_tests { let mut changes: Vec = changes.values().flatten().map(|edit| edit.range).collect(); changes.sort_by_key(|range| (range.start.line, range.start.character)); + if changes != ranges { + let extra_in_changes: Vec<_> = + changes.iter().filter(|range| !ranges.contains(range)).collect(); + let extra_in_ranges: Vec<_> = + ranges.iter().filter(|range| !changes.contains(range)).collect(); + panic!("Rename locations did not match.\nThese renames were not found: {:?}\nThese renames should not have been found: {:?}", extra_in_ranges, extra_in_changes); + } assert_eq!(changes, ranges); } } #[test] - async fn test_on_prepare_rename_request_cannot_be_applied() { + async fn test_on_prepare_rename_request_cannot_be_applied_if_there_are_no_matches() { let (mut state, noir_text_document) = test_utils::init_lsp_server("rename_function").await; let params = TextDocumentPositionParams { @@ -126,6 +141,25 @@ mod rename_tests { ); } + #[test] + async fn test_on_prepare_rename_request_cannot_be_applied_on_self_type_name() { + let (mut state, noir_text_document) = test_utils::init_lsp_server("rename_struct").await; + + let params = TextDocumentPositionParams { + text_document: lsp_types::TextDocumentIdentifier { uri: noir_text_document }, + position: lsp_types::Position { line: 11, character: 24 }, // At "Self" + }; + + let response = on_prepare_rename_request(&mut state, params) + .await + .expect("Could not execute on_prepare_rename_request"); + + assert_eq!( + response, + Some(PrepareRenameResponse::DefaultBehavior { default_behavior: false }) + ); + } + #[test] async fn test_rename_function() { check_rename_succeeds("rename_function", "another_function").await; @@ -150,4 +184,14 @@ mod rename_tests { async fn test_rename_trait() { check_rename_succeeds("rename_trait", "Foo").await; } + + #[test] + async fn test_rename_type_alias() { + check_rename_succeeds("rename_type_alias", "Bar").await; + } + + #[test] + async fn test_rename_global() { + check_rename_succeeds("rename_global", "FOO").await; + } } diff --git a/noir/noir-repo/tooling/lsp/test_programs/rename_function/src/main.nr b/noir/noir-repo/tooling/lsp/test_programs/rename_function/src/main.nr index ad526f10966..7a70084276e 100644 --- a/noir/noir-repo/tooling/lsp/test_programs/rename_function/src/main.nr +++ b/noir/noir-repo/tooling/lsp/test_programs/rename_function/src/main.nr @@ -19,3 +19,9 @@ mod foo { crate::another_function() } } + +use foo::some_other_function as bar; + +fn x() { + bar(); +} diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml b/noir/noir-repo/tooling/lsp/test_programs/rename_global/Nargo.toml similarity index 66% rename from noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml rename to noir/noir-repo/tooling/lsp/test_programs/rename_global/Nargo.toml index 8fce1bf44b6..350c6fe5506 100644 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml +++ b/noir/noir-repo/tooling/lsp/test_programs/rename_global/Nargo.toml @@ -1,5 +1,5 @@ [package] -name = "verify_honk_proof" +name = "rename_global" type = "bin" authors = [""] diff --git a/noir/noir-repo/tooling/lsp/test_programs/rename_global/src/main.nr b/noir/noir-repo/tooling/lsp/test_programs/rename_global/src/main.nr new file mode 100644 index 00000000000..3ae8cf4bfc3 --- /dev/null +++ b/noir/noir-repo/tooling/lsp/test_programs/rename_global/src/main.nr @@ -0,0 +1,22 @@ +mod foo { + global FOO = 1; +} + +use foo::FOO; + +fn main() { + let _ = foo::FOO; + let _ = FOO; + let _: [Field; FOO] = [1]; +} + +trait WithNumber { + +} + +struct Some { +} + +impl WithNumber for Some { + +} diff --git a/noir/noir-repo/tooling/lsp/test_programs/rename_struct/src/main.nr b/noir/noir-repo/tooling/lsp/test_programs/rename_struct/src/main.nr index 93a0779cf3b..d9da3e75763 100644 --- a/noir/noir-repo/tooling/lsp/test_programs/rename_struct/src/main.nr +++ b/noir/noir-repo/tooling/lsp/test_programs/rename_struct/src/main.nr @@ -6,6 +6,12 @@ mod foo { impl Foo { fn foo() {} + + fn bar(self) {} + + fn baz() -> Self { + Self { field: 1 } + } } } } diff --git a/noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/Nargo.toml b/noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/Nargo.toml new file mode 100644 index 00000000000..1b95727ed8d --- /dev/null +++ b/noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "rename_type_alias" +type = "bin" +authors = [""] + +[dependencies] diff --git a/noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/src/main.nr b/noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/src/main.nr new file mode 100644 index 00000000000..2072d9cae87 --- /dev/null +++ b/noir/noir-repo/tooling/lsp/test_programs/rename_type_alias/src/main.nr @@ -0,0 +1,24 @@ +mod foo { + struct Foo { + } + + type Bar = Foo; + + mod bar { + struct Baz { + + } + } +} + +use foo::Foo; +use foo::Bar; +use foo::bar; + +fn main() { + let x: Bar = Foo {}; +} + +fn x(b: Bar) -> Bar { + b +} diff --git a/noir/noir-repo/tooling/nargo_cli/build.rs b/noir/noir-repo/tooling/nargo_cli/build.rs index faac228cb63..3789595aa26 100644 --- a/noir/noir-repo/tooling/nargo_cli/build.rs +++ b/noir/noir-repo/tooling/nargo_cli/build.rs @@ -61,7 +61,7 @@ const IGNORED_BRILLIG_TESTS: [&str; 11] = [ /// Certain features are only available in the elaborator. /// We skip these tests for non-elaborator code since they are not /// expected to work there. This can be removed once the old code is removed. -const IGNORED_NEW_FEATURE_TESTS: [&str; 7] = [ +const IGNORED_NEW_FEATURE_TESTS: [&str; 8] = [ "macros", "wildcard_type", "type_definition_annotation", @@ -69,6 +69,7 @@ const IGNORED_NEW_FEATURE_TESTS: [&str; 7] = [ "derive_impl", "comptime_traits", "comptime_slice_methods", + "unquote_multiple_items_from_annotation", ]; fn read_test_cases( diff --git a/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json b/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json index 3ce97f89ec2..b0c9e85315a 100644 --- a/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json +++ b/noir/noir-repo/tooling/noir_js_backend_barretenberg/package.json @@ -41,7 +41,7 @@ "lint": "NODE_NO_WARNINGS=1 eslint . --ext .ts --ignore-path ./.eslintignore --max-warnings 0" }, "dependencies": { - "@aztec/bb.js": "portal:../../../../barretenberg/ts", + "@aztec/bb.js": "0.43.0", "@noir-lang/types": "workspace:*", "fflate": "^0.8.0" }, diff --git a/noir/noir-repo/tooling/noir_js_backend_barretenberg/src/backend.ts b/noir/noir-repo/tooling/noir_js_backend_barretenberg/src/backend.ts index 96c4d13aa61..8ede6a07b50 100644 --- a/noir/noir-repo/tooling/noir_js_backend_barretenberg/src/backend.ts +++ b/noir/noir-repo/tooling/noir_js_backend_barretenberg/src/backend.ts @@ -10,7 +10,7 @@ import { type Barretenberg } from '@aztec/bb.js'; // minus the public inputs. const numBytesInProofWithoutPublicInputs: number = 2144; -export class BarretenbergVerifierBackend implements VerifierBackend { +export class BarretenbergBackend implements Backend, VerifierBackend { // These type assertions are used so that we don't // have to initialize `api` and `acirComposer` in the constructor. // These are initialized asynchronously in the `init` function, @@ -60,29 +60,6 @@ export class BarretenbergVerifierBackend implements VerifierBackend { } } - /** @description Verifies a proof */ - async verifyProof(proofData: ProofData): Promise { - const proof = reconstructProofWithPublicInputs(proofData); - await this.instantiate(); - await this.api.acirInitVerificationKey(this.acirComposer); - return await this.api.acirVerifyProof(this.acirComposer, proof); - } - - async getVerificationKey(): Promise { - await this.instantiate(); - await this.api.acirInitVerificationKey(this.acirComposer); - return await this.api.acirGetVerificationKey(this.acirComposer); - } - - async destroy(): Promise { - if (!this.api) { - return; - } - await this.api.destroy(); - } -} - -export class BarretenbergBackend extends BarretenbergVerifierBackend implements Backend { /** @description Generates a proof */ async generateProof(compressedWitness: Uint8Array): Promise { await this.instantiate(); @@ -144,4 +121,25 @@ export class BarretenbergBackend extends BarretenbergVerifierBackend implements vkHash: vk[1].toString(), }; } + + /** @description Verifies a proof */ + async verifyProof(proofData: ProofData): Promise { + const proof = reconstructProofWithPublicInputs(proofData); + await this.instantiate(); + await this.api.acirInitVerificationKey(this.acirComposer); + return await this.api.acirVerifyProof(this.acirComposer, proof); + } + + async getVerificationKey(): Promise { + await this.instantiate(); + await this.api.acirInitVerificationKey(this.acirComposer); + return await this.api.acirGetVerificationKey(this.acirComposer); + } + + async destroy(): Promise { + if (!this.api) { + return; + } + await this.api.destroy(); + } } diff --git a/noir/noir-repo/tooling/noirc_abi_wasm/build.sh b/noir/noir-repo/tooling/noirc_abi_wasm/build.sh index c07d2d8a4c1..16fb26e55db 100755 --- a/noir/noir-repo/tooling/noirc_abi_wasm/build.sh +++ b/noir/noir-repo/tooling/noirc_abi_wasm/build.sh @@ -25,7 +25,7 @@ function run_if_available { require_command jq require_command cargo require_command wasm-bindgen -#require_command wasm-opt +require_command wasm-opt self_path=$(dirname "$(readlink -f "$0")") pname=$(cargo read-manifest | jq -r '.name') diff --git a/noir/noir-repo/yarn.lock b/noir/noir-repo/yarn.lock index 181b6b3b206..73dfbf6e82e 100644 --- a/noir/noir-repo/yarn.lock +++ b/noir/noir-repo/yarn.lock @@ -221,18 +221,19 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@portal:../../../../barretenberg/ts::locator=%40noir-lang%2Fbackend_barretenberg%40workspace%3Atooling%2Fnoir_js_backend_barretenberg": - version: 0.0.0-use.local - resolution: "@aztec/bb.js@portal:../../../../barretenberg/ts::locator=%40noir-lang%2Fbackend_barretenberg%40workspace%3Atooling%2Fnoir_js_backend_barretenberg" +"@aztec/bb.js@npm:0.43.0": + version: 0.43.0 + resolution: "@aztec/bb.js@npm:0.43.0" dependencies: comlink: ^4.4.1 commander: ^10.0.1 debug: ^4.3.4 tslib: ^2.4.0 bin: - bb.js: ./dest/node/main.js + bb.js: dest/node/main.js + checksum: 63d2617529e00a05e1ac9364639dc10761e50cb6a16e010ac6354011440de037112a82d7cdd29a65b139af528c7d865b047e157b25d15ac36ff701863d550a5b languageName: node - linkType: soft + linkType: hard "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.11, @babel/code-frame@npm:^7.16.0, @babel/code-frame@npm:^7.22.13, @babel/code-frame@npm:^7.23.5, @babel/code-frame@npm:^7.8.3": version: 7.23.5 @@ -4395,7 +4396,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: - "@aztec/bb.js": "portal:../../../../barretenberg/ts" + "@aztec/bb.js": 0.43.0 "@noir-lang/types": "workspace:*" "@types/node": ^20.6.2 "@types/prettier": ^3