From 1ae794c505a46a6c1b8b864a762c88c3e653564b Mon Sep 17 00:00:00 2001 From: AztecBot Date: Thu, 5 Sep 2024 08:02:02 +0000 Subject: [PATCH 1/2] [1 changes] feat: warn on unused functions (https://github.com/noir-lang/noir/pull/5892) feat: add `fmtstr::contents` (https://github.com/noir-lang/noir/pull/5928) fix: collect functions generated by attributes (https://github.com/noir-lang/noir/pull/5930) fix: Support debug comptime flag for attributes (https://github.com/noir-lang/noir/pull/5929) feat: Allow inserting new structs and into programs from attributes (https://github.com/noir-lang/noir/pull/5927) feat: module attributes (https://github.com/noir-lang/noir/pull/5888) feat: unquote some value as tokens, not as unquote markers (https://github.com/noir-lang/noir/pull/5924) feat: check argument count and types on attribute function callback (https://github.com/noir-lang/noir/pull/5921) feat: LSP will now suggest private items if they are visible (https://github.com/noir-lang/noir/pull/5923) --- .noir-sync-commit | 2 +- noir/noir-repo/.github/workflows/release.yml | 8 +- noir/noir-repo/Cargo.lock | 189 +++--- noir/noir-repo/acvm-repo/acvm_js/build.sh | 2 +- .../aztec_macros/src/utils/ast_utils.rs | 4 +- .../aztec_macros/src/utils/parse_utils.rs | 1 + .../compiler/noirc_driver/src/lib.rs | 10 +- .../compiler/noirc_errors/src/position.rs | 4 + .../src/brillig/brillig_gen/brillig_block.rs | 44 +- .../compiler/noirc_evaluator/src/errors.rs | 2 +- .../compiler/noirc_evaluator/src/ssa.rs | 4 +- .../noirc_evaluator/src/ssa/acir_gen/mod.rs | 10 +- .../check_for_underconstrained_values.rs | 2 +- .../noirc_evaluator/src/ssa/ir/function.rs | 7 + .../noirc_evaluator/src/ssa/ir/map.rs | 10 +- .../noirc_evaluator/src/ssa/opt/inlining.rs | 13 +- .../noirc_evaluator/src/ssa/opt/mem2reg.rs | 32 +- .../noirc_evaluator/src/ssa/opt/mod.rs | 1 + .../src/ssa/opt/normalize_value_ids.rs | 194 ++++++ .../noirc_frontend/src/ast/statement.rs | 1 + .../noirc_frontend/src/ast/visitor.rs | 13 +- .../noirc_frontend/src/elaborator/comptime.rs | 195 ++++-- .../noirc_frontend/src/elaborator/mod.rs | 10 +- .../noirc_frontend/src/elaborator/types.rs | 8 +- .../noirc_frontend/src/hir/comptime/errors.rs | 2 +- .../src/hir/comptime/interpreter.rs | 30 +- .../src/hir/comptime/interpreter/builtin.rs | 88 ++- .../interpreter/builtin/builtin_helpers.rs | 27 + .../noirc_frontend/src/hir/comptime/tests.rs | 8 +- .../noirc_frontend/src/hir/comptime/value.rs | 101 ++- .../src/hir/def_collector/dc_crate.rs | 58 +- .../src/hir/def_collector/dc_mod.rs | 538 ++++++++++------ .../noirc_frontend/src/hir/def_map/mod.rs | 8 +- .../src/hir/def_map/module_data.rs | 20 +- .../compiler/noirc_frontend/src/hir/mod.rs | 4 +- .../src/hir/resolution/errors.rs | 16 +- .../noirc_frontend/src/hir_def/function.rs | 3 +- .../noirc_frontend/src/hir_def/types.rs | 18 +- .../noirc_frontend/src/lexer/errors.rs | 8 + .../noirc_frontend/src/lexer/lexer.rs | 57 +- .../noirc_frontend/src/lexer/token.rs | 45 +- .../noirc_frontend/src/node_interner.rs | 2 +- .../compiler/noirc_frontend/src/parser/mod.rs | 12 +- .../noirc_frontend/src/parser/parser.rs | 56 +- .../src/parser/parser/attributes.rs | 9 + .../compiler/noirc_frontend/src/tests.rs | 133 +++- .../noirc_frontend/src/usage_tracker.rs | 52 +- .../docs/docs/noir/concepts/comptime.md | 2 +- .../docs/docs/noir/standard_library/fmtstr.md | 13 + .../docs/noir/standard_library/meta/module.md | 6 + .../noir_stdlib/src/meta/format_string.nr | 6 + noir/noir-repo/noir_stdlib/src/meta/mod.nr | 1 + noir/noir-repo/noir_stdlib/src/meta/module.nr | 5 + .../comptime_fmt_strings/src/main.nr | 14 + .../comptime_module/src/main.nr | 45 ++ .../comptime_module/src/separate_module.nr | 5 + .../unquote_function/Nargo.toml | 7 + .../unquote_function/src/main.nr | 12 + .../unquote_struct}/Nargo.toml | 3 +- .../unquote_struct/src/main.nr | 30 + .../verify_honk_proof/Prover.toml | 575 ------------------ .../verify_honk_proof/src/main.nr | 17 - noir/noir-repo/tooling/lsp/src/lib.rs | 11 +- noir/noir-repo/tooling/lsp/src/modules.rs | 5 +- .../tooling/lsp/src/notifications/mod.rs | 207 ++++--- .../tooling/lsp/src/requests/code_action.rs | 136 +---- .../code_action/fill_struct_fields.rs | 307 ++++++++++ .../requests/code_action/import_or_qualify.rs | 241 ++++++++ .../lsp/src/requests/code_action/tests.rs | 150 +---- .../tooling/lsp/src/requests/completion.rs | 22 +- .../src/requests/completion/auto_import.rs | 1 + .../lsp/src/requests/completion/tests.rs | 27 +- .../noir-repo/tooling/lsp/src/requests/mod.rs | 10 +- noir/noir-repo/tooling/lsp/src/visibility.rs | 28 +- .../tooling/nargo_cli/src/cli/lsp_cmd.rs | 2 - .../tooling/nargo_fmt/src/visitor/item.rs | 8 +- .../nargo_fmt/tests/expected/module.nr | 12 + .../tooling/nargo_fmt/tests/input/module.nr | 12 + .../noir_js_backend_barretenberg/package.json | 2 +- .../noir-repo/tooling/noirc_abi_wasm/build.sh | 2 +- noir/noir-repo/yarn.lock | 13 +- 81 files changed, 2470 insertions(+), 1528 deletions(-) create mode 100644 noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs create mode 100644 noir/noir-repo/docs/docs/noir/standard_library/fmtstr.md create mode 100644 noir/noir-repo/noir_stdlib/src/meta/format_string.nr create mode 100644 noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/separate_module.nr create mode 100644 noir/noir-repo/test_programs/compile_success_empty/unquote_function/Nargo.toml create mode 100644 noir/noir-repo/test_programs/compile_success_empty/unquote_function/src/main.nr rename noir/noir-repo/test_programs/{execution_success/verify_honk_proof => compile_success_empty/unquote_struct}/Nargo.toml (50%) create mode 100644 noir/noir-repo/test_programs/compile_success_empty/unquote_struct/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 create mode 100644 noir/noir-repo/tooling/lsp/src/requests/code_action/fill_struct_fields.rs create mode 100644 noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs diff --git a/.noir-sync-commit b/.noir-sync-commit index c253290bf18..24dd3f52fa7 100644 --- a/.noir-sync-commit +++ b/.noir-sync-commit @@ -1 +1 @@ -45344bfe1148a2f592c2e432744d3fb3d46340cc +af3db4bf2e8f7feba6d06c3095d7cdf17c8dde75 diff --git a/noir/noir-repo/.github/workflows/release.yml b/noir/noir-repo/.github/workflows/release.yml index d27fac0e039..5124592a3fe 100644 --- a/noir/noir-repo/.github/workflows/release.yml +++ b/noir/noir-repo/.github/workflows/release.yml @@ -54,8 +54,8 @@ jobs: - name: Configure git run: | - git config user.name kevaundray - git config user.email kevtheappdev@gmail.com + git config user.name noirwhal + git config user.email tomfrench@aztecprotocol.com - name: Commit updates run: | @@ -100,8 +100,8 @@ jobs: - name: Configure git run: | - git config --local user.name 'kevaundray' - git config --local user.email 'kevtheappdev@gmail.com' + git config --local user.name noirwhal + git config --local user.email tomfrench@aztecprotocol.com - name: Commit new documentation version run: | diff --git a/noir/noir-repo/Cargo.lock b/noir/noir-repo/Cargo.lock index cd936e4bca2..3f56f5b6965 100644 --- a/noir/noir-repo/Cargo.lock +++ b/noir/noir-repo/Cargo.lock @@ -7,7 +7,7 @@ name = "acir" version = "0.49.0" dependencies = [ "acir_field", - "base64 0.21.2", + "base64 0.21.7", "bincode", "brillig", "criterion", @@ -488,9 +488,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.2" +version = "0.21.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "604178f6c5c21f02dc555784810edfb88d34ac2c73b2eae109655649ee73ce3d" +checksum = "9d297deb1925b89f2ccc13d7635fa0714f12c87adce1c75356b39ca9b7178567" [[package]] name = "base64ct" @@ -665,7 +665,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6798148dccfbff0fae41c7574d2fa8f1ef3492fba0face179de5d8d447d67b05" dependencies = [ "memchr", - "regex-automata 0.3.3", + "regex-automata 0.3.9", "serde", ] @@ -771,9 +771,9 @@ checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" [[package]] name = "chrono" -version = "0.4.37" +version = "0.4.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a0d04d43504c61aa6c7531f1871dd0d418d91130162063b789da00fd7057a5e" +checksum = "a21f936df1771bf62b77f047b726c4625ff2e8aa607c01ec06e5a05bd8463401" dependencies = [ "android-tzdata", "iana-time-zone", @@ -781,7 +781,7 @@ dependencies = [ "num-traits", "serde", "wasm-bindgen", - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] @@ -1123,7 +1123,7 @@ dependencies = [ "autocfg", "cfg-if 1.0.0", "crossbeam-utils", - "memoffset 0.9.0", + "memoffset 0.9.1", "scopeguard", ] @@ -1454,12 +1454,12 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" [[package]] name = "errno" -version = "0.3.5" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3e13f66a2f95e32a39eaa81f6b95d42878ca0e1db0c7543723dfe12557e860" +checksum = "534c5cf6194dfab3db3242765c03bbe257cf92f22b38f6bc0c58d59108a820ba" dependencies = [ "libc", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -2428,7 +2428,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "507460a910eb7b32ee961886ff48539633b788a36b65692b95f225b844c82553" dependencies = [ - "regex-automata 0.4.5", + "regex-automata 0.4.7", ] [[package]] @@ -2471,9 +2471,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.3" +version = "0.4.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09fc20d2ca12cb9f044c93e3bd6d32d523e6e2ec3db4f7b2939cd99026ecd3f0" +checksum = "78b3ae25bc7c8c38cec158d1f2757ee79e9b3740fbc7ccf0e59e4b08d793fa89" [[package]] name = "lock_api" @@ -2567,9 +2567,9 @@ dependencies = [ [[package]] name = "memoffset" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a634b1c61a95585bd15607c6ab0c4e5b226e695ff2800ba0cdccddf208c406c" +checksum = "488016bfae457b036d996092f6cb448677611ce4449e970ceaf42695203f218a" dependencies = [ "autocfg", ] @@ -2582,9 +2582,9 @@ checksum = "2145869435ace5ea6ea3d35f59be559317ec9a0d04e1812d5f185a87b6d36f1a" [[package]] name = "miniz_oxide" -version = "0.7.1" +version = "0.7.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e7810e0be55b428ada41041c41f32c9f1a42817901b4ccf45fa3d4b6561e74c7" +checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" dependencies = [ "adler", ] @@ -2986,7 +2986,7 @@ name = "noirc_errors" version = "0.33.0" dependencies = [ "acvm", - "base64 0.21.2", + "base64 0.21.7", "chumsky", "codespan", "codespan-reporting", @@ -3027,7 +3027,7 @@ name = "noirc_frontend" version = "0.33.0" dependencies = [ "acvm", - "base64 0.21.2", + "base64 0.21.7", "bn254_blackbox_solver", "cfg-if 1.0.0", "chumsky", @@ -3272,7 +3272,7 @@ dependencies = [ "libc", "redox_syscall 0.3.5", "smallvec", - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -3743,9 +3743,9 @@ checksum = "977b1e897f9d764566891689e642653e5ed90c6895106acd005eb4c1d0203991" [[package]] name = "rayon" -version = "1.8.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9c27db03db7734835b3f53954b534c91069375ce6ccaa2e065441e07d9b6cdb1" +checksum = "b418a60154510ca1a002a752ca9714984e21e4241e804d32555251faf8b78ffa" dependencies = [ "either", "rayon-core", @@ -3753,9 +3753,9 @@ dependencies = [ [[package]] name = "rayon-core" -version = "1.12.0" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ce3fb6ad83f861aac485e76e1985cd109d9a3713802152be56c3b1f0e0658ed" +checksum = "1465873a3dfdaa8ae7cb14b4383657caab0b3e8a0aa9ae8e04b044854c8dfce2" dependencies = [ "crossbeam-deque", "crossbeam-utils", @@ -3813,7 +3813,7 @@ checksum = "b62dbe01f0b06f9d8dc7d49e05a0785f153b00b2c227856282f671e0318c9b15" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.5", + "regex-automata 0.4.7", "regex-syntax 0.8.2", ] @@ -3828,15 +3828,15 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.3.3" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "39354c10dd07468c2e73926b23bb9c2caca74c5501e38a35da70406f1d923310" +checksum = "59b23e92ee4318893fa3fe3e6fb365258efbfe6ac6ab30f090cdcbb7aa37efa9" [[package]] name = "regex-automata" -version = "0.4.5" +version = "0.4.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5bb987efffd3c6d0d8f5f89510bb458559eab11e4f869acb20bf845e016259cd" +checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" dependencies = [ "aho-corasick", "memchr", @@ -3945,15 +3945,15 @@ dependencies = [ [[package]] name = "rustix" -version = "0.38.4" +version = "0.38.34" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a962918ea88d644592894bc6dc55acc6c0956488adcebbfb6e273506b7fd6e5" +checksum = "70dc5ec042f7a43c4a73241207cecc9873a06d45debb38b329f8541d85c2730f" dependencies = [ "bitflags 2.5.0", "errno", "libc", "linux-raw-sys", - "windows-sys 0.48.0", + "windows-sys 0.52.0", ] [[package]] @@ -4113,9 +4113,9 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.202" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "226b61a0d411b2ba5ff6d7f73a476ac4f8bb900373459cd00fab8512828ba395" +checksum = "99fce0ffe7310761ca6bf9faf5115afbc19688edd00171d81b1bb1b116c63e09" dependencies = [ "serde_derive", ] @@ -4156,9 +4156,9 @@ dependencies = [ [[package]] name = "serde_derive" -version = "1.0.202" +version = "1.0.209" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6048858004bcff69094cd972ed40a32500f153bd3be9f716b2eed2e8217c4838" +checksum = "a5831b979fd7b5439637af1752d535ff49f4860c0f341d1baeb6faf0f4242170" dependencies = [ "proc-macro2", "quote", @@ -4202,7 +4202,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1402f54f9a3b9e2efe71c1cea24e648acce55887983553eeb858cf3115acfd49" dependencies = [ - "base64 0.21.2", + "base64 0.21.7", "chrono", "hex", "indexmap 1.9.3", @@ -4670,9 +4670,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.36.0" +version = "1.38.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61285f6515fa018fb2d1e46eb21223fff441ee8db5d0f1435e8ab4f5cdb80931" +checksum = "eb2caba9f80616f438e09748d5acda951967e1ea58508ef53d9c6402485a46df" dependencies = [ "backtrace", "bytes", @@ -4687,9 +4687,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.2.0" +version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b" +checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" dependencies = [ "proc-macro2", "quote", @@ -5215,7 +5215,7 @@ version = "0.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "af6041b3f84485c21b57acdc0fee4f4f0c93f426053dc05fa5d6fc262537bbff" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -5224,7 +5224,7 @@ version = "0.48.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" dependencies = [ - "windows-targets 0.48.1", + "windows-targets 0.48.5", ] [[package]] @@ -5233,122 +5233,129 @@ version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" dependencies = [ - "windows-targets 0.52.4", + "windows-targets 0.52.6", ] [[package]] name = "windows-targets" -version = "0.48.1" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "05d4b17490f70499f20b9e791dcf6a299785ce8af4d709018206dc5b4953e95f" +checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" dependencies = [ - "windows_aarch64_gnullvm 0.48.0", - "windows_aarch64_msvc 0.48.0", - "windows_i686_gnu 0.48.0", - "windows_i686_msvc 0.48.0", - "windows_x86_64_gnu 0.48.0", - "windows_x86_64_gnullvm 0.48.0", - "windows_x86_64_msvc 0.48.0", + "windows_aarch64_gnullvm 0.48.5", + "windows_aarch64_msvc 0.48.5", + "windows_i686_gnu 0.48.5", + "windows_i686_msvc 0.48.5", + "windows_x86_64_gnu 0.48.5", + "windows_x86_64_gnullvm 0.48.5", + "windows_x86_64_msvc 0.48.5", ] [[package]] name = "windows-targets" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7dd37b7e5ab9018759f893a1952c9420d060016fc19a472b4bb20d1bdd694d1b" +checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" dependencies = [ - "windows_aarch64_gnullvm 0.52.4", - "windows_aarch64_msvc 0.52.4", - "windows_i686_gnu 0.52.4", - "windows_i686_msvc 0.52.4", - "windows_x86_64_gnu 0.52.4", - "windows_x86_64_gnullvm 0.52.4", - "windows_x86_64_msvc 0.52.4", + "windows_aarch64_gnullvm 0.52.6", + "windows_aarch64_msvc 0.52.6", + "windows_i686_gnu 0.52.6", + "windows_i686_gnullvm", + "windows_i686_msvc 0.52.6", + "windows_x86_64_gnu 0.52.6", + "windows_x86_64_gnullvm 0.52.6", + "windows_x86_64_msvc 0.52.6", ] [[package]] name = "windows_aarch64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91ae572e1b79dba883e0d315474df7305d12f569b400fcf90581b06062f7e1bc" +checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" [[package]] name = "windows_aarch64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bcf46cf4c365c6f2d1cc93ce535f2c8b244591df96ceee75d8e83deb70a9cac9" +checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" [[package]] name = "windows_aarch64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2ef27e0d7bdfcfc7b868b317c1d32c641a6fe4629c171b8928c7b08d98d7cf3" +checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" [[package]] name = "windows_aarch64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da9f259dd3bcf6990b55bffd094c4f7235817ba4ceebde8e6d11cd0c5633b675" +checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" [[package]] name = "windows_i686_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "622a1962a7db830d6fd0a69683c80a18fda201879f0f447f065a3b7467daa241" +checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" [[package]] name = "windows_i686_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b474d8268f99e0995f25b9f095bc7434632601028cf86590aea5c8a5cb7801d3" +checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" + +[[package]] +name = "windows_i686_gnullvm" +version = "0.52.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" [[package]] name = "windows_i686_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4542c6e364ce21bf45d69fdd2a8e455fa38d316158cfd43b3ac1c5b1b19f8e00" +checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" [[package]] name = "windows_i686_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1515e9a29e5bed743cb4415a9ecf5dfca648ce85ee42e15873c3cd8610ff8e02" +checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" [[package]] name = "windows_x86_64_gnu" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ca2b8a661f7628cbd23440e50b05d705db3686f894fc9580820623656af974b1" +checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" [[package]] name = "windows_x86_64_gnu" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5eee091590e89cc02ad514ffe3ead9eb6b660aedca2183455434b93546371a03" +checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" [[package]] name = "windows_x86_64_gnullvm" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7896dbc1f41e08872e9d5e8f8baa8fdd2677f29468c4e156210174edc7f7b953" +checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" [[package]] name = "windows_x86_64_gnullvm" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77ca79f2451b49fa9e2af39f0747fe999fcda4f5e241b2898624dca97a1f2177" +checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" [[package]] name = "windows_x86_64_msvc" -version = "0.48.0" +version = "0.48.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a515f5799fe4961cb532f983ce2b23082366b898e52ffbce459c86f67c8378a" +checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" [[package]] name = "windows_x86_64_msvc" -version = "0.52.4" +version = "0.52.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32b752e52a2da0ddfbdbcc6fceadfeede4c939ed16d13e648833a61dfb611ed8" +checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "winnow" 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/aztec_macros/src/utils/ast_utils.rs b/noir/noir-repo/aztec_macros/src/utils/ast_utils.rs index 19372fa5cb5..316aa60da62 100644 --- a/noir/noir-repo/aztec_macros/src/utils/ast_utils.rs +++ b/noir/noir-repo/aztec_macros/src/utils/ast_utils.rs @@ -187,8 +187,8 @@ pub fn check_trait_method_implemented(trait_impl: &NoirTraitImpl, method_name: & /// Checks if an attribute is a custom attribute with a specific name pub fn is_custom_attribute(attr: &SecondaryAttribute, attribute_name: &str) -> bool { - if let SecondaryAttribute::Custom(custom_attr) = attr { - custom_attr.as_str() == attribute_name + if let SecondaryAttribute::Custom(custom_attribute) = attr { + custom_attribute.contents.as_str() == attribute_name } else { false } diff --git a/noir/noir-repo/aztec_macros/src/utils/parse_utils.rs b/noir/noir-repo/aztec_macros/src/utils/parse_utils.rs index 6a2a876e682..e7b3e347a96 100644 --- a/noir/noir-repo/aztec_macros/src/utils/parse_utils.rs +++ b/noir/noir-repo/aztec_macros/src/utils/parse_utils.rs @@ -53,6 +53,7 @@ fn empty_item(item: &mut Item) { ItemKind::Import(use_tree, _) => empty_use_tree(use_tree), ItemKind::Struct(noir_struct) => empty_noir_struct(noir_struct), ItemKind::TypeAlias(noir_type_alias) => empty_noir_type_alias(noir_type_alias), + ItemKind::InnerAttribute(_) => (), } } diff --git a/noir/noir-repo/compiler/noirc_driver/src/lib.rs b/noir/noir-repo/compiler/noirc_driver/src/lib.rs index 88918151366..a315e7ed397 100644 --- a/noir/noir-repo/compiler/noirc_driver/src/lib.rs +++ b/noir/noir-repo/compiler/noirc_driver/src/lib.rs @@ -452,9 +452,13 @@ fn compile_contract_inner( .attributes .secondary .iter() - .filter_map( - |attr| if let SecondaryAttribute::Custom(tag) = attr { Some(tag) } else { None }, - ) + .filter_map(|attr| { + if let SecondaryAttribute::Custom(attribute) = attr { + Some(&attribute.contents) + } else { + None + } + }) .cloned() .collect(); diff --git a/noir/noir-repo/compiler/noirc_errors/src/position.rs b/noir/noir-repo/compiler/noirc_errors/src/position.rs index 1792197eab7..9b031f56ae2 100644 --- a/noir/noir-repo/compiler/noirc_errors/src/position.rs +++ b/noir/noir-repo/compiler/noirc_errors/src/position.rs @@ -103,6 +103,10 @@ impl Span { let other_distance = other.end() - other.start(); self_distance < other_distance } + + pub fn shift_by(&self, offset: u32) -> Span { + Self::from(self.start() + offset..self.end() + offset) + } } impl From for Range { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs index 26abafe177f..ef5fbce83d4 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs @@ -255,16 +255,40 @@ impl<'block> BrilligBlock<'block> { self.convert_ssa_binary(binary, dfg, result_var); } Instruction::Constrain(lhs, rhs, assert_message) => { - let condition = SingleAddrVariable { - address: self.brillig_context.allocate_register(), - bit_size: 1, + let (condition, deallocate) = match ( + dfg.get_numeric_constant_with_type(*lhs), + dfg.get_numeric_constant_with_type(*rhs), + ) { + // If the constraint is of the form `x == u1 1` then we can simply constrain `x` directly + ( + Some((constant, Type::Numeric(NumericType::Unsigned { bit_size: 1 }))), + None, + ) if constant == FieldElement::one() => { + (self.convert_ssa_single_addr_value(*rhs, dfg), false) + } + ( + None, + Some((constant, Type::Numeric(NumericType::Unsigned { bit_size: 1 }))), + ) if constant == FieldElement::one() => { + (self.convert_ssa_single_addr_value(*lhs, dfg), false) + } + + // Otherwise we need to perform the equality explicitly. + _ => { + let condition = SingleAddrVariable { + address: self.brillig_context.allocate_register(), + bit_size: 1, + }; + self.convert_ssa_binary( + &Binary { lhs: *lhs, rhs: *rhs, operator: BinaryOp::Eq }, + dfg, + condition, + ); + + (condition, true) + } }; - self.convert_ssa_binary( - &Binary { lhs: *lhs, rhs: *rhs, operator: BinaryOp::Eq }, - dfg, - condition, - ); match assert_message { Some(ConstrainError::Dynamic(selector, values)) => { let payload_values = @@ -287,7 +311,9 @@ impl<'block> BrilligBlock<'block> { self.brillig_context.codegen_constrain(condition, None); } } - self.brillig_context.deallocate_single_addr(condition); + if deallocate { + self.brillig_context.deallocate_single_addr(condition); + } } Instruction::Allocate => { let result_value = dfg.instruction_results(instruction_id)[0]; diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/errors.rs b/noir/noir-repo/compiler/noirc_evaluator/src/errors.rs index 2c7ec0f8e1a..c4f56d032f9 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/errors.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/errors.rs @@ -44,7 +44,7 @@ pub enum RuntimeError { StaticAssertDynamicPredicate { call_stack: CallStack }, #[error("Argument is false")] StaticAssertFailed { call_stack: CallStack }, - #[error("Nested slices are not supported")] + #[error("Nested slices, i.e. slices within an array or slice, are not supported")] NestedSlice { call_stack: CallStack }, #[error("Big Integer modulus do no match")] BigIntModulus { call_stack: CallStack }, diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs index 57bd76d4f78..ad6645df228 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa.rs @@ -82,6 +82,7 @@ pub(crate) fn optimize_into_acir( ) -> Result { let ssa_gen_span = span!(Level::TRACE, "ssa_generation"); let ssa_gen_span_guard = ssa_gen_span.enter(); + let mut ssa = SsaBuilder::new( program, options.enable_ssa_logging, @@ -418,8 +419,9 @@ impl SsaBuilder { Ok(self.print(msg)) } - fn print(self, msg: &str) -> Self { + fn print(mut self, msg: &str) -> Self { if self.print_ssa_passes { + self.ssa.normalize_ids(); println!("{msg}\n{}", self.ssa); } self diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs index a2b9e46a15a..0360b15d950 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/acir_gen/mod.rs @@ -770,10 +770,12 @@ impl<'a> Context<'a> { .map(|result_id| dfg.type_of_value(*result_id).flattened_size()) .sum(); - let acir_function_id = ssa - .entry_point_to_generated_index - .get(id) - .expect("ICE: should have an associated final index"); + let Some(acir_function_id) = + ssa.entry_point_to_generated_index.get(id) + else { + unreachable!("Expected an associated final index for call to acir function {id} with args {arguments:?}"); + }; + let output_vars = self.acir_context.call_acir_function( AcirFunctionId(*acir_function_id), inputs, diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs index 26eab290d4b..aa5f4c8df95 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/checks/check_for_underconstrained_values.rs @@ -244,7 +244,7 @@ impl Context { } }, Value::ForeignFunction(..) => { - panic!("Should not be able to reach foreign function from non-brillig functions"); + panic!("Should not be able to reach foreign function from non-brillig functions, {func_id} in function {}", function.name()); } Value::Array { .. } | Value::Instruction { .. } diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs index bae9f82e4f1..65a616ef612 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/function.rs @@ -72,6 +72,13 @@ impl Function { Self { name: another.name.clone(), id, entry_block, dfg, runtime: another.runtime } } + /// Takes the signature (function name & runtime) from a function but does not copy the body. + pub(crate) fn clone_signature(id: FunctionId, another: &Function) -> Self { + let mut new_function = Function::new(another.name.clone(), id); + new_function.runtime = another.runtime; + new_function + } + /// The name of the function. /// Used exclusively for debugging purposes. pub(crate) fn name(&self) -> &str { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/map.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/map.rs index 769d52e6e65..23f5380f030 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/map.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/ir/map.rs @@ -1,6 +1,7 @@ use fxhash::FxHashMap as HashMap; use serde::{Deserialize, Serialize}; use std::{ + collections::BTreeMap, hash::Hash, str::FromStr, sync::atomic::{AtomicUsize, Ordering}, @@ -240,7 +241,7 @@ impl std::ops::IndexMut> for DenseMap { /// call to .remove(). #[derive(Debug)] pub(crate) struct SparseMap { - storage: HashMap, T>, + storage: BTreeMap, T>, } impl SparseMap { @@ -271,11 +272,16 @@ impl SparseMap { pub(crate) fn remove(&mut self, id: Id) -> Option { self.storage.remove(&id) } + + /// Unwraps the inner storage of this map + pub(crate) fn into_btree(self) -> BTreeMap, T> { + self.storage + } } impl Default for SparseMap { fn default() -> Self { - Self { storage: HashMap::default() } + Self { storage: Default::default() } } } 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 1ff593a1531..7843c55da65 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 @@ -2,7 +2,7 @@ //! The purpose of this pass is to inline the instructions of each function call //! within the function caller. If all function calls are known, there will only //! be a single function remaining when the pass finishes. -use std::collections::{BTreeSet, HashSet}; +use std::collections::{BTreeSet, HashSet, VecDeque}; use acvm::acir::AcirField; use iter_extended::{btree_map, vecmap}; @@ -372,14 +372,14 @@ impl<'function> PerFunctionContext<'function> { fn translate_block( &mut self, source_block: BasicBlockId, - block_queue: &mut Vec, + block_queue: &mut VecDeque, ) -> BasicBlockId { if let Some(block) = self.blocks.get(&source_block) { return *block; } // The block is not yet inlined, queue it - block_queue.push(source_block); + block_queue.push_back(source_block); // The block is not already present in the function being inlined into so we must create it. // The block's instructions are not copied over as they will be copied later in inlining. @@ -415,13 +415,14 @@ impl<'function> PerFunctionContext<'function> { /// Inline all reachable blocks within the source_function into the destination function. fn inline_blocks(&mut self, ssa: &Ssa) -> Vec { let mut seen_blocks = HashSet::new(); - let mut block_queue = vec![self.source_function.entry_block()]; + let mut block_queue = VecDeque::new(); + block_queue.push_back(self.source_function.entry_block()); // This Vec will contain each block with a Return instruction along with the // returned values of that block. let mut function_returns = vec![]; - while let Some(source_block_id) = block_queue.pop() { + while let Some(source_block_id) = block_queue.pop_front() { if seen_blocks.contains(&source_block_id) { continue; } @@ -609,7 +610,7 @@ impl<'function> PerFunctionContext<'function> { fn handle_terminator_instruction( &mut self, block_id: BasicBlockId, - block_queue: &mut Vec, + block_queue: &mut VecDeque, ) -> Option<(BasicBlockId, Vec)> { match self.source_function.dfg[block_id].unwrap_terminator() { TerminatorInstruction::Jmp { destination, arguments, call_stack } => { diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs index 9d6582c0db7..3d98f4126cf 100644 --- a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/mem2reg.rs @@ -116,7 +116,7 @@ struct PerFunctionContext<'f> { /// Track a value's last load across all blocks. /// If a value is not used in anymore loads we can remove the last store to that value. - last_loads: HashMap, + last_loads: HashMap, } impl<'f> PerFunctionContext<'f> { @@ -152,9 +152,31 @@ impl<'f> PerFunctionContext<'f> { // This rule does not apply to reference parameters, which we must also check for before removing these stores. for (block_id, block) in self.blocks.iter() { let block_params = self.inserter.function.dfg.block_parameters(*block_id); - for (value, store_instruction) in block.last_stores.iter() { - let is_reference_param = block_params.contains(value); - if self.last_loads.get(value).is_none() && !is_reference_param { + for (store_address, store_instruction) in block.last_stores.iter() { + let is_reference_param = block_params.contains(store_address); + let terminator = self.inserter.function.dfg[*block_id].unwrap_terminator(); + + let is_return = matches!(terminator, TerminatorInstruction::Return { .. }); + let remove_load = if is_return { + // Determine whether the last store is used in the return value + let mut is_return_value = false; + terminator.for_each_value(|return_value| { + is_return_value = return_value == *store_address || is_return_value; + }); + + // If the last load of a store is not part of the block with a return terminator, + // we can safely remove this store. + let last_load_not_in_return = self + .last_loads + .get(store_address) + .map(|(_, last_load_block)| *last_load_block != *block_id) + .unwrap_or(true); + !is_return_value && last_load_not_in_return + } else { + self.last_loads.get(store_address).is_none() + }; + + if remove_load && !is_reference_param { self.instructions_to_remove.insert(*store_instruction); } } @@ -259,7 +281,7 @@ impl<'f> PerFunctionContext<'f> { } else { references.mark_value_used(address, self.inserter.function); - self.last_loads.insert(address, instruction); + self.last_loads.insert(address, (instruction, block_id)); } } Instruction::Store { address, value } => { 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 4e5fa262696..bd9d0baff97 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 @@ -13,6 +13,7 @@ mod die; pub(crate) mod flatten_cfg; mod inlining; mod mem2reg; +mod normalize_value_ids; mod rc; mod remove_bit_shifts; mod remove_enable_side_effects; diff --git a/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs new file mode 100644 index 00000000000..f11b310494b --- /dev/null +++ b/noir/noir-repo/compiler/noirc_evaluator/src/ssa/opt/normalize_value_ids.rs @@ -0,0 +1,194 @@ +use std::collections::BTreeMap; + +use crate::ssa::{ + ir::{ + basic_block::BasicBlockId, + function::{Function, FunctionId}, + map::SparseMap, + post_order::PostOrder, + value::{Value, ValueId}, + }, + ssa_gen::Ssa, +}; +use fxhash::FxHashMap as HashMap; +use iter_extended::vecmap; + +impl Ssa { + /// This is a debugging pass which re-inserts each instruction + /// and block in a fresh DFG context for each function so that ValueIds, + /// BasicBlockIds, and FunctionIds are always identical for the same SSA code. + /// + /// During normal compilation this is often not the case since prior passes + /// may increase the ID counter so that later passes start at different offsets, + /// even if they contain the same SSA code. + pub(crate) fn normalize_ids(&mut self) { + let mut context = Context::default(); + context.populate_functions(&self.functions); + for function in self.functions.values_mut() { + context.normalize_ids(function); + } + self.functions = context.functions.into_btree(); + } +} + +#[derive(Default)] +struct Context { + functions: SparseMap, + + new_ids: IdMaps, +} + +/// Maps from old ids to new ones. +/// Separate from the rest of Context so we can call mutable methods on it +/// while Context gives out mutable references to functions within. +#[derive(Default)] +struct IdMaps { + // Maps old function id -> new function id + function_ids: HashMap, + + // Maps old block id -> new block id + // Cleared in between each function. + blocks: HashMap, + + // Maps old value id -> new value id + // Cleared in between each function. + values: HashMap, +} + +impl Context { + fn populate_functions(&mut self, functions: &BTreeMap) { + for (id, function) in functions { + self.functions.insert_with_id(|new_id| { + self.new_ids.function_ids.insert(*id, new_id); + Function::clone_signature(new_id, function) + }); + } + } + + fn normalize_ids(&mut self, old_function: &mut Function) { + self.new_ids.blocks.clear(); + self.new_ids.values.clear(); + + let new_function_id = self.new_ids.function_ids[&old_function.id()]; + let new_function = &mut self.functions[new_function_id]; + + let mut reachable_blocks = PostOrder::with_function(old_function).into_vec(); + reachable_blocks.reverse(); + + self.new_ids.populate_blocks(&reachable_blocks, old_function, new_function); + + // Map each parameter, instruction, and terminator + for old_block_id in reachable_blocks { + let new_block_id = self.new_ids.blocks[&old_block_id]; + + let old_block = &mut old_function.dfg[old_block_id]; + for old_instruction_id in old_block.take_instructions() { + let instruction = old_function.dfg[old_instruction_id] + .map_values(|value| self.new_ids.map_value(new_function, old_function, value)); + + let call_stack = old_function.dfg.get_call_stack(old_instruction_id); + let old_results = old_function.dfg.instruction_results(old_instruction_id); + + let ctrl_typevars = instruction + .requires_ctrl_typevars() + .then(|| vecmap(old_results, |result| old_function.dfg.type_of_value(*result))); + + let new_results = new_function.dfg.insert_instruction_and_results( + instruction, + new_block_id, + ctrl_typevars, + call_stack, + ); + + assert_eq!(old_results.len(), new_results.len()); + for (old_result, new_result) in old_results.iter().zip(new_results.results().iter()) + { + let old_result = old_function.dfg.resolve(*old_result); + self.new_ids.values.insert(old_result, *new_result); + } + } + + let old_block = &mut old_function.dfg[old_block_id]; + let mut terminator = old_block + .take_terminator() + .map_values(|value| self.new_ids.map_value(new_function, old_function, value)); + terminator.mutate_blocks(|old_block| self.new_ids.blocks[&old_block]); + new_function.dfg.set_block_terminator(new_block_id, terminator); + } + } +} + +impl IdMaps { + fn populate_blocks( + &mut self, + reachable_blocks: &[BasicBlockId], + old_function: &mut Function, + new_function: &mut Function, + ) { + let old_entry = old_function.entry_block(); + self.blocks.insert(old_entry, new_function.entry_block()); + + for old_id in reachable_blocks { + if *old_id != old_entry { + let new_id = new_function.dfg.make_block(); + self.blocks.insert(*old_id, new_id); + } + + let new_id = self.blocks[old_id]; + let old_block = &mut old_function.dfg[*old_id]; + for old_parameter in old_block.take_parameters() { + let old_parameter = old_function.dfg.resolve(old_parameter); + let typ = old_function.dfg.type_of_value(old_parameter); + let new_parameter = new_function.dfg.add_block_parameter(new_id, typ); + self.values.insert(old_parameter, new_parameter); + } + } + } + + fn map_value( + &mut self, + new_function: &mut Function, + old_function: &Function, + old_value: ValueId, + ) -> ValueId { + let old_value = old_function.dfg.resolve(old_value); + match &old_function.dfg[old_value] { + value @ Value::Instruction { instruction, .. } => { + *self.values.get(&old_value).unwrap_or_else(|| { + let instruction = &old_function.dfg[*instruction]; + unreachable!("Unmapped value with id {old_value}: {value:?}\n from instruction: {instruction:?}, SSA: {old_function}") + }) + } + + value @ Value::Param { .. } => { + *self.values.get(&old_value).unwrap_or_else(|| { + unreachable!("Unmapped value with id {old_value}: {value:?}") + }) + } + + Value::Function(id) => { + let new_id = self.function_ids[id]; + new_function.dfg.import_function(new_id) + } + + Value::NumericConstant { constant, typ } => { + new_function.dfg.make_constant(*constant, typ.clone()) + } + Value::Array { array, typ } => { + if let Some(value) = self.values.get(&old_value) { + return *value; + } + + let array = array + .iter() + .map(|value| self.map_value(new_function, old_function, *value)) + .collect(); + let new_value = new_function.dfg.make_array(array, typ.clone()); + self.values.insert(old_value, new_value); + new_value + } + Value::Intrinsic(intrinsic) => new_function.dfg.import_intrinsic(*intrinsic), + Value::ForeignFunction(name) => new_function.dfg.import_foreign_function(name), + } + } +} 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 2e14761a1cc..30db8ad63fd 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/statement.rs @@ -292,6 +292,7 @@ pub trait Recoverable { #[derive(Debug, PartialEq, Eq, Clone)] pub struct ModuleDeclaration { pub ident: Ident, + pub outer_attributes: Vec, } impl std::fmt::Display for ModuleDeclaration { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/ast/visitor.rs b/noir/noir-repo/compiler/noirc_frontend/src/ast/visitor.rs index 3955e50b03e..0aeeed39dd0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/ast/visitor.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/ast/visitor.rs @@ -16,7 +16,7 @@ use crate::{ QuotedTypeId, }, parser::{Item, ItemKind, ParsedSubModule}, - token::Tokens, + token::{SecondaryAttribute, Tokens}, ParsedModule, QuotedType, }; @@ -432,6 +432,8 @@ pub trait Visitor { fn visit_struct_pattern(&mut self, _: &Path, _: &[(Ident, Pattern)], _: Span) -> bool { true } + + fn visit_secondary_attribute(&mut self, _: &SecondaryAttribute, _: Span) {} } impl ParsedModule { @@ -481,6 +483,9 @@ impl Item { ItemKind::ModuleDecl(module_declaration) => { module_declaration.accept(self.span, visitor); } + ItemKind::InnerAttribute(attribute) => { + attribute.accept(self.span, visitor); + } } } } @@ -1289,6 +1294,12 @@ impl Pattern { } } +impl SecondaryAttribute { + pub fn accept(&self, span: Span, visitor: &mut impl Visitor) { + visitor.visit_secondary_attribute(self, span); + } +} + fn visit_expressions(expressions: &[Expression], visitor: &mut impl Visitor) { for expression in expressions { expression.accept(visitor); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/comptime.rs b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/comptime.rs index baa9c0ab371..7da5efd0b5a 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/comptime.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/comptime.rs @@ -10,11 +10,12 @@ use crate::{ comptime::{Interpreter, InterpreterError, Value}, def_collector::{ dc_crate::{ - CollectedItems, CompilationError, UnresolvedFunctions, UnresolvedStruct, - UnresolvedTrait, UnresolvedTraitImpl, + CollectedItems, CompilationError, ModuleAttribute, UnresolvedFunctions, + UnresolvedStruct, UnresolvedTrait, UnresolvedTraitImpl, }, dc_mod, }, + def_map::ModuleId, resolution::errors::ResolverError, }, hir_def::expr::HirIdent, @@ -24,7 +25,7 @@ use crate::{ }, node_interner::{DefinitionKind, DependencyId, FuncId, TraitId}, parser::{self, TopLevelStatement}, - Type, TypeBindings, + Type, TypeBindings, UnificationError, }; use super::{Elaborator, FunctionContext, ResolverMeta}; @@ -96,25 +97,40 @@ impl<'context> Elaborator<'context> { generated_items: &mut CollectedItems, ) { for attribute in attributes { - if let SecondaryAttribute::Custom(name) = attribute { - if let Err(error) = - self.run_comptime_attribute_on_item(name, item.clone(), span, generated_items) - { - self.errors.push(error); - } - } + self.run_comptime_attribute_on_item(attribute, &item, span, generated_items); } } fn run_comptime_attribute_on_item( + &mut self, + attribute: &SecondaryAttribute, + item: &Value, + span: Span, + generated_items: &mut CollectedItems, + ) { + if let SecondaryAttribute::Custom(attribute) = attribute { + if let Err(error) = self.run_comptime_attribute_name_on_item( + &attribute.contents, + item.clone(), + span, + attribute.contents_span, + generated_items, + ) { + self.errors.push(error); + } + } + } + + fn run_comptime_attribute_name_on_item( &mut self, attribute: &str, item: Value, span: Span, + attribute_span: Span, generated_items: &mut CollectedItems, ) -> Result<(), (CompilationError, FileId)> { - let location = Location::new(span, self.file); - let Some((function, arguments)) = Self::parse_attribute(attribute, self.file)? else { + let location = Location::new(attribute_span, self.file); + let Some((function, arguments)) = Self::parse_attribute(attribute, location)? else { // Do not issue an error if the attribute is unknown return Ok(()); }; @@ -141,12 +157,17 @@ impl<'context> Elaborator<'context> { }; let mut interpreter = self.setup_interpreter(); - let mut arguments = - Self::handle_attribute_arguments(&mut interpreter, function, arguments, location) - .map_err(|error| { - let file = error.get_location().file; - (error.into(), file) - })?; + let mut arguments = Self::handle_attribute_arguments( + &mut interpreter, + &item, + function, + arguments, + location, + ) + .map_err(|error| { + let file = error.get_location().file; + (error.into(), file) + })?; arguments.insert(0, (item, location)); @@ -154,6 +175,8 @@ impl<'context> Elaborator<'context> { .call_function(function, arguments, TypeBindings::new(), location) .map_err(|error| error.into_compilation_error_pair())?; + self.debug_comptime(location, |interner| value.display(interner).to_string()); + if value != Value::Unit { let items = value .into_top_level_items(location, self.interner) @@ -170,33 +193,62 @@ impl<'context> Elaborator<'context> { #[allow(clippy::type_complexity)] pub(crate) fn parse_attribute( annotation: &str, - file: FileId, + location: Location, ) -> Result)>, (CompilationError, FileId)> { let (tokens, mut lexing_errors) = Lexer::lex(annotation); if !lexing_errors.is_empty() { - return Err((lexing_errors.swap_remove(0).into(), file)); + return Err((lexing_errors.swap_remove(0).into(), location.file)); } let expression = parser::expression() .parse(tokens) - .map_err(|mut errors| (errors.swap_remove(0).into(), file))?; + .map_err(|mut errors| (errors.swap_remove(0).into(), location.file))?; - Ok(match expression.kind { - ExpressionKind::Call(call) => Some((*call.func, call.arguments)), - ExpressionKind::Variable(_) => Some((expression, Vec::new())), - _ => None, - }) + let (mut func, mut arguments) = match expression.kind { + ExpressionKind::Call(call) => (*call.func, call.arguments), + ExpressionKind::Variable(_) => (expression, Vec::new()), + _ => return Ok(None), + }; + + func.span = func.span.shift_by(location.span.start()); + + for argument in &mut arguments { + argument.span = argument.span.shift_by(location.span.start()); + } + + Ok(Some((func, arguments))) } fn handle_attribute_arguments( interpreter: &mut Interpreter, + item: &Value, function: FuncId, arguments: Vec, location: Location, ) -> Result, InterpreterError> { let meta = interpreter.elaborator.interner.function_meta(&function); + let mut parameters = vecmap(&meta.parameters.0, |(_, typ, _)| typ.clone()); + if parameters.is_empty() { + return Err(InterpreterError::ArgumentCountMismatch { + expected: 0, + actual: arguments.len() + 1, + location, + }); + } + + let expected_type = item.get_type(); + let expected_type = expected_type.as_ref(); + + if ¶meters[0] != expected_type { + return Err(InterpreterError::TypeMismatch { + expected: parameters[0].clone(), + actual: expected_type.clone(), + location, + }); + } + // Remove the initial parameter for the comptime item since that is not included // in `arguments` at this point. parameters.remove(0); @@ -213,6 +265,7 @@ impl<'context> Elaborator<'context> { let mut varargs = im::Vector::new(); for (i, arg) in arguments.into_iter().enumerate() { + let arg_location = Location::new(arg.span, location.file); let param_type = parameters.get(i).or(varargs_elem_type).unwrap_or(&Type::Error); let mut push_arg = |arg| { @@ -233,9 +286,17 @@ impl<'context> Elaborator<'context> { }?; push_arg(Value::TraitDefinition(trait_id)); } else { - let expr_id = interpreter.elaborator.elaborate_expression(arg).0; + let (expr_id, expr_type) = interpreter.elaborator.elaborate_expression(arg); push_arg(interpreter.evaluate(expr_id)?); - } + + if let Err(UnificationError) = expr_type.unify(param_type) { + return Err(InterpreterError::TypeMismatch { + expected: param_type.clone(), + actual: expr_type, + location: arg_location, + }); + } + }; } if is_varargs { @@ -265,24 +326,24 @@ impl<'context> Elaborator<'context> { ) { 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 module_id = self.module_id(); - if self.interner.is_in_lsp_mode() - && !function.def.is_test() - && !function.def.is_private() - { - self.interner.register_function(id, &function.def); + if let Some(id) = dc_mod::collect_function( + self.interner, + self.def_maps.get_mut(&self.crate_id).unwrap(), + &function, + module_id, + self.file, + &mut self.errors, + ) { + let functions = vec![(self.local_module, id, function)]; + generated_items.functions.push(UnresolvedFunctions { + file_id: self.file, + functions, + trait_id: None, + self_type: None, + }); } - - 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, associated_types, associated_constants) = @@ -329,16 +390,33 @@ impl<'context> Elaborator<'context> { self.errors.push(error); } } + TopLevelStatement::Struct(struct_def) => { + if let Some((type_id, the_struct)) = dc_mod::collect_struct( + self.interner, + self.def_maps.get_mut(&self.crate_id).unwrap(), + struct_def, + self.file, + self.local_module, + self.crate_id, + &mut self.errors, + ) { + generated_items.types.insert(type_id, the_struct); + } + } + TopLevelStatement::Impl(r#impl) => { + let module = self.module_id(); + dc_mod::collect_impl(self.interner, generated_items, r#impl, self.file, module); + } + // Assume that an error has already been issued TopLevelStatement::Error => (), TopLevelStatement::Module(_) | TopLevelStatement::Import(..) - | TopLevelStatement::Struct(_) | TopLevelStatement::Trait(_) - | TopLevelStatement::Impl(_) | TopLevelStatement::TypeAlias(_) - | TopLevelStatement::SubModule(_) => { + | TopLevelStatement::SubModule(_) + | TopLevelStatement::InnerAttribute(_) => { let item = item.to_string(); let error = InterpreterError::UnsupportedTopLevelItemUnquote { item, location }; self.errors.push(error.into_compilation_error_pair()); @@ -377,6 +455,7 @@ impl<'context> Elaborator<'context> { traits: &BTreeMap, types: &BTreeMap, functions: &[UnresolvedFunctions], + module_attributes: &[ModuleAttribute], ) -> CollectedItems { let mut generated_items = CollectedItems::default(); @@ -399,9 +478,31 @@ impl<'context> Elaborator<'context> { } self.run_attributes_on_functions(functions, &mut generated_items); + + self.run_attributes_on_modules(module_attributes, &mut generated_items); + generated_items } + fn run_attributes_on_modules( + &mut self, + module_attributes: &[ModuleAttribute], + generated_items: &mut CollectedItems, + ) { + for module_attribute in module_attributes { + let local_id = module_attribute.module_id; + let module_id = ModuleId { krate: self.crate_id, local_id }; + let item = Value::ModuleDefinition(module_id); + let attribute = &module_attribute.attribute; + let span = Span::default(); + + self.local_module = module_attribute.attribute_module_id; + self.file = module_attribute.attribute_file_id; + + self.run_comptime_attribute_on_item(attribute, &item, span, generated_items); + } + } + fn run_attributes_on_functions( &mut self, function_sets: &[UnresolvedFunctions], 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 e84ed76050d..161742029f6 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/mod.rs @@ -28,6 +28,7 @@ use crate::{ node_interner::{ DefinitionKind, DependencyId, ExprId, FuncId, GlobalId, ReferenceId, TraitId, TypeAliasId, }, + token::CustomAtrribute, Shared, Type, TypeVariable, }; use crate::{ @@ -320,7 +321,12 @@ impl<'context> Elaborator<'context> { // We have to run any comptime attributes on functions before the function is elaborated // since the generated items are checked beforehand as well. - let generated_items = self.run_attributes(&items.traits, &items.types, &items.functions); + let generated_items = self.run_attributes( + &items.traits, + &items.types, + &items.functions, + &items.module_attributes, + ); // After everything is collected, we can elaborate our generated items. // It may be better to inline these within `items` entirely since elaborating them @@ -819,7 +825,7 @@ impl<'context> Elaborator<'context> { let attributes = func.secondary_attributes().iter(); let attributes = attributes.filter_map(|secondary_attribute| secondary_attribute.as_custom()); - let attributes = attributes.map(|str| str.to_string()).collect(); + let attributes: Vec = attributes.cloned().collect(); let meta = FuncMeta { name: name_ident, 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 e41234a5be5..8dccd5f0344 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/elaborator/types.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/elaborator/types.rs @@ -36,7 +36,7 @@ use crate::{ TraitImplKind, TraitMethodId, }, Generics, Kind, ResolvedGeneric, Type, TypeBinding, TypeBindings, TypeVariable, - TypeVariableKind, + TypeVariableKind, UnificationError, }; use super::{lints, Elaborator}; @@ -713,9 +713,9 @@ impl<'context> Elaborator<'context> { expected: &Type, make_error: impl FnOnce() -> TypeCheckError, ) { - let mut errors = Vec::new(); - actual.unify(expected, &mut errors, make_error); - self.errors.extend(errors.into_iter().map(|error| (error.into(), self.file))); + if let Err(UnificationError) = actual.unify(expected) { + self.errors.push((make_error().into(), self.file)); + } } /// Wrapper of Type::unify_with_coercions using self.errors 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 cfee6bcedac..48efc08f463 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 @@ -488,7 +488,7 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { InterpreterError::UnsupportedTopLevelItemUnquote { item, location } => { let msg = "Unsupported statement type to unquote".into(); let secondary = - "Only functions, globals, and trait impls can be unquoted here".into(); + "Only functions, structs, globals, and impls can be unquoted here".into(); let mut error = CustomDiagnostic::simple_error(msg, secondary, location.span); error.add_note(format!("Unquoted item was:\n{item}")); error 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 4980045c68d..9f559b7c5e6 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 @@ -586,7 +586,19 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { consuming = false; if let Some(value) = values.pop_front() { - result.push_str(&value.display(self.elaborator.interner).to_string()); + // When interpolating a quoted value inside a format string, we don't include the + // surrounding `quote {` ... `}` as if we are unquoting the quoted value inside the string. + if let Value::Quoted(tokens) = value { + for (index, token) in tokens.iter().enumerate() { + if index > 0 { + result.push(' '); + } + result + .push_str(&token.display(self.elaborator.interner).to_string()); + } + } else { + result.push_str(&value.display(self.elaborator.interner).to_string()); + } } } other if !consuming => { @@ -1653,10 +1665,20 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { assert_eq!(arguments.len(), 2); let print_newline = arguments[0].0 == Value::Bool(true); - if print_newline { - println!("{}", arguments[1].0.display(self.elaborator.interner)); + let contents = arguments[1].0.display(self.elaborator.interner); + if self.elaborator.interner.is_in_lsp_mode() { + // If we `println!` in LSP it gets mixed with the protocol stream and leads to crashing + // the connection. If we use `eprintln!` not only it doesn't crash, but the output + // appears in the "Noir Language Server" output window in case you want to see it. + if print_newline { + eprintln!("{}", contents); + } else { + eprint!("{}", contents); + } + } else if print_newline { + println!("{}", contents); } else { - print!("{}", arguments[1].0.display(self.elaborator.interner)); + print!("{}", contents); } Ok(Value::Unit) diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index e5b098b41ed..d2c9e4ffc0c 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -7,9 +7,9 @@ use acvm::{AcirField, FieldElement}; use builtin_helpers::{ block_expression_to_value, check_argument_count, check_function_not_yet_resolved, check_one_argument, check_three_arguments, check_two_arguments, get_expr, get_field, - get_function_def, get_module, get_quoted, get_slice, get_struct, get_trait_constraint, - get_trait_def, get_trait_impl, get_tuple, get_type, get_typed_expr, get_u32, - get_unresolved_type, hir_pattern_to_tokens, mutate_func_meta_type, parse, + get_format_string, get_function_def, get_module, get_quoted, get_slice, get_struct, + get_trait_constraint, get_trait_def, get_trait_impl, get_tuple, get_type, get_typed_expr, + get_u32, get_unresolved_type, hir_pattern_to_tokens, mutate_func_meta_type, parse, replace_func_meta_parameters, replace_func_meta_return_type, }; use chumsky::{prelude::choice, Parser}; @@ -32,6 +32,7 @@ use crate::{ InterpreterError, Value, }, hir_def::function::FunctionBody, + lexer::Lexer, macros_api::{HirExpression, HirLiteral, ModuleDefId, NodeInterner, Signedness}, node_interner::{DefinitionKind, TraitImplKind}, parser::{self}, @@ -39,7 +40,7 @@ use crate::{ QuotedType, Shared, Type, }; -use self::builtin_helpers::{get_array, get_u8}; +use self::builtin_helpers::{get_array, get_str, get_u8}; use super::Interpreter; pub(crate) mod builtin_helpers; @@ -95,6 +96,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { "expr_is_continue" => expr_is_continue(interner, arguments, location), "expr_resolve" => expr_resolve(self, arguments, location), "is_unconstrained" => Ok(Value::Bool(true)), + "fmtstr_quoted_contents" => fmtstr_quoted_contents(interner, arguments, location), "function_def_body" => function_def_body(interner, arguments, location), "function_def_has_named_attribute" => { function_def_has_named_attribute(interner, arguments, location) @@ -108,6 +110,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { function_def_set_return_type(self, arguments, location) } "module_functions" => module_functions(self, arguments, location), + "module_has_named_attribute" => module_has_named_attribute(self, arguments, location), "module_is_contract" => module_is_contract(self, arguments, location), "module_name" => module_name(interner, arguments, location), "modulus_be_bits" => modulus_be_bits(interner, arguments, location), @@ -248,25 +251,15 @@ fn str_as_bytes( arguments: Vec<(Value, Location)>, location: Location, ) -> IResult { - let (string, string_location) = check_one_argument(arguments, location)?; + let string = check_one_argument(arguments, location)?; + let string = get_str(interner, string)?; - match string { - Value::String(string) => { - let string_as_bytes = string.as_bytes(); - let bytes_vector: Vec = string_as_bytes.iter().cloned().map(Value::U8).collect(); - let byte_array_type = Type::Array( - Box::new(Type::Constant(string_as_bytes.len() as u32)), - Box::new(Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight)), - ); - Ok(Value::Array(bytes_vector.into(), byte_array_type)) - } - value => { - let type_var = Box::new(interner.next_type_variable()); - let expected = Type::Array(type_var.clone(), type_var); - let actual = value.get_type().into_owned(); - Err(InterpreterError::TypeMismatch { expected, actual, location: string_location }) - } - } + let bytes: im::Vector = string.bytes().map(Value::U8).collect(); + let byte_array_type = Type::Array( + Box::new(Type::Constant(bytes.len() as u32)), + Box::new(Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight)), + ); + Ok(Value::Array(bytes, byte_array_type)) } /// fn as_type(self) -> Type @@ -1585,6 +1578,23 @@ fn unwrap_expr_value(interner: &NodeInterner, mut expr_value: ExprValue) -> Expr expr_value } +// fn quoted_contents(self) -> Quoted +fn fmtstr_quoted_contents( + interner: &NodeInterner, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let self_argument = check_one_argument(arguments, location)?; + let (string, _) = get_format_string(interner, self_argument)?; + let (tokens, _) = Lexer::lex(&string); + let mut tokens: Vec<_> = tokens.0.into_iter().map(|token| token.into_token()).collect(); + if let Some(Token::EOF) = tokens.last() { + tokens.pop(); + } + + Ok(Value::Quoted(Rc::new(tokens))) +} + // fn body(self) -> Expr fn function_def_body( interner: &NodeInterner, @@ -1619,7 +1629,7 @@ fn function_def_has_named_attribute( let name = name.iter().map(|token| token.to_string()).collect::>().join(""); for attribute in attributes { - let parse_result = Elaborator::parse_attribute(attribute, location.file); + let parse_result = Elaborator::parse_attribute(&attribute.contents, location); let Ok(Some((function, _arguments))) = parse_result else { continue; }; @@ -1826,6 +1836,38 @@ fn module_functions( Ok(Value::Slice(func_ids, slice_type)) } +// fn has_named_attribute(self, name: Quoted) -> bool +fn module_has_named_attribute( + interpreter: &Interpreter, + arguments: Vec<(Value, Location)>, + location: Location, +) -> IResult { + let (self_argument, name) = check_two_arguments(arguments, location)?; + let module_id = get_module(self_argument)?; + let module_data = interpreter.elaborator.get_module(module_id); + let name = get_quoted(name)?; + + let name = name.iter().map(|token| token.to_string()).collect::>().join(""); + + let attributes = module_data.outer_attributes.iter().chain(&module_data.inner_attributes); + for attribute in attributes { + let parse_result = Elaborator::parse_attribute(attribute, location); + let Ok(Some((function, _arguments))) = parse_result else { + continue; + }; + + let ExpressionKind::Variable(path) = function.kind else { + continue; + }; + + if path.last_name() == name { + return Ok(Value::Bool(true)); + } + } + + Ok(Value::Bool(false)) +} + // fn is_contract(self) -> bool fn module_is_contract( interpreter: &Interpreter, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs index dd9ea51961e..ff3da6d253f 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs @@ -104,6 +104,19 @@ pub(crate) fn get_slice( } } +pub(crate) fn get_str( + interner: &NodeInterner, + (value, location): (Value, Location), +) -> IResult> { + match value { + Value::String(string) => Ok(string), + value => { + let expected = Type::String(Box::new(interner.next_type_variable())); + type_mismatch(value, expected, location) + } + } +} + pub(crate) fn get_tuple( interner: &NodeInterner, (value, location): (Value, Location), @@ -176,6 +189,20 @@ pub(crate) fn get_expr( } } +pub(crate) fn get_format_string( + interner: &NodeInterner, + (value, location): (Value, Location), +) -> IResult<(Rc, Type)> { + match value { + Value::FormatString(value, typ) => Ok((value, typ)), + value => { + let n = Box::new(interner.next_type_variable()); + let e = Box::new(interner.next_type_variable()); + type_mismatch(value, Type::FmtString(n, e), location) + } + } +} + pub(crate) fn get_function_def((value, location): (Value, Location)) -> IResult { match value { Value::FunctionDefinition(id) => Ok(id), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/tests.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/tests.rs index 4c1adf9fca0..64b489422a0 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/tests.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/comptime/tests.rs @@ -23,7 +23,13 @@ fn interpret_helper(src: &str) -> Result { let module_id = LocalModuleId(Index::unsafe_zeroed()); let mut modules = noirc_arena::Arena::default(); let location = Location::new(Default::default(), file); - let root = LocalModuleId(modules.insert(ModuleData::new(None, location, false))); + let root = LocalModuleId(modules.insert(ModuleData::new( + None, + location, + Vec::new(), + Vec::new(), + false, + ))); assert_eq!(root, module_id); let file_manager = FileManager::new(&PathBuf::new()); 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 b96c4852931..7d6e4475c7b 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 @@ -429,6 +429,9 @@ impl Value { location: Location, ) -> IResult> { let token = match self { + Value::Unit => { + return Ok(vec![Token::LeftParen, Token::RightParen]); + } Value::Quoted(tokens) => return Ok(unwrap_rc(tokens)), Value::Type(typ) => Token::QuotedType(interner.push_quoted_type(typ)), Value::Expr(ExprValue::Expression(expr)) => { @@ -443,6 +446,40 @@ impl Value { Value::UnresolvedType(typ) => { Token::InternedUnresolvedTypeData(interner.push_unresolved_type_data(typ)) } + Value::U1(bool) => Token::Bool(bool), + Value::U8(value) => Token::Int((value as u128).into()), + Value::U16(value) => Token::Int((value as u128).into()), + Value::U32(value) => Token::Int((value as u128).into()), + Value::U64(value) => Token::Int((value as u128).into()), + Value::I8(value) => { + if value < 0 { + return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]); + } else { + Token::Int((value as u128).into()) + } + } + Value::I16(value) => { + if value < 0 { + return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]); + } else { + Token::Int((value as u128).into()) + } + } + Value::I32(value) => { + if value < 0 { + return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]); + } else { + Token::Int((value as u128).into()) + } + } + Value::I64(value) => { + if value < 0 { + return Ok(vec![Token::Minus, Token::Int((-value as u128).into())]); + } else { + Token::Int((value as u128).into()) + } + } + Value::Field(value) => Token::Int(value), other => Token::UnquoteMarker(other.into_hir_expression(interner, location)?), }; Ok(vec![token]) @@ -567,12 +604,8 @@ impl<'value, 'interner> Display for ValuePrinter<'value, 'interner> { Value::Quoted(tokens) => { write!(f, "quote {{")?; for token in tokens.iter() { - match token { - Token::QuotedType(id) => { - write!(f, " {}", self.interner.get_quoted_type(*id))?; - } - other => write!(f, " {other}")?, - } + write!(f, " ")?; + token.display(self.interner).fmt(f)?; } write!(f, " }}") } @@ -632,7 +665,16 @@ impl<'value, 'interner> Display for ValuePrinter<'value, 'interner> { Value::Expr(ExprValue::LValue(lvalue)) => { write!(f, "{}", remove_interned_in_lvalue(self.interner, lvalue.clone())) } - Value::TypedExpr(_) => write!(f, "(typed expr)"), + Value::TypedExpr(TypedExpr::ExprId(id)) => { + let hir_expr = self.interner.expression(id); + let expr = hir_expr.to_display_ast(self.interner, Span::default()); + write!(f, "{}", expr.kind) + } + Value::TypedExpr(TypedExpr::StmtId(id)) => { + let hir_statement = self.interner.statement(id); + let stmt = hir_statement.to_display_ast(self.interner, Span::default()); + write!(f, "{}", stmt.kind) + } Value::UnresolvedType(typ) => { if let UnresolvedTypeData::Interned(id) = typ { let typ = self.interner.get_unresolved_type_data(*id); @@ -645,6 +687,51 @@ impl<'value, 'interner> Display for ValuePrinter<'value, 'interner> { } } +impl Token { + pub fn display<'token, 'interner>( + &'token self, + interner: &'interner NodeInterner, + ) -> TokenPrinter<'token, 'interner> { + TokenPrinter { token: self, interner } + } +} + +pub struct TokenPrinter<'token, 'interner> { + token: &'token Token, + interner: &'interner NodeInterner, +} + +impl<'token, 'interner> Display for TokenPrinter<'token, 'interner> { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + match self.token { + Token::QuotedType(id) => { + write!(f, "{}", self.interner.get_quoted_type(*id)) + } + Token::InternedExpr(id) => { + let value = Value::expression(ExpressionKind::Interned(*id)); + value.display(self.interner).fmt(f) + } + Token::InternedStatement(id) => { + let value = Value::statement(StatementKind::Interned(*id)); + value.display(self.interner).fmt(f) + } + Token::InternedLValue(id) => { + let value = Value::lvalue(LValue::Interned(*id, Span::default())); + value.display(self.interner).fmt(f) + } + Token::InternedUnresolvedTypeData(id) => { + let value = Value::UnresolvedType(UnresolvedTypeData::Interned(*id)); + value.display(self.interner).fmt(f) + } + Token::UnquoteMarker(id) => { + let value = Value::TypedExpr(TypedExpr::ExprId(*id)); + value.display(self.interner).fmt(f) + } + other => write!(f, "{other}"), + } + } +} + fn display_trait_constraint(interner: &NodeInterner, trait_constraint: &TraitConstraint) -> String { let trait_ = interner.get_trait(trait_constraint.trait_id); format!("{}: {}{}", trait_constraint.typ, trait_.name, trait_constraint.trait_generics) 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 6a6cabe593d..3cfa0989d7d 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 @@ -7,6 +7,8 @@ use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}; use crate::hir::resolution::errors::ResolverError; use crate::hir::resolution::path_resolver; use crate::hir::type_check::TypeCheckError; +use crate::token::SecondaryAttribute; +use crate::usage_tracker::UnusedItem; use crate::{Generics, Type}; use crate::hir::resolution::import::{resolve_import, ImportDirective, PathResolution}; @@ -111,6 +113,21 @@ pub struct UnresolvedGlobal { pub stmt_def: LetStatement, } +pub struct ModuleAttribute { + // The file in which the module is defined + pub file_id: FileId, + // The module this attribute is attached to + pub module_id: LocalModuleId, + // The file where the attribute exists (it could be the same as `file_id` + // or a different one if it's an inner attribute in a different file) + pub attribute_file_id: FileId, + // The module where the attribute is defined (similar to `attribute_file_id`, + // it could be different than `module_id` for inner attributes) + pub attribute_module_id: LocalModuleId, + pub attribute: SecondaryAttribute, + pub is_inner: bool, +} + /// Given a Crate root, collect all definitions in that crate pub struct DefCollector { pub(crate) def_map: CrateDefMap, @@ -127,6 +144,7 @@ pub struct CollectedItems { pub globals: Vec, pub(crate) impls: ImplMap, pub(crate) trait_impls: Vec, + pub(crate) module_attributes: Vec, } impl CollectedItems { @@ -238,6 +256,7 @@ impl DefCollector { impls: HashMap::default(), globals: vec![], trait_impls: vec![], + module_attributes: vec![], }, } } @@ -253,7 +272,7 @@ impl DefCollector { root_file_id: FileId, debug_comptime_in_file: Option<&str>, enable_arithmetic_generics: bool, - error_on_usage_tracker: bool, + error_on_unused_items: bool, macro_processors: &[&dyn MacroProcessor], ) -> Vec<(CompilationError, FileId)> { let mut errors: Vec<(CompilationError, FileId)> = vec![]; @@ -388,20 +407,14 @@ impl DefCollector { let result = current_def_map.modules[resolved_import.module_scope.0] .import(name.clone(), visibility, module_def_id, is_prelude); - // Empty spans could come from implicitly injected imports, and we don't want to track those - if visibility != ItemVisibility::Public - && name.span().start() < name.span().end() - { - let module_id = ModuleId { - krate: crate_id, - local_id: resolved_import.module_scope, - }; - - context - .def_interner - .usage_tracker - .add_unused_import(module_id, name.clone()); - } + let module_id = + ModuleId { krate: crate_id, local_id: resolved_import.module_scope }; + context.def_interner.usage_tracker.add_unused_item( + module_id, + name.clone(), + UnusedItem::Import, + visibility, + ); if visibility != ItemVisibility::Private { let local_id = resolved_import.module_scope; @@ -476,26 +489,29 @@ impl DefCollector { ); } - if error_on_usage_tracker { - Self::check_usage_tracker(context, crate_id, &mut errors); + if error_on_unused_items { + Self::check_unused_items(context, crate_id, &mut errors); } errors } - fn check_usage_tracker( + fn check_unused_items( context: &Context, crate_id: CrateId, errors: &mut Vec<(CompilationError, FileId)>, ) { - let unused_imports = context.def_interner.usage_tracker.unused_imports().iter(); + let unused_imports = context.def_interner.usage_tracker.unused_items().iter(); let unused_imports = unused_imports.filter(|(module_id, _)| module_id.krate == crate_id); errors.extend(unused_imports.flat_map(|(module_id, usage_tracker)| { let module = &context.def_maps[&crate_id].modules()[module_id.local_id.0]; - usage_tracker.iter().map(|ident| { + usage_tracker.iter().map(|(ident, unused_item)| { let ident = ident.clone(); - let error = CompilationError::ResolverError(ResolverError::UnusedImport { ident }); + let error = CompilationError::ResolverError(ResolverError::UnusedItem { + ident, + item_type: unused_item.item_type(), + }); (error, module.location.file) }) })); 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 590cdc541ce..6c1b7632a2e 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 @@ -15,8 +15,10 @@ use crate::ast::{ TypeImpl, }; use crate::hir::resolution::errors::ResolverError; -use crate::macros_api::{Expression, NodeInterner, UnresolvedType, UnresolvedTypeData}; +use crate::macros_api::{Expression, NodeInterner, StructId, UnresolvedType, UnresolvedTypeData}; use crate::node_interner::ModuleAttributes; +use crate::token::SecondaryAttribute; +use crate::usage_tracker::UnusedItem; use crate::{ graph::CrateId, hir::def_collector::dc_crate::{UnresolvedStruct, UnresolvedTrait}, @@ -26,6 +28,8 @@ use crate::{ }; use crate::{Generics, Kind, ResolvedGeneric, Type, TypeVariable}; +use super::dc_crate::CollectedItems; +use super::dc_crate::ModuleAttribute; use super::{ dc_crate::{ CompilationError, DefCollector, UnresolvedFunctions, UnresolvedGlobal, UnresolvedTraitImpl, @@ -33,7 +37,7 @@ use super::{ }, errors::{DefCollectorErrorKind, DuplicateType}, }; -use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleData, ModuleId}; +use crate::hir::def_map::{CrateDefMap, LocalModuleId, ModuleData, ModuleId, MAIN_FUNCTION}; use crate::hir::resolution::import::ImportDirective; use crate::hir::Context; @@ -63,8 +67,10 @@ pub fn collect_defs( for decl in ast.module_decls { errors.extend(collector.parse_module_declaration( context, - &decl, + decl, crate_id, + file_id, + module_id, macro_processors, )); } @@ -72,6 +78,7 @@ pub fn collect_defs( errors.extend(collector.collect_submodules( context, crate_id, + module_id, ast.submodules, file_id, macro_processors, @@ -102,10 +109,40 @@ pub fn collect_defs( collector.collect_impls(context, ast.impls, crate_id); + collector.collect_attributes( + ast.inner_attributes, + file_id, + module_id, + file_id, + module_id, + true, + ); + errors } impl<'a> ModCollector<'a> { + fn collect_attributes( + &mut self, + attributes: Vec, + file_id: FileId, + module_id: LocalModuleId, + attribute_file_id: FileId, + attribute_module_id: LocalModuleId, + is_inner: bool, + ) { + for attribute in attributes { + self.def_collector.items.module_attributes.push(ModuleAttribute { + file_id, + module_id, + attribute_file_id, + attribute_module_id, + attribute, + is_inner, + }); + } + } + fn collect_globals( &mut self, context: &mut Context, @@ -136,24 +173,13 @@ impl<'a> ModCollector<'a> { let module_id = ModuleId { krate, local_id: self.module_id }; for r#impl in impls { - let mut unresolved_functions = UnresolvedFunctions { - file_id: self.file_id, - functions: Vec::new(), - trait_id: None, - self_type: None, - }; - - for (mut method, _) in r#impl.methods { - let func_id = context.def_interner.push_empty_fn(); - method.def.where_clause.extend(r#impl.where_clause.clone()); - let location = Location::new(method.span(), self.file_id); - context.def_interner.push_function(func_id, &method.def, module_id, location); - unresolved_functions.push_fn(self.module_id, func_id, method); - } - - let key = (r#impl.object_type, self.module_id); - let methods = self.def_collector.items.impls.entry(key).or_default(); - methods.push((r#impl.generics, r#impl.type_span, unresolved_functions)); + collect_impl( + &mut context.def_interner, + &mut self.def_collector.items, + r#impl, + self.file_id, + module_id, + ); } } @@ -223,28 +249,16 @@ impl<'a> ModCollector<'a> { let module = ModuleId { krate, local_id: self.module_id }; for function in functions { - // check if optional field attribute is compatible with native field - if let Some(field) = function.attributes().get_field_attribute() { - if !is_native_field(&field) { - continue; - } - } - - let name = function.name_ident().clone(); - let func_id = context.def_interner.push_empty_fn(); - let visibility = function.def.visibility; - - // First create dummy function in the DefInterner - // So that we can get a FuncId - let location = Location::new(function.span(), self.file_id); - context.def_interner.push_function(func_id, &function.def, module, location); - - if context.def_interner.is_in_lsp_mode() - && !function.def.is_test() - && !function.def.is_private() - { - context.def_interner.register_function(func_id, &function.def); - } + let Some(func_id) = collect_function( + &mut context.def_interner, + &mut self.def_collector.def_map, + &function, + module, + self.file_id, + &mut errors, + ) else { + continue; + }; // Now link this func_id to a crate level map with the noir function and the module id // Encountering a NoirFunction, we retrieve it's module_data to get the namespace @@ -253,19 +267,6 @@ impl<'a> ModCollector<'a> { // With this method we iterate each function in the Crate and not each module // This may not be great because we have to pull the module_data for each function unresolved_functions.push_fn(self.module_id, func_id, function); - - // Add function to scope/ns of the module - let result = self.def_collector.def_map.modules[self.module_id.0] - .declare_function(name, visibility, func_id); - - if let Err((first_def, second_def)) = result { - let error = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Function, - first_def, - second_def, - }; - errors.push((error.into(), self.file_id)); - } } self.def_collector.items.functions.push(unresolved_functions); @@ -283,90 +284,21 @@ impl<'a> ModCollector<'a> { ) -> Vec<(CompilationError, FileId)> { let mut definition_errors = vec![]; for struct_definition in types { - self.check_duplicate_field_names(&struct_definition, &mut definition_errors); - - let name = struct_definition.name.clone(); - - let unresolved = UnresolvedStruct { - file_id: self.file_id, - module_id: self.module_id, - struct_def: struct_definition, - }; - - let resolved_generics = context.resolve_generics( - &unresolved.struct_def.generics, - &mut definition_errors, + if let Some((id, the_struct)) = collect_struct( + &mut context.def_interner, + &mut self.def_collector.def_map, + struct_definition, self.file_id, - ); - - // Create the corresponding module for the struct namespace - let id = match self.push_child_module( - context, - &name, - Location::new(name.span(), self.file_id), - false, - false, + self.module_id, + krate, + &mut definition_errors, ) { - Ok(module_id) => context.def_interner.new_struct( - &unresolved, - resolved_generics, - krate, - module_id.local_id, - self.file_id, - ), - Err(error) => { - definition_errors.push((error.into(), self.file_id)); - continue; - } - }; - - // Add the struct to scope so its path can be looked up later - let result = self.def_collector.def_map.modules[self.module_id.0] - .declare_struct(name.clone(), id); - - if let Err((first_def, second_def)) = result { - let error = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::TypeDefinition, - first_def, - second_def, - }; - definition_errors.push((error.into(), self.file_id)); - } - - // And store the TypeId -> StructType mapping somewhere it is reachable - self.def_collector.items.types.insert(id, unresolved); - - if context.def_interner.is_in_lsp_mode() { - let parent_module_id = ModuleId { krate, local_id: self.module_id }; - context.def_interner.register_struct(id, name.to_string(), parent_module_id); + self.def_collector.items.types.insert(id, the_struct); } } definition_errors } - fn check_duplicate_field_names( - &self, - struct_definition: &NoirStruct, - definition_errors: &mut Vec<(CompilationError, FileId)>, - ) { - let mut seen_field_names = std::collections::HashSet::new(); - for (field_name, _) in &struct_definition.fields { - if seen_field_names.insert(field_name) { - continue; - } - - let previous_field_name = *seen_field_names.get(field_name).unwrap(); - definition_errors.push(( - DefCollectorErrorKind::DuplicateField { - first_def: previous_field_name.clone(), - second_def: field_name.clone(), - } - .into(), - self.file_id, - )); - } - } - /// Collect any type aliases definitions declared within the ast. /// Returns a vector of errors if any type aliases were already defined. fn collect_type_aliases( @@ -386,7 +318,8 @@ impl<'a> ModCollector<'a> { type_alias_def: type_alias, }; - let resolved_generics = context.resolve_generics( + let resolved_generics = Context::resolve_generics( + &context.def_interner, &unresolved.type_alias_def.generics, &mut errors, self.file_id, @@ -436,6 +369,8 @@ impl<'a> ModCollector<'a> { context, &name, Location::new(name.span(), self.file_id), + Vec::new(), + Vec::new(), false, false, ) { @@ -587,8 +522,12 @@ impl<'a> ModCollector<'a> { } } - let resolved_generics = - context.resolve_generics(&trait_definition.generics, &mut errors, self.file_id); + let resolved_generics = Context::resolve_generics( + &context.def_interner, + &trait_definition.generics, + &mut errors, + self.file_id, + ); let unresolved = UnresolvedTrait { file_id: self.file_id, @@ -619,6 +558,7 @@ impl<'a> ModCollector<'a> { &mut self, context: &mut Context, crate_id: CrateId, + parent_module_id: LocalModuleId, submodules: Vec, file_id: FileId, macro_processors: &[&dyn MacroProcessor], @@ -629,10 +569,21 @@ impl<'a> ModCollector<'a> { context, &submodule.name, Location::new(submodule.name.span(), file_id), + submodule.outer_attributes.clone(), + submodule.contents.inner_attributes.clone(), true, submodule.is_contract, ) { Ok(child) => { + self.collect_attributes( + submodule.outer_attributes, + file_id, + child.local_id, + file_id, + parent_module_id, + false, + ); + errors.extend(collect_defs( self.def_collector, submodule.contents, @@ -657,8 +608,10 @@ impl<'a> ModCollector<'a> { fn parse_module_declaration( &mut self, context: &mut Context, - mod_decl: &ModuleDeclaration, + mod_decl: ModuleDeclaration, crate_id: CrateId, + parent_file_id: FileId, + parent_module_id: LocalModuleId, macro_processors: &[&dyn MacroProcessor], ) -> Vec<(CompilationError, FileId)> { let mut errors: Vec<(CompilationError, FileId)> = vec![]; @@ -720,10 +673,21 @@ impl<'a> ModCollector<'a> { context, &mod_decl.ident, Location::new(Span::empty(0), child_file_id), + mod_decl.outer_attributes.clone(), + ast.inner_attributes.clone(), true, false, ) { Ok(child_mod_id) => { + self.collect_attributes( + mod_decl.outer_attributes, + child_file_id, + child_mod_id.local_id, + parent_file_id, + parent_module_id, + false, + ); + // Track that the "foo" in `mod foo;` points to the module "foo" context.def_interner.add_module_reference(child_mod_id, location); @@ -746,71 +710,28 @@ impl<'a> ModCollector<'a> { /// Add a child module to the current def_map. /// On error this returns None and pushes to `errors` + #[allow(clippy::too_many_arguments)] fn push_child_module( &mut self, context: &mut Context, mod_name: &Ident, mod_location: Location, + outer_attributes: Vec, + inner_attributes: Vec, add_to_parent_scope: bool, is_contract: bool, ) -> Result { - let parent = Some(self.module_id); - - // Note: the difference between `location` and `mod_location` is: - // - `mod_location` will point to either the token "foo" in `mod foo { ... }` - // if it's an inline module, or the first char of a the file if it's an external module. - // - `location` will always point to the token "foo" in `mod foo` regardless of whether - // it's inline or external. - // Eventually the location put in `ModuleData` is used for codelenses about `contract`s, - // so we keep using `location` so that it continues to work as usual. - let location = Location::new(mod_name.span(), mod_location.file); - let new_module = ModuleData::new(parent, location, is_contract); - let module_id = self.def_collector.def_map.modules.insert(new_module); - - let modules = &mut self.def_collector.def_map.modules; - - // Update the parent module to reference the child - modules[self.module_id.0].children.insert(mod_name.clone(), LocalModuleId(module_id)); - - let mod_id = ModuleId { - krate: self.def_collector.def_map.krate, - local_id: LocalModuleId(module_id), - }; - - // Add this child module into the scope of the parent module as a module definition - // module definitions are definitions which can only exist at the module level. - // ModuleDefinitionIds can be used across crates since they contain the CrateId - // - // We do not want to do this in the case of struct modules (each struct type corresponds - // to a child module containing its methods) since the module name should not shadow - // the struct name. - if add_to_parent_scope { - if let Err((first_def, second_def)) = - modules[self.module_id.0].declare_child_module(mod_name.to_owned(), mod_id) - { - let err = DefCollectorErrorKind::Duplicate { - typ: DuplicateType::Module, - first_def, - second_def, - }; - return Err(err); - } - - context.def_interner.add_module_attributes( - mod_id, - ModuleAttributes { - name: mod_name.0.contents.clone(), - location: mod_location, - parent: Some(self.module_id), - }, - ); - - if context.def_interner.is_in_lsp_mode() { - context.def_interner.register_module(mod_id, mod_name.0.contents.clone()); - } - } - - Ok(mod_id) + push_child_module( + &mut context.def_interner, + &mut self.def_collector.def_map, + self.module_id, + mod_name, + mod_location, + outer_attributes, + inner_attributes, + add_to_parent_scope, + is_contract, + ) } fn resolve_associated_constant_type( @@ -831,6 +752,212 @@ impl<'a> ModCollector<'a> { } } +/// Add a child module to the current def_map. +/// On error this returns None and pushes to `errors` +#[allow(clippy::too_many_arguments)] +fn push_child_module( + interner: &mut NodeInterner, + def_map: &mut CrateDefMap, + parent: LocalModuleId, + mod_name: &Ident, + mod_location: Location, + outer_attributes: Vec, + inner_attributes: Vec, + add_to_parent_scope: bool, + is_contract: bool, +) -> Result { + // Note: the difference between `location` and `mod_location` is: + // - `mod_location` will point to either the token "foo" in `mod foo { ... }` + // if it's an inline module, or the first char of a the file if it's an external module. + // - `location` will always point to the token "foo" in `mod foo` regardless of whether + // it's inline or external. + // Eventually the location put in `ModuleData` is used for codelenses about `contract`s, + // so we keep using `location` so that it continues to work as usual. + let location = Location::new(mod_name.span(), mod_location.file); + let new_module = + ModuleData::new(Some(parent), location, outer_attributes, inner_attributes, is_contract); + + let module_id = def_map.modules.insert(new_module); + let modules = &mut def_map.modules; + + // Update the parent module to reference the child + modules[parent.0].children.insert(mod_name.clone(), LocalModuleId(module_id)); + + let mod_id = ModuleId { krate: def_map.krate, local_id: LocalModuleId(module_id) }; + + // Add this child module into the scope of the parent module as a module definition + // module definitions are definitions which can only exist at the module level. + // ModuleDefinitionIds can be used across crates since they contain the CrateId + // + // We do not want to do this in the case of struct modules (each struct type corresponds + // to a child module containing its methods) since the module name should not shadow + // the struct name. + if add_to_parent_scope { + if let Err((first_def, second_def)) = + modules[parent.0].declare_child_module(mod_name.to_owned(), mod_id) + { + let err = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Module, + first_def, + second_def, + }; + return Err(err); + } + + interner.add_module_attributes( + mod_id, + ModuleAttributes { + name: mod_name.0.contents.clone(), + location: mod_location, + parent: Some(parent), + }, + ); + + if interner.is_in_lsp_mode() { + interner.register_module(mod_id, mod_name.0.contents.clone()); + } + } + + Ok(mod_id) +} + +pub fn collect_function( + interner: &mut NodeInterner, + def_map: &mut CrateDefMap, + function: &NoirFunction, + module: ModuleId, + file: FileId, + errors: &mut Vec<(CompilationError, FileId)>, +) -> Option { + if let Some(field) = function.attributes().get_field_attribute() { + if !is_native_field(&field) { + return None; + } + } + + let module_data = &mut def_map.modules[module.local_id.0]; + + let is_test = function.def.attributes.is_test_function(); + let is_entry_point_function = if module_data.is_contract { + function.attributes().is_contract_entry_point() + } else { + function.name() == MAIN_FUNCTION + }; + + let name = function.name_ident().clone(); + let func_id = interner.push_empty_fn(); + let visibility = function.def.visibility; + let location = Location::new(function.span(), file); + interner.push_function(func_id, &function.def, module, location); + if interner.is_in_lsp_mode() && !function.def.is_test() { + interner.register_function(func_id, &function.def); + } + + if !is_test && !is_entry_point_function { + let item = UnusedItem::Function(func_id); + interner.usage_tracker.add_unused_item(module, name.clone(), item, visibility); + } + + // Add function to scope/ns of the module + let result = def_map.modules[module.local_id.0].declare_function(name, visibility, func_id); + if let Err((first_def, second_def)) = result { + let error = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::Function, + first_def, + second_def, + }; + errors.push((error.into(), file)); + } + Some(func_id) +} + +pub fn collect_struct( + interner: &mut NodeInterner, + def_map: &mut CrateDefMap, + struct_definition: NoirStruct, + file_id: FileId, + module_id: LocalModuleId, + krate: CrateId, + definition_errors: &mut Vec<(CompilationError, FileId)>, +) -> Option<(StructId, UnresolvedStruct)> { + check_duplicate_field_names(&struct_definition, file_id, definition_errors); + + let name = struct_definition.name.clone(); + + let unresolved = UnresolvedStruct { file_id, module_id, struct_def: struct_definition }; + + let resolved_generics = Context::resolve_generics( + interner, + &unresolved.struct_def.generics, + definition_errors, + file_id, + ); + + // Create the corresponding module for the struct namespace + let location = Location::new(name.span(), file_id); + let id = match push_child_module( + interner, + def_map, + module_id, + &name, + location, + Vec::new(), + Vec::new(), + false, + false, + ) { + Ok(module_id) => { + interner.new_struct(&unresolved, resolved_generics, krate, module_id.local_id, file_id) + } + Err(error) => { + definition_errors.push((error.into(), file_id)); + return None; + } + }; + + // Add the struct to scope so its path can be looked up later + let result = def_map.modules[module_id.0].declare_struct(name.clone(), id); + + if let Err((first_def, second_def)) = result { + let error = DefCollectorErrorKind::Duplicate { + typ: DuplicateType::TypeDefinition, + first_def, + second_def, + }; + definition_errors.push((error.into(), file_id)); + } + + if interner.is_in_lsp_mode() { + let parent_module_id = ModuleId { krate, local_id: module_id }; + interner.register_struct(id, name.to_string(), parent_module_id); + } + + Some((id, unresolved)) +} + +pub fn collect_impl( + interner: &mut NodeInterner, + items: &mut CollectedItems, + r#impl: TypeImpl, + file_id: FileId, + module_id: ModuleId, +) { + let mut unresolved_functions = + UnresolvedFunctions { file_id, functions: Vec::new(), trait_id: None, self_type: None }; + + for (mut method, _) in r#impl.methods { + let func_id = interner.push_empty_fn(); + method.def.where_clause.extend(r#impl.where_clause.clone()); + let location = Location::new(method.span(), file_id); + interner.push_function(func_id, &method.def, module_id, location); + unresolved_functions.push_fn(module_id.local_id, func_id, method); + } + + let key = (r#impl.object_type, module_id.local_id); + let methods = items.impls.entry(key).or_default(); + methods.push((r#impl.generics, r#impl.type_span, unresolved_functions)); +} + fn find_module( file_manager: &FileManager, anchor: FileId, @@ -989,6 +1116,29 @@ pub(crate) fn collect_global( (global, error) } +fn check_duplicate_field_names( + struct_definition: &NoirStruct, + file: FileId, + definition_errors: &mut Vec<(CompilationError, FileId)>, +) { + let mut seen_field_names = std::collections::HashSet::new(); + for (field_name, _) in &struct_definition.fields { + if seen_field_names.insert(field_name) { + continue; + } + + let previous_field_name = *seen_field_names.get(field_name).unwrap(); + definition_errors.push(( + DefCollectorErrorKind::DuplicateField { + first_def: previous_field_name.clone(), + second_def: field_name.clone(), + } + .into(), + file, + )); + } +} + #[cfg(test)] mod find_module_tests { use super::*; diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/mod.rs index 758b4cf6e5c..a1c4d04cb30 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -111,7 +111,13 @@ impl CrateDefMap { // Allocate a default Module for the root, giving it a ModuleId let mut modules: Arena = Arena::default(); let location = Location::new(Default::default(), root_file_id); - let root = modules.insert(ModuleData::new(None, location, false)); + let root = modules.insert(ModuleData::new( + None, + location, + Vec::new(), + ast.inner_attributes.clone(), + false, + )); let def_map = CrateDefMap { root: LocalModuleId(root), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/module_data.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/module_data.rs index f9542094be7..e829df3572c 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/module_data.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/def_map/module_data.rs @@ -5,6 +5,7 @@ use noirc_errors::Location; use super::{ItemScope, LocalModuleId, ModuleDefId, ModuleId, PerNs}; use crate::ast::{Ident, ItemVisibility}; use crate::node_interner::{FuncId, GlobalId, StructId, TraitId, TypeAliasId}; +use crate::token::SecondaryAttribute; /// Contains the actual contents of a module: its parent (if one exists), /// children, and scope with all definitions defined within the scope. @@ -24,10 +25,25 @@ pub struct ModuleData { /// True if this module is a `contract Foo { ... }` module containing contract functions pub is_contract: bool, + + pub outer_attributes: Vec, + pub inner_attributes: Vec, } impl ModuleData { - pub fn new(parent: Option, location: Location, is_contract: bool) -> ModuleData { + pub fn new( + parent: Option, + location: Location, + outer_attributes: Vec, + inner_attributes: Vec, + is_contract: bool, + ) -> ModuleData { + let outer_attributes = outer_attributes.iter().filter_map(|attr| attr.as_custom()); + let outer_attributes = outer_attributes.map(|attr| attr.contents.to_string()).collect(); + + let inner_attributes = inner_attributes.iter().filter_map(|attr| attr.as_custom()); + let inner_attributes = inner_attributes.map(|attr| attr.contents.to_string()).collect(); + ModuleData { parent, children: HashMap::new(), @@ -35,6 +51,8 @@ impl ModuleData { definitions: ItemScope::default(), location, is_contract, + outer_attributes, + inner_attributes, } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs index e4f000778d1..c631edfa889 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/mod.rs @@ -272,14 +272,14 @@ impl Context<'_, '_> { /// Each result is returned in a list rather than returned as a single result as to allow /// definition collection to provide an error for each ill-formed numeric generic. pub(crate) fn resolve_generics( - &mut self, + interner: &NodeInterner, generics: &UnresolvedGenerics, errors: &mut Vec<(CompilationError, FileId)>, file_id: FileId, ) -> Generics { vecmap(generics, |generic| { // Map the generic to a fresh type variable - let id = self.def_interner.next_type_variable_id(); + let id = interner.next_type_variable_id(); let type_var = TypeVariable::unbound(id); let ident = generic.ident(); let span = ident.0.span(); diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs index cede04dd582..e74468bdf18 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -20,8 +20,8 @@ pub enum ResolverError { DuplicateDefinition { name: String, first_span: Span, second_span: Span }, #[error("Unused variable")] UnusedVariable { ident: Ident }, - #[error("Unused import")] - UnusedImport { ident: Ident }, + #[error("Unused {item_type}")] + UnusedItem { ident: Ident, item_type: &'static str }, #[error("Could not find variable in this scope")] VariableNotDeclared { name: String, span: Span }, #[error("path is not an identifier")] @@ -72,7 +72,7 @@ pub enum ResolverError { NumericConstantInFormatString { name: String, span: Span }, #[error("Closure environment must be a tuple or unit type")] InvalidClosureEnvironment { typ: Type, span: Span }, - #[error("Nested slices are not supported")] + #[error("Nested slices, i.e. slices within an array or slice, are not supported")] NestedSlices { span: Span }, #[error("#[recursive] attribute is only allowed on entry points to a program")] MisplacedRecursiveAttribute { ident: Ident }, @@ -158,12 +158,12 @@ impl<'a> From<&'a ResolverError> for Diagnostic { diagnostic.unnecessary = true; diagnostic } - ResolverError::UnusedImport { ident } => { + ResolverError::UnusedItem { ident, item_type } => { let name = &ident.0.contents; let mut diagnostic = Diagnostic::simple_warning( - format!("unused import {name}"), - "unused import ".to_string(), + format!("unused {item_type} {name}"), + format!("unused {item_type}"), ident.span(), ); diagnostic.unnecessary = true; @@ -323,8 +323,8 @@ impl<'a> From<&'a ResolverError> for Diagnostic { format!("{typ} is not a valid closure environment type"), "Closure environment must be a tuple or unit type".to_string(), *span), ResolverError::NestedSlices { span } => Diagnostic::simple_error( - "Nested slices are not supported".into(), - "Try to use a constant sized array instead".into(), + "Nested slices, i.e. slices within an array or slice, are not supported".into(), + "Try to use a constant sized array or BoundedVec instead".into(), *span, ), ResolverError::MisplacedRecursiveAttribute { ident } => { diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs index 7fa33746f31..8e3baef1d00 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/function.rs @@ -10,6 +10,7 @@ use crate::graph::CrateId; use crate::hir::def_map::LocalModuleId; use crate::macros_api::{BlockExpression, StructId}; use crate::node_interner::{ExprId, NodeInterner, TraitId, TraitImplId}; +use crate::token::CustomAtrribute; use crate::{ResolvedGeneric, Type}; /// A Hir function is a block expression with a list of statements. @@ -166,7 +167,7 @@ pub struct FuncMeta { pub self_type: Option, /// Custom attributes attached to this function. - pub custom_attributes: Vec, + pub custom_attributes: Vec, } #[derive(Debug, Clone)] diff --git a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs index 638003d3fcd..7b3d0d7a205 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/hir_def/types.rs @@ -1467,21 +1467,13 @@ impl Type { /// equal to the other type in the process. When comparing types, unification /// (including try_unify) are almost always preferred over Type::eq as unification /// will correctly handle generic types. - pub fn unify( - &self, - expected: &Type, - errors: &mut Vec, - make_error: impl FnOnce() -> TypeCheckError, - ) { + pub fn unify(&self, expected: &Type) -> Result<(), UnificationError> { let mut bindings = TypeBindings::new(); - match self.try_unify(expected, &mut bindings) { - Ok(()) => { - // Commit any type bindings on success - Self::apply_type_bindings(bindings); - } - Err(UnificationError) => errors.push(make_error()), - } + self.try_unify(expected, &mut bindings).map(|()| { + // Commit any type bindings on success + Self::apply_type_bindings(bindings); + }) } /// `try_unify` is a bit of a misnomer since although errors are not committed, diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/errors.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/errors.rs index be5180a777b..2440109af15 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/errors.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/errors.rs @@ -20,6 +20,8 @@ pub enum LexerErrorKind { IntegerLiteralTooLarge { span: Span, limit: String }, #[error("{:?} is not a valid attribute", found)] MalformedFuncAttribute { span: Span, found: String }, + #[error("{:?} is not a valid inner attribute", found)] + InvalidInnerAttribute { span: Span, found: String }, #[error("Logical and used instead of bitwise and")] LogicalAnd { span: Span }, #[error("Unterminated block comment")] @@ -57,6 +59,7 @@ impl LexerErrorKind { LexerErrorKind::InvalidIntegerLiteral { span, .. } => *span, LexerErrorKind::IntegerLiteralTooLarge { span, .. } => *span, LexerErrorKind::MalformedFuncAttribute { span, .. } => *span, + LexerErrorKind::InvalidInnerAttribute { span, .. } => *span, LexerErrorKind::LogicalAnd { span } => *span, LexerErrorKind::UnterminatedBlockComment { span } => *span, LexerErrorKind::UnterminatedStringLiteral { span } => *span, @@ -103,6 +106,11 @@ impl LexerErrorKind { format!(" {found} is not a valid attribute"), *span, ), + LexerErrorKind::InvalidInnerAttribute { span, found } => ( + "Invalid inner attribute".to_string(), + format!(" {found} is not a valid inner attribute"), + *span, + ), LexerErrorKind::LogicalAnd { span } => ( "Noir has no logical-and (&&) operator since short-circuiting is much less efficient when compiling to circuits".to_string(), "Try `&` instead, or use `if` only if you require short-circuiting".to_string(), diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs index 0afcb02caac..b7492396c90 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/lexer.rs @@ -286,6 +286,13 @@ impl<'a> Lexer<'a> { fn eat_attribute(&mut self) -> SpannedTokenResult { let start = self.position; + let is_inner = if self.peek_char_is('!') { + self.next_char(); + true + } else { + false + }; + if !self.peek_char_is('[') { return Err(LexerErrorKind::UnexpectedCharacter { span: Span::single_char(self.position), @@ -295,8 +302,12 @@ impl<'a> Lexer<'a> { } self.next_char(); + let contents_start = self.position + 1; + let word = self.eat_while(None, |ch| ch != ']'); + let contents_end = self.position; + if !self.peek_char_is(']') { return Err(LexerErrorKind::UnexpectedCharacter { span: Span::single_char(self.position), @@ -308,9 +319,23 @@ impl<'a> Lexer<'a> { let end = self.position; - let attribute = Attribute::lookup_attribute(&word, Span::inclusive(start, end))?; - - Ok(attribute.into_span(start, end)) + let span = Span::inclusive(start, end); + let contents_span = Span::inclusive(contents_start, contents_end); + + let attribute = Attribute::lookup_attribute(&word, span, contents_span)?; + if is_inner { + match attribute { + Attribute::Function(attribute) => Err(LexerErrorKind::InvalidInnerAttribute { + span: Span::from(start..end), + found: attribute.to_string(), + }), + Attribute::Secondary(attribute) => { + Ok(Token::InnerAttribute(attribute).into_span(start, end)) + } + } + } else { + Ok(Token::Attribute(attribute).into_span(start, end)) + } } //XXX(low): Can increase performance if we use iterator semantic and utilize some of the methods on String. See below @@ -682,7 +707,7 @@ mod tests { use iter_extended::vecmap; use super::*; - use crate::token::{FunctionAttribute, SecondaryAttribute, TestScope}; + use crate::token::{CustomAtrribute, FunctionAttribute, SecondaryAttribute, TestScope}; #[test] fn test_single_double_char() { @@ -810,9 +835,11 @@ mod tests { let token = lexer.next_token().unwrap(); assert_eq!( token.token(), - &Token::Attribute(Attribute::Secondary(SecondaryAttribute::Custom( - "custom(hello)".to_string() - ))) + &Token::Attribute(Attribute::Secondary(SecondaryAttribute::Custom(CustomAtrribute { + contents: "custom(hello)".to_string(), + span: Span::from(0..16), + contents_span: Span::from(2..15) + }))) ); } @@ -898,6 +925,22 @@ mod tests { assert_eq!(sub_string, "test(invalid_scope)"); } + #[test] + fn test_inner_attribute() { + let input = r#"#![something]"#; + let mut lexer = Lexer::new(input); + + let token = lexer.next_token().unwrap(); + assert_eq!( + token.token(), + &Token::InnerAttribute(SecondaryAttribute::Custom(CustomAtrribute { + contents: "something".to_string(), + span: Span::from(0..13), + contents_span: Span::from(3..12), + })) + ); + } + #[test] fn test_int_type() { let input = "u16 i16 i108 u104.5"; diff --git a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs index 585e22ce92b..7b805b5fd8d 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/lexer/token.rs @@ -27,6 +27,7 @@ pub enum BorrowedToken<'input> { Keyword(Keyword), IntType(IntType), Attribute(Attribute), + InnerAttribute(SecondaryAttribute), LineComment(&'input str, Option), BlockComment(&'input str, Option), Quote(&'input Tokens), @@ -132,6 +133,7 @@ pub enum Token { Keyword(Keyword), IntType(IntType), Attribute(Attribute), + InnerAttribute(SecondaryAttribute), LineComment(String, Option), BlockComment(String, Option), // A `quote { ... }` along with the tokens in its token stream. @@ -244,6 +246,7 @@ pub fn token_to_borrowed_token(token: &Token) -> BorrowedToken<'_> { Token::RawStr(ref b, hashes) => BorrowedToken::RawStr(b, *hashes), Token::Keyword(k) => BorrowedToken::Keyword(*k), Token::Attribute(ref a) => BorrowedToken::Attribute(a.clone()), + Token::InnerAttribute(ref a) => BorrowedToken::InnerAttribute(a.clone()), Token::LineComment(ref s, _style) => BorrowedToken::LineComment(s, *_style), Token::BlockComment(ref s, _style) => BorrowedToken::BlockComment(s, *_style), Token::Quote(stream) => BorrowedToken::Quote(stream), @@ -363,6 +366,7 @@ impl fmt::Display for Token { } Token::Keyword(k) => write!(f, "{k}"), Token::Attribute(ref a) => write!(f, "{a}"), + Token::InnerAttribute(ref a) => write!(f, "#![{a}]"), Token::LineComment(ref s, _style) => write!(f, "//{s}"), Token::BlockComment(ref s, _style) => write!(f, "/*{s}*/"), Token::Quote(ref stream) => { @@ -428,6 +432,7 @@ pub enum TokenKind { Literal, Keyword, Attribute, + InnerAttribute, Quote, QuotedType, InternedExpr, @@ -445,6 +450,7 @@ impl fmt::Display for TokenKind { TokenKind::Literal => write!(f, "literal"), TokenKind::Keyword => write!(f, "keyword"), TokenKind::Attribute => write!(f, "attribute"), + TokenKind::InnerAttribute => write!(f, "inner attribute"), TokenKind::Quote => write!(f, "quote"), TokenKind::QuotedType => write!(f, "quoted type"), TokenKind::InternedExpr => write!(f, "interned expr"), @@ -467,6 +473,7 @@ impl Token { | Token::FmtStr(_) => TokenKind::Literal, Token::Keyword(_) => TokenKind::Keyword, Token::Attribute(_) => TokenKind::Attribute, + Token::InnerAttribute(_) => TokenKind::InnerAttribute, Token::UnquoteMarker(_) => TokenKind::UnquoteMarker, Token::Quote(_) => TokenKind::Quote, Token::QuotedType(_) => TokenKind::QuotedType, @@ -697,7 +704,11 @@ impl fmt::Display for Attribute { impl Attribute { /// If the string is a fixed attribute return that, else /// return the custom attribute - pub(crate) fn lookup_attribute(word: &str, span: Span) -> Result { + pub(crate) fn lookup_attribute( + word: &str, + span: Span, + contents_span: Span, + ) -> Result { let word_segments: Vec<&str> = word .split(|c| c == '(' || c == ')') .filter(|string_segment| !string_segment.is_empty()) @@ -770,11 +781,15 @@ impl Attribute { ["varargs"] => Attribute::Secondary(SecondaryAttribute::Varargs), tokens => { tokens.iter().try_for_each(|token| validate(token))?; - Attribute::Secondary(SecondaryAttribute::Custom(word.to_owned())) + Attribute::Secondary(SecondaryAttribute::Custom(CustomAtrribute { + contents: word.to_owned(), + span, + contents_span, + })) } }; - Ok(Token::Attribute(attribute)) + Ok(attribute) } } @@ -863,17 +878,26 @@ pub enum SecondaryAttribute { ContractLibraryMethod, Export, Field(String), - Custom(String), + Custom(CustomAtrribute), Abi(String), /// A variable-argument comptime function. Varargs, } +#[derive(PartialEq, Eq, Hash, Debug, Clone, PartialOrd, Ord)] +pub struct CustomAtrribute { + pub contents: String, + // The span of the entire attribute, including leading `#[` and trailing `]` + pub span: Span, + // The span for the attribute contents (what's inside `#[...]`) + pub contents_span: Span, +} + impl SecondaryAttribute { - pub(crate) fn as_custom(&self) -> Option<&str> { - if let Self::Custom(str) = self { - Some(str) + pub(crate) fn as_custom(&self) -> Option<&CustomAtrribute> { + if let Self::Custom(attribute) = self { + Some(attribute) } else { None } @@ -887,7 +911,7 @@ impl fmt::Display for SecondaryAttribute { SecondaryAttribute::Deprecated(Some(ref note)) => { write!(f, r#"#[deprecated("{note}")]"#) } - SecondaryAttribute::Custom(ref k) => write!(f, "#[{k}]"), + SecondaryAttribute::Custom(ref attribute) => write!(f, "#[{}]", attribute.contents), SecondaryAttribute::ContractLibraryMethod => write!(f, "#[contract_library_method]"), SecondaryAttribute::Export => write!(f, "#[export]"), SecondaryAttribute::Field(ref k) => write!(f, "#[field({k})]"), @@ -916,9 +940,8 @@ impl AsRef for SecondaryAttribute { match self { SecondaryAttribute::Deprecated(Some(string)) => string, SecondaryAttribute::Deprecated(None) => "", - SecondaryAttribute::Custom(string) - | SecondaryAttribute::Field(string) - | SecondaryAttribute::Abi(string) => string, + SecondaryAttribute::Custom(attribute) => &attribute.contents, + SecondaryAttribute::Field(string) | SecondaryAttribute::Abi(string) => string, SecondaryAttribute::ContractLibraryMethod => "", SecondaryAttribute::Export => "", SecondaryAttribute::Varargs => "", 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 4a73df6a15f..aa51779d24b 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/node_interner.rs @@ -655,7 +655,7 @@ impl Default for NodeInterner { auto_import_names: HashMap::default(), comptime_scopes: vec![HashMap::default()], trait_impl_associated_types: HashMap::default(), - usage_tracker: UsageTracker::default(), + usage_tracker: UsageTracker::new(), } } } 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 c82906b69a2..596d15176bc 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/mod.rs @@ -16,7 +16,7 @@ use crate::ast::{ NoirFunction, NoirStruct, NoirTrait, NoirTraitImpl, NoirTypeAlias, Recoverable, StatementKind, TypeImpl, UseTree, }; -use crate::token::{Keyword, Token}; +use crate::token::{Keyword, SecondaryAttribute, Token}; use chumsky::prelude::*; use chumsky::primitive::Container; @@ -41,6 +41,7 @@ pub enum TopLevelStatement { TypeAlias(NoirTypeAlias), SubModule(ParsedSubModule), Global(LetStatement), + InnerAttribute(SecondaryAttribute), Error, } @@ -57,6 +58,7 @@ impl TopLevelStatement { TopLevelStatement::TypeAlias(t) => Some(ItemKind::TypeAlias(t)), TopLevelStatement::SubModule(s) => Some(ItemKind::Submodules(s)), TopLevelStatement::Global(c) => Some(ItemKind::Global(c)), + TopLevelStatement::InnerAttribute(a) => Some(ItemKind::InnerAttribute(a)), TopLevelStatement::Error => None, } } @@ -247,6 +249,8 @@ pub struct SortedModule { /// Full submodules as in `mod foo { ... definitions ... }` pub submodules: Vec, + + pub inner_attributes: Vec, } impl std::fmt::Display for SortedModule { @@ -309,6 +313,7 @@ impl ParsedModule { ItemKind::Global(global) => module.push_global(global), ItemKind::ModuleDecl(mod_name) => module.push_module_decl(mod_name), ItemKind::Submodules(submodule) => module.push_submodule(submodule.into_sorted()), + ItemKind::InnerAttribute(attribute) => module.inner_attributes.push(attribute), } } @@ -334,6 +339,7 @@ pub enum ItemKind { Global(LetStatement), ModuleDecl(ModuleDeclaration), Submodules(ParsedSubModule), + InnerAttribute(SecondaryAttribute), } /// A submodule defined via `mod name { contents }` in some larger file. @@ -342,6 +348,7 @@ pub enum ItemKind { pub struct ParsedSubModule { pub name: Ident, pub contents: ParsedModule, + pub outer_attributes: Vec, pub is_contract: bool, } @@ -350,6 +357,7 @@ impl ParsedSubModule { SortedSubModule { name: self.name, contents: self.contents.into_sorted(), + outer_attributes: self.outer_attributes, is_contract: self.is_contract, } } @@ -371,6 +379,7 @@ impl std::fmt::Display for SortedSubModule { pub struct SortedSubModule { pub name: Ident, pub contents: SortedModule, + pub outer_attributes: Vec, pub is_contract: bool, } @@ -512,6 +521,7 @@ impl std::fmt::Display for TopLevelStatement { TopLevelStatement::TypeAlias(t) => t.fmt(f), TopLevelStatement::SubModule(s) => s.fmt(f), TopLevelStatement::Global(c) => c.fmt(f), + TopLevelStatement::InnerAttribute(a) => write!(f, "#![{}]", a), TopLevelStatement::Error => write!(f, "error"), } } diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs index bead1e69006..2bc7a88c6c5 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser.rs @@ -26,6 +26,7 @@ use self::path::as_trait_path; use self::primitives::{keyword, macro_quote_marker, mutable_reference, variable}; use self::types::{generic_type_args, maybe_comp_time}; +use attributes::{attributes, inner_attribute, validate_secondary_attributes}; pub use types::parse_type; use visibility::visibility_modifier; @@ -91,7 +92,7 @@ pub fn parse_program(source_program: &str) -> (ParsedModule, Vec) { let (module, mut parsing_errors) = program().parse_recovery_verbose(tokens); parsing_errors.extend(lexing_errors.into_iter().map(Into::into)); - let parsed_module = module.unwrap_or(ParsedModule { items: vec![] }); + let parsed_module = module.unwrap_or_default(); if cfg!(feature = "experimental_parser") { for parsed_item in &parsed_module.items { @@ -215,6 +216,7 @@ fn top_level_statement<'a>( module_declaration().then_ignore(force(just(Token::Semicolon))), use_statement().then_ignore(force(just(Token::Semicolon))), global_declaration().then_ignore(force(just(Token::Semicolon))), + inner_attribute().map(TopLevelStatement::InnerAttribute), )) .recover_via(top_level_statement_recovery()) } @@ -287,25 +289,39 @@ fn global_declaration() -> impl NoirParser { /// submodule: 'mod' ident '{' module '}' fn submodule(module_parser: impl NoirParser) -> impl NoirParser { - keyword(Keyword::Mod) - .ignore_then(ident()) + attributes() + .then_ignore(keyword(Keyword::Mod)) + .then(ident()) .then_ignore(just(Token::LeftBrace)) .then(module_parser) .then_ignore(just(Token::RightBrace)) - .map(|(name, contents)| { - TopLevelStatement::SubModule(ParsedSubModule { name, contents, is_contract: false }) + .validate(|((attributes, name), contents), span, emit| { + let attributes = validate_secondary_attributes(attributes, span, emit); + TopLevelStatement::SubModule(ParsedSubModule { + name, + contents, + outer_attributes: attributes, + is_contract: false, + }) }) } /// contract: 'contract' ident '{' module '}' fn contract(module_parser: impl NoirParser) -> impl NoirParser { - keyword(Keyword::Contract) - .ignore_then(ident()) + attributes() + .then_ignore(keyword(Keyword::Contract)) + .then(ident()) .then_ignore(just(Token::LeftBrace)) .then(module_parser) .then_ignore(just(Token::RightBrace)) - .map(|(name, contents)| { - TopLevelStatement::SubModule(ParsedSubModule { name, contents, is_contract: true }) + .validate(|((attributes, name), contents), span, emit| { + let attributes = validate_secondary_attributes(attributes, span, emit); + TopLevelStatement::SubModule(ParsedSubModule { + name, + contents, + outer_attributes: attributes, + is_contract: true, + }) }) } @@ -434,9 +450,12 @@ fn optional_type_annotation<'a>() -> impl NoirParser + 'a { } fn module_declaration() -> impl NoirParser { - keyword(Keyword::Mod) - .ignore_then(ident()) - .map(|ident| TopLevelStatement::Module(ModuleDeclaration { ident })) + attributes().then_ignore(keyword(Keyword::Mod)).then(ident()).validate( + |(attributes, ident), span, emit| { + let attributes = validate_secondary_attributes(attributes, span, emit); + TopLevelStatement::Module(ModuleDeclaration { ident, outer_attributes: attributes }) + }, + ) } fn use_statement() -> impl NoirParser { @@ -1522,9 +1541,22 @@ mod test { #[test] fn parse_module_declaration() { parse_with(module_declaration(), "mod foo").unwrap(); + parse_with(module_declaration(), "#[attr] mod foo").unwrap(); parse_with(module_declaration(), "mod 1").unwrap_err(); } + #[test] + fn parse_submodule_declaration() { + parse_with(submodule(module()), "mod foo {}").unwrap(); + parse_with(submodule(module()), "#[attr] mod foo {}").unwrap(); + } + + #[test] + fn parse_contract() { + parse_with(contract(module()), "contract foo {}").unwrap(); + parse_with(contract(module()), "#[attr] contract foo {}").unwrap(); + } + #[test] fn parse_use() { let valid_use_statements = [ diff --git a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/attributes.rs b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/attributes.rs index 47add6f82e0..66d0ca29ca6 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/attributes.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/parser/parser/attributes.rs @@ -67,3 +67,12 @@ pub(super) fn validate_secondary_attributes( struct_attributes } + +pub(super) fn inner_attribute() -> impl NoirParser { + token_kind(TokenKind::InnerAttribute).map(|token| match token { + Token::InnerAttribute(attribute) => attribute, + _ => unreachable!( + "Parser should have already errored due to token not being an inner attribute" + ), + }) +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs index a30907211a3..04c4e414858 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/tests.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/tests.rs @@ -28,7 +28,8 @@ use crate::hir::def_collector::dc_crate::DefCollector; use crate::hir_def::expr::HirExpression; use crate::hir_def::stmt::HirStatement; use crate::monomorphization::monomorphize; -use crate::parser::ParserErrorReason; +use crate::parser::{ItemKind, ParserErrorReason}; +use crate::token::SecondaryAttribute; use crate::ParsedModule; use crate::{ hir::def_map::{CrateDefMap, LocalModuleId}, @@ -64,10 +65,28 @@ pub(crate) fn get_program(src: &str) -> (ParsedModule, Context, Vec<(Compilation remove_experimental_warnings(&mut errors); if !has_parser_error(&errors) { + let inner_attributes: Vec = program + .items + .iter() + .filter_map(|item| { + if let ItemKind::InnerAttribute(attribute) = &item.kind { + Some(attribute.clone()) + } else { + None + } + }) + .collect(); + // Allocate a default Module for the root, giving it a ModuleId let mut modules: Arena = Arena::default(); let location = Location::new(Default::default(), root_file_id); - let root = modules.insert(ModuleData::new(None, location, false)); + let root = modules.insert(ModuleData::new( + None, + location, + Vec::new(), + inner_attributes.clone(), + false, + )); let def_map = CrateDefMap { root: LocalModuleId(root), @@ -1362,7 +1381,7 @@ fn ban_mutable_globals() { fn deny_inline_attribute_on_unconstrained() { let src = r#" #[no_predicates] - unconstrained fn foo(x: Field, y: Field) { + unconstrained pub fn foo(x: Field, y: Field) { assert(x != y); } "#; @@ -1378,7 +1397,7 @@ fn deny_inline_attribute_on_unconstrained() { fn deny_fold_attribute_on_unconstrained() { let src = r#" #[fold] - unconstrained fn foo(x: Field, y: Field) { + unconstrained pub fn foo(x: Field, y: Field) { assert(x != y); } "#; @@ -1535,7 +1554,7 @@ fn struct_numeric_generic_in_function() { inner: u64 } - fn bar() { } + pub fn bar() { } "#; let errors = get_program_errors(src); assert_eq!(errors.len(), 1); @@ -1567,7 +1586,7 @@ fn struct_numeric_generic_in_struct() { #[test] fn bool_numeric_generic() { let src = r#" - fn read() -> Field { + pub fn read() -> Field { if N { 0 } else { @@ -1586,7 +1605,7 @@ fn bool_numeric_generic() { #[test] fn numeric_generic_binary_operation_type_mismatch() { let src = r#" - fn foo() -> bool { + pub fn foo() -> bool { let mut check: bool = true; check = N; check @@ -1603,7 +1622,7 @@ fn numeric_generic_binary_operation_type_mismatch() { #[test] fn bool_generic_as_loop_bound() { let src = r#" - fn read() { + pub fn read() { let mut fields = [0; N]; for i in 0..N { fields[i] = i + 1; @@ -1633,7 +1652,7 @@ fn bool_generic_as_loop_bound() { #[test] fn numeric_generic_in_function_signature() { let src = r#" - fn foo(arr: [Field; N]) -> [Field; N] { arr } + pub fn foo(arr: [Field; N]) -> [Field; N] { arr } "#; assert_no_errors(src); } @@ -1675,7 +1694,7 @@ fn normal_generic_as_array_length() { #[test] fn numeric_generic_as_param_type() { let src = r#" - fn foo(x: I) -> I { + pub fn foo(x: I) -> I { let _q: I = 5; x } @@ -1814,7 +1833,7 @@ fn numeric_generic_used_in_where_clause() { fn deserialize(fields: [Field; N]) -> Self; } - fn read() -> T where T: Deserialize { + pub fn read() -> T where T: Deserialize { let mut fields: [Field; N] = [0; N]; for i in 0..N { fields[i] = i as Field + 1; @@ -1828,12 +1847,12 @@ fn numeric_generic_used_in_where_clause() { #[test] fn numeric_generic_used_in_turbofish() { let src = r#" - fn double() -> u32 { + pub fn double() -> u32 { // Used as an expression N * 2 } - fn double_numeric_generics_test() { + pub fn double_numeric_generics_test() { // Example usage of a numeric generic arguments. assert(double::<9>() == 18); assert(double::<7 + 8>() == 30); @@ -1869,7 +1888,7 @@ fn normal_generic_used_when_numeric_expected_in_where_clause() { fn deserialize(fields: [Field; N]) -> Self; } - fn read() -> T where T: Deserialize { + pub fn read() -> T where T: Deserialize { T::deserialize([0, 1]) } "#; @@ -1885,7 +1904,7 @@ fn normal_generic_used_when_numeric_expected_in_where_clause() { fn deserialize(fields: [Field; N]) -> Self; } - fn read() -> T where T: Deserialize { + pub fn read() -> T where T: Deserialize { let mut fields: [Field; N] = [0; N]; for i in 0..N { fields[i] = i as Field + 1; @@ -2431,7 +2450,7 @@ fn use_super() { mod foo { use super::some_func; - fn bar() { + pub fn bar() { some_func(); } } @@ -2445,7 +2464,7 @@ fn use_super_in_path() { fn some_func() {} mod foo { - fn func() { + pub fn func() { super::some_func(); } } @@ -2736,7 +2755,7 @@ fn trait_constraint_on_tuple_type() { fn foo(self, x: A) -> bool; } - fn bar(x: (T, U), y: V) -> bool where (T, U): Foo { + pub fn bar(x: (T, U), y: V) -> bool where (T, U): Foo { x.foo(y) } @@ -3072,7 +3091,7 @@ fn trait_impl_for_a_type_that_implements_another_trait() { } } - fn use_it(t: T) -> i32 where T: Two { + pub fn use_it(t: T) -> i32 where T: Two { Two::two(t) } @@ -3112,7 +3131,7 @@ fn trait_impl_for_a_type_that_implements_another_trait_with_another_impl_used() } } - fn use_it(t: u32) -> i32 { + pub fn use_it(t: u32) -> i32 { Two::two(t) } @@ -3224,12 +3243,14 @@ fn errors_on_unused_private_import() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedImport { ident }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item_type }) = + &errors[0].0 else { - panic!("Expected an unused import error"); + panic!("Expected an unused item error"); }; assert_eq!(ident.to_string(), "bar"); + assert_eq!(*item_type, "import"); } #[test] @@ -3258,12 +3279,14 @@ fn errors_on_unused_pub_crate_import() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedImport { ident }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item_type }) = + &errors[0].0 else { - panic!("Expected an unused import error"); + panic!("Expected an unused item error"); }; assert_eq!(ident.to_string(), "bar"); + assert_eq!(*item_type, "import"); } #[test] @@ -3276,7 +3299,7 @@ fn warns_on_use_of_private_exported_item() { use bar::baz; - fn qux() { + pub fn qux() { baz(); } } @@ -3341,3 +3364,63 @@ fn warns_on_re_export_of_item_with_less_visibility() { ) )); } + +#[test] +fn unoquted_integer_as_integer_token() { + let src = r#" + trait Serialize { + fn serialize() {} + } + + #[attr] + pub fn foobar() {} + + fn attr(_f: FunctionDefinition) -> Quoted { + let serialized_len = 1; + // We are testing that when we unoqute $serialized_len, it's unquoted + // as the token `1` and not as something else that later won't be parsed correctly + // in the context of a generic argument. + quote { + impl Serialize<$serialized_len> for Field { + fn serialize() { } + } + } + } + + fn main() {} + "#; + + assert_no_errors(src); +} + +#[test] +fn errors_on_unused_function() { + let src = r#" + contract some_contract { + // This function is unused, but it's a contract entrypoint + // so it should not produce a warning + fn foo() -> pub Field { + 1 + } + } + + + fn foo() { + bar(); + } + + fn bar() {} + "#; + + let errors = get_program_errors(src); + assert_eq!(errors.len(), 1); + + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item_type }) = + &errors[0].0 + else { + panic!("Expected an unused item error"); + }; + + assert_eq!(ident.to_string(), "foo"); + assert_eq!(*item_type, "function"); +} diff --git a/noir/noir-repo/compiler/noirc_frontend/src/usage_tracker.rs b/noir/noir-repo/compiler/noirc_frontend/src/usage_tracker.rs index d8b7b271734..836f9824436 100644 --- a/noir/noir-repo/compiler/noirc_frontend/src/usage_tracker.rs +++ b/noir/noir-repo/compiler/noirc_frontend/src/usage_tracker.rs @@ -1,26 +1,54 @@ -use std::collections::HashSet; +use std::collections::HashMap; -use rustc_hash::FxHashMap as HashMap; +use crate::{ + ast::{Ident, ItemVisibility}, + hir::def_map::ModuleId, + node_interner::FuncId, +}; -use crate::{ast::Ident, hir::def_map::ModuleId}; +#[derive(Debug)] +pub enum UnusedItem { + Import, + Function(FuncId), +} + +impl UnusedItem { + pub fn item_type(&self) -> &'static str { + match self { + UnusedItem::Import => "import", + UnusedItem::Function(_) => "function", + } + } +} -#[derive(Debug, Default)] +#[derive(Debug)] pub struct UsageTracker { - /// List of all unused imports in each module. Each time something is imported it's added - /// to the module's set. When it's used, it's removed. At the end of the program only unused imports remain. - unused_imports: HashMap>, + unused_items: HashMap>, } impl UsageTracker { - pub(crate) fn add_unused_import(&mut self, module_id: ModuleId, name: Ident) { - self.unused_imports.entry(module_id).or_default().insert(name); + pub(crate) fn new() -> Self { + Self { unused_items: HashMap::new() } + } + + pub(crate) fn add_unused_item( + &mut self, + module_id: ModuleId, + name: Ident, + item: UnusedItem, + visibility: ItemVisibility, + ) { + // Empty spans could come from implicitly injected imports, and we don't want to track those + if visibility != ItemVisibility::Public && name.span().start() < name.span().end() { + self.unused_items.entry(module_id).or_default().insert(name, item); + } } pub(crate) fn mark_as_used(&mut self, current_mod_id: ModuleId, name: &Ident) { - self.unused_imports.entry(current_mod_id).or_default().remove(name); + self.unused_items.entry(current_mod_id).or_default().remove(name); } - pub(crate) fn unused_imports(&self) -> &HashMap> { - &self.unused_imports + pub(crate) fn unused_items(&self) -> &HashMap> { + &self.unused_items } } diff --git a/noir/noir-repo/docs/docs/noir/concepts/comptime.md b/noir/noir-repo/docs/docs/noir/concepts/comptime.md index ed55a541fbd..ba078c763d0 100644 --- a/noir/noir-repo/docs/docs/noir/concepts/comptime.md +++ b/noir/noir-repo/docs/docs/noir/concepts/comptime.md @@ -183,7 +183,7 @@ comptime fn my_function_annotation(f: FunctionDefinition) { Anything returned from one of these functions will be inserted at top-level along with the original item. Note that expressions are not valid at top-level so you'll get an error trying to return `3` or similar just as if you tried to write a program containing `3; struct Foo {}`. -You can insert other top-level items such as traits, structs, or functions this way though. +You can insert other top-level items such as trait impls, structs, or functions this way though. For example, this is the mechanism used to insert additional trait implementations into the program when deriving a trait impl from a struct: #include_code derive-field-count-example noir_stdlib/src/meta/mod.nr rust diff --git a/noir/noir-repo/docs/docs/noir/standard_library/fmtstr.md b/noir/noir-repo/docs/docs/noir/standard_library/fmtstr.md new file mode 100644 index 00000000000..293793e23ff --- /dev/null +++ b/noir/noir-repo/docs/docs/noir/standard_library/fmtstr.md @@ -0,0 +1,13 @@ +--- +title: fmtstr +--- + +`fmtstr` is the type resulting from using format string (`f"..."`). + +## Methods + +### quoted_contents + +#include_code quoted_contents noir_stdlib/src/meta/format_string.nr rust + +Returns the format string contents (that is, without the leading and trailing double quotes) as a `Quoted` value. \ No newline at end of file diff --git a/noir/noir-repo/docs/docs/noir/standard_library/meta/module.md b/noir/noir-repo/docs/docs/noir/standard_library/meta/module.md index d283f2da8b2..870e366461c 100644 --- a/noir/noir-repo/docs/docs/noir/standard_library/meta/module.md +++ b/noir/noir-repo/docs/docs/noir/standard_library/meta/module.md @@ -20,6 +20,12 @@ Returns the name of the module. Returns each function in the module. +### has_named_attribute + +#include_code has_named_attribute noir_stdlib/src/meta/module.nr rust + +Returns true if this module has a custom attribute with the given name. + ### is_contract #include_code is_contract noir_stdlib/src/meta/module.nr rust diff --git a/noir/noir-repo/noir_stdlib/src/meta/format_string.nr b/noir/noir-repo/noir_stdlib/src/meta/format_string.nr new file mode 100644 index 00000000000..44b69719efe --- /dev/null +++ b/noir/noir-repo/noir_stdlib/src/meta/format_string.nr @@ -0,0 +1,6 @@ +impl fmtstr { + #[builtin(fmtstr_quoted_contents)] + // docs:start:quoted_contents + fn quoted_contents(self) -> Quoted {} + // docs:end:quoted_contents +} diff --git a/noir/noir-repo/noir_stdlib/src/meta/mod.nr b/noir/noir-repo/noir_stdlib/src/meta/mod.nr index 24398054467..9fc399ddbf9 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/mod.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/mod.nr @@ -1,4 +1,5 @@ mod expr; +mod format_string; mod function_def; mod module; mod op; diff --git a/noir/noir-repo/noir_stdlib/src/meta/module.nr b/noir/noir-repo/noir_stdlib/src/meta/module.nr index 6ea3ca55fb1..b3f76812b8a 100644 --- a/noir/noir-repo/noir_stdlib/src/meta/module.nr +++ b/noir/noir-repo/noir_stdlib/src/meta/module.nr @@ -1,4 +1,9 @@ impl Module { + #[builtin(module_has_named_attribute)] + // docs:start:has_named_attribute + fn has_named_attribute(self, name: Quoted) -> bool {} + // docs:end:has_named_attribute + #[builtin(module_is_contract)] // docs:start:is_contract fn is_contract(self) -> bool {} diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr index 705a1b2ab4e..0e2d459a00f 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_fmt_strings/src/main.nr @@ -12,4 +12,18 @@ fn main() { }; assert_eq(s1, "x is 4, fake interpolation: {y}, y is 5"); assert_eq(s2, "\0\0\0\0"); + + // Mainly test fmtstr::quoted_contents + call!(glue(quote { hello }, quote { world })); +} + +fn glue(x: Quoted, y: Quoted) -> Quoted { + f"{x}_{y}".quoted_contents() } + +fn hello_world() {} + +comptime fn call(x: Quoted) -> Quoted { + quote { $x() } +} + diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr index 8d834381fea..5722d42ca26 100644 --- a/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/main.nr @@ -1,10 +1,45 @@ +#[outer_attribute] mod foo { + #![some_attribute] fn x() {} fn y() {} } contract bar {} +#[some_attribute] +mod another_module {} + +#[outer_attribute_func] +mod yet_another_module { + #![super::inner_attribute_func] + fn foo() {} +} + +#[outer_attribute_separate_module] +mod separate_module; + +comptime mut global counter = 0; + +fn increment_counter() { + counter += 1; +} + +fn outer_attribute_func(m: Module) { + assert_eq(m.name(), quote { yet_another_module }); + increment_counter(); +} + +fn inner_attribute_func(m: Module) { + assert_eq(m.name(), quote { yet_another_module }); + increment_counter(); +} + +fn outer_attribute_separate_module(m: Module) { + assert_eq(m.name(), quote { separate_module }); + increment_counter(); +} + fn main() { comptime { @@ -15,6 +50,8 @@ fn main() { let bar = quote { bar }.as_module().unwrap(); assert(bar.is_contract()); + let another_module = quote { another_module }.as_module().unwrap(); + // Check Module::functions assert_eq(foo.functions().len(), 2); assert_eq(bar.functions().len(), 0); @@ -22,7 +59,15 @@ fn main() { // Check Module::name assert_eq(foo.name(), quote { foo }); assert_eq(bar.name(), quote { bar }); + + // Check Module::has_named_attribute + assert(foo.has_named_attribute(quote { some_attribute })); + assert(foo.has_named_attribute(quote { outer_attribute })); + assert(!bar.has_named_attribute(quote { some_attribute })); + assert(another_module.has_named_attribute(quote { some_attribute })); } + + assert_eq(counter, 4); } // docs:start:as_module_example diff --git a/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/separate_module.nr b/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/separate_module.nr new file mode 100644 index 00000000000..53784101507 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/comptime_module/src/separate_module.nr @@ -0,0 +1,5 @@ +#![inner_attribute_separate_module] +fn inner_attribute_separate_module(m: Module) { + assert_eq(m.name(), quote { separate_module }); + super::increment_counter(); +} diff --git a/noir/noir-repo/test_programs/compile_success_empty/unquote_function/Nargo.toml b/noir/noir-repo/test_programs/compile_success_empty/unquote_function/Nargo.toml new file mode 100644 index 00000000000..aa56a5798df --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/unquote_function/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "unquote_function" +type = "bin" +authors = [""] +compiler_version = ">=0.33.0" + +[dependencies] diff --git a/noir/noir-repo/test_programs/compile_success_empty/unquote_function/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/unquote_function/src/main.nr new file mode 100644 index 00000000000..273a091b26d --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/unquote_function/src/main.nr @@ -0,0 +1,12 @@ +fn main() { + bar(); +} + +#[output_function] +fn foo() {} + +comptime fn output_function(_f: FunctionDefinition) -> Quoted { + quote { + fn bar() {} + } +} diff --git a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml b/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/Nargo.toml similarity index 50% rename from noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml rename to noir/noir-repo/test_programs/compile_success_empty/unquote_struct/Nargo.toml index 8fce1bf44b6..c40d6a07093 100644 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml +++ b/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/Nargo.toml @@ -1,6 +1,7 @@ [package] -name = "verify_honk_proof" +name = "unquote_struct" type = "bin" authors = [""] +compiler_version = ">=0.33.0" [dependencies] diff --git a/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/src/main.nr b/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/src/main.nr new file mode 100644 index 00000000000..603440b5c76 --- /dev/null +++ b/noir/noir-repo/test_programs/compile_success_empty/unquote_struct/src/main.nr @@ -0,0 +1,30 @@ +fn main() { + let foo = Foo { x: 4, y: 4 }; + foo.assert_equal(); +} + +#[output_struct] +fn foo(x: Field, y: u32) -> u32 { + x as u32 + y +} + +// Given a function, wrap its parameters in a struct definition +comptime fn output_struct(f: FunctionDefinition) -> Quoted { + let fields = f.parameters().map( + |param: (Quoted, Type)| { + let name = param.0; + let typ = param.1; + quote { $name: $typ, } + } + ).join(quote {}); + + quote { + struct Foo { $fields } + + impl Foo { + fn assert_equal(self) { + assert_eq(self.x as u32, self.y); + } + } + } +} 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 5bdebb476be..00000000000 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml +++ /dev/null @@ -1,575 +0,0 @@ -key_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" -proof = [ - "0x0000000000000000000000000000000000000000000000000000000000000040", - "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", - "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", - "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", - "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", - "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", - "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", - "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", - "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", - "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", - "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", - "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", - "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", - "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", - "0x000000000000000000000000000000286fcda0e28617c86e195005b9f2efc555", - "0x00000000000000000000000000000000000dc409eb684b23f6a97175bcb9b486", - "0x000000000000000000000000000000e8de6a193cd36414f598bc7c48d67c3b59", - "0x00000000000000000000000000000000002a8a791544cad8c712de871e3de50a", - "0x000000000000000000000000000000d6f1e64b562df0f17ecc6aa46392f8d5a3", - "0x00000000000000000000000000000000000aac977763f33fd6a360ccc50a827a", - "0x000000000000000000000000000000899fa957f5597c6419e3ead9843d21d917", - "0x000000000000000000000000000000000016c4611846952bd6833c35fb11c0da", - "0x013dbfbfbfb2ae7d524edb15343e551d9510b3116223baaa67312d17652f2fb1", - "0x2f268eb3217ef1ac66016aa14d43033f932335371795b5e6dcb0c87c8ad0d050", - "0x2d5dbd52e00ae837e9868289fbe9057f16ea5b76c7e362603e8883f0de4b3e94", - "0x0e357b6a266c20d5e546c2931475eb044d7e75e08ec31b5e8623aec30f964323", - "0x0a9ace4dea44d0a2e8d12d495a683f508714356656aea3882436b729ead24165", - "0x0c17102a98ccb76faf0f78d669ee9cfb694849896787c985225d92e1af3cab35", - "0x09cc7cb719deb139c84fd9fa273e862a1b5d1cec2501c6cd8ba3c37ca06ac07f", - "0x15a0369f3f95d53687dfe79483baf75597d8b281fe0595caf1f7c9ccf99d985e", - "0x17fb53a42b3d1fa5d26ab19dfcc0d74d1781cee0be98dcc492c22e8f3442c4db", - "0x291d6810fc6afc5c2254fd283843a74c85a77275eee3049ea8ed9c88e02a99b8", - "0x0ad40d1627c31247dfb894584a71f8599cfcb85afe84b20186fc07fccae1aa4a", - "0x251cd908fb4e9fe88660f2303f8d7e4d7886da32fddc0319a842b99543659c0b", - "0x1885bdea3dd82085ca67502ebec8ad87213493e18a06cfa27e2c69810481b4a7", - "0x239ab5ba86866bc6705091f82a6a29444dc76b0e7d94cede7eb745cce36ab2cf", - "0x088d29a03baa491845d152124189dfb8bf70ba9bf1fb00c379199dbb0195c663", - "0x18c9fbe3227988d2da599eba82d60f4de25b442b663585fdc611e37305fa77fc", - "0x010242ae641a8cc4d06b5d24e38d9fa6254f981e28f238ccf6aad580f780d3f5", - "0x00128d34b122e84d7e23276b1f13f5789a562e82c727e9ffcfd7bbaccbe69e04", - "0x0776defaf478bfea4db2698542314e27213f63c96e41f98d4d82a47ed6fab55d", - "0x273014a360eaaa493e398df82f18d9cae37f4b6c0ead20100cad3f5491805298", - "0x2b13528eb9ab6fa705f2b48c9ec6ce054ac984e3adf17d4d73431e8456bf4a3c", - "0x22dafe1d63e39cd2effb236da2e131ee1c8cf4049ce504431dcaf98f75c47ad8", - "0x1afb5bc7eb8d30d807101357bb290f9c3113523f4aacc1154a27b075e46a4fa4", - "0x0782dd7df679163e5f0c126abc901d00f3d7d0856b4c02a199ab691ecd7566e6", - "0x2e556c722c99a84a09ffdcc719178277f8e6c9e31a4769270e3b522b944b8ea2", - "0x1be933a48dca8ef26202d3f135998ac8bed6947020b7447ffb6033b0e37f2065", - "0x2d8ebae210848de2464f5435f1fd4b5467ee938910d7779002614943060bbb32", - "0x2da854bbee38a94a6a9c2c85dd05bb4c879173720b67f93f78b9de93cdb427b0", - "0x0fa2649472af2e79489c466b58002f8f284f953085ac0a98dfabee85b78f63cf", - "0x304a09437636026ef0746c4b8ac1ca0ff250c5630fb5bd03ddafddd7cbde850e", - "0x0c83bb3c6ee0faa1646ee4d8dd83f67ec98e5d63ac802f7bdebfcdf21dee62f1", - "0x229d7e4524b30c18a6b94f0054e6d2ea8eb2396f58f9c808d2c9f991e2be2399", - "0x1265bf5e1aaddeae09242b1435e2f8f9e7487bf76a0461752777f6ea1ff75ad6", - "0x2f32f53281b7a363d6bec84ca21c71c3206d906b036e8b36b0702780e3b1b870", - "0x017fb18c9aef4d6d2bc99f5d7f9a002c8921fcd7c7ba69bf05930b55c2829cb7", - "0x2ec761c02ef6f2eefb7c9b2d6df71795d0ce0820f86797e2e11415cb5b122f22", - "0x2b1722960f42a1b40ffae3e4b9419fc8ff5cb8139a2c7e89af332ba2e95c1b5f", - "0x2dafa15594da2318245475c77eae3712429226b3005852e70f567efff0a7d79a", - "0x2ed44d7e3d5f44ac8f7c144ee0ba9d369c82428827c19b010384708bbc52a3f9", - "0x2777eedda697c7f90aee44fa97cfe62596d16c43fa3545b48d622023ca7a446a", - "0x1a47a5c1b0f41905aa0bad6248be8c7887ddea3ad9dfc8462b23a95b073c8a49", - "0x093656d571e84ac676a265dd509c98513039552b7a24e001b003ca618cc4ea5c", - "0x15c901e8a7ff0f1ae1989b5cfb687975c16716a8014a4052d527d4db4ecbaeb4", - "0x08bfa20e83096b0be58e4c96232510c8ef9824c0a62b91ffcc4592b217753a72", - "0x021913efbdfbc73aa5f4a97c79f352ac61f71248947f5eb5713c1b107c632703", - "0x00df89625aef270fab2a8c33ba742e1375423f4cfb3f63514ae748e004bb8cf4", - "0x2455f76c8ee59e93cbe7fe192cf0f766e1399617cabfa230cf27ca2a18cd58d5", - "0x150c3e56ea4f6442ed6b11030c98682a8f5e3c9cd6fd18949254a7c79b3cb5b6", - "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", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x01e89c6fe644aea7f63301278dbdb4ea29cf4d33f8b0cdcd79cb106e0bf0a753", - "0x2d49d23421e253903b8a5d0911642b9ce218cef4e350cf8689704eb1f3ae38d4", - "0x072956ca447343d788791fee1ef222f280048ad4aefb6cb7bc96b538f482f525", - "0x168176bf15c8ca63457acf05efbe54af452ea41f935ab82c2a96fedde10ba52f", - "0x20a13690f13491f7f3b756a1dc3b69a3f96d78355c70289583032a593bfc87bc", - "0x273e0a32ab3ef0d3f179b62520b31015ccfc8b53c76a1bb323b41e40ff954596", - "0x28019d4b05546b44e35d5dc74375b75dabb6fae49a07381605c60423c6163d26", - "0x10beda0b8dd484c63f0937820e2c7e9be832a0031efe3557631608895255ca5f", - "0x095a8f04a901526e4d70b1560bfff29b5a3c30347725d1e420c1b30ee2bf8a1c", - "0x1fb742e863a5c76262ffec93b3351405b0840b326fa5fffd73f40abcd5f05f05", - "0x11fa63cfcb2e603fe4e4668d75f05a2cf22650b84a91d1753e83f0e7ae83b4ad", - "0x2872e3d3c431a8b7ee4cec1c2a999a42c40ae33382fbba80a6d4c1a39b2d57a3", - "0x17e8c2a5f809f9935d7c6d7cb2f8859a513864b53f53de3d2a14c74cd690bd1a", - "0x20a552298d691393ae401382b3015689231ad988d3eb0521d414dcd2e8781053", - "0x183eb6bca59a141b4e8136179a258272ec9c25ec80bdb0458b6880c711707a28", - "0x03cd147a2a4c8dc272f3e240b8b0090d45e994e5fd40e07a54f6765795cd5ef8", - "0x082b135b3a20da4c766242b4258e27dbc050e4b8958bb15431626f2eeed9bd2b", - "0x28c894a6a719a32fe8d78ded46bc685ba035e5579c88fbc5bcbc0f09d8c5268b", - "0x06418cceff50837f923e63a37c2c534d13d9f59793c3aa6274813baa64d1899e", - "0x2b4a27b672f85c4fc697605da213de8b950a629602c5b8c6403e6c1c1065388a", - "0x0e2b817c6a79d6d1027f0376fb26ec81a140a4402e2dcdff6152cf01f2f4dbf9", - "0x2ae0fbce87dc53f0ff5473117e1c49a8197a14f8eaaec00cb5b10f94e844111f", - "0x2368004a1dee06f505e75ada3e9f8cc4c801f6a2068620da51ba11f537453835", - "0x2009df8e6f49f67dcaecb93e4a9ef81aaff096136d26f0fe691e14cd580c47da", - "0x2e512617136e8da2817856e57f13087a75fcc512faefc6d4b2eedd73c58a9b35", - "0x2848fcd535bd7c8017ca331a14919aa492ed05b04e9d0745480d291205eac8dc", - "0x19bb0990cb37f3a8f6c3db78219b07d6accd08e889586660e92dd6000755f09a", - "0x15520c8158b2e36c40c5fa46d5281c45d3df2c7f5d974a1f9549bfca6cbceaea", - "0x0e285f4df658d99922c286c5a253d6f6f37aa6c52d7a0fc1a20f3e6da9df23e1", - "0x0f9cd4667f4c1e86f83eda9e752a05c0cc630b0827a93a68322fa258dffb0f24", - "0x12d8b0dbbea3dccfe5d2dd090daf8ab4d2fac74fada9c49875b0c9122663a8ad", - "0x2e8c814d93f027ecff08c4e58555aadfc0f9ec3889eff2150f2b5bb6c557add0", - "0x013516a1456c5831aba87e4057878f6f3f18471e0674fd1e89be3e18351ec394", - "0x14418aa79dc84fd791d5638bdc103786ef8181a714ee8e022d3a1e792cbc7959", - "0x14418aa79dc84fd791d5638bdc103786ef8181a714ee8e022d3a1e792cbc7959", - "0x25c5e6c96a39bb36e19106d4049b675f0279084cc757c4e2acf6e497c61056a2", - "0x231aaafcf2a4c6fd8da18ce5ae5b33790f2c306a2692c6383c9a0787c50ac269", - "0x0a5f7665f0997081f9b38ec64e9a18542ac3a9648060f8cc720fc04669224730", - "0x0f1c9d9d1ac6f62825c6038117ed30540be434e8fd2d88150dcd4fece39b335a", - "0x1308871c8fcb09f07e5257f5cc5678d98842a8d18b2af09b5132d9af3cb1893e", - "0x28801985290dac4eba72ed01ee06fe88f6fc533dc1a46bd86e2d35be8021b042", - "0x14407f38cfba3cc61fca173b41133ab05a1c176caf8bb597588b01817e9eeaa3", - "0x0ea1a9f6f95f6193e512a7bd3db0c147f66687662934aed53cb657935b1e4eb9", - "0x1bc4ab6eacd61b5fd9e414b0186ef5deaadaf59aa9e53cb8d8812255baa28109", - "0x00000000000000000000000000000093a4da68a2fac0ee94841efdfc57eb748c", - "0x00000000000000000000000000000000001c22f1f5f927bee6adb649cc132391", - "0x0000000000000000000000000000003d0c2acea76c551f58876b3c35f19f345a", - "0x00000000000000000000000000000000002e94fded0a0b7f4fd1c882fd2a4e52", - "0x00000000000000000000000000000022e23b6fa0f72844bf8f60ea140cca5663", - "0x000000000000000000000000000000000013380f284bf3cb98b9a7cbae7d702b", - "0x000000000000000000000000000000942a13cf93056815c3f7439c9eed0a103e", - "0x00000000000000000000000000000000002be14bec02c6dae4625d32866de4fc", - "0x000000000000000000000000000000e2a2c75dc664c12695b4f7795c61f92669", - "0x000000000000000000000000000000000000725da448f376bde6cf63bcf79463", - "0x000000000000000000000000000000f54eee585f8ab367dc66a587e1d4cdbd8c", - "0x0000000000000000000000000000000000071106624ae5623a070f0addc18433", - "0x000000000000000000000000000000d60352bea3b2adb311b1a3beb25acb8aed", - "0x00000000000000000000000000000000001965b7c781e33f94e90c743c7881ed", - "0x0000000000000000000000000000006458a2aa57539e2b192f9c3ed69f9fb674", - "0x00000000000000000000000000000000001fc9c667723a4e66d752c6b426d444", - "0x0000000000000000000000000000008d1ff1c5d59a463c5b46bcf52f41ad3c63", - "0x00000000000000000000000000000000001b3e73df070a35c49a03fab1c76e9b", - "0x0000000000000000000000000000001c17a62b6c0a7ab14de83391e06f780adb", - "0x000000000000000000000000000000000012c7fbe2591b9ae72dd526e4ed1d7f", - "0x000000000000000000000000000000a758fa0c72d6a93155cb18b3fcc7defd34", - "0x00000000000000000000000000000000000cea12961770ce7cb6f2a4aed009fe", - "0x000000000000000000000000000000ef6e9647803aac315fa6d287e0e66f4767", - "0x0000000000000000000000000000000000259a82b8d6c6015cc51d2681f26ad4", - "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", - "0x0000000000000000000000000000008152b373c87004bef7d2c55ec8c540b67f", - "0x00000000000000000000000000000000000a55be5fdcb0a0dce4976d7bb78b0c", - "0x000000000000000000000000000000f749ea03f04ac964706139b9d1db595ecb", - "0x000000000000000000000000000000000013218e14dae80c066b4e46e9309fb2", - "0x0000000000000000000000000000004bbd7f950c36ce69db39e2b234a9e3f9b0", - "0x00000000000000000000000000000000002a0c3994d892ca5ea26984abbb30fb", - "0x0000000000000000000000000000006c1b39306846620bd546ac2c897834f259", - "0x000000000000000000000000000000000020350b9f507d6e25961a11be3e494b", -] -public_inputs = [ - "0x0000000000000000000000000000000000000000000000000000000000000003", -] -verification_key = [ - "0x0000000000000000000000000000000000000000000000000000000000000040", - "0x0000000000000000000000000000000000000000000000000000000000000011", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000003", - "0x0000000000000000000000000000000000000000000000000000000000000004", - "0x0000000000000000000000000000000000000000000000000000000000000005", - "0x0000000000000000000000000000000000000000000000000000000000000006", - "0x0000000000000000000000000000000000000000000000000000000000000007", - "0x0000000000000000000000000000000000000000000000000000000000000008", - "0x0000000000000000000000000000000000000000000000000000000000000009", - "0x000000000000000000000000000000000000000000000000000000000000000a", - "0x000000000000000000000000000000000000000000000000000000000000000b", - "0x000000000000000000000000000000000000000000000000000000000000000c", - "0x000000000000000000000000000000000000000000000000000000000000000d", - "0x000000000000000000000000000000000000000000000000000000000000000e", - "0x000000000000000000000000000000000000000000000000000000000000000f", - "0x0000000000000000000000000000000000000000000000000000000000000010", - "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", - "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", - "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", - "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", - "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", - "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", - "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", - "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", - "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", - "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", - "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", - "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", - "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", - "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", - "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", - "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", - "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", - "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", - "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", - "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", - "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", - "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", - "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", - "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", - "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", - "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", - "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", - "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", - "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", - "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", - "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", - "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", - "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", - "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", - "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", - "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", - "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", - "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", - "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", - "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", - "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", - "0x000000000000000000000000000000e97954ad6cd6f45fb15c91434121db4304", - "0x00000000000000000000000000000000002e20a97e09d50f227ced47e7a98250", - "0x0000000000000000000000000000001ebbc27eb9ebededefba79522eb58ae89b", - "0x0000000000000000000000000000000000090efa4974e566e81d1177b85a30be", - "0x0000000000000000000000000000005eafa070b9c9632404052642e3bc14f9fd", - "0x00000000000000000000000000000000001489068864102daca6a6b8bc4d448b", - "0x0000000000000000000000000000009ebc91aaaac036a6477cadbe54e8556dfd", - "0x00000000000000000000000000000000000ef6d835e2ed3343b95c82c8c54037", - "0x00000000000000000000000000000033b28b529dff46e93af4e7422530478e4a", - "0x000000000000000000000000000000000020a86c2f8591bf190bcddcc03c42fb", - "0x000000000000000000000000000000a9679d0acc088f7dc27bf6d866bcd2dda2", - "0x00000000000000000000000000000000002fb9d0d2d4099402bed74f738f64cc", - "0x00000000000000000000000000000023b09f876a29a061582848a8b9a5870c12", - "0x00000000000000000000000000000000001d5bb906f03f0d49e9c4791bc43af9", - "0x00000000000000000000000000000017aac9854ea240d8ec97bf760c4d4ba870", - "0x00000000000000000000000000000000000b227a556c414ada0dc75bb303e30e", - "0x0000000000000000000000000000000000000000000000000000000000000001", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000000000000000000000000000000000000002", - "0x0000000000000000000000000000000000000000000000000000000000000000", - "0x0000000000000000000000000000009b624fa65d1a24b7f14a8f25f3789622af", - "0x000000000000000000000000000000000013d47bff8c630e847b70e2732fd3f0", - "0x00000000000000000000000000000061d21663e93132f32921075f4c936a84df", - "0x00000000000000000000000000000000001a74ca4e118fb480b9b999902989a3", -] 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 b60a47ccc7f..00000000000 --- a/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr +++ /dev/null @@ -1,17 +0,0 @@ - -// This circuit aggregates a single Honk proof from `assert_statement_recursive`. -global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 439; -global HONK_IDENTIFIER : u32 = 1; -fn main( - verification_key: [Field; 128], - // 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, proof, public_inputs, key_hash); -} diff --git a/noir/noir-repo/tooling/lsp/src/lib.rs b/noir/noir-repo/tooling/lsp/src/lib.rs index 4a764f4268b..6557975743c 100644 --- a/noir/noir-repo/tooling/lsp/src/lib.rs +++ b/noir/noir-repo/tooling/lsp/src/lib.rs @@ -4,7 +4,7 @@ #![cfg_attr(not(test), warn(unused_crate_dependencies, unused_extern_crates))] use std::{ - collections::{BTreeMap, HashMap}, + collections::{BTreeMap, HashMap, HashSet}, future::Future, ops::{self, ControlFlow}, path::{Path, PathBuf}, @@ -91,10 +91,13 @@ pub struct LspState { open_documents_count: usize, input_files: HashMap, cached_lenses: HashMap>, - cached_definitions: HashMap, + cached_definitions: HashMap, cached_parsed_files: HashMap))>, - cached_def_maps: HashMap>, + cached_def_maps: HashMap>, options: LspInitializationOptions, + + // Tracks files that currently have errors, by package root. + files_with_errors: HashMap>, } impl LspState { @@ -113,6 +116,8 @@ impl LspState { cached_parsed_files: HashMap::new(), cached_def_maps: HashMap::new(), options: Default::default(), + + files_with_errors: HashMap::new(), } } } diff --git a/noir/noir-repo/tooling/lsp/src/modules.rs b/noir/noir-repo/tooling/lsp/src/modules.rs index 54074dbd94c..d78da15a8ff 100644 --- a/noir/noir-repo/tooling/lsp/src/modules.rs +++ b/noir/noir-repo/tooling/lsp/src/modules.rs @@ -47,10 +47,11 @@ pub(crate) fn module_full_path( current_module_id: ModuleId, current_module_parent_id: Option, interner: &NodeInterner, + def_maps: &BTreeMap, ) -> Option { let full_path; if let ModuleDefId::ModuleId(module_id) = module_def_id { - if !is_visible(visibility, current_module_id, module_id) { + if !is_visible(module_id, current_module_id, visibility, def_maps) { return None; } @@ -61,7 +62,7 @@ pub(crate) fn module_full_path( return None; }; - if !is_visible(visibility, current_module_id, parent_module) { + if !is_visible(parent_module, current_module_id, visibility, def_maps) { return None; } diff --git a/noir/noir-repo/tooling/lsp/src/notifications/mod.rs b/noir/noir-repo/tooling/lsp/src/notifications/mod.rs index d1ffdb55066..87e7bea8c3b 100644 --- a/noir/noir-repo/tooling/lsp/src/notifications/mod.rs +++ b/noir/noir-repo/tooling/lsp/src/notifications/mod.rs @@ -1,8 +1,12 @@ +use std::collections::HashSet; use std::ops::ControlFlow; +use std::path::PathBuf; use crate::insert_all_files_for_workspace_into_file_manager; use async_lsp::{ErrorCode, LanguageClient, ResponseError}; -use lsp_types::DiagnosticTag; +use fm::{FileManager, FileMap}; +use fxhash::FxHashMap as HashMap; +use lsp_types::{DiagnosticTag, Url}; use noirc_driver::{check_crate, file_manager_with_stdlib}; use noirc_errors::{DiagnosticKind, FileDiagnostic}; @@ -105,7 +109,7 @@ pub(super) fn on_did_save_text_document( // caching code lenses and type definitions, and notifying about compilation errors. pub(crate) fn process_workspace_for_noir_document( state: &mut LspState, - document_uri: lsp_types::Url, + document_uri: Url, output_diagnostics: bool, ) -> Result<(), async_lsp::Error> { let file_path = document_uri.to_file_path().map_err(|_| { @@ -125,100 +129,123 @@ pub(crate) fn process_workspace_for_noir_document( let parsed_files = parse_diff(&workspace_file_manager, state); - let diagnostics: Vec<_> = workspace - .into_iter() - .flat_map(|package| -> Vec { - let package_root_dir: String = package.root_dir.as_os_str().to_string_lossy().into(); - - let (mut context, crate_id) = - crate::prepare_package(&workspace_file_manager, &parsed_files, package); - - let file_diagnostics = match check_crate(&mut context, crate_id, &Default::default()) { - Ok(((), warnings)) => warnings, - Err(errors_and_warnings) => errors_and_warnings, - }; - - // We don't add test headings for a package if it contains no `#[test]` functions - if let Some(tests) = get_package_tests_in_crate(&context, &crate_id, &package.name) { - let _ = state.client.notify::(NargoPackageTests { - package: package.name.to_string(), - tests, - }); - } - - let collected_lenses = crate::requests::collect_lenses_for_package( - &context, - crate_id, - &workspace, - package, - Some(&file_path), - ); - state.cached_lenses.insert(document_uri.to_string(), collected_lenses); - state.cached_definitions.insert(package_root_dir.clone(), context.def_interner); - state.cached_def_maps.insert(package_root_dir.clone(), context.def_maps); - - let fm = &context.file_manager; - let files = fm.as_file_map(); - - if output_diagnostics { - file_diagnostics - .into_iter() - .filter_map(|FileDiagnostic { file_id, diagnostic, call_stack: _ }| { - // Ignore diagnostics for any file that wasn't the file we saved - // TODO: In the future, we could create "related" diagnostics for these files - if fm.path(file_id).expect("file must exist to have emitted diagnostic") - != file_path - { - return None; - } - - // TODO: Should this be the first item in secondaries? Should we bail when we find a range? - let range = diagnostic - .secondaries - .into_iter() - .filter_map(|sec| byte_span_to_range(files, file_id, sec.span.into())) - .last() - .unwrap_or_default(); - - let severity = match diagnostic.kind { - DiagnosticKind::Error => DiagnosticSeverity::ERROR, - DiagnosticKind::Warning => DiagnosticSeverity::WARNING, - DiagnosticKind::Info => DiagnosticSeverity::INFORMATION, - DiagnosticKind::Bug => DiagnosticSeverity::WARNING, - }; - - let mut tags = Vec::new(); - if diagnostic.unnecessary { - tags.push(DiagnosticTag::UNNECESSARY); - } - if diagnostic.deprecated { - tags.push(DiagnosticTag::DEPRECATED); - } - - Some(Diagnostic { - range, - severity: Some(severity), - message: diagnostic.message, - tags: if tags.is_empty() { None } else { Some(tags) }, - ..Default::default() - }) - }) - .collect() - } else { - vec![] - } - }) - .collect(); - - if output_diagnostics { + for package in workspace.into_iter() { + let (mut context, crate_id) = + crate::prepare_package(&workspace_file_manager, &parsed_files, package); + + let file_diagnostics = match check_crate(&mut context, crate_id, &Default::default()) { + Ok(((), warnings)) => warnings, + Err(errors_and_warnings) => errors_and_warnings, + }; + + // We don't add test headings for a package if it contains no `#[test]` functions + if let Some(tests) = get_package_tests_in_crate(&context, &crate_id, &package.name) { + let _ = state.client.notify::(NargoPackageTests { + package: package.name.to_string(), + tests, + }); + } + + let collected_lenses = crate::requests::collect_lenses_for_package( + &context, + crate_id, + &workspace, + package, + Some(&file_path), + ); + state.cached_lenses.insert(document_uri.to_string(), collected_lenses); + state.cached_definitions.insert(package.root_dir.clone(), context.def_interner); + state.cached_def_maps.insert(package.root_dir.clone(), context.def_maps); + + let fm = &context.file_manager; + let files = fm.as_file_map(); + + if output_diagnostics { + publish_diagnostics(state, &package.root_dir, files, fm, file_diagnostics); + } + } + + Ok(()) +} + +fn publish_diagnostics( + state: &mut LspState, + package_root_dir: &PathBuf, + files: &FileMap, + fm: &FileManager, + file_diagnostics: Vec, +) { + let mut diagnostics_per_url: HashMap> = HashMap::default(); + + for file_diagnostic in file_diagnostics.into_iter() { + let file_id = file_diagnostic.file_id; + let diagnostic = file_diagnostic_to_diagnostic(file_diagnostic, files); + + let path = fm.path(file_id).expect("file must exist to have emitted diagnostic"); + if let Ok(uri) = Url::from_file_path(path) { + diagnostics_per_url.entry(uri).or_default().push(diagnostic); + } + } + + let new_files_with_errors: HashSet<_> = diagnostics_per_url.keys().cloned().collect(); + + for (uri, diagnostics) in diagnostics_per_url { let _ = state.client.publish_diagnostics(PublishDiagnosticsParams { - uri: document_uri, + uri, version: None, diagnostics, }); } - Ok(()) + // For files that previously had errors but no longer have errors we still need to publish empty diagnostics + if let Some(old_files_with_errors) = state.files_with_errors.get(package_root_dir) { + for uri in old_files_with_errors.difference(&new_files_with_errors) { + let _ = state.client.publish_diagnostics(PublishDiagnosticsParams { + uri: uri.clone(), + version: None, + diagnostics: vec![], + }); + } + } + + // Remember which files currently have errors, for next time + state.files_with_errors.insert(package_root_dir.clone(), new_files_with_errors); +} + +fn file_diagnostic_to_diagnostic(file_diagnostic: FileDiagnostic, files: &FileMap) -> Diagnostic { + let file_id = file_diagnostic.file_id; + let diagnostic = file_diagnostic.diagnostic; + + // TODO: Should this be the first item in secondaries? Should we bail when we find a range? + let range = diagnostic + .secondaries + .into_iter() + .filter_map(|sec| byte_span_to_range(files, file_id, sec.span.into())) + .last() + .unwrap_or_default(); + + let severity = match diagnostic.kind { + DiagnosticKind::Error => DiagnosticSeverity::ERROR, + DiagnosticKind::Warning => DiagnosticSeverity::WARNING, + DiagnosticKind::Info => DiagnosticSeverity::INFORMATION, + DiagnosticKind::Bug => DiagnosticSeverity::WARNING, + }; + + let mut tags = Vec::new(); + if diagnostic.unnecessary { + tags.push(DiagnosticTag::UNNECESSARY); + } + if diagnostic.deprecated { + tags.push(DiagnosticTag::DEPRECATED); + } + + Diagnostic { + range, + severity: Some(severity), + message: diagnostic.message, + tags: if tags.is_empty() { None } else { Some(tags) }, + ..Default::default() + } } pub(super) fn on_exit( diff --git a/noir/noir-repo/tooling/lsp/src/requests/code_action.rs b/noir/noir-repo/tooling/lsp/src/requests/code_action.rs index 8e153bb0b46..95cdc0b88b4 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/code_action.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/code_action.rs @@ -7,26 +7,26 @@ use async_lsp::ResponseError; use fm::{FileId, FileMap, PathString}; use lsp_types::{ CodeAction, CodeActionKind, CodeActionOrCommand, CodeActionParams, CodeActionResponse, - Position, Range, TextDocumentPositionParams, TextEdit, Url, WorkspaceEdit, + TextDocumentPositionParams, TextEdit, Url, WorkspaceEdit, }; -use noirc_errors::{Location, Span}; +use noirc_errors::Span; use noirc_frontend::{ - ast::{Ident, Path, Visitor}, + ast::{ConstructorExpression, Path, Visitor}, graph::CrateId, hir::def_map::{CrateDefMap, LocalModuleId, ModuleId}, - macros_api::{ModuleDefId, NodeInterner}, + macros_api::NodeInterner, +}; +use noirc_frontend::{ parser::{Item, ItemKind, ParsedSubModule}, ParsedModule, }; -use crate::{ - byte_span_to_range, - modules::{get_parent_module_id, module_full_path, module_id_path}, - utils, LspState, -}; +use crate::{utils, LspState}; use super::{process_request, to_lsp_location}; +mod fill_struct_fields; +mod import_or_qualify; #[cfg(test)] mod tests; @@ -68,6 +68,7 @@ struct CodeActionFinder<'a> { uri: Url, files: &'a FileMap, file: FileId, + source: &'a str, lines: Vec<&'a str>, byte_index: usize, /// The module ID in scope. This might change as we traverse the AST @@ -108,6 +109,7 @@ impl<'a> CodeActionFinder<'a> { uri, files, file, + source, lines: source.lines().collect(), byte_index, module_id, @@ -137,46 +139,7 @@ impl<'a> CodeActionFinder<'a> { Some(code_actions) } - fn push_import_code_action(&mut self, full_path: &str) { - let line = self.auto_import_line as u32; - let character = (self.nesting * 4) as u32; - let indent = " ".repeat(self.nesting * 4); - let mut newlines = "\n"; - - // If the line we are inserting into is not an empty line, insert an extra line to make some room - if let Some(line_text) = self.lines.get(line as usize) { - if !line_text.trim().is_empty() { - newlines = "\n\n"; - } - } - - let title = format!("Import {}", full_path); - let text_edit = TextEdit { - range: Range { start: Position { line, character }, end: Position { line, character } }, - new_text: format!("use {};{}{}", full_path, newlines, indent), - }; - - let code_action = self.new_quick_fix(title, text_edit); - self.code_actions.push(CodeActionOrCommand::CodeAction(code_action)); - } - - fn push_qualify_code_action(&mut self, ident: &Ident, prefix: &str, full_path: &str) { - let Some(range) = byte_span_to_range( - self.files, - self.file, - ident.span().start() as usize..ident.span().start() as usize, - ) else { - return; - }; - - let title = format!("Qualify as {}", full_path); - let text_edit = TextEdit { range, new_text: format!("{}::", prefix) }; - - let code_action = self.new_quick_fix(title, text_edit); - self.code_actions.push(CodeActionOrCommand::CodeAction(code_action)); - } - - fn new_quick_fix(&self, title: String, text_edit: TextEdit) -> CodeAction { + fn new_quick_fix(&self, title: String, text_edit: TextEdit) -> CodeActionOrCommand { let mut changes = HashMap::new(); changes.insert(self.uri.clone(), vec![text_edit]); @@ -186,7 +149,7 @@ impl<'a> CodeActionFinder<'a> { change_annotations: None, }; - CodeAction { + CodeActionOrCommand::CodeAction(CodeAction { title, kind: Some(CodeActionKind::QUICKFIX), diagnostics: None, @@ -195,7 +158,7 @@ impl<'a> CodeActionFinder<'a> { is_preferred: None, disabled: None, data: None, - } + }) } fn includes_span(&self, span: Span) -> bool { @@ -244,69 +207,16 @@ impl<'a> Visitor for CodeActionFinder<'a> { } fn visit_path(&mut self, path: &Path) { - if path.segments.len() != 1 { - return; - } - - let ident = &path.segments[0].ident; - if !self.includes_span(ident.span()) { - return; - } - - let location = Location::new(ident.span(), self.file); - if self.interner.find_referenced(location).is_some() { - return; - } - - let current_module_parent_id = get_parent_module_id(self.def_maps, self.module_id); - - // The Path doesn't resolve to anything so it means it's an error and maybe we - // can suggest an import or to fully-qualify the path. - for (name, entries) in self.interner.get_auto_import_names() { - if name != &ident.0.contents { - continue; - } - - for (module_def_id, visibility, defining_module) in entries { - let module_full_path = if let Some(defining_module) = defining_module { - module_id_path( - *defining_module, - &self.module_id, - current_module_parent_id, - self.interner, - ) - } else { - let Some(module_full_path) = module_full_path( - *module_def_id, - *visibility, - self.module_id, - current_module_parent_id, - self.interner, - ) else { - continue; - }; - module_full_path - }; - - let full_path = if defining_module.is_some() - || !matches!(module_def_id, ModuleDefId::ModuleId(..)) - { - format!("{}::{}", module_full_path, name) - } else { - module_full_path.clone() - }; + self.import_or_qualify(path); + } - let qualify_prefix = if let ModuleDefId::ModuleId(..) = module_def_id { - let mut segments: Vec<_> = module_full_path.split("::").collect(); - segments.pop(); - segments.join("::") - } else { - module_full_path - }; + fn visit_constructor_expression( + &mut self, + constructor: &ConstructorExpression, + span: Span, + ) -> bool { + self.fill_struct_fields(constructor, span); - self.push_import_code_action(&full_path); - self.push_qualify_code_action(ident, &qualify_prefix, &full_path); - } - } + true } } diff --git a/noir/noir-repo/tooling/lsp/src/requests/code_action/fill_struct_fields.rs b/noir/noir-repo/tooling/lsp/src/requests/code_action/fill_struct_fields.rs new file mode 100644 index 00000000000..f57fbc652ad --- /dev/null +++ b/noir/noir-repo/tooling/lsp/src/requests/code_action/fill_struct_fields.rs @@ -0,0 +1,307 @@ +use lsp_types::TextEdit; +use noirc_errors::{Location, Span}; +use noirc_frontend::{ast::ConstructorExpression, node_interner::ReferenceId}; + +use crate::byte_span_to_range; + +use super::CodeActionFinder; + +impl<'a> CodeActionFinder<'a> { + pub(super) fn fill_struct_fields(&mut self, constructor: &ConstructorExpression, span: Span) { + if !self.includes_span(span) { + return; + } + + // Find out which struct this is + let location = Location::new(constructor.type_name.last_ident().span(), self.file); + let Some(ReferenceId::Struct(struct_id)) = self.interner.find_referenced(location) else { + return; + }; + + let struct_type = self.interner.get_struct(struct_id); + let struct_type = struct_type.borrow(); + + // First get all of the struct's fields + let mut fields = struct_type.get_fields_as_written(); + + // Remove the ones that already exists in the constructor + for (field, _) in &constructor.fields { + fields.retain(|(name, _)| name != &field.0.contents); + } + + if fields.is_empty() { + return; + } + + // Some fields are missing. Let's suggest a quick fix that adds them. + let bytes = self.source.as_bytes(); + let right_brace_index = span.end() as usize - 1; + let mut index = right_brace_index - 1; + while bytes[index].is_ascii_whitespace() { + index -= 1; + } + + let char_before_right_brace = bytes[index] as char; + + index += 1; + + let Some(range) = byte_span_to_range(self.files, self.file, index..index) else { + return; + }; + + // If the constructor spans multiple lines, we'll add the new fields in new lines too. + // Otherwise we'll add all the fields in a single line. + let constructor_range = + byte_span_to_range(self.files, self.file, span.start() as usize..span.end() as usize); + + // If it's multiline, find out the indent of the beginning line: we'll add new fields + // with that indent "plus one" (4 more spaces). + let line_indent = if let Some(constructor_range) = constructor_range { + if constructor_range.start.line == constructor_range.end.line { + None + } else { + let line = self.lines[constructor_range.start.line as usize]; + let whitespace_bytes = + line.bytes().take_while(|byte| byte.is_ascii_whitespace()).count(); + Some(whitespace_bytes) + } + } else { + None + }; + let line_indent = line_indent.map(|indent| " ".repeat(indent + 4)); + + let on_whitespace = bytes[index].is_ascii_whitespace(); + + let mut new_text = String::new(); + + // Add a comma if there's not a trailing one (if there are existing fields) + if !constructor.fields.is_empty() && char_before_right_brace != ',' { + new_text.push(','); + } + + // Add space or newline depending on whether it's multiline or not + if let Some(line_indent) = &line_indent { + new_text.push('\n'); + new_text.push_str(line_indent); + } else if !on_whitespace || constructor.fields.is_empty() { + new_text.push(' '); + } + + for (index, (name, _)) in fields.iter().enumerate() { + if index > 0 { + new_text.push(','); + if let Some(line_indent) = &line_indent { + new_text.push('\n'); + new_text.push_str(line_indent); + } else { + new_text.push(' '); + } + } + new_text.push_str(name); + new_text.push_str(": ()"); + } + + if !bytes[right_brace_index - 1].is_ascii_whitespace() { + new_text.push(' '); + } + + let title = "Fill struct fields".to_string(); + let text_edit = TextEdit { range, new_text }; + let code_action = self.new_quick_fix(title, text_edit); + self.code_actions.push(code_action); + } +} + +#[cfg(test)] +mod tests { + use tokio::test; + + use crate::requests::code_action::tests::assert_code_action; + + #[test] + async fn test_fill_struct_fields_code_action_no_space() { + let title = "Fill struct fields"; + + let src = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo {>|<} + } + "#; + + let expected = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo { one: (), two: () } + } + "#; + + assert_code_action(title, src, expected).await; + } + + #[test] + async fn test_fill_struct_fields_code_action_space() { + let title = "Fill struct fields"; + + let src = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo { >|<} + } + "#; + + let expected = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo { one: (), two: () } + } + "#; + + assert_code_action(title, src, expected).await; + } + + #[test] + async fn test_fill_struct_fields_code_action_some_fields() { + let title = "Fill struct fields"; + + let src = r#" + struct Foo { + one: Field, + two: Field, + three: Field, + } + + fn main() { + Foo { two: 1>|<} + } + "#; + + let expected = r#" + struct Foo { + one: Field, + two: Field, + three: Field, + } + + fn main() { + Foo { two: 1, one: (), three: () } + } + "#; + + assert_code_action(title, src, expected).await; + } + + #[test] + async fn test_fill_struct_fields_code_action_some_fields_trailing_comma() { + let title = "Fill struct fields"; + + let src = r#" + struct Foo { + one: Field, + two: Field, + three: Field, + } + + fn main() { + Foo { two: 1,>|<} + } + "#; + + let expected = r#" + struct Foo { + one: Field, + two: Field, + three: Field, + } + + fn main() { + Foo { two: 1, one: (), three: () } + } + "#; + + assert_code_action(title, src, expected).await; + } + + #[test] + async fn test_fill_struct_fields_code_action_multiline_empty() { + let title = "Fill struct fields"; + + let src = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo {>|< + } + } + "#; + + let expected = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo { + one: (), + two: () + } + } + "#; + + assert_code_action(title, src, expected).await; + } + + #[test] + async fn test_fill_struct_fields_code_action_multiline_some_fields() { + let title = "Fill struct fields"; + + let src = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo {>|< + one: 1, + } + } + "#; + + let expected = r#" + struct Foo { + one: Field, + two: Field, + } + + fn main() { + Foo { + one: 1, + two: () + } + } + "#; + + assert_code_action(title, src, expected).await; + } +} diff --git a/noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs b/noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs new file mode 100644 index 00000000000..25accc8a008 --- /dev/null +++ b/noir/noir-repo/tooling/lsp/src/requests/code_action/import_or_qualify.rs @@ -0,0 +1,241 @@ +use lsp_types::{Position, Range, TextEdit}; +use noirc_errors::Location; +use noirc_frontend::{ + ast::{Ident, Path}, + macros_api::ModuleDefId, +}; + +use crate::{ + byte_span_to_range, + modules::{get_parent_module_id, module_full_path, module_id_path}, +}; + +use super::CodeActionFinder; + +impl<'a> CodeActionFinder<'a> { + pub(super) fn import_or_qualify(&mut self, path: &Path) { + if path.segments.len() != 1 { + return; + } + + let ident = &path.segments[0].ident; + if !self.includes_span(ident.span()) { + return; + } + + let location = Location::new(ident.span(), self.file); + if self.interner.find_referenced(location).is_some() { + return; + } + + let current_module_parent_id = get_parent_module_id(self.def_maps, self.module_id); + + // The Path doesn't resolve to anything so it means it's an error and maybe we + // can suggest an import or to fully-qualify the path. + for (name, entries) in self.interner.get_auto_import_names() { + if name != &ident.0.contents { + continue; + } + + for (module_def_id, visibility, defining_module) in entries { + let module_full_path = if let Some(defining_module) = defining_module { + module_id_path( + *defining_module, + &self.module_id, + current_module_parent_id, + self.interner, + ) + } else { + let Some(module_full_path) = module_full_path( + *module_def_id, + *visibility, + self.module_id, + current_module_parent_id, + self.interner, + self.def_maps, + ) else { + continue; + }; + module_full_path + }; + + let full_path = if defining_module.is_some() + || !matches!(module_def_id, ModuleDefId::ModuleId(..)) + { + format!("{}::{}", module_full_path, name) + } else { + module_full_path.clone() + }; + + let qualify_prefix = if let ModuleDefId::ModuleId(..) = module_def_id { + let mut segments: Vec<_> = module_full_path.split("::").collect(); + segments.pop(); + segments.join("::") + } else { + module_full_path + }; + + self.push_import_code_action(&full_path); + self.push_qualify_code_action(ident, &qualify_prefix, &full_path); + } + } + } + + fn push_import_code_action(&mut self, full_path: &str) { + let line = self.auto_import_line as u32; + let character = (self.nesting * 4) as u32; + let indent = " ".repeat(self.nesting * 4); + let mut newlines = "\n"; + + // If the line we are inserting into is not an empty line, insert an extra line to make some room + if let Some(line_text) = self.lines.get(line as usize) { + if !line_text.trim().is_empty() { + newlines = "\n\n"; + } + } + + let title = format!("Import {}", full_path); + let text_edit = TextEdit { + range: Range { start: Position { line, character }, end: Position { line, character } }, + new_text: format!("use {};{}{}", full_path, newlines, indent), + }; + + let code_action = self.new_quick_fix(title, text_edit); + self.code_actions.push(code_action); + } + + fn push_qualify_code_action(&mut self, ident: &Ident, prefix: &str, full_path: &str) { + let Some(range) = byte_span_to_range( + self.files, + self.file, + ident.span().start() as usize..ident.span().start() as usize, + ) else { + return; + }; + + let title = format!("Qualify as {}", full_path); + let text_edit = TextEdit { range, new_text: format!("{}::", prefix) }; + + let code_action = self.new_quick_fix(title, text_edit); + self.code_actions.push(code_action); + } +} + +#[cfg(test)] +mod tests { + use tokio::test; + + use crate::requests::code_action::tests::assert_code_action; + + #[test] + async fn test_qualify_code_action_for_struct() { + let title = "Qualify as foo::bar::SomeTypeInBar"; + + let src = r#" + mod foo { + mod bar { + struct SomeTypeInBar {} + } + } + + fn foo(x: SomeType>|||| CodeActionResponse { .unwrap() } -async fn assert_code_action(title: &str, src: &str, expected: &str) { +pub(crate) async fn assert_code_action(title: &str, src: &str, expected: &str) { let actions = get_code_action(src).await; let action = actions .iter() @@ -87,150 +86,3 @@ fn apply_text_edit(src: &str, text_edit: &TextEdit) -> String { lines[text_edit.range.start.line as usize] = &line; lines.join("\n") } - -#[test] -async fn test_qualify_code_action_for_struct() { - let title = "Qualify as foo::bar::SomeTypeInBar"; - - let src = r#" - mod foo { - mod bar { - struct SomeTypeInBar {} - } - } - - fn foo(x: SomeType>||||| Option, -) -> bool { - can_reference_module_id( - def_maps, - current_module_id.krate, - current_module_id.local_id, - target_module_id, - visibility, - ) -} - #[cfg(test)] mod completion_name_matches_tests { use crate::requests::completion::name_matches; diff --git a/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs b/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs index bbd471dfea1..d8823794999 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/completion/auto_import.rs @@ -53,6 +53,7 @@ impl<'a> NodeFinder<'a> { self.module_id, current_module_parent_id, self.interner, + self.def_maps, ) else { continue; }; diff --git a/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs b/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs index d621ca21bb8..a7cfa77a73d 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/completion/tests.rs @@ -336,7 +336,7 @@ mod completion_tests { fo>|< } "#; - assert_completion(src, vec![module_completion_item("foobar")]).await; + assert_completion_excluding_auto_import(src, vec![module_completion_item("foobar")]).await; } #[test] @@ -1863,4 +1863,29 @@ mod completion_tests { Some("(use bar::foobar)".to_string()), ); } + + #[test] + async fn test_auto_import_suggests_private_function_if_visibile() { + let src = r#" + mod foo { + fn qux() { + barba>|< + } + } + + fn barbaz() {} + + fn main() {} + "#; + + let items = get_completions(src).await; + assert_eq!(items.len(), 1); + + let item = &items[0]; + assert_eq!(item.label, "barbaz()"); + assert_eq!( + item.label_details.as_ref().unwrap().detail, + Some("(use super::barbaz)".to_string()), + ); + } } diff --git a/noir/noir-repo/tooling/lsp/src/requests/mod.rs b/noir/noir-repo/tooling/lsp/src/requests/mod.rs index 5bd9959fd63..af58396550d 100644 --- a/noir/noir-repo/tooling/lsp/src/requests/mod.rs +++ b/noir/noir-repo/tooling/lsp/src/requests/mod.rs @@ -407,7 +407,7 @@ pub(crate) struct ProcessRequestCallbackArgs<'a> { location: noirc_errors::Location, files: &'a FileMap, interner: &'a NodeInterner, - interners: &'a HashMap, + interners: &'a HashMap, crate_id: CrateId, crate_name: String, dependencies: &'a Vec, @@ -432,8 +432,6 @@ where ResponseError::new(ErrorCode::REQUEST_FAILED, "Could not find package for file") })?; - let package_root_path: String = package.root_dir.as_os_str().to_string_lossy().into(); - let mut workspace_file_manager = file_manager_with_stdlib(&workspace.root_dir); insert_all_files_for_workspace_into_file_manager( state, @@ -447,9 +445,9 @@ where let interner; let def_maps; - if let Some(def_interner) = state.cached_definitions.get(&package_root_path) { + if let Some(def_interner) = state.cached_definitions.get(&package.root_dir) { interner = def_interner; - def_maps = state.cached_def_maps.get(&package_root_path).unwrap(); + def_maps = state.cached_def_maps.get(&package.root_dir).unwrap(); } else { // We ignore the warnings and errors produced by compilation while resolving the definition let _ = noirc_driver::check_crate(&mut context, crate_id, &Default::default()); @@ -479,7 +477,7 @@ where pub(crate) fn find_all_references_in_workspace( location: noirc_errors::Location, interner: &NodeInterner, - cached_interners: &HashMap, + cached_interners: &HashMap, files: &FileMap, include_declaration: bool, include_self_type_name: bool, diff --git a/noir/noir-repo/tooling/lsp/src/visibility.rs b/noir/noir-repo/tooling/lsp/src/visibility.rs index aad8b47fbbe..d6e26f7bc48 100644 --- a/noir/noir-repo/tooling/lsp/src/visibility.rs +++ b/noir/noir-repo/tooling/lsp/src/visibility.rs @@ -1,13 +1,25 @@ -use noirc_frontend::{ast::ItemVisibility, hir::def_map::ModuleId}; +use std::collections::BTreeMap; + +use noirc_frontend::{ + ast::ItemVisibility, + graph::CrateId, + hir::{ + def_map::{CrateDefMap, ModuleId}, + resolution::import::can_reference_module_id, + }, +}; pub(super) fn is_visible( + target_module_id: ModuleId, + current_module_id: ModuleId, visibility: ItemVisibility, - current_module: ModuleId, - target_module: ModuleId, + def_maps: &BTreeMap, ) -> bool { - match visibility { - ItemVisibility::Public => true, - ItemVisibility::Private => false, - ItemVisibility::PublicCrate => current_module.krate == target_module.krate, - } + can_reference_module_id( + def_maps, + current_module_id.krate, + current_module_id.local_id, + target_module_id, + visibility, + ) } diff --git a/noir/noir-repo/tooling/nargo_cli/src/cli/lsp_cmd.rs b/noir/noir-repo/tooling/nargo_cli/src/cli/lsp_cmd.rs index 9ff7a42e5f5..bfaa913b33a 100644 --- a/noir/noir-repo/tooling/nargo_cli/src/cli/lsp_cmd.rs +++ b/noir/noir-repo/tooling/nargo_cli/src/cli/lsp_cmd.rs @@ -35,8 +35,6 @@ pub(crate) fn run(_args: LspCommand, _config: NargoConfig) -> Result<(), CliErro .service(router) }); - eprintln!("LSP starting..."); - // Prefer truly asynchronous piped stdin/stdout without blocking tasks. #[cfg(unix)] let (stdin, stdout) = ( diff --git a/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs b/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs index 0e2d07f13d0..9e556e0fcbe 100644 --- a/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs +++ b/noir/noir-repo/tooling/nargo_fmt/src/visitor/item.rs @@ -165,6 +165,11 @@ impl super::FmtVisitor<'_> { continue; } + for attribute in module.outer_attributes { + self.push_str(&format!("#[{}]\n", attribute.as_ref())); + self.push_str(&self.indent.to_string()); + } + let name = module.name; let after_brace = self.span_after(span, Token::LeftBrace).start(); self.last_position = after_brace; @@ -227,7 +232,8 @@ impl super::FmtVisitor<'_> { | ItemKind::TraitImpl(_) | ItemKind::TypeAlias(_) | ItemKind::Global(_) - | ItemKind::ModuleDecl(_) => { + | ItemKind::ModuleDecl(_) + | ItemKind::InnerAttribute(_) => { self.push_rewrite(self.slice(span).to_string(), span); self.last_position = span.end(); } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr b/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr index e419543dbc4..0a051a1b50f 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/expected/module.nr @@ -1,3 +1,6 @@ +#![inner] +#![inner2] + mod a { mod b { struct Data { @@ -13,6 +16,8 @@ mod a { Data2 { a } } + #[custom] + #[another_custom] mod tests { #[test] fn test() { @@ -20,4 +25,11 @@ mod a { data2(1); } } + + #[attr] + mod baz; + + mod empty { + #![inner] + } } diff --git a/noir/noir-repo/tooling/nargo_fmt/tests/input/module.nr b/noir/noir-repo/tooling/nargo_fmt/tests/input/module.nr index e419543dbc4..0a051a1b50f 100644 --- a/noir/noir-repo/tooling/nargo_fmt/tests/input/module.nr +++ b/noir/noir-repo/tooling/nargo_fmt/tests/input/module.nr @@ -1,3 +1,6 @@ +#![inner] +#![inner2] + mod a { mod b { struct Data { @@ -13,6 +16,8 @@ mod a { Data2 { a } } + #[custom] + #[another_custom] mod tests { #[test] fn test() { @@ -20,4 +25,11 @@ mod a { data2(1); } } + + #[attr] + mod baz; + + mod empty { + #![inner] + } } 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 a5593cc284c..4ec715e27eb 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.51.1", "@noir-lang/types": "workspace:*", "fflate": "^0.8.0" }, 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 f77e9f7e72e..5d1d41f58fd 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.51.1": + version: 0.51.1 + resolution: "@aztec/bb.js@npm:0.51.1" 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: 246953d4d2becc86001b8e6d49ab8c0b4fa4833a9bf1d2177d0fb4e271e66f9dc65e3b02b69b00fbfcb935a11e2f90b5ac229b8c8938c34604fe54b29b3accfb 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 @@ -4160,7 +4161,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.51.1 "@noir-lang/types": "workspace:*" "@types/node": ^20.6.2 "@types/prettier": ^3 From 5b204a393f9b6948df77d2c47aa54302b1aaa537 Mon Sep 17 00:00:00 2001 From: AztecBot Date: Thu, 5 Sep 2024 08:02:57 +0000 Subject: [PATCH 2/2] chore: apply sync fixes --- noir/noir-repo/acvm-repo/acvm_js/build.sh | 2 +- .../verify_honk_proof/Nargo.toml | 6 + .../verify_honk_proof/Prover.toml | 575 ++++++++++++++++++ .../verify_honk_proof/src/main.nr | 17 + .../noir_js_backend_barretenberg/package.json | 2 +- .../noir-repo/tooling/noirc_abi_wasm/build.sh | 2 +- noir/noir-repo/yarn.lock | 13 +- 7 files changed, 607 insertions(+), 10 deletions(-) create mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml create mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml create mode 100644 noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr diff --git a/noir/noir-repo/acvm-repo/acvm_js/build.sh b/noir/noir-repo/acvm-repo/acvm_js/build.sh index 16fb26e55db..c07d2d8a4c1 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/test_programs/execution_success/verify_honk_proof/Nargo.toml b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml new file mode 100644 index 00000000000..8fce1bf44b6 --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Nargo.toml @@ -0,0 +1,6 @@ +[package] +name = "verify_honk_proof" +type = "bin" +authors = [""] + +[dependencies] 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 new file mode 100644 index 00000000000..5bdebb476be --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/Prover.toml @@ -0,0 +1,575 @@ +key_hash = "0x0000000000000000000000000000000000000000000000000000000000000000" +proof = [ + "0x0000000000000000000000000000000000000000000000000000000000000040", + "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", + "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", + "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", + "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", + "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", + "0x0000000000000000000000000000006cf7dd96d7636fda5953191b1ad776d491", + "0x00000000000000000000000000000000001633d881a08d136e834cb13a28fcc6", + "0x00000000000000000000000000000001254956cff6908b069fca0e6cf1c47eb1", + "0x000000000000000000000000000000000006f4d4dd3890e997e75e75886bf8f7", + "0x000000000000000000000000000000f968b227a358a305607f3efc933823d288", + "0x00000000000000000000000000000000000eaf8adb390375a76d95e918b65e08", + "0x000000000000000000000000000000bb34b4b447aae56f5e24f81c3acd6d547f", + "0x00000000000000000000000000000000002175d012746260ebcfe339a91a81e1", + "0x000000000000000000000000000000286fcda0e28617c86e195005b9f2efc555", + "0x00000000000000000000000000000000000dc409eb684b23f6a97175bcb9b486", + "0x000000000000000000000000000000e8de6a193cd36414f598bc7c48d67c3b59", + "0x00000000000000000000000000000000002a8a791544cad8c712de871e3de50a", + "0x000000000000000000000000000000d6f1e64b562df0f17ecc6aa46392f8d5a3", + "0x00000000000000000000000000000000000aac977763f33fd6a360ccc50a827a", + "0x000000000000000000000000000000899fa957f5597c6419e3ead9843d21d917", + "0x000000000000000000000000000000000016c4611846952bd6833c35fb11c0da", + "0x013dbfbfbfb2ae7d524edb15343e551d9510b3116223baaa67312d17652f2fb1", + "0x2f268eb3217ef1ac66016aa14d43033f932335371795b5e6dcb0c87c8ad0d050", + "0x2d5dbd52e00ae837e9868289fbe9057f16ea5b76c7e362603e8883f0de4b3e94", + "0x0e357b6a266c20d5e546c2931475eb044d7e75e08ec31b5e8623aec30f964323", + "0x0a9ace4dea44d0a2e8d12d495a683f508714356656aea3882436b729ead24165", + "0x0c17102a98ccb76faf0f78d669ee9cfb694849896787c985225d92e1af3cab35", + "0x09cc7cb719deb139c84fd9fa273e862a1b5d1cec2501c6cd8ba3c37ca06ac07f", + "0x15a0369f3f95d53687dfe79483baf75597d8b281fe0595caf1f7c9ccf99d985e", + "0x17fb53a42b3d1fa5d26ab19dfcc0d74d1781cee0be98dcc492c22e8f3442c4db", + "0x291d6810fc6afc5c2254fd283843a74c85a77275eee3049ea8ed9c88e02a99b8", + "0x0ad40d1627c31247dfb894584a71f8599cfcb85afe84b20186fc07fccae1aa4a", + "0x251cd908fb4e9fe88660f2303f8d7e4d7886da32fddc0319a842b99543659c0b", + "0x1885bdea3dd82085ca67502ebec8ad87213493e18a06cfa27e2c69810481b4a7", + "0x239ab5ba86866bc6705091f82a6a29444dc76b0e7d94cede7eb745cce36ab2cf", + "0x088d29a03baa491845d152124189dfb8bf70ba9bf1fb00c379199dbb0195c663", + "0x18c9fbe3227988d2da599eba82d60f4de25b442b663585fdc611e37305fa77fc", + "0x010242ae641a8cc4d06b5d24e38d9fa6254f981e28f238ccf6aad580f780d3f5", + "0x00128d34b122e84d7e23276b1f13f5789a562e82c727e9ffcfd7bbaccbe69e04", + "0x0776defaf478bfea4db2698542314e27213f63c96e41f98d4d82a47ed6fab55d", + "0x273014a360eaaa493e398df82f18d9cae37f4b6c0ead20100cad3f5491805298", + "0x2b13528eb9ab6fa705f2b48c9ec6ce054ac984e3adf17d4d73431e8456bf4a3c", + "0x22dafe1d63e39cd2effb236da2e131ee1c8cf4049ce504431dcaf98f75c47ad8", + "0x1afb5bc7eb8d30d807101357bb290f9c3113523f4aacc1154a27b075e46a4fa4", + "0x0782dd7df679163e5f0c126abc901d00f3d7d0856b4c02a199ab691ecd7566e6", + "0x2e556c722c99a84a09ffdcc719178277f8e6c9e31a4769270e3b522b944b8ea2", + "0x1be933a48dca8ef26202d3f135998ac8bed6947020b7447ffb6033b0e37f2065", + "0x2d8ebae210848de2464f5435f1fd4b5467ee938910d7779002614943060bbb32", + "0x2da854bbee38a94a6a9c2c85dd05bb4c879173720b67f93f78b9de93cdb427b0", + "0x0fa2649472af2e79489c466b58002f8f284f953085ac0a98dfabee85b78f63cf", + "0x304a09437636026ef0746c4b8ac1ca0ff250c5630fb5bd03ddafddd7cbde850e", + "0x0c83bb3c6ee0faa1646ee4d8dd83f67ec98e5d63ac802f7bdebfcdf21dee62f1", + "0x229d7e4524b30c18a6b94f0054e6d2ea8eb2396f58f9c808d2c9f991e2be2399", + "0x1265bf5e1aaddeae09242b1435e2f8f9e7487bf76a0461752777f6ea1ff75ad6", + "0x2f32f53281b7a363d6bec84ca21c71c3206d906b036e8b36b0702780e3b1b870", + "0x017fb18c9aef4d6d2bc99f5d7f9a002c8921fcd7c7ba69bf05930b55c2829cb7", + "0x2ec761c02ef6f2eefb7c9b2d6df71795d0ce0820f86797e2e11415cb5b122f22", + "0x2b1722960f42a1b40ffae3e4b9419fc8ff5cb8139a2c7e89af332ba2e95c1b5f", + "0x2dafa15594da2318245475c77eae3712429226b3005852e70f567efff0a7d79a", + "0x2ed44d7e3d5f44ac8f7c144ee0ba9d369c82428827c19b010384708bbc52a3f9", + "0x2777eedda697c7f90aee44fa97cfe62596d16c43fa3545b48d622023ca7a446a", + "0x1a47a5c1b0f41905aa0bad6248be8c7887ddea3ad9dfc8462b23a95b073c8a49", + "0x093656d571e84ac676a265dd509c98513039552b7a24e001b003ca618cc4ea5c", + "0x15c901e8a7ff0f1ae1989b5cfb687975c16716a8014a4052d527d4db4ecbaeb4", + "0x08bfa20e83096b0be58e4c96232510c8ef9824c0a62b91ffcc4592b217753a72", + "0x021913efbdfbc73aa5f4a97c79f352ac61f71248947f5eb5713c1b107c632703", + "0x00df89625aef270fab2a8c33ba742e1375423f4cfb3f63514ae748e004bb8cf4", + "0x2455f76c8ee59e93cbe7fe192cf0f766e1399617cabfa230cf27ca2a18cd58d5", + "0x150c3e56ea4f6442ed6b11030c98682a8f5e3c9cd6fd18949254a7c79b3cb5b6", + "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", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x01e89c6fe644aea7f63301278dbdb4ea29cf4d33f8b0cdcd79cb106e0bf0a753", + "0x2d49d23421e253903b8a5d0911642b9ce218cef4e350cf8689704eb1f3ae38d4", + "0x072956ca447343d788791fee1ef222f280048ad4aefb6cb7bc96b538f482f525", + "0x168176bf15c8ca63457acf05efbe54af452ea41f935ab82c2a96fedde10ba52f", + "0x20a13690f13491f7f3b756a1dc3b69a3f96d78355c70289583032a593bfc87bc", + "0x273e0a32ab3ef0d3f179b62520b31015ccfc8b53c76a1bb323b41e40ff954596", + "0x28019d4b05546b44e35d5dc74375b75dabb6fae49a07381605c60423c6163d26", + "0x10beda0b8dd484c63f0937820e2c7e9be832a0031efe3557631608895255ca5f", + "0x095a8f04a901526e4d70b1560bfff29b5a3c30347725d1e420c1b30ee2bf8a1c", + "0x1fb742e863a5c76262ffec93b3351405b0840b326fa5fffd73f40abcd5f05f05", + "0x11fa63cfcb2e603fe4e4668d75f05a2cf22650b84a91d1753e83f0e7ae83b4ad", + "0x2872e3d3c431a8b7ee4cec1c2a999a42c40ae33382fbba80a6d4c1a39b2d57a3", + "0x17e8c2a5f809f9935d7c6d7cb2f8859a513864b53f53de3d2a14c74cd690bd1a", + "0x20a552298d691393ae401382b3015689231ad988d3eb0521d414dcd2e8781053", + "0x183eb6bca59a141b4e8136179a258272ec9c25ec80bdb0458b6880c711707a28", + "0x03cd147a2a4c8dc272f3e240b8b0090d45e994e5fd40e07a54f6765795cd5ef8", + "0x082b135b3a20da4c766242b4258e27dbc050e4b8958bb15431626f2eeed9bd2b", + "0x28c894a6a719a32fe8d78ded46bc685ba035e5579c88fbc5bcbc0f09d8c5268b", + "0x06418cceff50837f923e63a37c2c534d13d9f59793c3aa6274813baa64d1899e", + "0x2b4a27b672f85c4fc697605da213de8b950a629602c5b8c6403e6c1c1065388a", + "0x0e2b817c6a79d6d1027f0376fb26ec81a140a4402e2dcdff6152cf01f2f4dbf9", + "0x2ae0fbce87dc53f0ff5473117e1c49a8197a14f8eaaec00cb5b10f94e844111f", + "0x2368004a1dee06f505e75ada3e9f8cc4c801f6a2068620da51ba11f537453835", + "0x2009df8e6f49f67dcaecb93e4a9ef81aaff096136d26f0fe691e14cd580c47da", + "0x2e512617136e8da2817856e57f13087a75fcc512faefc6d4b2eedd73c58a9b35", + "0x2848fcd535bd7c8017ca331a14919aa492ed05b04e9d0745480d291205eac8dc", + "0x19bb0990cb37f3a8f6c3db78219b07d6accd08e889586660e92dd6000755f09a", + "0x15520c8158b2e36c40c5fa46d5281c45d3df2c7f5d974a1f9549bfca6cbceaea", + "0x0e285f4df658d99922c286c5a253d6f6f37aa6c52d7a0fc1a20f3e6da9df23e1", + "0x0f9cd4667f4c1e86f83eda9e752a05c0cc630b0827a93a68322fa258dffb0f24", + "0x12d8b0dbbea3dccfe5d2dd090daf8ab4d2fac74fada9c49875b0c9122663a8ad", + "0x2e8c814d93f027ecff08c4e58555aadfc0f9ec3889eff2150f2b5bb6c557add0", + "0x013516a1456c5831aba87e4057878f6f3f18471e0674fd1e89be3e18351ec394", + "0x14418aa79dc84fd791d5638bdc103786ef8181a714ee8e022d3a1e792cbc7959", + "0x14418aa79dc84fd791d5638bdc103786ef8181a714ee8e022d3a1e792cbc7959", + "0x25c5e6c96a39bb36e19106d4049b675f0279084cc757c4e2acf6e497c61056a2", + "0x231aaafcf2a4c6fd8da18ce5ae5b33790f2c306a2692c6383c9a0787c50ac269", + "0x0a5f7665f0997081f9b38ec64e9a18542ac3a9648060f8cc720fc04669224730", + "0x0f1c9d9d1ac6f62825c6038117ed30540be434e8fd2d88150dcd4fece39b335a", + "0x1308871c8fcb09f07e5257f5cc5678d98842a8d18b2af09b5132d9af3cb1893e", + "0x28801985290dac4eba72ed01ee06fe88f6fc533dc1a46bd86e2d35be8021b042", + "0x14407f38cfba3cc61fca173b41133ab05a1c176caf8bb597588b01817e9eeaa3", + "0x0ea1a9f6f95f6193e512a7bd3db0c147f66687662934aed53cb657935b1e4eb9", + "0x1bc4ab6eacd61b5fd9e414b0186ef5deaadaf59aa9e53cb8d8812255baa28109", + "0x00000000000000000000000000000093a4da68a2fac0ee94841efdfc57eb748c", + "0x00000000000000000000000000000000001c22f1f5f927bee6adb649cc132391", + "0x0000000000000000000000000000003d0c2acea76c551f58876b3c35f19f345a", + "0x00000000000000000000000000000000002e94fded0a0b7f4fd1c882fd2a4e52", + "0x00000000000000000000000000000022e23b6fa0f72844bf8f60ea140cca5663", + "0x000000000000000000000000000000000013380f284bf3cb98b9a7cbae7d702b", + "0x000000000000000000000000000000942a13cf93056815c3f7439c9eed0a103e", + "0x00000000000000000000000000000000002be14bec02c6dae4625d32866de4fc", + "0x000000000000000000000000000000e2a2c75dc664c12695b4f7795c61f92669", + "0x000000000000000000000000000000000000725da448f376bde6cf63bcf79463", + "0x000000000000000000000000000000f54eee585f8ab367dc66a587e1d4cdbd8c", + "0x0000000000000000000000000000000000071106624ae5623a070f0addc18433", + "0x000000000000000000000000000000d60352bea3b2adb311b1a3beb25acb8aed", + "0x00000000000000000000000000000000001965b7c781e33f94e90c743c7881ed", + "0x0000000000000000000000000000006458a2aa57539e2b192f9c3ed69f9fb674", + "0x00000000000000000000000000000000001fc9c667723a4e66d752c6b426d444", + "0x0000000000000000000000000000008d1ff1c5d59a463c5b46bcf52f41ad3c63", + "0x00000000000000000000000000000000001b3e73df070a35c49a03fab1c76e9b", + "0x0000000000000000000000000000001c17a62b6c0a7ab14de83391e06f780adb", + "0x000000000000000000000000000000000012c7fbe2591b9ae72dd526e4ed1d7f", + "0x000000000000000000000000000000a758fa0c72d6a93155cb18b3fcc7defd34", + "0x00000000000000000000000000000000000cea12961770ce7cb6f2a4aed009fe", + "0x000000000000000000000000000000ef6e9647803aac315fa6d287e0e66f4767", + "0x0000000000000000000000000000000000259a82b8d6c6015cc51d2681f26ad4", + "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", + "0x0000000000000000000000000000008152b373c87004bef7d2c55ec8c540b67f", + "0x00000000000000000000000000000000000a55be5fdcb0a0dce4976d7bb78b0c", + "0x000000000000000000000000000000f749ea03f04ac964706139b9d1db595ecb", + "0x000000000000000000000000000000000013218e14dae80c066b4e46e9309fb2", + "0x0000000000000000000000000000004bbd7f950c36ce69db39e2b234a9e3f9b0", + "0x00000000000000000000000000000000002a0c3994d892ca5ea26984abbb30fb", + "0x0000000000000000000000000000006c1b39306846620bd546ac2c897834f259", + "0x000000000000000000000000000000000020350b9f507d6e25961a11be3e494b", +] +public_inputs = [ + "0x0000000000000000000000000000000000000000000000000000000000000003", +] +verification_key = [ + "0x0000000000000000000000000000000000000000000000000000000000000040", + "0x0000000000000000000000000000000000000000000000000000000000000011", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000003", + "0x0000000000000000000000000000000000000000000000000000000000000004", + "0x0000000000000000000000000000000000000000000000000000000000000005", + "0x0000000000000000000000000000000000000000000000000000000000000006", + "0x0000000000000000000000000000000000000000000000000000000000000007", + "0x0000000000000000000000000000000000000000000000000000000000000008", + "0x0000000000000000000000000000000000000000000000000000000000000009", + "0x000000000000000000000000000000000000000000000000000000000000000a", + "0x000000000000000000000000000000000000000000000000000000000000000b", + "0x000000000000000000000000000000000000000000000000000000000000000c", + "0x000000000000000000000000000000000000000000000000000000000000000d", + "0x000000000000000000000000000000000000000000000000000000000000000e", + "0x000000000000000000000000000000000000000000000000000000000000000f", + "0x0000000000000000000000000000000000000000000000000000000000000010", + "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", + "0x000000000000000000000000000000ee40d90bea71fba7a412dd61fcf34e8ceb", + "0x0000000000000000000000000000000000140b0936c323fd2471155617b6af56", + "0x0000000000000000000000000000002b90071823185c5ff8e440fd3d73b6fefc", + "0x00000000000000000000000000000000002b6c10790a5f6631c87d652e059df4", + "0x00000000000000000000000000000029a17181c7934fc3fdbd352eac5cb521b9", + "0x00000000000000000000000000000000001f497cbf5284ff29a2d336e5991999", + "0x000000000000000000000000000000072bd9c0c6beda1fdee6d4ff0432ba9e1b", + "0x000000000000000000000000000000000013ea38a0bd2aa751a490a724fac818", + "0x000000000000000000000000000000c599f63dcd3edd49f08ae5c3141c1e3493", + "0x00000000000000000000000000000000002bdb36be0bea09950dd32a8ccf6fbc", + "0x00000000000000000000000000000047f27f29724e7f19eba0340256a0bd4b7d", + "0x00000000000000000000000000000000001c1c5ccf87a962129ca785f8f35120", + "0x000000000000000000000000000000c5c71efdae00679bbe4a95096e012b1817", + "0x000000000000000000000000000000000017a365de041e317817d0135f2b48e0", + "0x0000000000000000000000000000008ae711ac402f7848d719c93a89ba8d39f1", + "0x00000000000000000000000000000000002b6fb40ed8a1935226f4f9786a0499", + "0x0000000000000000000000000000002f03a71501d83de1da5715a4e9462d6198", + "0x00000000000000000000000000000000001644064443b8546f48eae693af47b8", + "0x00000000000000000000000000000083763ab1b6e8fe269b2fe4c7b9c448c08d", + "0x000000000000000000000000000000000021d7cc18c59676a8eeb47c0111c251", + "0x000000000000000000000000000000b5f937153073e03ea7d51a996e0ebc2e6b", + "0x000000000000000000000000000000000011ddd0e26457373eb06e0493177672", + "0x000000000000000000000000000000c5f6eb9f6fc8fa99811a4a88c74a6d018b", + "0x000000000000000000000000000000000025bcd07a0732c123567834f5109558", + "0x000000000000000000000000000000aeb08a0b1a4442189448b4e97490568146", + "0x000000000000000000000000000000000002a1744e4771705536a88f07e0f90f", + "0x000000000000000000000000000000b938568293bd0724b0ea76c2ec34c4a829", + "0x0000000000000000000000000000000000053296e8f3b9ad3af877dfa9c7c2a7", + "0x000000000000000000000000000000f0ca1db6323996eba26bdc86dafef9d10b", + "0x00000000000000000000000000000000001441a46c58af03d5645d52721d956a", + "0x0000000000000000000000000000008bbf8f884013c66c28ba09c2fbd573b656", + "0x0000000000000000000000000000000000206c391ca06fac27d1908e94570243", + "0x0000000000000000000000000000002d4f5aaed88ba4f79612d53b804ca8f194", + "0x00000000000000000000000000000000001674011c96392df08970fa6b7b4cb8", + "0x0000000000000000000000000000009f88297c1729d76c4d9306853598c91325", + "0x0000000000000000000000000000000000256f51adfcacc3c1e340be4d32d3e9", + "0x0000000000000000000000000000000ab9955eec0d74eb799afed2a802b24d75", + "0x00000000000000000000000000000000001fcbe43ea105b30d36ed0b21b03411", + "0x000000000000000000000000000000d66b1d5433f1aa5305cd1edce7c22de466", + "0x00000000000000000000000000000000002331546a256b8a3b751956806680d4", + "0x000000000000000000000000000000e97954ad6cd6f45fb15c91434121db4304", + "0x00000000000000000000000000000000002e20a97e09d50f227ced47e7a98250", + "0x0000000000000000000000000000001ebbc27eb9ebededefba79522eb58ae89b", + "0x0000000000000000000000000000000000090efa4974e566e81d1177b85a30be", + "0x0000000000000000000000000000005eafa070b9c9632404052642e3bc14f9fd", + "0x00000000000000000000000000000000001489068864102daca6a6b8bc4d448b", + "0x0000000000000000000000000000009ebc91aaaac036a6477cadbe54e8556dfd", + "0x00000000000000000000000000000000000ef6d835e2ed3343b95c82c8c54037", + "0x00000000000000000000000000000033b28b529dff46e93af4e7422530478e4a", + "0x000000000000000000000000000000000020a86c2f8591bf190bcddcc03c42fb", + "0x000000000000000000000000000000a9679d0acc088f7dc27bf6d866bcd2dda2", + "0x00000000000000000000000000000000002fb9d0d2d4099402bed74f738f64cc", + "0x00000000000000000000000000000023b09f876a29a061582848a8b9a5870c12", + "0x00000000000000000000000000000000001d5bb906f03f0d49e9c4791bc43af9", + "0x00000000000000000000000000000017aac9854ea240d8ec97bf760c4d4ba870", + "0x00000000000000000000000000000000000b227a556c414ada0dc75bb303e30e", + "0x0000000000000000000000000000000000000000000000000000000000000001", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000000000000000000000000000000000000002", + "0x0000000000000000000000000000000000000000000000000000000000000000", + "0x0000000000000000000000000000009b624fa65d1a24b7f14a8f25f3789622af", + "0x000000000000000000000000000000000013d47bff8c630e847b70e2732fd3f0", + "0x00000000000000000000000000000061d21663e93132f32921075f4c936a84df", + "0x00000000000000000000000000000000001a74ca4e118fb480b9b999902989a3", +] 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 new file mode 100644 index 00000000000..b60a47ccc7f --- /dev/null +++ b/noir/noir-repo/test_programs/execution_success/verify_honk_proof/src/main.nr @@ -0,0 +1,17 @@ + +// This circuit aggregates a single Honk proof from `assert_statement_recursive`. +global SIZE_OF_PROOF_IF_LOGN_IS_28 : u32 = 439; +global HONK_IDENTIFIER : u32 = 1; +fn main( + verification_key: [Field; 128], + // 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, proof, public_inputs, key_hash); +} 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 4ec715e27eb..a5593cc284c 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": "0.51.1", + "@aztec/bb.js": "portal:../../../../barretenberg/ts", "@noir-lang/types": "workspace:*", "fflate": "^0.8.0" }, diff --git a/noir/noir-repo/tooling/noirc_abi_wasm/build.sh b/noir/noir-repo/tooling/noirc_abi_wasm/build.sh index 16fb26e55db..c07d2d8a4c1 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 5d1d41f58fd..f77e9f7e72e 100644 --- a/noir/noir-repo/yarn.lock +++ b/noir/noir-repo/yarn.lock @@ -221,19 +221,18 @@ __metadata: languageName: node linkType: hard -"@aztec/bb.js@npm:0.51.1": - version: 0.51.1 - resolution: "@aztec/bb.js@npm:0.51.1" +"@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" dependencies: comlink: ^4.4.1 commander: ^10.0.1 debug: ^4.3.4 tslib: ^2.4.0 bin: - bb.js: dest/node/main.js - checksum: 246953d4d2becc86001b8e6d49ab8c0b4fa4833a9bf1d2177d0fb4e271e66f9dc65e3b02b69b00fbfcb935a11e2f90b5ac229b8c8938c34604fe54b29b3accfb + bb.js: ./dest/node/main.js languageName: node - linkType: hard + linkType: soft "@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 @@ -4161,7 +4160,7 @@ __metadata: version: 0.0.0-use.local resolution: "@noir-lang/backend_barretenberg@workspace:tooling/noir_js_backend_barretenberg" dependencies: - "@aztec/bb.js": 0.51.1 + "@aztec/bb.js": "portal:../../../../barretenberg/ts" "@noir-lang/types": "workspace:*" "@types/node": ^20.6.2 "@types/prettier": ^3