From 70e35b9046252ec761a74b078724070ef25c3e68 Mon Sep 17 00:00:00 2001 From: kevaundray Date: Thu, 7 Sep 2023 18:17:41 +0100 Subject: [PATCH 1/4] chore(noir): Release 0.11.1 (#2594) --- .release-please-manifest.json | 2 +- CHANGELOG.md | 12 ++++++++++++ Cargo.lock | 30 +++++++++++++++--------------- Cargo.toml | 2 +- crates/wasm/package.json | 2 +- flake.nix | 2 +- 6 files changed, 31 insertions(+), 19 deletions(-) diff --git a/.release-please-manifest.json b/.release-please-manifest.json index 78e7f271d7f..ddfa3e36c2e 100644 --- a/.release-please-manifest.json +++ b/.release-please-manifest.json @@ -1,3 +1,3 @@ { - ".": "0.11.0" + ".": "0.11.1" } diff --git a/CHANGELOG.md b/CHANGELOG.md index e8f0d9b20a3..7dc8c64779d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Changelog +## [0.11.1](https://github.com/noir-lang/noir/compare/v0.11.0...v0.11.1) (2023-09-07) + + +### Features + +* Enable dynamic indices on slices ([#2446](https://github.com/noir-lang/noir/issues/2446)) ([c5c4052](https://github.com/noir-lang/noir/commit/c5c40529d8c000ba61f3372b336e57947673646a)) + + +### Bug Fixes + +* Disable loop unrolling in brillig ([#2590](https://github.com/noir-lang/noir/issues/2590)) ([464f878](https://github.com/noir-lang/noir/commit/464f87834ada04320ea396cb4bdbab3317e036db)) + ## [0.11.0](https://github.com/noir-lang/noir/compare/v0.10.5...v0.11.0) (2023-09-07) diff --git a/Cargo.lock b/Cargo.lock index cbfb3ecffe5..736f3159151 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -217,7 +217,7 @@ dependencies = [ [[package]] name = "arena" -version = "0.11.0" +version = "0.11.1" dependencies = [ "generational-arena", ] @@ -1437,7 +1437,7 @@ dependencies = [ [[package]] name = "fm" -version = "0.11.0" +version = "0.11.1" dependencies = [ "cfg-if", "codespan-reporting", @@ -1988,7 +1988,7 @@ dependencies = [ [[package]] name = "iter-extended" -version = "0.11.0" +version = "0.11.1" [[package]] name = "itertools" @@ -2183,7 +2183,7 @@ checksum = "7843ec2de400bcbc6a6328c958dc38e5359da6e93e72e37bc5246bf1ae776389" [[package]] name = "nargo" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "base64", @@ -2201,7 +2201,7 @@ dependencies = [ [[package]] name = "nargo_cli" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "acvm-backend-barretenberg", @@ -2244,7 +2244,7 @@ dependencies = [ [[package]] name = "nargo_toml" -version = "0.11.0" +version = "0.11.1" dependencies = [ "dirs", "fm", @@ -2270,7 +2270,7 @@ dependencies = [ [[package]] name = "noir_lsp" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "async-lsp", @@ -2291,7 +2291,7 @@ dependencies = [ [[package]] name = "noir_wasm" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "build-data", @@ -2309,7 +2309,7 @@ dependencies = [ [[package]] name = "noirc_abi" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "iter-extended", @@ -2326,7 +2326,7 @@ dependencies = [ [[package]] name = "noirc_abi_wasm" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "build-data", @@ -2343,7 +2343,7 @@ dependencies = [ [[package]] name = "noirc_driver" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "base64", @@ -2358,7 +2358,7 @@ dependencies = [ [[package]] name = "noirc_errors" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "chumsky", @@ -2371,7 +2371,7 @@ dependencies = [ [[package]] name = "noirc_evaluator" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "fxhash", @@ -2386,7 +2386,7 @@ dependencies = [ [[package]] name = "noirc_frontend" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "arena", @@ -2407,7 +2407,7 @@ dependencies = [ [[package]] name = "noirc_printable_type" -version = "0.11.0" +version = "0.11.1" dependencies = [ "acvm", "iter-extended", diff --git a/Cargo.toml b/Cargo.toml index cf6a8df4a8b..a34473880dd 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -22,7 +22,7 @@ resolver = "2" [workspace.package] # x-release-please-start-version -version = "0.11.0" +version = "0.11.1" # x-release-please-end authors = ["The Noir Team "] edition = "2021" diff --git a/crates/wasm/package.json b/crates/wasm/package.json index 62e442b541b..05fffcabac8 100644 --- a/crates/wasm/package.json +++ b/crates/wasm/package.json @@ -3,7 +3,7 @@ "collaborators": [ "The Noir Team " ], - "version": "0.11.0", + "version": "0.11.1", "license": "(MIT OR Apache-2.0)", "main": "./nodejs/noir_wasm.js", "types": "./web/noir_wasm.d.ts", diff --git a/flake.nix b/flake.nix index 985af5d3e43..c04229fa173 100644 --- a/flake.nix +++ b/flake.nix @@ -134,7 +134,7 @@ sharedArgs = { # x-release-please-start-version - version = "0.11.0"; + version = "0.11.1"; # x-release-please-end src = pkgs.lib.cleanSourceWith { From 3c731b11b31b8556eeebc4fe59b68609aa96c463 Mon Sep 17 00:00:00 2001 From: jfecher Date: Thu, 7 Sep 2023 12:21:17 -0500 Subject: [PATCH 2/4] fix: Implement auto-dereferencing when calling methods (#2581) Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> --- .../execution_success/references/src/main.nr | 13 ++++++++ .../noirc_frontend/src/hir/type_check/expr.rs | 31 +++++++++++++++++-- 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/crates/nargo_cli/tests/execution_success/references/src/main.nr b/crates/nargo_cli/tests/execution_success/references/src/main.nr index 70de5cada3f..be02f2b10d6 100644 --- a/crates/nargo_cli/tests/execution_success/references/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/references/src/main.nr @@ -41,6 +41,8 @@ fn main(mut x: Field) { regression_2218_if_inner_else(20, x); regression_2218_else(x, 3); regression_2218_loop(x, 10); + + regression_2560(s_ref); } fn add1(x: &mut Field) { @@ -64,6 +66,10 @@ impl S { fn add2(&mut self) { self.y += 2; } + + fn get_y(self) -> Field { + self.y + } } fn mutate_copy(mut a: Field) { @@ -230,3 +236,10 @@ fn regression_2218_loop(x: Field, y: Field) { } assert(*q1 == 2); } + +// This is more a feature test than a proper regression. +// Before, we never automatically dereferenced objects in method calls to their value types. +// Now, we insert as many `*` as necessary to get to `S`. +fn regression_2560(s_ref: &mut S) { + assert(s_ref.get_y() == 7); +} diff --git a/crates/noirc_frontend/src/hir/type_check/expr.rs b/crates/noirc_frontend/src/hir/type_check/expr.rs index a150f198281..e4e632835a1 100644 --- a/crates/noirc_frontend/src/hir/type_check/expr.rs +++ b/crates/noirc_frontend/src/hir/type_check/expr.rs @@ -319,9 +319,9 @@ impl<'interner> TypeChecker<'interner> { }; if let Some(expected_object_type) = expected_object_type { - if matches!(expected_object_type.follow_bindings(), Type::MutableReference(_)) { - let actual_type = argument_types[0].0.follow_bindings(); + let actual_type = argument_types[0].0.follow_bindings(); + if matches!(expected_object_type.follow_bindings(), Type::MutableReference(_)) { if !matches!(actual_type, Type::MutableReference(_)) { if let Err(error) = verify_mutable_reference(self.interner, method_call.object) { @@ -350,10 +350,37 @@ impl<'interner> TypeChecker<'interner> { ); } } + // Otherwise if the object type is a mutable reference and the method is not, insert as + // many dereferences as needed. + } else if matches!(actual_type, Type::MutableReference(_)) { + let (object, new_type) = + self.insert_auto_dereferences(method_call.object, actual_type); + method_call.object = object; + argument_types[0].0 = new_type; } } } + /// Insert as many dereference operations as necessary to automatically dereference a method + /// call object to its base value type T. + fn insert_auto_dereferences(&mut self, object: ExprId, typ: Type) -> (ExprId, Type) { + if let Type::MutableReference(element) = typ { + let location = self.interner.id_location(object); + + let object = self.interner.push_expr(HirExpression::Prefix(HirPrefixExpression { + operator: UnaryOp::Dereference { implicitly_added: true }, + rhs: object, + })); + self.interner.push_expr_type(&object, element.as_ref().clone()); + self.interner.push_expr_location(object, location.span, location.file); + + // Recursively dereference to allow for converting &mut &mut T to T + self.insert_auto_dereferences(object, *element) + } else { + (object, typ) + } + } + /// Given a method object: `(*foo).bar` of a method call `(*foo).bar.baz()`, remove the /// implicitly added dereference operator if one is found. /// From ed7ad6e78faa04778e3f65bcdd05e325976457f7 Mon Sep 17 00:00:00 2001 From: Tom French <15848336+TomAFrench@users.noreply.github.com> Date: Thu, 7 Sep 2023 18:25:08 +0100 Subject: [PATCH 3/4] chore: remove usage of `serial_test` dependency (#2598) --- Cargo.lock | 38 ------------------- crates/acvm_backend_barretenberg/Cargo.toml | 1 - .../src/cli/contract.rs | 1 - .../src/cli/gates.rs | 1 - .../acvm_backend_barretenberg/src/cli/info.rs | 1 - .../acvm_backend_barretenberg/src/cli/mod.rs | 1 - .../src/cli/prove.rs | 1 - .../src/cli/verify.rs | 1 - .../src/cli/write_vk.rs | 1 - .../src/smart_contract.rs | 1 - 10 files changed, 47 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 736f3159151..7a1611e0a1c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -58,7 +58,6 @@ dependencies = [ "reqwest", "serde", "serde_json", - "serial_test", "tar", "tempfile", "test-binary", @@ -1483,7 +1482,6 @@ checksum = "23342abe12aba583913b2e62f22225ff9c950774065e4bfb61a19cd9770fec40" dependencies = [ "futures-channel", "futures-core", - "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -1506,17 +1504,6 @@ version = "0.3.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4bca583b7e26f571124fe5b7561d49cb2868d79116cfa0eefce955557c6fee8c" -[[package]] -name = "futures-executor" -version = "0.3.28" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ccecee823288125bd88b4d7f565c9e58e41858e47ab72e8ea2d64e93624386e0" -dependencies = [ - "futures-core", - "futures-task", - "futures-util", -] - [[package]] name = "futures-io" version = "0.3.28" @@ -3415,31 +3402,6 @@ dependencies = [ "syn 2.0.26", ] -[[package]] -name = "serial_test" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0e56dd856803e253c8f298af3f4d7eb0ae5e23a737252cd90bb4f3b435033b2d" -dependencies = [ - "dashmap", - "futures", - "lazy_static", - "log", - "parking_lot", - "serial_test_derive", -] - -[[package]] -name = "serial_test_derive" -version = "2.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91d129178576168c589c9ec973feedf7d3126c01ac2bf08795109aa35b69fb8f" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.26", -] - [[package]] name = "sha2" version = "0.10.7" diff --git a/crates/acvm_backend_barretenberg/Cargo.toml b/crates/acvm_backend_barretenberg/Cargo.toml index 8bc32129ce5..847b8a224d8 100644 --- a/crates/acvm_backend_barretenberg/Cargo.toml +++ b/crates/acvm_backend_barretenberg/Cargo.toml @@ -27,7 +27,6 @@ reqwest = { version = "0.11.16", default-features = false, features = [ ] } [dev-dependencies] -serial_test = "2.0.0" test-binary = "3.0.1" [build-dependencies] diff --git a/crates/acvm_backend_barretenberg/src/cli/contract.rs b/crates/acvm_backend_barretenberg/src/cli/contract.rs index 63b32da506d..103b5ce0d60 100644 --- a/crates/acvm_backend_barretenberg/src/cli/contract.rs +++ b/crates/acvm_backend_barretenberg/src/cli/contract.rs @@ -38,7 +38,6 @@ impl ContractCommand { } #[test] -#[serial_test::serial] fn contract_command() { use tempfile::tempdir; diff --git a/crates/acvm_backend_barretenberg/src/cli/gates.rs b/crates/acvm_backend_barretenberg/src/cli/gates.rs index 46ff3c6f80c..5b99a245371 100644 --- a/crates/acvm_backend_barretenberg/src/cli/gates.rs +++ b/crates/acvm_backend_barretenberg/src/cli/gates.rs @@ -52,7 +52,6 @@ impl GatesCommand { } #[test] -#[serial_test::serial] fn gate_command() { use tempfile::tempdir; diff --git a/crates/acvm_backend_barretenberg/src/cli/info.rs b/crates/acvm_backend_barretenberg/src/cli/info.rs index a39122567d9..d8cc13fb9ca 100644 --- a/crates/acvm_backend_barretenberg/src/cli/info.rs +++ b/crates/acvm_backend_barretenberg/src/cli/info.rs @@ -71,7 +71,6 @@ impl InfoCommand { } #[test] -#[serial_test::serial] fn info_command() { use acvm::acir::circuit::black_box_functions::BlackBoxFunc; use acvm::acir::circuit::opcodes::{BlackBoxFuncCall, Opcode}; diff --git a/crates/acvm_backend_barretenberg/src/cli/mod.rs b/crates/acvm_backend_barretenberg/src/cli/mod.rs index f34738acb62..594cc51925f 100644 --- a/crates/acvm_backend_barretenberg/src/cli/mod.rs +++ b/crates/acvm_backend_barretenberg/src/cli/mod.rs @@ -15,7 +15,6 @@ pub(crate) use verify::VerifyCommand; pub(crate) use write_vk::WriteVkCommand; #[test] -#[serial_test::serial] fn no_command_provided_works() { // This is a simple test to check that the binaries work diff --git a/crates/acvm_backend_barretenberg/src/cli/prove.rs b/crates/acvm_backend_barretenberg/src/cli/prove.rs index 602cb0f88a8..f3519d60abe 100644 --- a/crates/acvm_backend_barretenberg/src/cli/prove.rs +++ b/crates/acvm_backend_barretenberg/src/cli/prove.rs @@ -46,7 +46,6 @@ impl ProveCommand { } #[test] -#[serial_test::serial] fn prove_command() { use tempfile::tempdir; diff --git a/crates/acvm_backend_barretenberg/src/cli/verify.rs b/crates/acvm_backend_barretenberg/src/cli/verify.rs index 9b497bf7f8b..eaf31b6016c 100644 --- a/crates/acvm_backend_barretenberg/src/cli/verify.rs +++ b/crates/acvm_backend_barretenberg/src/cli/verify.rs @@ -34,7 +34,6 @@ impl VerifyCommand { } #[test] -#[serial_test::serial] fn verify_command() { use tempfile::tempdir; diff --git a/crates/acvm_backend_barretenberg/src/cli/write_vk.rs b/crates/acvm_backend_barretenberg/src/cli/write_vk.rs index ae8e2ecd747..77904a0a1fd 100644 --- a/crates/acvm_backend_barretenberg/src/cli/write_vk.rs +++ b/crates/acvm_backend_barretenberg/src/cli/write_vk.rs @@ -38,7 +38,6 @@ impl WriteVkCommand { } #[test] -#[serial_test::serial] fn write_vk_command() { use tempfile::tempdir; diff --git a/crates/acvm_backend_barretenberg/src/smart_contract.rs b/crates/acvm_backend_barretenberg/src/smart_contract.rs index f848d6cab9d..468be1cd8da 100644 --- a/crates/acvm_backend_barretenberg/src/smart_contract.rs +++ b/crates/acvm_backend_barretenberg/src/smart_contract.rs @@ -61,7 +61,6 @@ mod tests { use crate::get_mock_backend; #[test] - #[serial_test::serial] fn test_smart_contract() { let expression = &(Witness(1) + Witness(2)) - &Expression::from(Witness(3)); let constraint = Opcode::Arithmetic(expression); From 6110638ec743616b9a3f38650838dda631a25efd Mon Sep 17 00:00:00 2001 From: Maxim Vezenov Date: Thu, 7 Sep 2023 19:12:16 +0100 Subject: [PATCH 4/4] fix(ssa): Slice mergers with multiple ifs (#2597) --- .../slice_dynamic_index/src/main.nr | 30 ++++++++++ .../execution_success/slices/src/main.nr | 56 ++++++++++++++++++- .../noirc_evaluator/src/ssa/ir/instruction.rs | 2 +- .../src/ssa/ir/instruction/call.rs | 12 +++- .../src/ssa/opt/flatten_cfg.rs | 27 +++++---- 5 files changed, 110 insertions(+), 17 deletions(-) diff --git a/crates/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr b/crates/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr index 48229a0ced3..de5b4caef29 100644 --- a/crates/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/slice_dynamic_index/src/main.nr @@ -20,6 +20,7 @@ fn regression_dynamic_slice_index(x: Field, y: Field) { dynamic_slice_merge_if(slice, x); dynamic_slice_merge_else(slice, x); + dynamic_slice_merge_two_ifs(slice, x); } fn dynamic_slice_index_set_if(mut slice: [Field], x: Field, y: Field) { @@ -164,6 +165,35 @@ fn dynamic_slice_merge_else(mut slice: [Field], x: Field) { assert(slice[slice.len() - 1] == 20); } +fn dynamic_slice_merge_two_ifs(mut slice: [Field], x: Field) { + if x as u32 > 10 { + assert(slice[x] == 0); + slice[x] = 2; + } else { + assert(slice[x] == 4); + slice[x] = slice[x] - 2; + slice = slice.push_back(10); + } + + assert(slice.len() == 6); + assert(slice[slice.len() - 1] == 10); + + if x == 20 { + slice = slice.push_back(20); + } else { + slice = slice.push_back(15); + } + // TODO(#2599): Breaks if the push back happens without the else case + // slice = slice.push_back(15); + + assert(slice.len() == 7); + assert(slice[slice.len() - 1] == 15); + + slice = slice.push_back(20); + assert(slice.len() == 8); + assert(slice[slice.len() - 1] == 20); +} + fn dynamic_slice_index_set_nested_if_else_else(mut slice: [Field], x: Field, y: Field) { assert(slice[x] == 4); assert(slice[y] == 1); diff --git a/crates/nargo_cli/tests/execution_success/slices/src/main.nr b/crates/nargo_cli/tests/execution_success/slices/src/main.nr index 26cf173a253..8fbe14bfea3 100644 --- a/crates/nargo_cli/tests/execution_success/slices/src/main.nr +++ b/crates/nargo_cli/tests/execution_success/slices/src/main.nr @@ -102,6 +102,18 @@ fn merge_slices_if(x: Field, y: Field) { let slice = merge_slices_mutate_in_loop(x, y); assert(slice[6] == 4); assert(slice.len() == 7); + + let slice = merge_slices_mutate_two_ifs(x, y); + assert(slice.len() == 6); + assert(slice[3] == 5); + assert(slice[4] == 15); + assert(slice[5] == 30); + + let slice = merge_slices_mutate_between_ifs(x, y); + assert(slice.len() == 6); + assert(slice[3] == 5); + assert(slice[4] == 30); + assert(slice[5] == 15); } fn merge_slices_else(x: Field) { @@ -156,4 +168,46 @@ fn merge_slices_mutate_in_loop(x: Field, y: Field) -> [Field] { slice = slice.push_back(x); } slice -} \ No newline at end of file +} + +fn merge_slices_mutate_two_ifs(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + slice = slice.push_back(y); + slice = slice.push_back(x); + } else { + slice = slice.push_back(x); + } + if x == 20 { + slice = slice.push_back(20); + } else { + slice = slice.push_back(15); + } + // TODO(#2599): Breaks if the push back happens without the else case + // slice = slice.push_back(15); + slice = slice.push_back(30); + + slice +} + +fn merge_slices_mutate_between_ifs(x: Field, y: Field) -> [Field] { + let mut slice = [0; 2]; + if x != y { + slice = slice.push_back(y); + slice = slice.push_back(x); + } else { + slice = slice.push_back(x); + } + + slice = slice.push_back(30); + + if x == 20 { + slice = slice.push_back(20); + } else { + slice = slice.push_back(15); + } + // TODO(#2599): Breaks if the push back happens without the else case + // slice = slice.push_back(15); + + slice +} diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction.rs b/crates/noirc_evaluator/src/ssa/ir/instruction.rs index feca2f56046..1dd2368b1a0 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction.rs @@ -171,7 +171,7 @@ pub(crate) enum Instruction { /// Creates a new array with the new value at the given index. All other elements are identical /// to those in the given array. This will not modify the original array. /// - /// An optional length can be provided to enabling handling of dynamic slice indices + /// An optional length can be provided to enable handling of dynamic slice indices. ArraySet { array: ValueId, index: ValueId, value: ValueId, length: Option }, } diff --git a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs b/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs index dbc358c5f19..42d0aa0a4e4 100644 --- a/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs +++ b/crates/noirc_evaluator/src/ssa/ir/instruction/call.rs @@ -5,18 +5,19 @@ use iter_extended::vecmap; use num_bigint::BigUint; use crate::ssa::ir::{ + basic_block::BasicBlockId, dfg::DataFlowGraph, instruction::Intrinsic, map::Id, types::Type, - value::{Value, ValueId}, basic_block::BasicBlockId, + value::{Value, ValueId}, }; use super::{Binary, BinaryOp, Endian, Instruction, SimplifyResult}; /// Try to simplify this call instruction. If the instruction can be simplified to a known value, /// that value is returned. Otherwise None is returned. -/// +/// /// The `block` parameter indicates the block any new instructions that are part of a call's /// simplification will be inserted into. For example, all slice intrinsics require updates /// to the slice length, which requires inserting a binary instruction. This update instruction @@ -232,7 +233,12 @@ pub(super) fn simplify_call( /// The binary operation performed on the slice length is always an addition or subtraction of `1`. /// This is because the slice length holds the user length (length as displayed by a `.len()` call), /// and not a flattened length used internally to represent arrays of tuples. -fn update_slice_length(slice_len: ValueId, dfg: &mut DataFlowGraph, operator: BinaryOp, block: BasicBlockId) -> ValueId { +fn update_slice_length( + slice_len: ValueId, + dfg: &mut DataFlowGraph, + operator: BinaryOp, + block: BasicBlockId, +) -> ValueId { let one = dfg.make_constant(FieldElement::one(), Type::field()); let instruction = Instruction::Binary(Binary { lhs: slice_len, operator, rhs: one }); let call_stack = dfg.get_value_call_stack(slice_len); diff --git a/crates/noirc_evaluator/src/ssa/opt/flatten_cfg.rs b/crates/noirc_evaluator/src/ssa/opt/flatten_cfg.rs index 2b9991844c8..d57c2cc7933 100644 --- a/crates/noirc_evaluator/src/ssa/opt/flatten_cfg.rs +++ b/crates/noirc_evaluator/src/ssa/opt/flatten_cfg.rs @@ -489,33 +489,36 @@ impl<'f> Context<'f> { let value = &self.inserter.function.dfg[value_id]; match value { Value::Array { array, .. } => array.len(), - Value::NumericConstant { constant, .. } => constant.to_u128() as usize, Value::Instruction { instruction: instruction_id, .. } => { let instruction = &self.inserter.function.dfg[*instruction_id]; match instruction { - Instruction::ArraySet { length, .. } => { - let length = length.expect("ICE: array set on a slice must have a length"); - self.get_slice_length(length) - } + Instruction::ArraySet { array, .. } => self.get_slice_length(*array), Instruction::Load { address } => { - let context_store = self - .outer_block_stores - .get(address) - .expect("ICE: load in merger should have store from outer block"); + let context_store = if let Some(store) = self.store_values.get(address) { + store + } else { + self.outer_block_stores + .get(address) + .expect("ICE: load in merger should have store from outer block") + }; self.get_slice_length(context_store.new_value) } Instruction::Call { func, arguments } => { let func = &self.inserter.function.dfg[*func]; - let length = arguments[0]; + let slice_contents = arguments[1]; match func { Value::Intrinsic(intrinsic) => match intrinsic { Intrinsic::SlicePushBack | Intrinsic::SlicePushFront - | Intrinsic::SliceInsert => self.get_slice_length(length) + 1, + | Intrinsic::SliceInsert => { + self.get_slice_length(slice_contents) + 1 + } Intrinsic::SlicePopBack | Intrinsic::SlicePopFront - | Intrinsic::SliceRemove => self.get_slice_length(length) - 1, + | Intrinsic::SliceRemove => { + self.get_slice_length(slice_contents) - 1 + } _ => { unreachable!("ICE: Intrinsic not supported, got {intrinsic:?}") }