From 677c10c50e6944e9e11d5579048f77cab59cf91a Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 25 Feb 2025 13:10:38 -0300 Subject: [PATCH 1/4] fix: don't crash on broken impl syntax (#7512) --- compiler/noirc_frontend/src/elaborator/mod.rs | 2 +- test_programs/compile_failure/broken_impl/Nargo.toml | 7 +++++++ test_programs/compile_failure/broken_impl/src/main.nr | 2 ++ 3 files changed, 10 insertions(+), 1 deletion(-) create mode 100644 test_programs/compile_failure/broken_impl/Nargo.toml create mode 100644 test_programs/compile_failure/broken_impl/src/main.nr diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index 7b553b88ac9..a65a1a94cf1 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -2134,7 +2134,7 @@ impl<'context> Elaborator<'context> { let span = location.span; let found = trait_impl.r#trait.typ.to_string(); self.push_err(ResolverError::ExpectedTrait { span, found }, location.file); - continue; + (None, GenericTypeArgs::default(), location) } }; diff --git a/test_programs/compile_failure/broken_impl/Nargo.toml b/test_programs/compile_failure/broken_impl/Nargo.toml new file mode 100644 index 00000000000..a200adc27b0 --- /dev/null +++ b/test_programs/compile_failure/broken_impl/Nargo.toml @@ -0,0 +1,7 @@ +[package] +name = "broken_impl" +type = "bin" +authors = [""] +compiler_version = ">=0.26.0" + +[dependencies] diff --git a/test_programs/compile_failure/broken_impl/src/main.nr b/test_programs/compile_failure/broken_impl/src/main.nr new file mode 100644 index 00000000000..033b0e741ed --- /dev/null +++ b/test_programs/compile_failure/broken_impl/src/main.nr @@ -0,0 +1,2 @@ +// This used to crash the compiler +impl< Foo for From f0c7feb1c18a6b0ae97cfaaf93f21c0c24863ad0 Mon Sep 17 00:00:00 2001 From: jfecher Date: Tue, 25 Feb 2025 13:43:21 -0600 Subject: [PATCH 2/4] chore: Increaes base64's allotted time (#7521) --- EXTERNAL_NOIR_LIBRARIES.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/EXTERNAL_NOIR_LIBRARIES.yml b/EXTERNAL_NOIR_LIBRARIES.yml index 65ac17ef8c9..9232e5ac4ce 100644 --- a/EXTERNAL_NOIR_LIBRARIES.yml +++ b/EXTERNAL_NOIR_LIBRARIES.yml @@ -29,7 +29,7 @@ libraries: timeout: 330 noir_base64: repo: noir-lang/noir_base64 - timeout: 2 + timeout: 3 noir_string_search: repo: noir-lang/noir_string_search timeout: 2 From 4fdc742369c4f0cda307b5b1904260133d1add64 Mon Sep 17 00:00:00 2001 From: Ary Borenszweig Date: Tue, 25 Feb 2025 16:49:03 -0300 Subject: [PATCH 3/4] feat: let all compiler errors carry a Location instead of a Span (#7486) Co-authored-by: jfecher --- .github/benchmark_projects.yml | 2 +- Cargo.lock | 218 ++++---- compiler/noirc_driver/src/abi_gen.rs | 14 +- compiler/noirc_driver/src/lib.rs | 5 +- compiler/noirc_errors/src/reporter.rs | 66 ++- compiler/noirc_evaluator/src/errors.rs | 13 +- compiler/noirc_frontend/src/ast/expression.rs | 8 +- compiler/noirc_frontend/src/ast/statement.rs | 42 +- compiler/noirc_frontend/src/ast/visitor.rs | 22 +- compiler/noirc_frontend/src/debug/mod.rs | 49 +- .../noirc_frontend/src/elaborator/comptime.rs | 97 ++-- .../noirc_frontend/src/elaborator/enums.rs | 75 ++- .../src/elaborator/expressions.rs | 258 ++++------ .../noirc_frontend/src/elaborator/lints.rs | 29 +- compiler/noirc_frontend/src/elaborator/mod.rs | 225 +++------ .../src/elaborator/path_resolution.rs | 5 +- .../noirc_frontend/src/elaborator/patterns.rs | 154 +++--- .../noirc_frontend/src/elaborator/scope.rs | 54 +- .../src/elaborator/statements.rs | 208 ++++---- .../src/elaborator/trait_impls.rs | 66 +-- .../noirc_frontend/src/elaborator/traits.rs | 31 +- .../noirc_frontend/src/elaborator/types.rs | 450 +++++++---------- .../src/hir/comptime/display.rs | 9 +- .../noirc_frontend/src/hir/comptime/errors.rs | 157 +++--- .../src/hir/comptime/hir_to_display_ast.rs | 16 +- .../src/hir/comptime/interpreter.rs | 19 +- .../src/hir/comptime/interpreter/builtin.rs | 76 +-- .../interpreter/builtin/builtin_helpers.rs | 3 +- .../noirc_frontend/src/hir/comptime/tests.rs | 2 +- .../noirc_frontend/src/hir/comptime/value.rs | 6 +- .../src/hir/def_collector/dc_crate.rs | 70 +-- .../src/hir/def_collector/dc_mod.rs | 142 +++--- .../src/hir/def_collector/errors.rs | 178 +++---- .../noirc_frontend/src/hir/def_map/mod.rs | 8 +- compiler/noirc_frontend/src/hir/mod.rs | 5 +- .../src/hir/resolution/errors.rs | 461 ++++++++++------- .../src/hir/resolution/import.rs | 47 +- .../src/hir/type_check/errors.rs | 471 +++++++++++------- compiler/noirc_frontend/src/hir_def/expr.rs | 3 +- compiler/noirc_frontend/src/hir_def/traits.rs | 5 +- compiler/noirc_frontend/src/hir_def/types.rs | 93 ++-- .../src/hir_def/types/arithmetic.rs | 44 +- compiler/noirc_frontend/src/lexer/errors.rs | 37 +- .../src/monomorphization/errors.rs | 10 +- .../src/monomorphization/mod.rs | 24 +- compiler/noirc_frontend/src/node_interner.rs | 23 +- compiler/noirc_frontend/src/parser/errors.rs | 30 +- .../src/parser/parser/expression.rs | 15 +- .../noirc_frontend/src/parser/parser/path.rs | 15 +- .../src/parser/parser/use_tree.rs | 6 +- .../src/parser/parser/where_clause.rs | 8 +- compiler/noirc_frontend/src/tests.rs | 368 +++++++------- .../noirc_frontend/src/tests/bound_checks.rs | 16 +- compiler/noirc_frontend/src/tests/imports.rs | 18 +- .../src/tests/metaprogramming.rs | 17 +- .../noirc_frontend/src/tests/references.rs | 8 +- compiler/noirc_frontend/src/tests/traits.rs | 55 +- .../noirc_frontend/src/tests/turbofish.rs | 48 +- .../noirc_frontend/src/tests/unused_items.rs | 14 +- .../noirc_frontend/src/tests/visibility.rs | 20 +- compiler/wasm/src/errors.rs | 4 +- tooling/lsp/src/notifications/mod.rs | 11 +- tooling/lsp/src/with_file.rs | 13 +- tooling/nargo/src/errors.rs | 2 +- tooling/nargo_fmt/src/formatter/expression.rs | 4 +- tooling/nargo_fmt/src/formatter/statement.rs | 5 +- tooling/profiler/src/errors.rs | 6 +- 67 files changed, 2218 insertions(+), 2465 deletions(-) diff --git a/.github/benchmark_projects.yml b/.github/benchmark_projects.yml index 83e8e6ae908..cabc53d38bb 100644 --- a/.github/benchmark_projects.yml +++ b/.github/benchmark_projects.yml @@ -18,7 +18,7 @@ projects: compilation-timeout: 1.2 execution-timeout: 0.02 compilation-memory-limit: 250 - execution-memory-limit: 200 + execution-memory-limit: 210 private-kernel-reset: repo: AztecProtocol/aztec-packages ref: *AZ_COMMIT diff --git a/Cargo.lock b/Cargo.lock index 5a7740dfcd8..2962b688996 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -110,7 +110,7 @@ dependencies = [ "build-data", "console_error_panic_hook", "const-str", - "getrandom 0.2.15", + "getrandom", "gloo-utils", "js-sys", "pkg-config", @@ -150,7 +150,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ "cfg-if", - "getrandom 0.2.15", + "getrandom", "once_cell", "version_check", "zerocopy", @@ -386,7 +386,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "62945a2f7e6de02a31fe400aa489f0e0f5b2502e69f95f853adb82a96c7a6b60" dependencies = [ "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -412,7 +412,7 @@ dependencies = [ "num-traits", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -499,7 +499,7 @@ checksum = "213888f660fddcca0d257e88e54ac05bca01885f258ccdf695bafd77031bb69d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -587,13 +587,13 @@ dependencies = [ [[package]] name = "async-trait" -version = "0.1.86" +version = "0.1.85" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "644dd749086bf3771a2fbc5f256fdb982d53f011c7d5d560304eafeecebce79d" +checksum = "3f934833b4b7233644e5848f235df3f57ed8c80f1528a26c3dfa13d2147fa056" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -721,9 +721,9 @@ dependencies = [ [[package]] name = "blake2b_simd" -version = "1.0.3" +version = "1.0.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06e903a20b159e944f91ec8499fe1e55651480c541ea0a584f5d967c49ad9d99" +checksum = "23285ad32269793932e830392f2fe2f83e26488fd3ec778883a93c8323735780" dependencies = [ "arrayref", "arrayvec", @@ -826,9 +826,9 @@ dependencies = [ [[package]] name = "bumpalo" -version = "3.17.0" +version = "3.16.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf" +checksum = "79296716171880943b8470b5f8d03aa55eb2e645a4874bdbb28adb49162e012c" [[package]] name = "bytemuck" @@ -844,9 +844,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.10.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f61dac84819c6588b558454b194026eb1f09c293b9036ae9b159e74e73ab6cf9" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cast" @@ -856,9 +856,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5" [[package]] name = "cc" -version = "1.2.13" +version = "1.2.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c7777341816418c02e033934a09f20dc0ccaf65a5201ef8a450ae0105a573fda" +checksum = "13208fcbb66eaeffe09b99fffbe1af420f00a7b35aa99ad683dfc1aa76145229" dependencies = [ "shlex", ] @@ -919,9 +919,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.28" +version = "4.5.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3e77c3243bd94243c03672cb5154667347c457ca271254724f9f393aee1c05ff" +checksum = "769b0145982b4b48713e01ec42d61614425f27b7058bda7180a3a41f30104796" dependencies = [ "clap_builder", "clap_derive", @@ -949,23 +949,23 @@ dependencies = [ [[package]] name = "clap_complete" -version = "4.5.44" +version = "4.5.43" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375f9d8255adeeedd51053574fd8d4ba875ea5fa558e86617b07f09f1680c8b6" +checksum = "0952013545c9c6dca60f491602655b795c6c062ab180c9cb0bccb83135461861" dependencies = [ "clap", ] [[package]] name = "clap_derive" -version = "4.5.28" +version = "4.5.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bf4ced95c6f4a675af3da73304b9ac4ed991640c36374e4b46795c49e17cf1ed" +checksum = "54b755194d6389280185988721fffba69495eed5ee9feeee9a599b53db80318c" dependencies = [ "heck 0.5.0", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1329,7 +1329,7 @@ dependencies = [ "proc-macro2", "quote", "strsim", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1340,7 +1340,7 @@ checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" dependencies = [ "darling_core", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1463,7 +1463,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1508,7 +1508,7 @@ dependencies = [ "enum-ordinalize", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1566,7 +1566,7 @@ checksum = "0d28318a75d4aead5c4db25382e8ef717932d0346600cacae6357eb5941bc5ff" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1605,7 +1605,7 @@ checksum = "3bf679796c0322556351f287a51b49e48f7c4986e727b5dd78c972d30e2e16cc" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1849,7 +1849,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -1910,22 +1910,10 @@ dependencies = [ "cfg-if", "js-sys", "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "wasm-bindgen", ] -[[package]] -name = "getrandom" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" -dependencies = [ - "cfg-if", - "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", -] - [[package]] name = "gimli" version = "0.28.1" @@ -2372,7 +2360,7 @@ checksum = "1ec89e9337638ecdc08744df490b221a7399bf8d164eb52a665454e60e075ad6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -2641,7 +2629,7 @@ dependencies = [ "jsonrpsee-types", "parking_lot", "rand", - "rustc-hash 2.1.1", + "rustc-hash 2.1.0", "serde", "serde_json", "thiserror", @@ -2684,7 +2672,7 @@ dependencies = [ "proc-macro-crate", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -2973,7 +2961,7 @@ checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" dependencies = [ "libc", "log", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.48.0", ] @@ -2984,7 +2972,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2886843bf800fba2e3377cff24abf6379b4c4d5c6681eaf9ea5b0d15090450bd" dependencies = [ "libc", - "wasi 0.11.0+wasi-snapshot-preview1", + "wasi", "windows-sys 0.52.0", ] @@ -3295,7 +3283,7 @@ dependencies = [ "build-data", "console_error_panic_hook", "fm", - "getrandom 0.2.15", + "getrandom", "gloo-utils", "js-sys", "nargo", @@ -3337,7 +3325,7 @@ dependencies = [ "acvm", "build-data", "console_error_panic_hook", - "getrandom 0.2.15", + "getrandom", "gloo-utils", "iter-extended", "js-sys", @@ -3626,9 +3614,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "oorandom" @@ -3795,22 +3783,22 @@ dependencies = [ [[package]] name = "pin-project" -version = "1.1.9" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfe2e71e1471fe07709406bf725f710b02927c9c54b2b5b2ec0e8087d97c327d" +checksum = "1e2ec53ad785f4d35dac0adea7f7dc6f1bb277ad84a680c7afefeae05d1f5916" dependencies = [ "pin-project-internal", ] [[package]] name = "pin-project-internal" -version = "1.1.9" +version = "1.1.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6e859e6e5bd50440ab63c47e3ebabc90f26251f7c73c3d3e837b74a1cc3fa67" +checksum = "d56a66c0c55993aa927429d0f8a0abfd74f084e4d9c192cffed01e418d83eefb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -3968,7 +3956,7 @@ version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8ecf48c7ca261d60b74ab1a7b20da18bede46776b2e55535cb958eb595c5fa7b" dependencies = [ - "toml_edit 0.22.24", + "toml_edit 0.22.22", ] [[package]] @@ -4014,7 +4002,7 @@ checksum = "4ee1c9ac207483d5e7db4940700de86a9aae46ef90c48b57f99fe7edb8345e49" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -4084,7 +4072,7 @@ version = "0.6.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c" dependencies = [ - "getrandom 0.2.15", + "getrandom", ] [[package]] @@ -4161,7 +4149,7 @@ version = "0.4.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ - "getrandom 0.2.15", + "getrandom", "libredox 0.1.3", "thiserror", ] @@ -4251,7 +4239,7 @@ checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" dependencies = [ "cc", "cfg-if", - "getrandom 0.2.15", + "getrandom", "libc", "spin", "untrusted", @@ -4284,7 +4272,7 @@ dependencies = [ "proc-macro2", "quote", "rust-embed-utils", - "syn 2.0.98", + "syn 2.0.96", "walkdir", ] @@ -4312,9 +4300,9 @@ checksum = "08d43f7aa6b08d49f382cde6a7982047c3426db949b1424bc4b7ec9ae12c6ce2" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497" [[package]] name = "rustc_version" @@ -4340,9 +4328,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.22" +version = "0.23.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fb9263ab4eb695e42321db096e3b8fbd715a59b154d5c88d82db2175b681ba7" +checksum = "8f287924602bf649d949c63dc8ac8b235fa5387d394020705b80c4eb597ce5b8" dependencies = [ "log", "once_cell", @@ -4655,14 +4643,14 @@ checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] name = "serde_json" -version = "1.0.138" +version = "1.0.137" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d434192e7da787e94a6ea7e9670b26a036d0ca41e0b7efb2676dd32bae872949" +checksum = "930cfb6e6abf99298aaad7d29abbef7a9999a9a8806a40088f55f0dcec03146b" dependencies = [ "itoa", "memchr", @@ -4678,7 +4666,7 @@ checksum = "6c64451ba24fc7a6a2d60fc75dd9c83c90903b19028d4eff35e88fc1e86564e9" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -4717,7 +4705,7 @@ dependencies = [ "darling", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -4966,9 +4954,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "symbolic-common" -version = "12.13.4" +version = "12.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b6189977df1d6ec30c920647919d76f29fb8d8f25e8952e835b0fcda25e8f792" +checksum = "13a4dfe4bbeef59c1f32fc7524ae7c95b9e1de5e79a43ce1604e181081d71b0c" dependencies = [ "debugid", "memmap2", @@ -4978,9 +4966,9 @@ dependencies = [ [[package]] name = "symbolic-demangle" -version = "12.13.4" +version = "12.13.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d234917f7986498e7f62061438cee724bafb483fe84cfbe2486f68dce48240d7" +checksum = "98cf6a95abff97de4d7ff3473f33cacd38f1ddccad5c1feab435d6760300e3b6" dependencies = [ "cpp_demangle", "rustc-demangle", @@ -5000,9 +4988,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.98" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "36147f1a48ae0ec2b5b3bc5b537d267457555a10dc06f3dbc8cb11ba3006d3b1" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -5017,7 +5005,7 @@ checksum = "c8af7666ab7b6390ab78131fb5b0fce11d6b7a6951602017c35fa82800708971" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -5028,13 +5016,13 @@ checksum = "55937e1799185b12863d447f42597ed69d9928686b8d88a1df17376a097d8369" [[package]] name = "tempfile" -version = "3.16.0" +version = "3.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c246215d7d24f48ae091a2902398798e05d978b24315d6efbc00ede9a8bb91" +checksum = "9a8a559c81686f576e8cd0290cd2a24a2a9ad80c98b3478856500fcbd7acd704" dependencies = [ "cfg-if", "fastrand", - "getrandom 0.3.1", + "getrandom", "once_cell", "rustix", "windows-sys 0.59.0", @@ -5096,7 +5084,7 @@ dependencies = [ "cfg-if", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -5107,7 +5095,7 @@ checksum = "5c89e72a01ed4c579669add59014b9a524d609c0c88c6a585ce37485879f6ffb" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", "test-case-core", ] @@ -5149,7 +5137,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -5237,7 +5225,7 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -5312,13 +5300,13 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.22.24" +version = "0.22.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17b4795ff5edd201c7cd6dca065ae59972ce77d1b80fa0a84d94950ece7d1474" +checksum = "4ae48d6208a266e853d946088ed816055e556cc6028c5e8e2b84d9fa5dd7c7f5" dependencies = [ "indexmap 2.7.1", "toml_datetime", - "winnow 0.7.2", + "winnow 0.6.25", ] [[package]] @@ -5380,7 +5368,7 @@ checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -5463,7 +5451,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "04659ddb06c87d233c566112c1c9c5b9e98256d9af50ec3bc9c8327f873a7568" dependencies = [ "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -5574,9 +5562,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.13.1" +version = "1.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ced87ca4be083373936a67f8de945faa23b6b42384bd5b64434850802c6dccd0" +checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b" [[package]] name = "valuable" @@ -5607,9 +5595,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a" [[package]] name = "wait-timeout" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +checksum = "9f200f5b12eb75f8c1ed65abd4b2db8a6e1b138a20de009dacee265a2498f3f6" dependencies = [ "libc", ] @@ -5649,15 +5637,6 @@ version = "0.11.0+wasi-snapshot-preview1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" -[[package]] -name = "wasi" -version = "0.13.3+wasi-0.2.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" -dependencies = [ - "wit-bindgen-rt", -] - [[package]] name = "wasm-bindgen" version = "0.2.86" @@ -5681,7 +5660,7 @@ dependencies = [ "once_cell", "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", "wasm-bindgen-shared", ] @@ -5715,7 +5694,7 @@ checksum = "e128beba882dd1eb6200e1dc92ae6c5dbaa4311aa7bb211ca035779e5efc39f8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5762,9 +5741,9 @@ dependencies = [ [[package]] name = "webpki-roots" -version = "0.26.8" +version = "0.26.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2210b291f7ea53617fbafcc4939f10914214ec15aace5ba62293a668f322c5c9" +checksum = "5d642ff16b7e79272ae451b7322067cdc17cadf68c23264be9d94a32319efe7e" dependencies = [ "rustls-pki-types", ] @@ -5968,22 +5947,13 @@ dependencies = [ [[package]] name = "winnow" -version = "0.7.2" +version = "0.6.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "59690dea168f2198d1a3b0cac23b8063efcd11012f10ae4698f284808c8ef603" +checksum = "ad699df48212c6cc6eb4435f35500ac6fd3b9913324f938aea302022ce19d310" dependencies = [ "memchr", ] -[[package]] -name = "wit-bindgen-rt" -version = "0.33.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" -dependencies = [ - "bitflags 2.8.0", -] - [[package]] name = "write16" version = "1.0.0" @@ -6025,7 +5995,7 @@ checksum = "2380878cad4ac9aac1e2435f3eb4020e8374b5f13c296cb75b4620ff8e229154" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", "synstructure", ] @@ -6047,7 +6017,7 @@ checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -6067,7 +6037,7 @@ checksum = "595eed982f7d355beb85837f651fa22e90b3c044842dc7f2c2842c086f295808" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", "synstructure", ] @@ -6088,7 +6058,7 @@ checksum = "ce36e65b0d2999d2aafac989fb249189a141aee1f53c612c1f37d72631959f69" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] @@ -6110,7 +6080,7 @@ checksum = "6eafa6dfb17584ea3e2bd6e76e0cc15ad7af12b09abdd1ca55961bed9b1063c6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.98", + "syn 2.0.96", ] [[package]] diff --git a/compiler/noirc_driver/src/abi_gen.rs b/compiler/noirc_driver/src/abi_gen.rs index 9838a8af210..bcaedba8417 100644 --- a/compiler/noirc_driver/src/abi_gen.rs +++ b/compiler/noirc_driver/src/abi_gen.rs @@ -6,7 +6,7 @@ use iter_extended::vecmap; use noirc_abi::{ Abi, AbiErrorType, AbiParameter, AbiReturnType, AbiType, AbiValue, AbiVisibility, Sign, }; -use noirc_errors::Span; +use noirc_errors::Location; use noirc_evaluator::ErrorType; use noirc_frontend::ast::{Signedness, Visibility}; use noirc_frontend::TypeBinding; @@ -42,11 +42,11 @@ pub(super) fn gen_abi( } // Get the Span of the root crate's main function, or else a dummy span if that fails -fn get_main_function_span(context: &Context) -> Span { +fn get_main_function_location(context: &Context) -> Location { if let Some(func_id) = context.get_main_function(context.root_crate_id()) { - context.function_meta(&func_id).location.span + context.function_meta(&func_id).location } else { - Span::default() + Location::dummy() } } @@ -54,7 +54,7 @@ fn build_abi_error_type(context: &Context, typ: ErrorType) -> AbiErrorType { match typ { ErrorType::Dynamic(typ) => { if let Type::FmtString(len, item_types) = typ { - let span = get_main_function_span(context); + let span = get_main_function_location(context); let length = len.evaluate_to_u32(span).expect("Cannot evaluate fmt length"); let Type::Tuple(item_types) = item_types.as_ref() else { unreachable!("FmtString items must be a tuple") @@ -74,7 +74,7 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType { match typ { Type::FieldElement => AbiType::Field, Type::Array(size, typ) => { - let span = get_main_function_span(context); + let span = get_main_function_location(context); let length = size .evaluate_to_u32(span) .expect("Cannot have variable sized arrays as a parameter to main"); @@ -103,7 +103,7 @@ pub(super) fn abi_type_from_hir_type(context: &Context, typ: &Type) -> AbiType { } Type::Bool => AbiType::Boolean, Type::String(size) => { - let span = get_main_function_span(context); + let span = get_main_function_location(context); let size = size .evaluate_to_u32(span) .expect("Cannot have variable sized strings as a parameter to main"); diff --git a/compiler/noirc_driver/src/lib.rs b/compiler/noirc_driver/src/lib.rs index fb52a87b4d1..50c437d8d20 100644 --- a/compiler/noirc_driver/src/lib.rs +++ b/compiler/noirc_driver/src/lib.rs @@ -352,9 +352,10 @@ pub fn check_crate( let crate_files = context.crate_files(&crate_id); let warnings_and_errors: Vec = diagnostics .into_iter() - .map(|(error, file_id)| { + .map(|error| { + let location = error.location(); let diagnostic = CustomDiagnostic::from(&error); - diagnostic.in_file(file_id) + diagnostic.in_file(location.file) }) .filter(|diagnostic| { // We filter out any warnings if they're going to be ignored later on to free up memory. diff --git a/compiler/noirc_errors/src/reporter.rs b/compiler/noirc_errors/src/reporter.rs index 30bf49348b6..e516f690ddc 100644 --- a/compiler/noirc_errors/src/reporter.rs +++ b/compiler/noirc_errors/src/reporter.rs @@ -50,12 +50,12 @@ impl CustomDiagnostic { fn simple_with_kind( primary_message: String, secondary_message: String, - secondary_span: Span, + secondary_location: Location, kind: DiagnosticKind, ) -> CustomDiagnostic { CustomDiagnostic { message: primary_message, - secondaries: vec![CustomLabel::new(secondary_message, secondary_span, None)], + secondaries: vec![CustomLabel::new(secondary_message, secondary_location)], notes: Vec::new(), kind, deprecated: false, @@ -67,12 +67,12 @@ impl CustomDiagnostic { pub fn simple_error( primary_message: String, secondary_message: String, - secondary_span: Span, + secondary_location: Location, ) -> CustomDiagnostic { Self::simple_with_kind( primary_message, secondary_message, - secondary_span, + secondary_location, DiagnosticKind::Error, ) } @@ -80,12 +80,12 @@ impl CustomDiagnostic { pub fn simple_warning( primary_message: String, secondary_message: String, - secondary_span: Span, + secondary_location: Location, ) -> CustomDiagnostic { Self::simple_with_kind( primary_message, secondary_message, - secondary_span, + secondary_location, DiagnosticKind::Warning, ) } @@ -93,12 +93,12 @@ impl CustomDiagnostic { pub fn simple_info( primary_message: String, secondary_message: String, - secondary_span: Span, + secondary_location: Location, ) -> CustomDiagnostic { Self::simple_with_kind( primary_message, secondary_message, - secondary_span, + secondary_location, DiagnosticKind::Info, ) } @@ -106,11 +106,11 @@ impl CustomDiagnostic { pub fn simple_bug( primary_message: String, secondary_message: String, - secondary_span: Span, + secondary_location: Location, ) -> CustomDiagnostic { CustomDiagnostic { message: primary_message, - secondaries: vec![CustomLabel::new(secondary_message, secondary_span, None)], + secondaries: vec![CustomLabel::new(secondary_message, secondary_location)], notes: Vec::new(), kind: DiagnosticKind::Bug, deprecated: false, @@ -132,12 +132,8 @@ impl CustomDiagnostic { self.notes.push(message); } - pub fn add_secondary(&mut self, message: String, span: Span) { - self.secondaries.push(CustomLabel::new(message, span, None)); - } - - pub fn add_secondary_with_file(&mut self, message: String, span: Span, file: fm::FileId) { - self.secondaries.push(CustomLabel::new(message, span, Some(file))); + pub fn add_secondary(&mut self, message: String, location: Location) { + self.secondaries.push(CustomLabel::new(message, location)); } pub fn is_error(&self) -> bool { @@ -176,13 +172,12 @@ impl std::fmt::Display for CustomDiagnostic { #[derive(Debug, Clone, PartialEq, Eq)] pub struct CustomLabel { pub message: String, - pub span: Span, - pub file: Option, + pub location: Location, } impl CustomLabel { - fn new(message: String, span: Span, file: Option) -> CustomLabel { - CustomLabel { message, span, file } + fn new(message: String, location: Location) -> CustomLabel { + CustomLabel { message, location } } } @@ -217,7 +212,7 @@ impl FileDiagnostic { files: &'files impl Files<'files, FileId = fm::FileId>, deny_warnings: bool, ) -> bool { - report(files, &self.diagnostic, Some(self.file_id), deny_warnings) + report(files, &self.diagnostic, deny_warnings) } } @@ -225,7 +220,6 @@ impl FileDiagnostic { pub fn report<'files>( files: &'files impl Files<'files, FileId = fm::FileId>, custom_diagnostic: &CustomDiagnostic, - file: Option, deny_warnings: bool, ) -> bool { let color_choice = @@ -234,7 +228,7 @@ pub fn report<'files>( let config = term::Config::default(); let stack_trace = stack_trace(files, &custom_diagnostic.call_stack); - let diagnostic = convert_diagnostic(custom_diagnostic, file, stack_trace, deny_warnings); + let diagnostic = convert_diagnostic(custom_diagnostic, stack_trace, deny_warnings); term::emit(&mut writer.lock(), &config, files, &diagnostic).unwrap(); deny_warnings || custom_diagnostic.is_error() @@ -242,7 +236,6 @@ pub fn report<'files>( fn convert_diagnostic( cd: &CustomDiagnostic, - file: Option, stack_trace: String, deny_warnings: bool, ) -> Diagnostic { @@ -253,19 +246,18 @@ fn convert_diagnostic( _ => Diagnostic::error(), }; - let secondary_labels = if let Some(file_id) = file { - cd.secondaries - .iter() - .map(|sl| { - let start_span = sl.span.start() as usize; - let end_span = sl.span.end() as usize; - let file = sl.file.unwrap_or(file_id); - Label::secondary(file, start_span..end_span).with_message(&sl.message) - }) - .collect() - } else { - vec![] - }; + let secondary_labels = cd + .secondaries + .iter() + .map(|custom_label| { + let location = custom_label.location; + let span = location.span; + let start_span = span.start() as usize; + let end_span = span.end() as usize; + let file = location.file; + Label::secondary(file, start_span..end_span).with_message(&custom_label.message) + }) + .collect(); let mut notes = cd.notes.clone(); notes.push(stack_trace); diff --git a/compiler/noirc_evaluator/src/errors.rs b/compiler/noirc_evaluator/src/errors.rs index 94c0e0554a4..a81d99ef346 100644 --- a/compiler/noirc_evaluator/src/errors.rs +++ b/compiler/noirc_evaluator/src/errors.rs @@ -9,7 +9,7 @@ //! An Error of the latter is an error in the implementation of the compiler use acvm::FieldElement; use iter_extended::vecmap; -use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic}; +use noirc_errors::{CustomDiagnostic as Diagnostic, FileDiagnostic, Location}; use thiserror::Error; use crate::ssa::ir::{call_stack::CallStack, types::NumericType}; @@ -85,8 +85,7 @@ impl From for FileDiagnostic { let call_stack = vecmap(call_stack, |location| location); let file_id = call_stack.last().map(|location| location.file).unwrap_or_default(); let location = call_stack.last().expect("Expected RuntimeError to have a location"); - let diagnostic = - Diagnostic::simple_warning(message, secondary_message, location.span); + let diagnostic = Diagnostic::simple_warning(message, secondary_message, *location); diagnostic.with_call_stack(call_stack).in_file(file_id) } SsaReport::Bug(bug) => { @@ -103,7 +102,7 @@ impl From for FileDiagnostic { let call_stack = vecmap(call_stack, |location| location); let file_id = call_stack.last().map(|location| location.file).unwrap_or_default(); let location = call_stack.last().expect("Expected RuntimeError to have a location"); - let diagnostic = Diagnostic::simple_bug(message, secondary_message, location.span); + let diagnostic = Diagnostic::simple_bug(message, secondary_message, *location); diagnostic.with_call_stack(call_stack).in_file(file_id) } } @@ -195,7 +194,7 @@ impl RuntimeError { "Internal Consistency Evaluators Errors: \n This is likely a bug. Consider opening an issue at https://github.com/noir-lang/noir/issues".to_owned(), cause.to_string(), - noirc_errors::Span::inclusive(0, 0) + Location::dummy(), ) } RuntimeError::UnknownLoopBound { .. } => { @@ -206,7 +205,7 @@ impl RuntimeError { Diagnostic::simple_error( primary_message, "If attempting to fetch the length of a slice, try converting to an array. Slices only use dynamic lengths.".to_string(), - location.span, + *location, ) } _ => { @@ -214,7 +213,7 @@ impl RuntimeError { let location = self.call_stack().last().unwrap_or_else(|| panic!("Expected RuntimeError to have a location. Error message: {message}")); - Diagnostic::simple_error(message, String::new(), location.span) + Diagnostic::simple_error(message, String::new(), *location) } } } diff --git a/compiler/noirc_frontend/src/ast/expression.rs b/compiler/noirc_frontend/src/ast/expression.rs index 12916f88d95..5dab9650373 100644 --- a/compiler/noirc_frontend/src/ast/expression.rs +++ b/compiler/noirc_frontend/src/ast/expression.rs @@ -14,7 +14,7 @@ use acvm::{acir::AcirField, FieldElement}; use iter_extended::vecmap; use noirc_errors::{Located, Location, Span}; -use super::{AsTraitPath, TypePath}; +use super::{AsTraitPath, TypePath, UnsafeExpression}; #[derive(Debug, PartialEq, Eq, Clone)] pub enum ExpressionKind { @@ -38,7 +38,7 @@ pub enum ExpressionKind { Quote(Tokens), Unquote(Box), Comptime(BlockExpression, Location), - Unsafe(BlockExpression, Location), + Unsafe(UnsafeExpression), AsTraitPath(AsTraitPath), TypePath(TypePath), @@ -249,7 +249,7 @@ impl Expression { match &self.kind { ExpressionKind::Block(block_expression) | ExpressionKind::Comptime(block_expression, _) - | ExpressionKind::Unsafe(block_expression, _) => { + | ExpressionKind::Unsafe(UnsafeExpression { block: block_expression, .. }) => { if let Some(statement) = block_expression.statements.last() { statement.type_location() } else { @@ -652,7 +652,7 @@ impl Display for ExpressionKind { Lambda(lambda) => lambda.fmt(f), Parenthesized(sub_expr) => write!(f, "({sub_expr})"), Comptime(block, _) => write!(f, "comptime {block}"), - Unsafe(block, _) => write!(f, "unsafe {block}"), + Unsafe(UnsafeExpression { block, .. }) => write!(f, "unsafe {block}"), Error => write!(f, "Error"), Resolved(_) => write!(f, "?Resolved"), Interned(_) => write!(f, "?Interned"), diff --git a/compiler/noirc_frontend/src/ast/statement.rs b/compiler/noirc_frontend/src/ast/statement.rs index 2b6695777f9..ae7f0bef150 100644 --- a/compiler/noirc_frontend/src/ast/statement.rs +++ b/compiler/noirc_frontend/src/ast/statement.rs @@ -243,14 +243,9 @@ impl From for Ident { impl From for Expression { fn from(i: Ident) -> Expression { - Expression { - location: i.0.location(), - kind: ExpressionKind::Variable(Path { - location: i.location(), - segments: vec![PathSegment::from(i)], - kind: PathKind::Plain, - }), - } + let location = i.location(); + let kind = ExpressionKind::Variable(Path::plain(vec![PathSegment::from(i)], location)); + Expression { location, kind } } } @@ -360,6 +355,12 @@ impl UseTree { } } +#[derive(Debug, PartialEq, Eq, Clone)] +pub struct UnsafeExpression { + pub block: BlockExpression, + pub unsafe_keyword_location: Location, +} + /// A special kind of path in the form `::ident`. /// Note that this path must consist of exactly two segments. /// @@ -390,9 +391,15 @@ pub struct Path { pub segments: Vec, pub kind: PathKind, pub location: Location, + // The location of `kind` (this is the same as `location` for plain kinds) + pub kind_location: Location, } impl Path { + pub fn plain(segments: Vec, location: Location) -> Self { + Self { segments, location, kind: PathKind::Plain, kind_location: location } + } + pub fn pop(&mut self) -> PathSegment { self.segments.pop().unwrap() } @@ -409,11 +416,8 @@ impl Path { } pub fn from_ident(name: Ident) -> Path { - Path { - location: name.location(), - segments: vec![PathSegment::from(name)], - kind: PathKind::Plain, - } + let location = name.location(); + Path::plain(vec![PathSegment::from(name)], location) } pub fn span(&self) -> Span { @@ -812,11 +816,7 @@ impl ForRange { // array.len() let segments = vec![PathSegment::from(array_ident)]; - let array_ident = ExpressionKind::Variable(Path { - segments, - kind: PathKind::Plain, - location: array_location, - }); + let array_ident = ExpressionKind::Variable(Path::plain(segments, array_location)); let end_range = ExpressionKind::MethodCall(Box::new(MethodCallExpression { object: Expression::new(array_ident.clone(), array_location), @@ -833,11 +833,7 @@ impl ForRange { // array[i] let segments = vec![PathSegment::from(Ident::new(index_name, array_location))]; - let index_ident = ExpressionKind::Variable(Path { - segments, - kind: PathKind::Plain, - location: array_location, - }); + let index_ident = ExpressionKind::Variable(Path::plain(segments, array_location)); let loop_element = ExpressionKind::Index(Box::new(IndexExpression { collection: Expression::new(array_ident, array_location), diff --git a/compiler/noirc_frontend/src/ast/visitor.rs b/compiler/noirc_frontend/src/ast/visitor.rs index b1d1c6cef8f..d913fadbbc1 100644 --- a/compiler/noirc_frontend/src/ast/visitor.rs +++ b/compiler/noirc_frontend/src/ast/visitor.rs @@ -24,7 +24,7 @@ use super::{ ForBounds, FunctionReturnType, GenericTypeArgs, IntegerBitSize, ItemVisibility, MatchExpression, NoirEnumeration, Pattern, Signedness, TraitBound, TraitImplItemKind, TypePath, UnresolvedGenerics, UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, - UnresolvedTypeExpression, + UnresolvedTypeExpression, UnsafeExpression, }; #[derive(Debug, Copy, Clone, PartialEq, Eq)] @@ -242,7 +242,7 @@ pub trait Visitor { true } - fn visit_unsafe(&mut self, _: &BlockExpression, _: Span) -> bool { + fn visit_unsafe_expression(&mut self, _: &UnsafeExpression, _: Span) -> bool { true } @@ -905,10 +905,8 @@ impl Expression { block_expression.accept(None, visitor); } } - ExpressionKind::Unsafe(block_expression, _) => { - if visitor.visit_unsafe(block_expression, span) { - block_expression.accept(None, visitor); - } + ExpressionKind::Unsafe(unsafe_expression) => { + unsafe_expression.accept(span, visitor); } ExpressionKind::Variable(path) => { if visitor.visit_variable(path, span) { @@ -1304,6 +1302,18 @@ impl ForRange { } } +impl UnsafeExpression { + pub fn accept(&self, span: Span, visitor: &mut impl Visitor) { + if visitor.visit_unsafe_expression(self, span) { + self.accept_children(span, visitor); + } + } + + pub fn accept_children(&self, span: Span, visitor: &mut impl Visitor) { + self.block.accept(Some(span), visitor); + } +} + impl AsTraitPath { pub fn accept(&self, span: Span, visitor: &mut impl Visitor) { if visitor.visit_as_trait_path(self, span) { diff --git a/compiler/noirc_frontend/src/debug/mod.rs b/compiler/noirc_frontend/src/debug/mod.rs index 75729c23acf..3ba0e7b5bb1 100644 --- a/compiler/noirc_frontend/src/debug/mod.rs +++ b/compiler/noirc_frontend/src/debug/mod.rs @@ -3,7 +3,7 @@ use crate::parse_program; use crate::parser::ParsedModule; use crate::{ ast, - ast::{Path, PathKind}, + ast::Path, parser::{Item, ItemKind}, }; use fm::FileId; @@ -179,11 +179,10 @@ impl DebugInstrumenter { let last_stmt = if has_ret_expr { ast::Statement { kind: ast::StatementKind::Expression(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![PathSegment::from(ident("__debug_expr", location))], - kind: PathKind::Plain, + kind: ast::ExpressionKind::Variable(ast::Path::plain( + vec![PathSegment::from(ident("__debug_expr", location))], location, - }), + )), location, }), location, @@ -633,11 +632,10 @@ fn build_assign_var_stmt(var_id: SourceVarId, expr: ast::Expression) -> ast::Sta let location = expr.location; let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![PathSegment::from(ident("__debug_var_assign", location))], - kind: PathKind::Plain, + kind: ast::ExpressionKind::Variable(ast::Path::plain( + vec![PathSegment::from(ident("__debug_var_assign", location))], location, - }), + )), location, }), is_macro_call: false, @@ -649,11 +647,10 @@ fn build_assign_var_stmt(var_id: SourceVarId, expr: ast::Expression) -> ast::Sta fn build_drop_var_stmt(var_id: SourceVarId, location: Location) -> ast::Statement { let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![PathSegment::from(ident("__debug_var_drop", location))], - kind: PathKind::Plain, + kind: ast::ExpressionKind::Variable(ast::Path::plain( + vec![PathSegment::from(ident("__debug_var_drop", location))], location, - }), + )), location, }), is_macro_call: false, @@ -674,14 +671,10 @@ fn build_assign_member_stmt( let location = expr.location; let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![PathSegment::from(ident( - &format!["__debug_member_assign_{arity}"], - location, - ))], - kind: PathKind::Plain, + kind: ast::ExpressionKind::Variable(ast::Path::plain( + vec![PathSegment::from(ident(&format!["__debug_member_assign_{arity}"], location))], location, - }), + )), location, }), is_macro_call: false, @@ -698,11 +691,10 @@ fn build_assign_member_stmt( fn build_debug_call_stmt(fname: &str, fn_id: DebugFnId, location: Location) -> ast::Statement { let kind = ast::ExpressionKind::Call(Box::new(ast::CallExpression { func: Box::new(ast::Expression { - kind: ast::ExpressionKind::Variable(ast::Path { - segments: vec![PathSegment::from(ident(&format!["__debug_fn_{fname}"], location))], - kind: PathKind::Plain, + kind: ast::ExpressionKind::Variable(ast::Path::plain( + vec![PathSegment::from(ident(&format!["__debug_fn_{fname}"], location))], location, - }), + )), location, }), is_macro_call: false, @@ -767,11 +759,10 @@ fn ident(s: &str, location: Location) -> ast::Ident { fn id_expr(id: &ast::Ident) -> ast::Expression { ast::Expression { - kind: ast::ExpressionKind::Variable(Path { - segments: vec![PathSegment::from(id.clone())], - kind: PathKind::Plain, - location: id.location(), - }), + kind: ast::ExpressionKind::Variable(Path::plain( + vec![PathSegment::from(id.clone())], + id.location(), + )), location: id.location(), } } diff --git a/compiler/noirc_frontend/src/elaborator/comptime.rs b/compiler/noirc_frontend/src/elaborator/comptime.rs index 58a467eef1b..6c9937dedc3 100644 --- a/compiler/noirc_frontend/src/elaborator/comptime.rs +++ b/compiler/noirc_frontend/src/elaborator/comptime.rs @@ -1,8 +1,7 @@ use std::{collections::BTreeMap, fmt::Display}; -use fm::FileId; use iter_extended::vecmap; -use noirc_errors::{Location, Span}; +use noirc_errors::Location; use crate::{ ast::{Documented, Expression, ExpressionKind}, @@ -29,21 +28,17 @@ use super::{ElaborateReason, Elaborator, FunctionContext, ResolverMeta}; #[derive(Debug, Copy, Clone)] struct AttributeContext { - // The file where generated items should be added - file: FileId, // The module where generated items should be added module: LocalModuleId, - // The file where the attribute is located - attribute_file: FileId, // The module where the attribute is located attribute_module: LocalModuleId, } -type CollectedAttributes = Vec<(FuncId, Value, Vec, AttributeContext, Span)>; +type CollectedAttributes = Vec<(FuncId, Value, Vec, AttributeContext, Location)>; impl AttributeContext { - fn new(file: FileId, module: LocalModuleId) -> Self { - Self { file, module, attribute_file: file, attribute_module: module } + fn new(module: LocalModuleId) -> Self { + Self { module, attribute_module: module } } } @@ -62,7 +57,6 @@ impl<'context> Elaborator<'context> { elaborator.current_item = Some(DependencyId::Function(function)); elaborator.crate_id = meta.source_crate; elaborator.local_module = meta.source_module; - elaborator.file = meta.source_file; elaborator.introduce_generics_into_scope(meta.all_generics.clone()); } }) @@ -71,14 +65,12 @@ impl<'context> Elaborator<'context> { pub fn elaborate_item_from_comptime_in_module<'a, T>( &'a mut self, module: ModuleId, - file: FileId, f: impl FnOnce(&mut Elaborator<'a>) -> T, ) -> T { self.elaborate_item_from_comptime(f, |elaborator| { elaborator.current_item = None; elaborator.crate_id = module.krate; elaborator.local_module = module.local_id; - elaborator.file = file; }) } @@ -104,7 +96,6 @@ impl<'context> Elaborator<'context> { elaborator.scopes.start_function(); elaborator.local_module = self.local_module; - elaborator.file = self.file; setup(&mut elaborator); @@ -161,13 +152,13 @@ impl<'context> Elaborator<'context> { ) { if let SecondaryAttribute::Meta(attribute) = attribute { self.elaborate_in_comptime_context(|this| { - if let Err((error, file)) = this.collect_comptime_attribute_name_on_item( + if let Err(error) = this.collect_comptime_attribute_name_on_item( attribute, item.clone(), attribute_context, attributes_to_run, ) { - this.push_err(error, file); + this.push_err(error); } }); } @@ -180,11 +171,9 @@ impl<'context> Elaborator<'context> { item: Value, attribute_context: AttributeContext, attributes_to_run: &mut CollectedAttributes, - ) -> Result<(), (CompilationError, FileId)> { - self.file = attribute_context.attribute_file; + ) -> Result<(), CompilationError> { self.local_module = attribute_context.attribute_module; let location = attribute.location; - let span = location.span; let function = Expression { kind: ExpressionKind::Variable(attribute.name.clone()), location }; @@ -199,22 +188,25 @@ impl<'context> Elaborator<'context> { let definition_id = match self.interner.expression(&function) { HirExpression::Ident(ident, _) => ident.id, _ => { - let error = - ResolverError::AttributeFunctionIsNotAPath { function: function_string, span }; - return Err((error.into(), location.file)); + let error = ResolverError::AttributeFunctionIsNotAPath { + function: function_string, + location, + }; + return Err(error.into()); } }; let Some(definition) = self.interner.try_definition(definition_id) else { - let error = ResolverError::AttributeFunctionNotInScope { name: function_string, span }; - return Err((error.into(), location.file)); + let error = + ResolverError::AttributeFunctionNotInScope { name: function_string, location }; + return Err(error.into()); }; let DefinitionKind::Function(function) = definition.kind else { - return Err((ResolverError::NonFunctionInAnnotation { span }.into(), location.file)); + return Err(ResolverError::NonFunctionInAnnotation { location }.into()); }; - attributes_to_run.push((function, item, arguments, attribute_context, span)); + attributes_to_run.push((function, item, arguments, attribute_context, location)); Ok(()) } @@ -226,8 +218,7 @@ impl<'context> Elaborator<'context> { item: Value, location: Location, generated_items: &mut CollectedItems, - ) -> Result<(), (CompilationError, FileId)> { - self.file = attribute_context.file; + ) -> Result<(), CompilationError> { self.local_module = attribute_context.module; let mut interpreter = self.setup_interpreter(); @@ -238,20 +229,19 @@ impl<'context> Elaborator<'context> { arguments, location, ) - .map_err(|error| error.into_compilation_error_pair())?; + .map_err(CompilationError::from)?; arguments.insert(0, (item, location)); let value = interpreter .call_function(function, arguments, TypeBindings::new(), location) - .map_err(|error| error.into_compilation_error_pair())?; + .map_err(CompilationError::from)?; self.debug_comptime(location, |interner| value.display(interner).to_string()); if value != Value::Unit { - let items = value - .into_top_level_items(location, self) - .map_err(|error| error.into_compilation_error_pair())?; + let items = + value.into_top_level_items(location, self).map_err(CompilationError::from)?; self.add_items(items, generated_items, location); } @@ -432,8 +422,8 @@ impl<'context> Elaborator<'context> { ); generated_items.globals.push(global); - if let Some((error, file)) = error { - self.push_err(error, file); + if let Some(error) = error { + self.push_err(error); } } ItemKind::Struct(struct_def) => { @@ -484,8 +474,7 @@ impl<'context> Elaborator<'context> { let location = item.location; let item = item.kind.to_string(); let error = InterpreterError::UnsupportedTopLevelItemUnquote { item, location }; - let (error, file) = error.into_compilation_error_pair(); - self.push_err(error, file); + self.push_err(error); } } } @@ -507,7 +496,7 @@ impl<'context> Elaborator<'context> { let displayed_expr = expr_f(self.interner); let error: CompilationError = InterpreterError::debug_evaluate_comptime(displayed_expr, location).into(); - self.push_err(error, location.file); + self.push_err(error); } } @@ -526,7 +515,7 @@ impl<'context> Elaborator<'context> { for (trait_id, trait_) in traits { let attributes = &trait_.trait_def.attributes; let item = Value::TraitDefinition(*trait_id); - let context = AttributeContext::new(trait_.file_id, trait_.module_id); + let context = AttributeContext::new(trait_.module_id); self.collect_comptime_attributes_on_item( attributes, item, @@ -538,7 +527,7 @@ impl<'context> Elaborator<'context> { for (struct_id, struct_def) in types { let attributes = &struct_def.struct_def.attributes; let item = Value::StructDefinition(*struct_id); - let context = AttributeContext::new(struct_def.file_id, struct_def.module_id); + let context = AttributeContext::new(struct_def.module_id); self.collect_comptime_attributes_on_item( attributes, item, @@ -553,12 +542,10 @@ impl<'context> Elaborator<'context> { self.sort_attributes_by_run_order(&mut attributes_to_run); // run - for (attribute, item, args, context, span) in attributes_to_run { - let location = Location::new(span, context.attribute_file); - + for (attribute, item, args, context, location) in attributes_to_run { let mut generated_items = CollectedItems::default(); self.elaborate_in_comptime_context(|this| { - if let Err((error, file)) = this.run_attribute( + if let Err(error) = this.run_attribute( context, attribute, args, @@ -566,7 +553,7 @@ impl<'context> Elaborator<'context> { location, &mut generated_items, ) { - this.push_err(error, file); + this.push_err(error); } }); @@ -588,8 +575,8 @@ impl<'context> Elaborator<'context> { // Sort each attribute by (module, location in file) so that we can execute in // the order they were defined in, running attributes in child modules first. - attributes.sort_by_key(|(_, _, _, ctx, span)| { - (module_order[&ctx.attribute_module], span.start()) + attributes.sort_by_key(|(_, _, _, ctx, location)| { + (module_order[&ctx.attribute_module], location.span.start()) }); } @@ -605,9 +592,7 @@ impl<'context> Elaborator<'context> { let attribute = &module_attribute.attribute; let context = AttributeContext { - file: module_attribute.file_id, module: module_attribute.module_id, - attribute_file: module_attribute.attribute_file_id, attribute_module: module_attribute.attribute_module_id, }; @@ -624,7 +609,7 @@ impl<'context> Elaborator<'context> { self.self_type = function_set.self_type.clone(); for (local_module, function_id, function) in &function_set.functions { - let context = AttributeContext::new(function_set.file_id, *local_module); + let context = AttributeContext::new(*local_module); let attributes = function.secondary_attributes(); let item = Value::FunctionDefinition(*function_id); self.collect_comptime_attributes_on_item( @@ -672,17 +657,14 @@ impl<'context> Elaborator<'context> { &mut self, reason: ElaborateReason, location: Location, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { self.elaborate_reasons.push_back((reason, location)); std::mem::take(&mut self.errors) } /// Pops en ElaborateREason. Receives the errors that were returned by `push_elaborate_reason` /// so they are restored, while also wrapping errors in the current Elaborator in a ComptimeError. - pub(crate) fn pop_elaborate_reason( - &mut self, - previous_errors: Vec<(CompilationError, FileId)>, - ) { + pub(crate) fn pop_elaborate_reason(&mut self, previous_errors: Vec) { let new_errors = std::mem::take(&mut self.errors); let new_errors = self.wrap_errors_in_macro_error(new_errors); self.errors = previous_errors; @@ -690,11 +672,8 @@ impl<'context> Elaborator<'context> { self.elaborate_reasons.pop_back(); } - fn wrap_errors_in_macro_error( - &self, - errors: Vec<(CompilationError, FileId)>, - ) -> Vec<(CompilationError, FileId)> { - vecmap(errors, |(error, file_id)| (self.wrap_error_in_macro_error(error), file_id)) + fn wrap_errors_in_macro_error(&self, errors: Vec) -> Vec { + vecmap(errors, |error| self.wrap_error_in_macro_error(error)) } fn wrap_error_in_macro_error(&self, mut error: CompilationError) -> CompilationError { diff --git a/compiler/noirc_frontend/src/elaborator/enums.rs b/compiler/noirc_frontend/src/elaborator/enums.rs index b09deb58b15..ec8fc8fef17 100644 --- a/compiler/noirc_frontend/src/elaborator/enums.rs +++ b/compiler/noirc_frontend/src/elaborator/enums.rs @@ -1,6 +1,5 @@ use std::collections::BTreeMap; -use fm::FileId; use fxhash::FxHashMap as HashMap; use iter_extended::{try_vecmap, vecmap}; use noirc_errors::Location; @@ -281,12 +280,10 @@ impl Elaborator<'_> { let body_location = branch.type_location(); let (body, body_type) = self.elaborate_expression(branch); - self.unify(&body_type, &result_type, body_location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: result_type.to_string(), - expr_typ: body_type.to_string(), - expr_span: body_location.span, - } + self.unify(&body_type, &result_type, || TypeCheckError::TypeMismatch { + expected_typ: result_type.to_string(), + expr_typ: body_type.to_string(), + expr_location: body_location, }); self.pop_scope(); @@ -304,20 +301,17 @@ impl Elaborator<'_> { ) -> Pattern { let expr_location = expression.type_location(); let unify_with_expected_type = |this: &mut Self, actual| { - this.unify(actual, expected_type, expr_location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: expected_type.to_string(), - expr_typ: actual.to_string(), - expr_span: expr_location.span, - } + this.unify(actual, expected_type, || TypeCheckError::TypeMismatch { + expected_typ: expected_type.to_string(), + expr_typ: actual.to_string(), + expr_location, }); }; - // We want the actual expression's span here, not the innermost one from `type_location()` - let span = expression.location.span; + // We want the actual expression's location here, not the innermost one from `type_location()` let syntax_error = |this: &mut Self| { - let errors = ResolverError::InvalidSyntaxInPattern { span }; - this.push_err(errors, this.file); + let errors = ResolverError::InvalidSyntaxInPattern { location: expression.location }; + this.push_err(errors); Pattern::Error }; @@ -362,9 +356,9 @@ impl Elaborator<'_> { if last_ident.0.contents != "_" { let error = ResolverError::VariableAlreadyDefinedInPattern { existing: existing.clone(), - new_span: last_ident.span(), + new_location: last_ident.location(), }; - self.push_err(error, self.file); + self.push_err(error); } } else { variables_defined.push(last_ident.clone()); @@ -375,7 +369,7 @@ impl Elaborator<'_> { Pattern::Binding(id) } Err(error) => { - self.push_err(error, location.file); + self.push_err(error); Pattern::Error } } @@ -433,7 +427,7 @@ impl Elaborator<'_> { | ExpressionKind::Quote(_) | ExpressionKind::Unquote(_) | ExpressionKind::Comptime(_, _) - | ExpressionKind::Unsafe(_, _) + | ExpressionKind::Unsafe(_) | ExpressionKind::AsTraitPath(_) | ExpressionKind::TypePath(_) | ExpressionKind::Resolved(_) @@ -466,7 +460,7 @@ impl Elaborator<'_> { let struct_definition = struct_name.clone(); ResolverError::NoSuchField { field: field_name, struct_definition } }; - self.push_err(error, self.file); + self.push_err(error); continue; }; @@ -478,10 +472,10 @@ impl Elaborator<'_> { if !expected_field_types.is_empty() { let struct_definition = struct_name; - let span = location.span; let missing_fields = vecmap(expected_field_types, |(name, _)| name); - let error = ResolverError::MissingFields { span, missing_fields, struct_definition }; - self.push_err(error, self.file); + let error = + ResolverError::MissingFields { location, missing_fields, struct_definition }; + self.push_err(error); } let args = vecmap(fields, |(_name, field)| field); @@ -508,7 +502,7 @@ impl Elaborator<'_> { variables_defined, ), Err(error) => { - self.push_err(error, location.file); + self.push_err(error); let id = self.fresh_match_variable(expected_type.clone(), location); Pattern::Binding(id) } @@ -546,8 +540,6 @@ impl Elaborator<'_> { location: Location, variables_defined: &mut Vec, ) -> Pattern { - let span = location.span; - let (actual_type, expected_arg_types, variant_index) = match name { PathResolutionItem::Global(id) => { // variant constant @@ -591,10 +583,10 @@ impl Elaborator<'_> { // We must unify the actual type before `expected_arg_types` are used since those // are instantiated and rely on this already being unified. - self.unify(&actual_type, expected_type, location.file, || TypeCheckError::TypeMismatch { + self.unify(&actual_type, expected_type, || TypeCheckError::TypeMismatch { expected_typ: expected_type.to_string(), expr_typ: actual_type.to_string(), - expr_span: span, + expr_location: location, }); if args.len() != expected_arg_types.len() { @@ -620,9 +612,8 @@ impl Elaborator<'_> { } } - let error = - ResolverError::NonStructUsedInConstructor { typ: typ.to_string(), span: location.span }; - self.push_err(error, location.file); + let error = ResolverError::NonStructUsedInConstructor { typ: typ.to_string(), location }; + self.push_err(error); None } @@ -631,13 +622,13 @@ impl Elaborator<'_> { /// This is an adaptation of https://github.com/yorickpeterse/pattern-matching-in-rust/tree/main/jacobs2021 /// which is an implementation of https://julesjacobs.com/notes/patternmatching/patternmatching.pdf pub(super) fn elaborate_match_rows(&mut self, rows: Vec) -> HirMatch { - self.compile_rows(rows).unwrap_or_else(|(error, file)| { - self.push_err(error, file); + self.compile_rows(rows).unwrap_or_else(|error| { + self.push_err(error); HirMatch::Failure }) } - fn compile_rows(&mut self, mut rows: Vec) -> Result { + fn compile_rows(&mut self, mut rows: Vec) -> Result { if rows.is_empty() { eprintln!("Warning: missing case"); return Ok(HirMatch::Failure); @@ -767,7 +758,7 @@ impl Elaborator<'_> { &mut self, rows: Vec, branch_var: DefinitionId, - ) -> Result<(Vec, Box), (ResolverError, FileId)> { + ) -> Result<(Vec, Box), ResolverError> { let mut raw_cases: Vec<(Constructor, Vec, Vec)> = Vec::new(); let mut fallback_rows = Vec::new(); let mut tested: HashMap<(SignedField, SignedField), usize> = HashMap::default(); @@ -806,7 +797,7 @@ impl Elaborator<'_> { let cases = try_vecmap(raw_cases, |(cons, vars, rows)| { let rows = self.compile_rows(rows)?; - Ok::<_, (ResolverError, FileId)>(Case::new(cons, vars, rows)) + Ok::<_, ResolverError>(Case::new(cons, vars, rows)) })?; Ok((cases, Box::new(self.compile_rows(fallback_rows)?))) @@ -842,7 +833,7 @@ impl Elaborator<'_> { rows: Vec, branch_var: DefinitionId, mut cases: Vec<(Constructor, Vec, Vec)>, - ) -> Result<(Vec, Option>), (ResolverError, FileId)> { + ) -> Result<(Vec, Option>), ResolverError> { for mut row in rows { if let Some(col) = row.remove_column(branch_var) { if let Pattern::Constructor(cons, args) = col.pattern { @@ -864,7 +855,7 @@ impl Elaborator<'_> { let cases = try_vecmap(cases, |(cons, vars, rows)| { let rows = self.compile_rows(rows)?; - Ok::<_, (ResolverError, FileId)>(Case::new(cons, vars, rows)) + Ok::<_, ResolverError>(Case::new(cons, vars, rows)) })?; Ok(Self::deduplicate_cases(cases)) @@ -976,8 +967,8 @@ impl Elaborator<'_> { let let_ = self.interner.push_stmt(let_); let body = self.interner.push_stmt(HirStatement::Expression(body)); - self.interner.push_stmt_location(let_, location.span, location.file); - self.interner.push_stmt_location(body, location.span, location.file); + self.interner.push_stmt_location(let_, location); + self.interner.push_stmt_location(body, location); let block = HirExpression::Block(HirBlockExpression { statements: vec![let_, body] }); let block = self.interner.push_expr(block); diff --git a/compiler/noirc_frontend/src/elaborator/expressions.rs b/compiler/noirc_frontend/src/elaborator/expressions.rs index 8f49c47a058..5503b5a7bbe 100644 --- a/compiler/noirc_frontend/src/elaborator/expressions.rs +++ b/compiler/noirc_frontend/src/elaborator/expressions.rs @@ -1,6 +1,6 @@ use acvm::{AcirField, FieldElement}; use iter_extended::vecmap; -use noirc_errors::{Located, Location, Span}; +use noirc_errors::{Located, Location}; use rustc_hash::FxHashSet as HashSet; use crate::{ @@ -10,9 +10,11 @@ use crate::{ Ident, IfExpression, IndexExpression, InfixExpression, ItemVisibility, Lambda, Literal, MatchExpression, MemberAccessExpression, MethodCallExpression, Path, PathSegment, PrefixExpression, StatementKind, UnaryOp, UnresolvedTypeData, UnresolvedTypeExpression, + UnsafeExpression, }, hir::{ comptime::{self, InterpreterError}, + def_collector::dc_crate::CompilationError, resolution::{ errors::ResolverError, import::PathResolutionError, visibility::method_call_is_visible, }, @@ -48,7 +50,7 @@ impl<'context> Elaborator<'context> { target_type: Option<&Type>, ) -> (ExprId, Type) { let (hir_expr, typ) = match expr.kind { - ExpressionKind::Literal(literal) => self.elaborate_literal(literal, expr.location.span), + ExpressionKind::Literal(literal) => self.elaborate_literal(literal, expr.location), ExpressionKind::Block(block) => self.elaborate_block(block, target_type), ExpressionKind::Prefix(prefix) => return self.elaborate_prefix(*prefix, expr.location), ExpressionKind::Index(index) => self.elaborate_index(*index), @@ -75,8 +77,8 @@ impl<'context> Elaborator<'context> { ExpressionKind::Comptime(comptime, _) => { return self.elaborate_comptime_block(comptime, expr.location, target_type) } - ExpressionKind::Unsafe(block_expression, location) => { - self.elaborate_unsafe_block(block_expression, location, target_type) + ExpressionKind::Unsafe(unsafe_expression) => { + self.elaborate_unsafe_block(unsafe_expression, target_type) } ExpressionKind::Resolved(id) => return (id, self.interner.id_type(id)), ExpressionKind::Interned(id) => { @@ -89,17 +91,13 @@ impl<'context> Elaborator<'context> { } ExpressionKind::Error => (HirExpression::Error, Type::Error), ExpressionKind::Unquote(_) => { - self.push_err( - ResolverError::UnquoteUsedOutsideQuote { span: expr.location.span }, - expr.location.file, - ); + self.push_err(ResolverError::UnquoteUsedOutsideQuote { location: expr.location }); (HirExpression::Error, Type::Error) } ExpressionKind::AsTraitPath(_) => { - self.push_err( - ResolverError::AsTraitPathNotYetImplemented { span: expr.location.span }, - expr.location.file, - ); + self.push_err(ResolverError::AsTraitPathNotYetImplemented { + location: expr.location, + }); (HirExpression::Error, Type::Error) } ExpressionKind::TypePath(path) => return self.elaborate_type_path(path), @@ -126,13 +124,10 @@ impl<'context> Elaborator<'context> { } other => { let statement = other.to_string(); - self.push_err( - ResolverError::InvalidInternedStatementInExpr { - statement, - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::InvalidInternedStatementInExpr { + statement, + location, + }); let expr = Expression::new(ExpressionKind::Error, location); self.elaborate_expression(expr) } @@ -167,13 +162,10 @@ impl<'context> Elaborator<'context> { if let HirStatement::Semi(expr) = self.interner.statement(&id) { let inner_expr_type = self.interner.id_type(expr); let location = self.interner.expr_location(&expr); - let span = location.span; - self.unify(&inner_expr_type, &Type::Unit, location.file, || { - TypeCheckError::UnusedResultError { - expr_type: inner_expr_type.clone(), - expr_span: span, - } + self.unify(&inner_expr_type, &Type::Unit, || TypeCheckError::UnusedResultError { + expr_type: inner_expr_type.clone(), + expr_location: location, }); } @@ -188,28 +180,29 @@ impl<'context> Elaborator<'context> { fn elaborate_unsafe_block( &mut self, - block: BlockExpression, - location: Location, + unsafe_expression: UnsafeExpression, target_type: Option<&Type>, ) -> (HirExpression, Type) { // Before entering the block we cache the old value of `in_unsafe_block` so it can be restored. - let span = location.span; let old_in_unsafe_block = self.unsafe_block_status; let is_nested_unsafe_block = !matches!(old_in_unsafe_block, UnsafeBlockStatus::NotInUnsafeBlock); if is_nested_unsafe_block { - let span = Span::from(span.start()..span.start() + 6); // Only highlight the `unsafe` keyword - self.push_err(TypeCheckError::NestedUnsafeBlock { span }, location.file); + self.push_err(TypeCheckError::NestedUnsafeBlock { + location: unsafe_expression.unsafe_keyword_location, + }); } self.unsafe_block_status = UnsafeBlockStatus::InUnsafeBlockWithoutUnconstrainedCalls; - let (hir_block_expression, typ) = self.elaborate_block_expression(block, target_type); + let (hir_block_expression, typ) = + self.elaborate_block_expression(unsafe_expression.block, target_type); if let UnsafeBlockStatus::InUnsafeBlockWithoutUnconstrainedCalls = self.unsafe_block_status { - let span = Span::from(span.start()..span.start() + 6); // Only highlight the `unsafe` keyword - self.push_err(TypeCheckError::UnnecessaryUnsafeBlock { span }, location.file); + self.push_err(TypeCheckError::UnnecessaryUnsafeBlock { + location: unsafe_expression.unsafe_keyword_location, + }); } // Finally, we restore the original value of `self.in_unsafe_block`, @@ -222,7 +215,7 @@ impl<'context> Elaborator<'context> { (HirExpression::Unsafe(hir_block_expression), typ) } - fn elaborate_literal(&mut self, literal: Literal, span: Span) -> (HirExpression, Type) { + fn elaborate_literal(&mut self, literal: Literal, location: Location) -> (HirExpression, Type) { use HirExpression::Literal as Lit; match literal { Literal::Unit => (Lit(HirLiteral::Unit), Type::Unit), @@ -237,10 +230,10 @@ impl<'context> Elaborator<'context> { } Literal::FmtStr(fragments, length) => self.elaborate_fmt_string(fragments, length), Literal::Array(array_literal) => { - self.elaborate_array_literal(array_literal, span, true) + self.elaborate_array_literal(array_literal, location, true) } Literal::Slice(array_literal) => { - self.elaborate_array_literal(array_literal, span, false) + self.elaborate_array_literal(array_literal, location, false) } } } @@ -248,25 +241,24 @@ impl<'context> Elaborator<'context> { fn elaborate_array_literal( &mut self, array_literal: ArrayLiteral, - span: Span, + location: Location, is_array: bool, ) -> (HirExpression, Type) { let (expr, elem_type, length) = match array_literal { ArrayLiteral::Standard(elements) => { let first_elem_type = self.interner.next_type_variable(); - let first_span = elements.first().map(|elem| elem.location.span).unwrap_or(span); + let first_location = elements.first().map(|elem| elem.location).unwrap_or(location); let elements = vecmap(elements.into_iter().enumerate(), |(i, elem)| { - let span = elem.location.span; - let file = elem.location.file; + let location = elem.location; let (elem_id, elem_type) = self.elaborate_expression(elem); - self.unify(&elem_type, &first_elem_type, file, || { + self.unify(&elem_type, &first_elem_type, || { TypeCheckError::NonHomogeneousArray { - first_span, + first_location, first_type: first_elem_type.to_string(), first_index: 0, - second_span: span, + second_location: location, second_type: elem_type.to_string(), second_index: i, } @@ -282,7 +274,7 @@ impl<'context> Elaborator<'context> { let location = length.location; let length = UnresolvedTypeExpression::from_expr(*length, location).unwrap_or_else( |error| { - self.push_err(ResolverError::ParserError(Box::new(error)), location.file); + self.push_err(ResolverError::ParserError(Box::new(error))); UnresolvedTypeExpression::Constant(FieldElement::zero(), location) }, ); @@ -325,13 +317,10 @@ impl<'context> Elaborator<'context> { { HirIdent::non_trait_method(definition_id, *location) } else { - self.push_err( - ResolverError::VariableNotDeclared { - name: ident_name.to_owned(), - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::VariableNotDeclared { + name: ident_name.to_owned(), + location: *location, + }); continue; }; @@ -381,13 +370,10 @@ impl<'context> Elaborator<'context> { HirExpression::Ident(hir_ident, _) => { if let Some(definition) = self.interner.try_definition(hir_ident.id) { if !definition.mutable { - self.push_err( - TypeCheckError::CannotMutateImmutableVariable { - name: definition.name.clone(), - span: location.span, - }, - location.file, - ); + self.push_err(TypeCheckError::CannotMutateImmutableVariable { + name: definition.name.clone(), + location, + }); } } } @@ -399,22 +385,20 @@ impl<'context> Elaborator<'context> { } fn elaborate_index(&mut self, index_expr: IndexExpression) -> (HirExpression, Type) { - let span = index_expr.index.location.span; - let file = index_expr.index.location.file; + let location = index_expr.index.location; let (index, index_type) = self.elaborate_expression(index_expr.index); let expected = self.polymorphic_integer_or_field(); - self.unify(&index_type, &expected, file, || TypeCheckError::TypeMismatch { + self.unify(&index_type, &expected, || TypeCheckError::TypeMismatch { expected_typ: "an integer".to_owned(), expr_typ: index_type.to_string(), - expr_span: span, + expr_location: location, }); // When writing `a[i]`, if `a : &mut ...` then automatically dereference `a` as many // times as needed to get the underlying array. let lhs_location = index_expr.collection.location; - let lhs_span = lhs_location.span; let (lhs, lhs_type) = self.elaborate_expression(index_expr.collection); let (collection, lhs_type) = self.insert_auto_dereferences(lhs, lhs_type); @@ -425,21 +409,17 @@ impl<'context> Elaborator<'context> { Type::Slice(base_type) => *base_type, Type::Error => Type::Error, Type::TypeVariable(_) => { - self.push_err( - TypeCheckError::TypeAnnotationsNeededForIndex { span: lhs_span }, - lhs_location.file, - ); + self.push_err(TypeCheckError::TypeAnnotationsNeededForIndex { + location: lhs_location, + }); Type::Error } typ => { - self.push_err( - TypeCheckError::TypeMismatch { - expected_typ: "Array".to_owned(), - expr_typ: typ.to_string(), - expr_span: lhs_span, - }, - lhs_location.file, - ); + self.push_err(TypeCheckError::TypeMismatch { + expected_typ: "Array".to_owned(), + expr_typ: typ.to_string(), + expr_location: lhs_location, + }); Type::Error } }; @@ -629,20 +609,16 @@ impl<'context> Elaborator<'context> { mut expr: ConstrainExpression, ) -> (HirExpression, Type) { let location = expr.location; - let span = location.span; let min_args_count = expr.kind.required_arguments_count(); let max_args_count = min_args_count + 1; let actual_args_count = expr.arguments.len(); let (message, expr) = if !(min_args_count..=max_args_count).contains(&actual_args_count) { - self.push_err( - TypeCheckError::AssertionParameterCountMismatch { - kind: expr.kind, - found: actual_args_count, - span, - }, - location.file, - ); + self.push_err(TypeCheckError::AssertionParameterCountMismatch { + kind: expr.kind, + found: actual_args_count, + location, + }); // Given that we already produced an error, let's make this an `assert(true)` so // we don't get further errors. @@ -668,17 +644,16 @@ impl<'context> Elaborator<'context> { (message, expr) }; - let expr_span = expr.location.span; - let expr_file = expr.location.file; + let expr_location = expr.location; let (expr_id, expr_type) = self.elaborate_expression(expr); // Must type check the assertion message expression so that we instantiate bindings let msg = message.map(|assert_msg_expr| self.elaborate_expression(assert_msg_expr).0); - self.unify(&expr_type, &Type::Bool, expr_file, || TypeCheckError::TypeMismatch { + self.unify(&expr_type, &Type::Bool, || TypeCheckError::TypeMismatch { expr_typ: expr_type.to_string(), expected_typ: Type::Bool.to_string(), - expr_span, + expr_location, }); (HirExpression::Constrain(HirConstrainExpression(expr_id, location.file, msg)), Type::Unit) @@ -712,10 +687,9 @@ impl<'context> Elaborator<'context> { self.interner, self.def_maps, ) { - self.push_err( - ResolverError::PathResolutionError(PathResolutionError::Private(name.clone())), - name.location().file, - ); + self.push_err(ResolverError::PathResolutionError(PathResolutionError::Private( + name.clone(), + ))); } } @@ -744,13 +718,10 @@ impl<'context> Elaborator<'context> { ); } let UnresolvedTypeData::Named(mut path, generics, _) = typ else { - self.push_err( - ResolverError::NonStructUsedInConstructor { - typ: typ.to_string(), - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::NonStructUsedInConstructor { + typ: typ.to_string(), + location, + }); return (HirExpression::Error, Type::Error); }; @@ -781,13 +752,10 @@ impl<'context> Elaborator<'context> { (r#type, struct_generics) } typ => { - self.push_err( - ResolverError::NonStructUsedInConstructor { - typ: typ.to_string(), - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::NonStructUsedInConstructor { + typ: typ.to_string(), + location, + }); return (HirExpression::Error, Type::Error); } }; @@ -884,24 +852,18 @@ impl<'context> Elaborator<'context> { || TypeCheckError::TypeMismatch { expected_typ: expected_type.to_string(), expr_typ: field_type.to_string(), - expr_span: field_location.span, + expr_location: field_location, }, ); } else if seen_fields.contains(&field_name) { // duplicate field - self.push_err( - ResolverError::DuplicateField { field: field_name.clone() }, - field_name.location().file, - ); + self.push_err(ResolverError::DuplicateField { field: field_name.clone() }); } else { // field not required by struct - self.push_err( - ResolverError::NoSuchField { - field: field_name.clone(), - struct_definition: struct_type.borrow().name.clone(), - }, - field_name.location().file, - ); + self.push_err(ResolverError::NoSuchField { + field: field_name.clone(), + struct_definition: struct_type.borrow().name.clone(), + }); } if let Some((index, visibility)) = expected_index_and_visibility { @@ -922,17 +884,11 @@ impl<'context> Elaborator<'context> { } if !unseen_fields.is_empty() { - self.push_err( - ResolverError::MissingFields { - span: location.span, - missing_fields: unseen_fields - .into_iter() - .map(|field| field.to_string()) - .collect(), - struct_definition: struct_type.borrow().name.clone(), - }, - location.file, - ); + self.push_err(ResolverError::MissingFields { + location, + missing_fields: unseen_fields.into_iter().map(|field| field.to_string()).collect(), + struct_definition: struct_type.borrow().name.clone(), + }); } ret @@ -1024,7 +980,7 @@ impl<'context> Elaborator<'context> { trait_bound: ResolvedTraitBound { trait_id: trait_id.trait_id, trait_generics: TraitGenerics::default(), - span: location.span, + location, }, }; self.push_trait_constraint( @@ -1036,7 +992,7 @@ impl<'context> Elaborator<'context> { typ } Err(error) => { - self.push_err(error, location.file); + self.push_err(error); Type::Error } } @@ -1053,10 +1009,10 @@ impl<'context> Elaborator<'context> { let (consequence, mut ret_type) = self.elaborate_expression_with_target_type(if_expr.consequence, target_type); - self.unify(&cond_type, &Type::Bool, expr_location.file, || TypeCheckError::TypeMismatch { + self.unify(&cond_type, &Type::Bool, || TypeCheckError::TypeMismatch { expected_typ: Type::Bool.to_string(), expr_typ: cond_type.to_string(), - expr_span: expr_location.span, + expr_location, }); let (alternative, else_type, error_location) = @@ -1069,11 +1025,11 @@ impl<'context> Elaborator<'context> { (None, Type::Unit, consequence_location) }; - self.unify(&ret_type, &else_type, error_location.file, || { + self.unify(&ret_type, &else_type, || { let err = TypeCheckError::TypeMismatch { expected_typ: ret_type.to_string(), expr_typ: else_type.to_string(), - expr_span: error_location.span, + expr_location: error_location, }; let context = if ret_type == Type::Unit { @@ -1100,8 +1056,7 @@ impl<'context> Elaborator<'context> { match_expr: MatchExpression, location: Location, ) -> (HirExpression, Type) { - let span = location.span; - self.use_unstable_feature(super::UnstableFeature::Enums, span); + self.use_unstable_feature(super::UnstableFeature::Enums, location); let (expression, typ) = self.elaborate_expression(match_expr.expression); let (let_, variable) = self.wrap_in_let(expression, typ); @@ -1113,7 +1068,7 @@ impl<'context> Elaborator<'context> { self.interner.push_expr_location(tree, location); let tree = self.interner.push_stmt(HirStatement::Expression(tree)); - self.interner.push_stmt_location(tree, span, self.file); + self.interner.push_stmt_location(tree, location); let block = HirExpression::Block(HirBlockExpression { statements: vec![let_, tree] }); (block, result_type) @@ -1129,7 +1084,7 @@ impl<'context> Elaborator<'context> { let pattern = HirPattern::Identifier(HirIdent::non_trait_method(variable, location)); let let_ = HirStatement::Let(HirLetStatement::basic(pattern, typ, expr_id)); let let_ = self.interner.push_stmt(let_); - self.interner.push_stmt_location(let_, location.span, location.file); + self.interner.push_stmt_location(let_, location); (let_, variable) } @@ -1207,10 +1162,10 @@ impl<'context> Elaborator<'context> { let lambda_context = self.lambda_stack.pop().unwrap(); self.pop_scope(); - self.unify(&body_type, &return_type, body_location.file, || TypeCheckError::TypeMismatch { + self.unify(&body_type, &return_type, || TypeCheckError::TypeMismatch { expected_typ: return_type.to_string(), expr_typ: body_type.to_string(), - expr_span: body_location.span, + expr_location: body_location, }); let captured_vars = vecmap(&lambda_context.captures, |capture| { @@ -1231,7 +1186,7 @@ impl<'context> Elaborator<'context> { if self.in_comptime_context() { (HirExpression::Quote(tokens), Type::Quoted(QuotedType::Quoted)) } else { - self.push_err(ResolverError::QuoteInRuntimeCode { span: location.span }, location.file); + self.push_err(ResolverError::QuoteInRuntimeCode { location }); (HirExpression::Error, Type::Quoted(QuotedType::Quoted)) } } @@ -1264,8 +1219,8 @@ impl<'context> Elaborator<'context> { location: Location, ) -> (ExprId, Type) { let make_error = |this: &mut Self, error: InterpreterError| { - let (error, file) = error.into_compilation_error_pair(); - this.push_err(error, file); + let error: CompilationError = error.into(); + this.push_err(error); let error = this.interner.push_expr(HirExpression::Error); this.interner.push_expr_location(error, location); (error, Type::Error) @@ -1305,17 +1260,17 @@ impl<'context> Elaborator<'context> { if meta.is_comptime { Ok(Some(function)) } else { - Err(ResolverError::MacroIsNotComptime { span: location.span }) + Err(ResolverError::MacroIsNotComptime { location }) } } else { - Err(ResolverError::InvalidSyntaxInMacroCall { span: location.span }) + Err(ResolverError::InvalidSyntaxInMacroCall { location }) } } else { // Assume a name resolution error has already been issued Ok(None) } } - _ => Err(ResolverError::InvalidSyntaxInMacroCall { span: location.span }), + _ => Err(ResolverError::InvalidSyntaxInMacroCall { location }), } } @@ -1328,19 +1283,18 @@ impl<'context> Elaborator<'context> { location: Location, return_type: Type, ) -> Option<(HirExpression, Type)> { - self.unify(&return_type, &Type::Quoted(QuotedType::Quoted), location.file, || { - TypeCheckError::MacroReturningNonExpr { typ: return_type.clone(), span: location.span } + self.unify(&return_type, &Type::Quoted(QuotedType::Quoted), || { + TypeCheckError::MacroReturningNonExpr { typ: return_type.clone(), location } }); let function = match self.try_get_comptime_function(func, location) { Ok(function) => function?, Err(error) => { - self.push_err(error, location.file); + self.push_err(error); return None; } }; - let file = self.file; let mut interpreter = self.setup_interpreter(); let mut comptime_args = Vec::new(); let mut errors = Vec::new(); @@ -1351,7 +1305,7 @@ impl<'context> Elaborator<'context> { let location = interpreter.elaborator.interner.expr_location(&argument); comptime_args.push((arg, location)); } - Err(error) => errors.push((error.into(), file)), + Err(error) => errors.push(error.into()), } } diff --git a/compiler/noirc_frontend/src/elaborator/lints.rs b/compiler/noirc_frontend/src/elaborator/lints.rs index 4f29b5acbda..f8adb75ea23 100644 --- a/compiler/noirc_frontend/src/elaborator/lints.rs +++ b/compiler/noirc_frontend/src/elaborator/lints.rs @@ -16,7 +16,7 @@ use crate::{ Type, }; -use noirc_errors::{Located, Location, Span}; +use noirc_errors::{Located, Location}; pub(super) fn deprecated_function(interner: &NodeInterner, expr: ExprId) -> Option { let HirExpression::Ident(HirIdent { location, id, impl_kind: _ }, _) = @@ -34,7 +34,7 @@ pub(super) fn deprecated_function(interner: &NodeInterner, expr: ExprId) -> Opti attributes.get_deprecated_note().map(|note| TypeCheckError::CallDeprecated { name: interner.definition_name(id).to_string(), note, - span: location.span, + location, }) } @@ -97,7 +97,7 @@ pub(super) fn oracle_called_from_constrained_function( interner: &NodeInterner, called_func: &FuncId, calling_from_constrained_runtime: bool, - span: Span, + location: Location, ) -> Option { if !calling_from_constrained_runtime { return None; @@ -106,7 +106,7 @@ pub(super) fn oracle_called_from_constrained_function( let function_attributes = interner.function_attributes(called_func); let is_oracle_call = function_attributes.function().map_or(false, |func| func.is_oracle()); if is_oracle_call { - Some(ResolverError::UnconstrainedOracleReturnToConstrained { span }) + Some(ResolverError::UnconstrainedOracleReturnToConstrained { location }) } else { None } @@ -133,8 +133,7 @@ pub(super) fn unconstrained_function_args( .iter() .filter_map(|(typ, _, location)| { if !typ.is_valid_for_unconstrained_boundary() { - let span = location.span; - Some(TypeCheckError::ConstrainedReferenceToUnconstrained { span }) + Some(TypeCheckError::ConstrainedReferenceToUnconstrained { location: *location }) } else { None } @@ -145,12 +144,12 @@ pub(super) fn unconstrained_function_args( /// Check that we are not passing a slice from an unconstrained runtime to a constrained runtime. pub(super) fn unconstrained_function_return( return_type: &Type, - span: Span, + location: Location, ) -> Option { if return_type.contains_slice() { - Some(TypeCheckError::UnconstrainedSliceReturnToConstrained { span }) + Some(TypeCheckError::UnconstrainedSliceReturnToConstrained { location }) } else if !return_type.is_valid_for_unconstrained_boundary() { - Some(TypeCheckError::UnconstrainedReferenceToConstrained { span }) + Some(TypeCheckError::UnconstrainedReferenceToConstrained { location }) } else { None } @@ -198,7 +197,7 @@ pub(crate) fn overflowing_int( annotated_type: &Type, ) -> Vec { let expr = interner.expression(rhs_expr); - let span = interner.expr_span(rhs_expr); + let location = interner.expr_location(rhs_expr); let mut errors = Vec::with_capacity(2); match expr { @@ -211,7 +210,7 @@ pub(crate) fn overflowing_int( expr: if negative { -value } else { value }, ty: annotated_type.clone(), range: format!("0..={}", max), - span, + location, }); } } @@ -224,7 +223,7 @@ pub(crate) fn overflowing_int( expr: if negative { -value } else { value }, ty: annotated_type.clone(), range: format!("-{}..={}", min, max), - span, + location, }); } } @@ -235,7 +234,7 @@ pub(crate) fn overflowing_int( if expr.operator == UnaryOp::Minus && annotated_type.is_unsigned() { errors.push(TypeCheckError::InvalidUnaryOp { kind: annotated_type.to_string(), - span, + location, }); } } @@ -258,13 +257,13 @@ pub(crate) fn unbounded_recursion<'a>( interner: &'a NodeInterner, func_id: FuncId, func_name: impl FnOnce() -> &'a str, - func_span: Span, + func_location: Location, body_id: ExprId, ) -> Option { if !can_return_without_recursing(interner, func_id, body_id) { Some(ResolverError::UnconditionalRecursion { name: func_name().to_string(), - span: func_span, + location: func_location, }) } else { None diff --git a/compiler/noirc_frontend/src/elaborator/mod.rs b/compiler/noirc_frontend/src/elaborator/mod.rs index a65a1a94cf1..659bc72982c 100644 --- a/compiler/noirc_frontend/src/elaborator/mod.rs +++ b/compiler/noirc_frontend/src/elaborator/mod.rs @@ -63,9 +63,8 @@ mod traits; pub mod types; mod unquote; -use fm::FileId; use iter_extended::vecmap; -use noirc_errors::{Located, Location, Span}; +use noirc_errors::{Located, Location}; pub(crate) use options::ElaboratorOptions; pub use options::{FrontendOptions, UnstableFeature}; pub use path_resolution::Turbofish; @@ -109,15 +108,13 @@ pub struct Loop { pub struct Elaborator<'context> { scopes: ScopeForest, - pub(crate) errors: Vec<(CompilationError, FileId)>, + pub(crate) errors: Vec, pub(crate) interner: &'context mut NodeInterner, pub(crate) def_maps: &'context mut DefMaps, pub(crate) usage_tracker: &'context mut UsageTracker, pub(crate) crate_graph: &'context CrateGraph, - pub(crate) file: FileId, - unsafe_block_status: UnsafeBlockStatus, current_loop: Option, @@ -263,7 +260,6 @@ impl<'context> Elaborator<'context> { def_maps, usage_tracker, crate_graph, - file: FileId::dummy(), unsafe_block_status: UnsafeBlockStatus::NotInUnsafeBlock, current_loop: None, generics: Vec::new(), @@ -308,7 +304,7 @@ impl<'context> Elaborator<'context> { crate_id: CrateId, items: CollectedItems, options: ElaboratorOptions<'context>, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { Self::elaborate_and_return_self(context, crate_id, items, options).errors } @@ -466,7 +462,6 @@ impl<'context> Elaborator<'context> { ); self.local_module = func_meta.source_module; - self.file = func_meta.source_file; self.self_type = func_meta.self_type.clone(); self.current_trait_impl = func_meta.trait_impl; @@ -553,12 +548,12 @@ impl<'context> Elaborator<'context> { // Check that the body can return without calling the function. if let FunctionKind::Normal = kind { - self.run_lint(func_meta.name.location.file, |elaborator| { + self.run_lint(|elaborator| { lints::unbounded_recursion( elaborator.interner, id, || elaborator.interner.definition_name(func_meta.name.id), - func_meta.name.location.span, + func_meta.name.location, hir_func.as_expr(), ) .map(Into::into) @@ -649,7 +644,7 @@ impl<'context> Elaborator<'context> { let (type_var, name) = match self.resolve_generic(generic) { Ok(values) => values, Err(error) => { - self.push_err(error, generic.location().file); + self.push_err(error); is_error = true; let id = self.interner.next_type_variable_id(); let kind = self.resolve_generic_kind(generic); @@ -667,14 +662,11 @@ impl<'context> Elaborator<'context> { // are all given the same default name "(error)". if !is_error { if let Some(generic) = self.find_generic(&name_owned) { - self.push_err( - ResolverError::DuplicateDefinition { - name: name_owned, - first_span: generic.location.span, - second_span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::DuplicateDefinition { + name: name_owned, + first_location: generic.location, + second_location: location, + }); } else { self.generics.push(resolved_generic.clone()); } @@ -704,7 +696,7 @@ impl<'context> Elaborator<'context> { match self.interner.get_quoted_type(*id).follow_bindings() { Type::NamedGeneric(type_variable, name) => Ok((type_variable.clone(), name)), other => Err(ResolverError::MacroResultInGenericsListNotAGeneric { - span: location.span, + location: *location, typ: other.clone(), }), } @@ -732,7 +724,7 @@ impl<'context> Elaborator<'context> { ident: ident.clone(), typ: unresolved_typ.typ.clone(), }); - self.push_err(unsupported_typ_err, generic.location().file); + self.push_err(unsupported_typ_err); } Kind::numeric(typ) } else { @@ -740,21 +732,18 @@ impl<'context> Elaborator<'context> { } } - pub(crate) fn push_err(&mut self, error: impl Into, file: FileId) { + pub(crate) fn push_err(&mut self, error: impl Into) { let error: CompilationError = error.into(); - self.errors.push((error, file)); + self.errors.push(error); } - pub(crate) fn push_errors( - &mut self, - errors: impl IntoIterator, - ) { + pub(crate) fn push_errors(&mut self, errors: impl IntoIterator) { self.errors.extend(errors); } - fn run_lint(&mut self, file: FileId, lint: impl Fn(&Elaborator) -> Option) { + fn run_lint(&mut self, lint: impl Fn(&Elaborator) -> Option) { if let Some(error) = lint(self) { - self.push_err(error, file); + self.push_err(error); } } @@ -772,18 +761,17 @@ impl<'context> Elaborator<'context> { } fn resolve_trait_by_path(&mut self, path: Path) -> Option { - let file = path.location.file; let error = match self.resolve_path(path.clone()) { Ok(PathResolution { item: PathResolutionItem::Trait(trait_id), errors }) => { for error in errors { - self.push_err(error, file); + self.push_err(error); } return Some(trait_id); } Ok(_) => DefCollectorErrorKind::NotATrait { not_a_trait_name: path }, Err(_) => DefCollectorErrorKind::TraitNotFound { trait_path: path }, }; - self.push_err(error, file); + self.push_err(error); None } @@ -912,7 +900,7 @@ impl<'context> Elaborator<'context> { self.resolve_type_args(bound.trait_generics.clone(), trait_id, location); let trait_generics = TraitGenerics { ordered, named }; - Some(ResolvedTraitBound { trait_id, trait_generics, span: location.span }) + Some(ResolvedTraitBound { trait_id, trait_generics, location }) } /// Extract metadata from a NoirFunction @@ -961,8 +949,8 @@ impl<'context> Elaborator<'context> { let mut parameter_types = Vec::new(); let mut parameter_idents = Vec::new(); - for Param { visibility, pattern, typ, location } in func.parameters().iter().cloned() { - self.run_lint(location.file, |_| { + for Param { visibility, pattern, typ, location: _ } in func.parameters().iter().cloned() { + self.run_lint(|_| { lints::unnecessary_pub_argument(func, visibility, is_pub_allowed).map(Into::into) }); @@ -1119,17 +1107,14 @@ impl<'context> Elaborator<'context> { } fn run_function_lints(&mut self, func: &FuncMeta, modifiers: &FunctionModifiers) { - let file = func.location.file; - self.run_lint(file, |_| lints::inlining_attributes(func, modifiers).map(Into::into)); - self.run_lint(file, |_| lints::missing_pub(func, modifiers).map(Into::into)); - self.run_lint(file, |_| { + self.run_lint(|_| lints::inlining_attributes(func, modifiers).map(Into::into)); + self.run_lint(|_| lints::missing_pub(func, modifiers).map(Into::into)); + self.run_lint(|_| { let pub_allowed = func.is_entry_point || modifiers.attributes.is_foldable(); lints::unnecessary_pub_return(func, modifiers, pub_allowed).map(Into::into) }); - self.run_lint(file, |_| { - lints::oracle_not_marked_unconstrained(func, modifiers).map(Into::into) - }); - self.run_lint(file, |elaborator| { + self.run_lint(|_| lints::oracle_not_marked_unconstrained(func, modifiers).map(Into::into)); + self.run_lint(|elaborator| { lints::low_level_function_outside_stdlib(func, modifiers, elaborator.crate_id) .map(Into::into) }); @@ -1148,8 +1133,7 @@ impl<'context> Elaborator<'context> { if (is_entry_point && !typ.is_valid_for_program_input()) || (has_inline_attribute && !typ.is_valid_non_inlined_function_input()) { - let span = location.span; - self.push_err(TypeCheckError::InvalidTypeForEntryPoint { span }, location.file); + self.push_err(TypeCheckError::InvalidTypeForEntryPoint { location }); } } @@ -1230,7 +1214,6 @@ impl<'context> Elaborator<'context> { trait_bound: &ResolvedTraitBound, starting_trait_id: TraitId, ) { - let span = location.span; let trait_id = trait_bound.trait_id; let generics = trait_bound.trait_generics.clone(); @@ -1238,10 +1221,11 @@ impl<'context> Elaborator<'context> { if let Some(the_trait) = self.interner.try_get_trait(trait_id) { let trait_name = the_trait.name.to_string(); let typ = object.clone(); - self.push_err( - TypeCheckError::UnneededTraitConstraint { trait_name, typ, span }, - location.file, - ); + self.push_err(TypeCheckError::UnneededTraitConstraint { + trait_name, + typ, + location, + }); } } @@ -1269,13 +1253,11 @@ impl<'context> Elaborator<'context> { fn elaborate_impls(&mut self, impls: Vec<(UnresolvedGenerics, Location, UnresolvedFunctions)>) { for (_, _, functions) in impls { - self.file = functions.file_id; self.recover_generics(|this| this.elaborate_functions(functions)); } } fn elaborate_trait_impl(&mut self, trait_impl: UnresolvedTraitImpl) { - self.file = trait_impl.file_id; self.local_module = trait_impl.module_id; self.generics = trait_impl.resolved_generics.clone(); @@ -1286,11 +1268,10 @@ impl<'context> Elaborator<'context> { self.check_parent_traits_are_implemented(&trait_impl); self.remove_trait_impl_assumed_trait_implementations(trait_impl.impl_id); - for (module, function, noir_function) in &trait_impl.methods.functions { + for (module, function, _) in &trait_impl.methods.functions { self.local_module = *module; - let file = noir_function.location().file; let errors = check_trait_impl_method_matches_declaration(self.interner, *function); - self.push_errors(errors.into_iter().map(|error| (error.into(), file))); + self.push_errors(errors.into_iter().map(|error| error.into())); } self.elaborate_functions(trait_impl.methods); @@ -1346,7 +1327,6 @@ impl<'context> Elaborator<'context> { } let impl_trait = the_trait.name.to_string(); - let the_trait_file = the_trait.location.file; let mut bindings = TypeBindings::new(); bind_ordered_generics( @@ -1378,16 +1358,13 @@ impl<'context> Elaborator<'context> { { let missing_trait = format!("{}{}", trait_constraint_trait.name, trait_bound.trait_generics); - self.push_err( - ResolverError::TraitNotImplemented { - impl_trait: impl_trait.clone(), - missing_trait, - type_missing_trait: trait_constraint_type.to_string(), - span: trait_impl.object_type.location.span, - missing_trait_location: Location::new(trait_bound.span, the_trait_file), - }, - trait_impl.object_type.location.file, - ); + self.push_err(ResolverError::TraitNotImplemented { + impl_trait: impl_trait.clone(), + missing_trait, + type_missing_trait: trait_constraint_type.to_string(), + location: trait_impl.object_type.location, + missing_trait_location: trait_bound.location, + }); } } } @@ -1410,7 +1387,6 @@ impl<'context> Elaborator<'context> { } let impl_trait = the_trait.name.to_string(); - let the_trait_file = the_trait.location.file; let mut bindings = TypeBindings::new(); bind_ordered_generics( @@ -1448,19 +1424,13 @@ impl<'context> Elaborator<'context> { { let missing_trait = format!("{}{}", parent_trait.name, parent_trait_bound.trait_generics); - self.push_err( - ResolverError::TraitNotImplemented { - impl_trait: impl_trait.clone(), - missing_trait, - type_missing_trait: trait_impl.object_type.to_string(), - span: trait_impl.object_type.location.span, - missing_trait_location: Location::new( - parent_trait_bound.span, - the_trait_file, - ), - }, - trait_impl.object_type.location.file, - ); + self.push_err(ResolverError::TraitNotImplemented { + impl_trait: impl_trait.clone(), + missing_trait, + type_missing_trait: trait_impl.object_type.to_string(), + location: trait_impl.object_type.location, + missing_trait_location: parent_trait_bound.location, + }); } } } @@ -1473,7 +1443,6 @@ impl<'context> Elaborator<'context> { self.local_module = module; for (generics, location, unresolved) in impls { - self.file = unresolved.file_id; let old_generic_count = self.generics.len(); self.add_generics(generics); self.declare_methods_on_struct(None, unresolved, *location); @@ -1483,7 +1452,6 @@ impl<'context> Elaborator<'context> { fn collect_trait_impl(&mut self, trait_impl: &mut UnresolvedTraitImpl) { self.local_module = trait_impl.module_id; - self.file = trait_impl.file_id; self.current_trait_impl = trait_impl.impl_id; let self_type = trait_impl.methods.self_type.clone(); @@ -1494,11 +1462,9 @@ impl<'context> Elaborator<'context> { let self_type_location = trait_impl.object_type.location; if matches!(self_type, Type::MutableReference(_)) { - let span = self_type_location.span; - self.push_err( - DefCollectorErrorKind::MutableReferenceInTraitImpl { span }, - self_type_location.file, - ); + self.push_err(DefCollectorErrorKind::MutableReferenceInTraitImpl { + location: self_type_location, + }); } if let Some(trait_id) = trait_impl.trait_id { @@ -1554,29 +1520,18 @@ impl<'context> Elaborator<'context> { let generics = vecmap(&self.generics, |generic| generic.type_var.clone()); - if let Err((prev_location, prev_file)) = self.interner.add_trait_implementation( + if let Err(prev_location) = self.interner.add_trait_implementation( self_type.clone(), trait_id, trait_impl.impl_id.expect("impl_id should be set in define_function_metas"), generics, resolved_trait_impl, ) { - self.push_err( - DefCollectorErrorKind::OverlappingImpl { - typ: self_type.clone(), - span: self_type_location.span, - }, - self_type_location.file, - ); - - // The 'previous impl defined here' note must be a separate error currently - // since it may be in a different file and all errors have the same file id. - self.file = prev_file; - self.push_err( - DefCollectorErrorKind::OverlappingImplNote { span: prev_location.span }, - prev_location.file, - ); - self.file = trait_impl.file_id; + self.push_err(DefCollectorErrorKind::OverlappingImpl { + typ: self_type.clone(), + location: self_type_location, + prev_location, + }); } } @@ -1602,7 +1557,6 @@ impl<'context> Elaborator<'context> { functions: &mut UnresolvedFunctions, location: Location, ) { - let span = location.span; let self_type = functions.self_type.as_ref(); let self_type = self_type.expect("Expected struct type to be set before declare_methods_on_struct"); @@ -1615,10 +1569,7 @@ impl<'context> Elaborator<'context> { // `impl`s are only allowed on types defined within the current crate if trait_id.is_none() && struct_ref.id.krate() != self.crate_id { let type_name = struct_ref.name.to_string(); - self.push_err( - DefCollectorErrorKind::ForeignImpl { span, type_name }, - location.file, - ); + self.push_err(DefCollectorErrorKind::ForeignImpl { location, type_name }); return; } @@ -1664,7 +1615,7 @@ impl<'context> Elaborator<'context> { self.declare_methods(self_type, &function_ids); } } else { - self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { span }, location.file); + self.push_err(DefCollectorErrorKind::NonStructTypeInImpl { location }); } } } @@ -1680,16 +1631,15 @@ impl<'context> Elaborator<'context> { let second_location = self.interner.function_ident(method_id).location(); let error = ResolverError::DuplicateDefinition { name: method_name, - first_span: first_location.span, - second_span: second_location.span, + first_location, + second_location, }; - self.push_err(error, second_location.file); + self.push_err(error); } } } fn define_type_alias(&mut self, alias_id: TypeAliasId, alias: UnresolvedTypeAlias) { - self.file = alias.file_id; self.local_module = alias.module_id; let name = &alias.type_alias_def.name; @@ -1761,14 +1711,11 @@ impl<'context> Elaborator<'context> { if struct_module_id.krate == self.crate_id { if let Some(aliased_visibility) = self.find_struct_visibility(&struct_type) { if aliased_visibility < visibility { - self.push_err( - ResolverError::TypeIsMorePrivateThenItem { - typ: struct_type.name.to_string(), - item: name.to_string(), - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::TypeIsMorePrivateThenItem { + typ: struct_type.name.to_string(), + item: name.to_string(), + location, + }); } } } @@ -1839,7 +1786,6 @@ impl<'context> Elaborator<'context> { // Resolve each field in each struct. // Each struct should already be present in the NodeInterner after def collection. for (type_id, typ) in structs { - self.file = typ.file_id; self.local_module = typ.module_id; let fields = self.resolve_struct_fields(&typ.struct_def, *type_id); @@ -1892,9 +1838,7 @@ impl<'context> Elaborator<'context> { for (_, field_type) in fields.iter() { if field_type.is_nested_slice() { let location = struct_type.borrow().location; - let span = location.span; - self.file = location.file; - self.push_err(ResolverError::NestedSlices { span }, location.file); + self.push_err(ResolverError::NestedSlices { location }); } } } @@ -1929,7 +1873,6 @@ impl<'context> Elaborator<'context> { fn collect_enum_definitions(&mut self, enums: &BTreeMap) { for (type_id, typ) in enums { - self.file = typ.file_id; self.local_module = typ.module_id; self.generics.clear(); @@ -1938,7 +1881,7 @@ impl<'context> Elaborator<'context> { let generics = datatype_ref.generic_types(); self.add_existing_generics(&typ.enum_def.generics, &datatype_ref.generics); - self.use_unstable_feature(UnstableFeature::Enums, datatype_ref.name.span()); + self.use_unstable_feature(UnstableFeature::Enums, datatype_ref.name.location()); drop(datatype_ref); let self_type = Type::DataType(datatype.clone(), generics); @@ -1980,7 +1923,6 @@ impl<'context> Elaborator<'context> { fn elaborate_global(&mut self, global: UnresolvedGlobal) { let old_module = std::mem::replace(&mut self.local_module, global.module_id); - let old_file = std::mem::replace(&mut self.file, global.file_id); let old_item = self.current_item.take(); let global_id = global.global_id; @@ -1994,16 +1936,15 @@ impl<'context> Elaborator<'context> { }; let location = let_stmt.pattern.location(); - let span = location.span; if !self.in_contract() && let_stmt.attributes.iter().any(|attr| matches!(attr, SecondaryAttribute::Abi(_))) { - self.push_err(ResolverError::AbiAttributeOutsideContract { span }, location.file); + self.push_err(ResolverError::AbiAttributeOutsideContract { location }); } if !let_stmt.comptime && matches!(let_stmt.pattern, Pattern::Mutable(..)) { - self.push_err(ResolverError::MutableGlobal { span }, location.file); + self.push_err(ResolverError::MutableGlobal { location }); } let (let_statement, _typ) = self @@ -2025,7 +1966,6 @@ impl<'context> Elaborator<'context> { } self.local_module = old_module; - self.file = old_file; self.current_item = old_item; } @@ -2041,8 +1981,8 @@ impl<'context> Elaborator<'context> { let mut interpreter = self.setup_interpreter(); if let Err(error) = interpreter.evaluate_let(let_statement) { - let (error, file) = error.into_compilation_error_pair(); - self.push_err(error, file); + let error: CompilationError = error.into(); + self.push_err(error); } else { let value = interpreter .lookup_id(definition_id, location) @@ -2078,7 +2018,6 @@ impl<'context> Elaborator<'context> { self.local_module = *local_module; for (generics, _, function_set) in function_sets { - self.file = function_set.file_id; self.add_generics(generics); let self_type = self.resolve_type(self_type.clone()); function_set.self_type = Some(self_type.clone()); @@ -2090,7 +2029,6 @@ impl<'context> Elaborator<'context> { } for trait_impl in trait_impls { - self.file = trait_impl.file_id; self.local_module = trait_impl.module_id; let (trait_id, mut trait_generics, path_location) = match &trait_impl.r#trait.typ { @@ -2101,10 +2039,9 @@ impl<'context> Elaborator<'context> { UnresolvedTypeData::Resolved(quoted_type_id) => { let typ = self.interner.get_quoted_type(*quoted_type_id); let location = trait_impl.r#trait.location; - let span = location.span; let Type::TraitAsType(trait_id, _, trait_generics) = typ else { let found = typ.to_string(); - self.push_err(ResolverError::ExpectedTrait { span, found }, location.file); + self.push_err(ResolverError::ExpectedTrait { location, found }); continue; }; @@ -2131,9 +2068,8 @@ impl<'context> Elaborator<'context> { } _ => { let location = trait_impl.r#trait.location; - let span = location.span; let found = trait_impl.r#trait.typ.to_string(); - self.push_err(ResolverError::ExpectedTrait { span, found }, location.file); + self.push_err(ResolverError::ExpectedTrait { location, found }); (None, GenericTypeArgs::default(), location) } }; @@ -2203,8 +2139,6 @@ impl<'context> Elaborator<'context> { } fn define_function_metas_for_functions(&mut self, function_set: &mut UnresolvedFunctions) { - self.file = function_set.file_id; - for (local_module, id, func) in &mut function_set.functions { self.local_module = *local_module; self.recover_generics(|this| { @@ -2227,11 +2161,10 @@ impl<'context> Elaborator<'context> { /// Register a use of the given unstable feature. Errors if the feature has not /// been explicitly enabled in this package. - pub fn use_unstable_feature(&mut self, feature: UnstableFeature, span: Span) { + pub fn use_unstable_feature(&mut self, feature: UnstableFeature, location: Location) { if !self.options.enabled_unstable_features.contains(&feature) { let reason = ParserErrorReason::ExperimentalFeature(feature); - let location = Location::new(span, self.file); - self.push_err(ParserError::with_reason(reason, location), self.file); + self.push_err(ParserError::with_reason(reason, location)); } } } diff --git a/compiler/noirc_frontend/src/elaborator/path_resolution.rs b/compiler/noirc_frontend/src/elaborator/path_resolution.rs index 8eb24b30d23..bbe90e8db24 100644 --- a/compiler/noirc_frontend/src/elaborator/path_resolution.rs +++ b/compiler/noirc_frontend/src/elaborator/path_resolution.rs @@ -107,11 +107,10 @@ impl<'context> Elaborator<'context> { &mut self, path: Path, ) -> Result { - let file = path.location.file; let path_resolution = self.resolve_path(path)?; for error in path_resolution.errors { - self.push_err(error, file); + self.push_err(error); } Ok(path_resolution.item) @@ -219,7 +218,7 @@ impl<'context> Elaborator<'context> { if last_segment_generics.is_some() { errors.push(PathResolutionError::TurbofishNotAllowedOnItem { item: format!("module `{last_ident}`"), - span: last_segment.turbofish_span(), + location: last_segment.turbofish_location(), }); } diff --git a/compiler/noirc_frontend/src/elaborator/patterns.rs b/compiler/noirc_frontend/src/elaborator/patterns.rs index 1bb7889a9a1..94ec95ba9bf 100644 --- a/compiler/noirc_frontend/src/elaborator/patterns.rs +++ b/compiler/noirc_frontend/src/elaborator/patterns.rs @@ -1,5 +1,5 @@ use iter_extended::vecmap; -use noirc_errors::{Location, Span}; +use noirc_errors::Location; use rustc_hash::FxHashSet as HashSet; use crate::{ @@ -66,7 +66,7 @@ impl<'context> Elaborator<'context> { pattern: Pattern, expected_type: Type, definition: DefinitionKind, - mutable: Option, + mutable: Option, new_definitions: &mut Vec, warn_if_unused: bool, ) -> HirPattern { @@ -98,17 +98,17 @@ impl<'context> Elaborator<'context> { } Pattern::Mutable(pattern, location, _) => { if let Some(first_mut) = mutable { - self.push_err( - ResolverError::UnnecessaryMut { first_mut, second_mut: location.span }, - location.file, - ); + self.push_err(ResolverError::UnnecessaryMut { + first_mut, + second_mut: location, + }); } let pattern = self.elaborate_pattern_mut( *pattern, expected_type, definition, - Some(location.span), + Some(location), new_definitions, warn_if_unused, ); @@ -122,15 +122,12 @@ impl<'context> Elaborator<'context> { let tuple = Type::Tuple(vecmap(&fields, |_| self.interner.next_type_variable())); - self.push_err( - TypeCheckError::TypeMismatchWithSource { - expected: expected_type, - actual: tuple, - span: location.span, - source: Source::Assignment, - }, - location.file, - ); + self.push_err(TypeCheckError::TypeMismatchWithSource { + expected: expected_type, + actual: tuple, + location, + source: Source::Assignment, + }); Vec::new() } }; @@ -179,7 +176,7 @@ impl<'context> Elaborator<'context> { location: Location, expected_type: Type, definition: DefinitionKind, - mutable: Option, + mutable: Option, new_definitions: &mut Vec, ) -> HirPattern { let last_segment = name.last_segment(); @@ -204,10 +201,7 @@ impl<'context> Elaborator<'context> { None => return error_identifier(self), Some(typ) => { let typ = typ.to_string(); - self.push_err( - ResolverError::NonStructUsedInConstructor { typ, span: location.span }, - location.file, - ); + self.push_err(ResolverError::NonStructUsedInConstructor { typ, location }); return error_identifier(self); } }; @@ -223,13 +217,11 @@ impl<'context> Elaborator<'context> { let actual_type = Type::DataType(struct_type.clone(), generics); - self.unify(&actual_type, &expected_type, location.file, || { - TypeCheckError::TypeMismatchWithSource { - expected: expected_type.clone(), - actual: actual_type.clone(), - span: location.span, - source: Source::Assignment, - } + self.unify(&actual_type, &expected_type, || TypeCheckError::TypeMismatchWithSource { + expected: expected_type.clone(), + actual: actual_type.clone(), + location, + source: Source::Assignment, }); let typ = struct_type.clone(); @@ -266,7 +258,7 @@ impl<'context> Elaborator<'context> { location: Location, expected_type: Type, definition: DefinitionKind, - mutable: Option, + mutable: Option, new_definitions: &mut Vec, ) -> Vec<(Ident, HirPattern)> { let mut ret = Vec::with_capacity(fields.len()); @@ -301,36 +293,24 @@ impl<'context> Elaborator<'context> { ); } else if seen_fields.contains(&field) { // duplicate field - self.push_err( - ResolverError::DuplicateField { field: field.clone() }, - field.location().file, - ); + self.push_err(ResolverError::DuplicateField { field: field.clone() }); } else { // field not required by struct - self.push_err( - ResolverError::NoSuchField { - field: field.clone(), - struct_definition: struct_type.borrow().name.clone(), - }, - field.location().file, - ); + self.push_err(ResolverError::NoSuchField { + field: field.clone(), + struct_definition: struct_type.borrow().name.clone(), + }); } ret.push((field, resolved)); } if !unseen_fields.is_empty() { - self.push_err( - ResolverError::MissingFields { - span: location.span, - missing_fields: unseen_fields - .into_iter() - .map(|field| field.to_string()) - .collect(), - struct_definition: struct_type.borrow().name.clone(), - }, - location.file, - ); + self.push_err(ResolverError::MissingFields { + location, + missing_fields: unseen_fields.into_iter().map(|field| field.to_string()).collect(), + struct_definition: struct_type.borrow().name.clone(), + }); } ret @@ -363,14 +343,11 @@ impl<'context> Elaborator<'context> { if !allow_shadowing { if let Some(old_value) = old_value { - self.push_err( - ResolverError::DuplicateDefinition { - name, - first_span: old_value.ident.location.span, - second_span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::DuplicateDefinition { + name, + first_location: old_value.ident.location, + second_location: location, + }); } } } @@ -385,17 +362,17 @@ impl<'context> Elaborator<'context> { warn_if_unused: bool, ) { let second_location = ident.location; - let second_span = second_location.span; let resolver_meta = ResolverMeta { num_times_used: 0, ident, warn_if_unused }; let old_value = self.scopes.get_mut_scope().add_key_value(name.clone(), resolver_meta); if let Some(old_value) = old_value { - let first_span = old_value.ident.location.span; - self.push_err( - ResolverError::DuplicateDefinition { name, first_span, second_span }, - second_location.file, - ); + let first_location = old_value.ident.location; + self.push_err(ResolverError::DuplicateDefinition { + name, + first_location, + second_location, + }); } } @@ -408,15 +385,11 @@ impl<'context> Elaborator<'context> { let old_global_value = scope.add_key_value(name.0.contents.clone(), resolver_meta); if let Some(old_global_value) = old_global_value { - let file = name.location().file; - self.push_err( - ResolverError::DuplicateDefinition { - second_span: name.span(), - name: name.0.contents, - first_span: old_global_value.ident.location.span, - }, - file, - ); + self.push_err(ResolverError::DuplicateDefinition { + first_location: old_global_value.ident.location, + second_location: name.location(), + name: name.0.contents, + }); } ident } @@ -440,7 +413,7 @@ impl<'context> Elaborator<'context> { } else { Err(ResolverError::VariableNotDeclared { name: name.0.contents.clone(), - span: name.0.span(), + location: name.0.location(), }) } } @@ -460,9 +433,9 @@ impl<'context> Elaborator<'context> { let type_check_err = TypeCheckError::IncorrectTurbofishGenericCount { expected_count: direct_generic_kinds.len(), actual_count: unresolved_turbofish.len(), - span: location.span, + location, }; - self.push_err(type_check_err, location.file); + self.push_err(type_check_err); } self.resolve_turbofish_generics(direct_generic_kinds, unresolved_turbofish) @@ -537,15 +510,12 @@ impl<'context> Elaborator<'context> { }; if turbofish_generics.len() != generics.len() { - self.push_err( - TypeCheckError::GenericCountMismatch { - item: format!("{item_kind} {item_name}"), - expected: generics.len(), - found: turbofish_generics.len(), - span: location.span, - }, - location.file, - ); + self.push_err(TypeCheckError::GenericCountMismatch { + item: format!("{item_kind} {item_name}"), + expected: generics.len(), + found: turbofish_generics.len(), + location, + }); return generics; } @@ -671,7 +641,7 @@ impl<'context> Elaborator<'context> { fn resolve_variable(&mut self, path: Path) -> (HirIdent, Option) { if let Some(trait_path_resolution) = self.resolve_trait_generic_path(&path) { for error in trait_path_resolution.errors { - self.push_err(error, path.location.file); + self.push_err(error); } ( @@ -774,14 +744,13 @@ impl<'context> Elaborator<'context> { _ => 0, }); - let span = self.interner.expr_span(&expr_id); let location = self.interner.expr_location(&expr_id); // This instantiates a trait's generics as well which need to be set // when the constraint below is later solved for when the function is // finished. How to link the two? let (typ, bindings) = - self.instantiate(t, bindings, generics, function_generic_count, span, location); + self.instantiate(t, bindings, generics, function_generic_count, location); // Push any trait constraints required by this definition to the context // to be checked later when the type of this variable is further constrained. @@ -828,7 +797,6 @@ impl<'context> Elaborator<'context> { bindings: TypeBindings, turbofish_generics: Option>, function_generic_count: usize, - span: Span, location: Location, ) -> (Type, TypeBindings) { match turbofish_generics { @@ -837,9 +805,9 @@ impl<'context> Elaborator<'context> { let type_check_err = TypeCheckError::IncorrectTurbofishGenericCount { expected_count: function_generic_count, actual_count: turbofish_generics.len(), - span, + location, }; - self.push_err(CompilationError::TypeError(type_check_err), location.file); + self.push_err(CompilationError::TypeError(type_check_err)); typ.instantiate_with_bindings(bindings, self.interner) } else { // Fetch the count of any implicit generics on the function, such as @@ -877,7 +845,7 @@ impl<'context> Elaborator<'context> { Err(error) => error, }, }; - self.push_err(error, location.file); + self.push_err(error); let id = DefinitionId::dummy_id(); ((HirIdent::non_trait_method(id, location), 0), None) } diff --git a/compiler/noirc_frontend/src/elaborator/scope.rs b/compiler/noirc_frontend/src/elaborator/scope.rs index d3c6e8ed725..b6cc789f38f 100644 --- a/compiler/noirc_frontend/src/elaborator/scope.rs +++ b/compiler/noirc_frontend/src/elaborator/scope.rs @@ -83,7 +83,7 @@ impl<'context> Elaborator<'context> { &mut self, path: Path, ) -> Result<(DefinitionId, PathResolutionItem), ResolverError> { - let span = path.span(); + let location = path.location; let item = self.resolve_path_or_error(path)?; if let Some(function) = item.function_id() { @@ -97,7 +97,7 @@ impl<'context> Elaborator<'context> { let expected = "global variable"; let got = "local variable"; - Err(ResolverError::Expected { span, expected, got }) + Err(ResolverError::Expected { location, expected, got }) } pub fn push_scope(&mut self) { @@ -122,10 +122,7 @@ impl<'context> Elaborator<'context> { let name = &definition_info.name; if name != ERROR_IDENT && !definition_info.is_global() { let ident = Ident(Located::from(unused_var.location, name.to_owned())); - self.push_err( - ResolverError::UnusedVariable { ident }, - unused_var.location.file, - ); + self.push_err(ResolverError::UnusedVariable { ident }); } } } @@ -147,19 +144,16 @@ impl<'context> Elaborator<'context> { if let PathResolutionItem::Trait(trait_id) = item { Some(self.get_trait_mut(trait_id)) } else { - self.push_err( - ResolverError::Expected { - expected: "trait", - got: item.description(), - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::Expected { + expected: "trait", + got: item.description(), + location, + }); None } } Err(err) => { - self.push_err(err, location.file); + self.push_err(err); None } } @@ -173,19 +167,16 @@ impl<'context> Elaborator<'context> { if let PathResolutionItem::Type(struct_id) = item { Some(self.get_type(struct_id)) } else { - self.push_err( - ResolverError::Expected { - expected: "type", - got: item.description(), - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::Expected { + expected: "type", + got: item.description(), + location, + }); None } } Err(err) => { - self.push_err(err, location.file); + self.push_err(err); None } } @@ -214,18 +205,15 @@ impl<'context> Elaborator<'context> { Some(alias.instantiate(self.interner)) } Ok(other) => { - self.push_err( - ResolverError::Expected { - expected: "type", - got: other.description(), - span: location.span, - }, - location.file, - ); + self.push_err(ResolverError::Expected { + expected: "type", + got: other.description(), + location, + }); None } Err(error) => { - self.push_err(error, location.file); + self.push_err(error); None } } diff --git a/compiler/noirc_frontend/src/elaborator/statements.rs b/compiler/noirc_frontend/src/elaborator/statements.rs index 6c0e87e061e..bd41cad391e 100644 --- a/compiler/noirc_frontend/src/elaborator/statements.rs +++ b/compiler/noirc_frontend/src/elaborator/statements.rs @@ -1,4 +1,4 @@ -use noirc_errors::{Location, Span}; +use noirc_errors::Location; use crate::{ ast::{ @@ -71,7 +71,7 @@ impl<'context> Elaborator<'context> { let (hir_statement, typ) = self.elaborate_statement_value_with_target_type(statement, target_type); let id = self.interner.push_stmt(hir_statement); - self.interner.push_stmt_location(id, location.span, location.file); + self.interner.push_stmt_location(id, location); (id, typ) } @@ -97,10 +97,10 @@ impl<'context> Elaborator<'context> { // Require the top-level of a global's type to be fully-specified if type_contains_unspecified && global_id.is_some() { - let span = expr_location.span; let expected_type = annotated_type.clone(); - let error = ResolverError::UnspecifiedGlobalType { span, expected_type }; - self.push_err(error, expr_location.file); + let error = + ResolverError::UnspecifiedGlobalType { location: expr_location, expected_type }; + self.push_err(error); } let definition = match global_id { @@ -114,14 +114,14 @@ impl<'context> Elaborator<'context> { TypeCheckError::TypeMismatch { expected_typ: annotated_type.to_string(), expr_typ: expr_type.to_string(), - expr_span: expr_location.span, + expr_location, } }); if annotated_type.is_integer() { let errors = lints::overflowing_int(self.interner, &expression, &annotated_type); for error in errors { - self.push_err(error, expr_location.file); + self.push_err(error); } } @@ -151,15 +151,15 @@ impl<'context> Elaborator<'context> { let (lvalue, lvalue_type, mutable) = self.elaborate_lvalue(assign.lvalue); if !mutable { - let (name, span) = self.get_lvalue_name_and_span(&lvalue); - self.push_err(TypeCheckError::VariableMustBeMutable { name, span }, expr_location.file); + let (name, location) = self.get_lvalue_name_and_location(&lvalue); + self.push_err(TypeCheckError::VariableMustBeMutable { name, location }); } self.unify_with_coercions(&expr_type, &lvalue_type, expression, expr_location, || { TypeCheckError::TypeMismatchWithSource { actual: expr_type.clone(), expected: lvalue_type.clone(), - span: expr_location.span, + location: expr_location, source: Source::Assignment, } }); @@ -203,22 +203,18 @@ impl<'context> Elaborator<'context> { // Check that start range and end range have the same types let range_location = start_location.merge(end_location); - self.unify(&start_range_type, &end_range_type, range_location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: start_range_type.to_string(), - expr_typ: end_range_type.to_string(), - expr_span: range_location.span, - } + self.unify(&start_range_type, &end_range_type, || TypeCheckError::TypeMismatch { + expected_typ: start_range_type.to_string(), + expr_typ: end_range_type.to_string(), + expr_location: range_location, }); let expected_type = self.polymorphic_integer(); - self.unify(&start_range_type, &expected_type, range_location.file, || { - TypeCheckError::TypeCannotBeUsed { - typ: start_range_type.clone(), - place: "for loop", - span: range_location.span, - } + self.unify(&start_range_type, &expected_type, || TypeCheckError::TypeCannotBeUsed { + typ: start_range_type.clone(), + place: "for loop", + location: range_location, }); self.interner.push_definition_type(identifier.id, start_range_type); @@ -226,12 +222,10 @@ impl<'context> Elaborator<'context> { let block_location = block.type_location(); let (block, block_type) = self.elaborate_expression(block); - self.unify(&block_type, &Type::Unit, block_location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: Type::Unit.to_string(), - expr_typ: block_type.to_string(), - expr_span: block_location.span, - } + self.unify(&block_type, &Type::Unit, || TypeCheckError::TypeMismatch { + expected_typ: Type::Unit.to_string(), + expr_typ: block_type.to_string(), + expr_location: block_location, }); self.pop_scope(); @@ -248,10 +242,9 @@ impl<'context> Elaborator<'context> { block: Expression, location: Location, ) -> (HirStatement, Type) { - let span = location.span; let in_constrained_function = self.in_constrained_function(); if in_constrained_function { - self.push_err(ResolverError::LoopInConstrainedFn { span }, location.file); + self.push_err(ResolverError::LoopInConstrainedFn { location }); } let old_loop = std::mem::take(&mut self.current_loop); @@ -261,12 +254,10 @@ impl<'context> Elaborator<'context> { let block_location = block.type_location(); let (block, block_type) = self.elaborate_expression(block); - self.unify(&block_type, &Type::Unit, block_location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: Type::Unit.to_string(), - expr_typ: block_type.to_string(), - expr_span: block_location.span, - } + self.unify(&block_type, &Type::Unit, || TypeCheckError::TypeMismatch { + expected_typ: Type::Unit.to_string(), + expr_typ: block_type.to_string(), + expr_location: block_location, }); self.pop_scope(); @@ -274,7 +265,7 @@ impl<'context> Elaborator<'context> { let last_loop = std::mem::replace(&mut self.current_loop, old_loop).expect("Expected a loop"); if !last_loop.has_break { - self.push_err(ResolverError::LoopWithoutBreak { span }, location.file); + self.push_err(ResolverError::LoopWithoutBreak { location }); } let statement = HirStatement::Loop(block); @@ -285,10 +276,9 @@ impl<'context> Elaborator<'context> { pub(super) fn elaborate_while(&mut self, while_: WhileStatement) -> (HirStatement, Type) { let in_constrained_function = self.in_constrained_function(); if in_constrained_function { - self.push_err( - ResolverError::WhileInConstrainedFn { span: while_.while_keyword_location.span }, - while_.while_keyword_location.file, - ); + self.push_err(ResolverError::WhileInConstrainedFn { + location: while_.while_keyword_location, + }); } let old_loop = std::mem::take(&mut self.current_loop); @@ -298,21 +288,19 @@ impl<'context> Elaborator<'context> { let location = while_.condition.type_location(); let (condition, cond_type) = self.elaborate_expression(while_.condition); - self.unify(&cond_type, &Type::Bool, location.file, || TypeCheckError::TypeMismatch { + self.unify(&cond_type, &Type::Bool, || TypeCheckError::TypeMismatch { expected_typ: Type::Bool.to_string(), expr_typ: cond_type.to_string(), - expr_span: location.span, + expr_location: location, }); let block_location = while_.body.type_location(); let (block, block_type) = self.elaborate_expression(while_.body); - self.unify(&block_type, &Type::Unit, block_location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: Type::Unit.to_string(), - expr_typ: block_type.to_string(), - expr_span: block_location.span, - } + self.unify(&block_type, &Type::Unit, || TypeCheckError::TypeMismatch { + expected_typ: Type::Unit.to_string(), + expr_typ: block_type.to_string(), + expr_location: block_location, }); self.pop_scope(); @@ -328,10 +316,7 @@ impl<'context> Elaborator<'context> { let in_constrained_function = self.in_constrained_function(); if in_constrained_function { - self.push_err( - ResolverError::JumpInConstrainedFn { is_break, span: location.span }, - location.file, - ); + self.push_err(ResolverError::JumpInConstrainedFn { is_break, location }); } if let Some(current_loop) = &mut self.current_loop { @@ -339,30 +324,27 @@ impl<'context> Elaborator<'context> { current_loop.has_break = true; } } else { - self.push_err( - ResolverError::JumpOutsideLoop { is_break, span: location.span }, - location.file, - ); + self.push_err(ResolverError::JumpOutsideLoop { is_break, location }); } let expr = if is_break { HirStatement::Break } else { HirStatement::Continue }; (expr, self.interner.next_type_variable()) } - fn get_lvalue_name_and_span(&self, lvalue: &HirLValue) -> (String, Span) { + fn get_lvalue_name_and_location(&self, lvalue: &HirLValue) -> (String, Location) { match lvalue { HirLValue::Ident(name, _) => { - let span = name.location.span; + let location = name.location; if let Some(definition) = self.interner.try_definition(name.id) { - (definition.name.clone(), span) + (definition.name.clone(), location) } else { - ("(undeclared variable)".into(), span) + ("(undeclared variable)".into(), location) } } - HirLValue::MemberAccess { object, .. } => self.get_lvalue_name_and_span(object), - HirLValue::Index { array, .. } => self.get_lvalue_name_and_span(array), - HirLValue::Dereference { lvalue, .. } => self.get_lvalue_name_and_span(lvalue), + HirLValue::MemberAccess { object, .. } => self.get_lvalue_name_and_location(object), + HirLValue::Index { array, .. } => self.get_lvalue_name_and_location(array), + HirLValue::Dereference { lvalue, .. } => self.get_lvalue_name_and_location(lvalue), } } @@ -383,13 +365,10 @@ impl<'context> Elaborator<'context> { mutable = definition.mutable; if definition.comptime && !self.in_comptime_context() { - self.push_err( - ResolverError::MutatingComptimeInNonComptimeContext { - name: definition.name.clone(), - span: ident.location.span, - }, - ident.location.file, - ); + self.push_err(ResolverError::MutatingComptimeInNonComptimeContext { + name: definition.name.clone(), + location: ident.location, + }); } } @@ -443,12 +422,10 @@ impl<'context> Elaborator<'context> { let (index, index_type) = self.elaborate_expression(index); let expected = self.polymorphic_integer_or_field(); - self.unify(&index_type, &expected, expr_location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: "an integer".to_owned(), - expr_typ: index_type.to_string(), - expr_span: expr_location.span, - } + self.unify(&index_type, &expected, || TypeCheckError::TypeMismatch { + expected_typ: "an integer".to_owned(), + expr_typ: index_type.to_string(), + expr_location, }); let (mut lvalue, mut lvalue_type, mut mutable) = self.elaborate_lvalue(*array); @@ -469,29 +446,23 @@ impl<'context> Elaborator<'context> { Type::Slice(elem_type) => *elem_type, Type::Error => Type::Error, Type::String(_) => { - let (_lvalue_name, lvalue_span) = self.get_lvalue_name_and_span(&lvalue); - self.push_err( - TypeCheckError::StringIndexAssign { span: lvalue_span }, - location.file, - ); + let (_lvalue_name, lvalue_location) = + self.get_lvalue_name_and_location(&lvalue); + self.push_err(TypeCheckError::StringIndexAssign { + location: lvalue_location, + }); Type::Error } Type::TypeVariable(_) => { - self.push_err( - TypeCheckError::TypeAnnotationsNeededForIndex { span: location.span }, - location.file, - ); + self.push_err(TypeCheckError::TypeAnnotationsNeededForIndex { location }); Type::Error } other => { - self.push_err( - TypeCheckError::TypeMismatch { - expected_typ: "array".to_string(), - expr_typ: other.to_string(), - expr_span: location.span, - }, - location.file, - ); + self.push_err(TypeCheckError::TypeMismatch { + expected_typ: "array".to_string(), + expr_typ: other.to_string(), + expr_location: location, + }); Type::Error } }; @@ -507,12 +478,10 @@ impl<'context> Elaborator<'context> { let element_type = Type::type_variable(self.interner.next_type_variable_id()); let expected_type = Type::MutableReference(Box::new(element_type.clone())); - self.unify(&reference_type, &expected_type, location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: expected_type.to_string(), - expr_typ: reference_type.to_string(), - expr_span: location.span, - } + self.unify(&reference_type, &expected_type, || TypeCheckError::TypeMismatch { + expected_typ: expected_type.to_string(), + expr_typ: reference_type.to_string(), + expr_location: location, }); // Dereferences are always mutable since we already type checked against a &mut T @@ -535,7 +504,6 @@ impl<'context> Elaborator<'context> { location: Location, dereference_lhs: Option, ) -> Option<(Type, usize)> { - let span = location.span; let lhs_type = lhs_type.follow_bindings(); match &lhs_type { @@ -555,10 +523,12 @@ impl<'context> Elaborator<'context> { if index < length { return Some((elements[index].clone(), index)); } else { - self.push_err( - TypeCheckError::TupleIndexOutOfBounds { index, lhs_type, length, span }, - location.file, - ); + self.push_err(TypeCheckError::TupleIndexOutOfBounds { + index, + lhs_type, + length, + location, + }); return None; } } @@ -586,19 +556,13 @@ impl<'context> Elaborator<'context> { // If we get here the type has no field named 'access.rhs'. // Now we specialize the error message based on whether we know the object type in question yet. if let Type::TypeVariable(..) = &lhs_type { - self.push_err( - TypeCheckError::TypeAnnotationsNeededForFieldAccess { span }, - location.file, - ); + self.push_err(TypeCheckError::TypeAnnotationsNeededForFieldAccess { location }); } else if lhs_type != Type::Error { - self.push_err( - TypeCheckError::AccessUnknownMember { - lhs_type, - field_name: field_name.to_string(), - span, - }, - location.file, - ); + self.push_err(TypeCheckError::AccessUnknownMember { + lhs_type, + field_name: field_name.to_string(), + location, + }); } None @@ -616,13 +580,9 @@ impl<'context> Elaborator<'context> { } if !struct_member_is_visible(struct_type.id, visibility, self.module_id(), self.def_maps) { - self.push_err( - ResolverError::PathResolutionError(PathResolutionError::Private(Ident::new( - field_name.to_string(), - location, - ))), - location.file, - ); + self.push_err(ResolverError::PathResolutionError(PathResolutionError::Private( + Ident::new(field_name.to_string(), location), + ))); } } diff --git a/compiler/noirc_frontend/src/elaborator/trait_impls.rs b/compiler/noirc_frontend/src/elaborator/trait_impls.rs index 2eb763d3d5a..3ff757246f6 100644 --- a/compiler/noirc_frontend/src/elaborator/trait_impls.rs +++ b/compiler/noirc_frontend/src/elaborator/trait_impls.rs @@ -15,7 +15,6 @@ use crate::{ Type, }; -use noirc_errors::Location; use rustc_hash::FxHashSet as HashSet; use super::Elaborator; @@ -28,7 +27,6 @@ impl<'context> Elaborator<'context> { trait_impl_where_clause: &[TraitConstraint], ) { self.local_module = trait_impl.module_id; - self.file = trait_impl.file_id; let impl_id = trait_impl.impl_id.expect("impl_id should be set in define_function_metas"); @@ -62,9 +60,7 @@ impl<'context> Elaborator<'context> { let func_id = self.interner.push_empty_fn(); let module = self.module_id(); - // TODO: check this, it doesn't make sense to mix locations from two different files - let location = - Location::new(default_impl.def.location.span, trait_impl.file_id); + let location = default_impl.def.location; self.interner.push_function(func_id, &default_impl.def, module, location); self.define_function_meta(&mut default_impl_clone, func_id, None); func_ids_in_trait.insert(func_id); @@ -74,14 +70,11 @@ impl<'context> Elaborator<'context> { *default_impl_clone, )); } else { - self.push_err( - DefCollectorErrorKind::TraitMissingMethod { - trait_name: self.interner.get_trait(trait_id).name.clone(), - method_name: method.name.clone(), - trait_impl_span: trait_impl.object_type.location.span, - }, - trait_impl.object_type.location.file, - ); + self.push_err(DefCollectorErrorKind::TraitMissingMethod { + trait_name: self.interner.get_trait(trait_id).name.clone(), + method_name: method.name.clone(), + trait_impl_location: trait_impl.object_type.location, + }); } } else { for (_, func_id, _) in &overrides { @@ -98,14 +91,11 @@ impl<'context> Elaborator<'context> { } if overrides.len() > 1 { - self.push_err( - DefCollectorErrorKind::Duplicate { - typ: DuplicateType::TraitAssociatedFunction, - first_def: overrides[0].2.name_ident().clone(), - second_def: overrides[1].2.name_ident().clone(), - }, - overrides[1].2.name_ident().location().file, - ); + self.push_err(DefCollectorErrorKind::Duplicate { + typ: DuplicateType::TraitAssociatedFunction, + first_def: overrides[0].2.name_ident().clone(), + second_def: overrides[1].2.name_ident().clone(), + }); } ordered_methods.push(overrides[0].clone()); @@ -123,11 +113,10 @@ impl<'context> Elaborator<'context> { for (_, func_id, func) in &trait_impl.methods.functions { if !func_ids_in_trait.contains(func_id) { let trait_name = trait_name.clone(); - let trait_name_file = trait_name.location().file; let impl_method = func.name_ident().clone(); let error = DefCollectorErrorKind::MethodNotInTrait { trait_name, impl_method }; let error: CompilationError = error.into(); - self.push_err(error, trait_name_file); + self.push_err(error); } } @@ -211,17 +200,14 @@ impl<'context> Elaborator<'context> { )) { let the_trait = self.interner.get_trait(override_trait_constraint.trait_bound.trait_id); - self.push_err( - DefCollectorErrorKind::ImplIsStricterThanTrait { - constraint_typ: override_trait_constraint.typ, - constraint_name: the_trait.name.0.contents.clone(), - constraint_generics: override_trait_constraint.trait_bound.trait_generics, - constraint_span: override_trait_constraint.trait_bound.span, - trait_method_name: method.name.0.contents.clone(), - trait_method_span: method.location.span, - }, - method.location.file, - ); + self.push_err(DefCollectorErrorKind::ImplIsStricterThanTrait { + constraint_typ: override_trait_constraint.typ, + constraint_name: the_trait.name.0.contents.clone(), + constraint_generics: override_trait_constraint.trait_bound.trait_generics, + constraint_location: override_trait_constraint.trait_bound.location, + trait_method_name: method.name.0.contents.clone(), + trait_method_location: method.location, + }); } } } @@ -232,7 +218,6 @@ impl<'context> Elaborator<'context> { trait_impl: &UnresolvedTraitImpl, ) { self.local_module = trait_impl.module_id; - self.file = trait_impl.file_id; let object_crate = match &trait_impl.resolved_object_type { Some(Type::DataType(struct_type, _)) => struct_type.borrow().id.krate(), @@ -241,12 +226,9 @@ impl<'context> Elaborator<'context> { let the_trait = self.interner.get_trait(trait_id); if self.crate_id != the_trait.crate_id && self.crate_id != object_crate { - self.push_err( - DefCollectorErrorKind::TraitImplOrphaned { - span: trait_impl.object_type.location.span, - }, - trait_impl.object_type.location.file, - ); + self.push_err(DefCollectorErrorKind::TraitImplOrphaned { + location: trait_impl.object_type.location, + }); } } @@ -260,7 +242,7 @@ impl<'context> Elaborator<'context> { let typ = match UnresolvedTypeExpression::from_expr(expr, location) { Ok(expr) => UnresolvedTypeData::Expression(expr).with_location(location), Err(error) => { - self.push_err(error, location.file); + self.push_err(error); UnresolvedTypeData::Error.with_location(location) } }; diff --git a/compiler/noirc_frontend/src/elaborator/traits.rs b/compiler/noirc_frontend/src/elaborator/traits.rs index e61931739a2..bfd46c9fa8a 100644 --- a/compiler/noirc_frontend/src/elaborator/traits.rs +++ b/compiler/noirc_frontend/src/elaborator/traits.rs @@ -1,7 +1,7 @@ use std::{collections::BTreeMap, rc::Rc}; use iter_extended::vecmap; -use noirc_errors::{Location, Span}; +use noirc_errors::Location; use crate::{ ast::{ @@ -97,7 +97,6 @@ impl<'context> Elaborator<'context> { unresolved_trait: &UnresolvedTrait, ) -> Vec { self.local_module = unresolved_trait.module_id; - self.file = self.def_maps[&self.crate_id].file_id(unresolved_trait.module_id); let mut functions = vec![]; @@ -297,9 +296,9 @@ pub(crate) fn check_trait_impl_method_matches_declaration( if trait_info.generics.len() != impl_.trait_generics.len() { let expected = trait_info.generics.len(); let found = impl_.trait_generics.len(); - let span = impl_.ident.span(); + let location = impl_.ident.location(); let item = trait_info.name.to_string(); - errors.push(TypeCheckError::GenericCountMismatch { item, expected, found, span }); + errors.push(TypeCheckError::GenericCountMismatch { item, expected, found, location }); } // Substitute each generic on the trait with the corresponding generic on the impl @@ -319,17 +318,17 @@ pub(crate) fn check_trait_impl_method_matches_declaration( if modifiers.is_unconstrained != trait_fn_modifiers.is_unconstrained { let expected = trait_fn_modifiers.is_unconstrained; - let span = meta.name.location.span; + let location = meta.name.location; let item = method_name.to_string(); - errors.push(TypeCheckError::UnconstrainedMismatch { item, expected, span }); + errors.push(TypeCheckError::UnconstrainedMismatch { item, expected, location }); } if trait_fn_meta.direct_generics.len() != meta.direct_generics.len() { let expected = trait_fn_meta.direct_generics.len(); let found = meta.direct_generics.len(); - let span = meta.name.location.span; + let location = meta.name.location; let item = method_name.to_string(); - errors.push(TypeCheckError::GenericCountMismatch { item, expected, found, span }); + errors.push(TypeCheckError::GenericCountMismatch { item, expected, found, location }); } // Substitute each generic on the trait function with the corresponding generic on the impl function @@ -350,7 +349,7 @@ pub(crate) fn check_trait_impl_method_matches_declaration( definition_type, method_name, &meta.parameters, - meta.name.location.span, + meta.name.location, &trait_info.name.0.contents, &mut errors, ); @@ -364,7 +363,7 @@ fn check_function_type_matches_expected_type( actual: &Type, method_name: &str, actual_parameters: &Parameters, - span: Span, + location: Location, trait_name: &str, errors: &mut Vec, ) { @@ -386,7 +385,7 @@ fn check_function_type_matches_expected_type( method_name: method_name.to_string(), expected_typ: a.to_string(), actual_typ: b.to_string(), - parameter_span: actual_parameters.0[i].0.span(), + parameter_location: actual_parameters.0[i].0.location(), parameter_index: i + 1, }); } @@ -396,7 +395,7 @@ fn check_function_type_matches_expected_type( errors.push(TypeCheckError::TypeMismatch { expected_typ: ret_a.to_string(), expr_typ: ret_b.to_string(), - expr_span: span, + expr_location: location, }); } } else { @@ -405,7 +404,7 @@ fn check_function_type_matches_expected_type( expected_num_parameters: params_a.len(), trait_name: trait_name.to_string(), method_name: method_name.to_string(), - span, + location, }); } } @@ -416,6 +415,10 @@ fn check_function_type_matches_expected_type( if !bindings.is_empty() { let expected_typ = expected.to_string(); let expr_typ = actual.to_string(); - errors.push(TypeCheckError::TypeMismatch { expected_typ, expr_typ, expr_span: span }); + errors.push(TypeCheckError::TypeMismatch { + expected_typ, + expr_typ, + expr_location: location, + }); } } diff --git a/compiler/noirc_frontend/src/elaborator/types.rs b/compiler/noirc_frontend/src/elaborator/types.rs index 1bcc7b3d47c..23706c0c25a 100644 --- a/compiler/noirc_frontend/src/elaborator/types.rs +++ b/compiler/noirc_frontend/src/elaborator/types.rs @@ -1,6 +1,5 @@ use std::{borrow::Cow, rc::Rc}; -use fm::FileId; use im::HashSet; use iter_extended::vecmap; use noirc_errors::Location; @@ -52,10 +51,9 @@ impl<'context> Elaborator<'context> { /// Translates an UnresolvedType to a Type with a `TypeKind::Normal` pub(crate) fn resolve_type(&mut self, typ: UnresolvedType) -> Type { let location = typ.location; - let span = location.span; let resolved_type = self.resolve_type_inner(typ, &Kind::Normal); if resolved_type.is_nested_slice() { - self.push_err(ResolverError::NestedSlices { span }, location.file); + self.push_err(ResolverError::NestedSlices { location }); } resolved_type } @@ -66,8 +64,6 @@ impl<'context> Elaborator<'context> { use crate::ast::UnresolvedTypeData::*; let location = typ.location; - let span = location.span; - let file = location.file; let (named_path_location, is_self_type_name, is_synthetic) = if let Named(ref named_path, _, synthetic) = typ.typ { ( @@ -106,20 +102,15 @@ impl<'context> Elaborator<'context> { let in_function = matches!(self.current_item, Some(DependencyId::Function(_))); if in_function && !self.in_comptime_context() { let location = typ.location; - let span = location.span; let typ = quoted.to_string(); - self.push_err( - ResolverError::ComptimeTypeInRuntimeCode { span, typ }, - location.file, - ); + self.push_err(ResolverError::ComptimeTypeInRuntimeCode { location, typ }); } Type::Quoted(quoted) } Unit => Type::Unit, Unspecified => { let location = typ.location; - let span = location.span; - self.push_err(TypeCheckError::UnspecifiedType { span }, location.file); + self.push_err(TypeCheckError::UnspecifiedType { location }); Type::Error } Error => Type::Error, @@ -141,13 +132,10 @@ impl<'context> Elaborator<'context> { Type::Function(args, ret, env, unconstrained) } _ => { - self.push_err( - ResolverError::InvalidClosureEnvironment { - typ: *env, - span: env_location.span, - }, - env_location.file, - ); + self.push_err(ResolverError::InvalidClosureEnvironment { + typ: *env, + location: env_location, + }); Type::Error } } @@ -187,9 +175,9 @@ impl<'context> Elaborator<'context> { let expected_typ_err = CompilationError::TypeError(TypeCheckError::TypeKindMismatch { expected_kind: kind.to_string(), expr_kind: resolved_type.kind().to_string(), - expr_span: span, + expr_location: location, }); - self.push_err(expected_typ_err, file); + self.push_err(expected_typ_err); return Type::Error; } @@ -235,10 +223,9 @@ impl<'context> Elaborator<'context> { if name == SELF_TYPE_NAME { if let Some(self_type) = self.self_type.clone() { if !args.is_empty() { - self.push_err( - ResolverError::GenericsOnSelfType { span: path.span() }, - path.location.file, - ); + self.push_err(ResolverError::GenericsOnSelfType { + location: path.location, + }); } return self_type; } @@ -247,10 +234,7 @@ impl<'context> Elaborator<'context> { } } else if let Some(typ) = self.lookup_associated_type_on_self(&path) { if !args.is_empty() { - self.push_err( - ResolverError::GenericsOnAssociatedType { span: path.span() }, - path.location.file, - ); + self.push_err(ResolverError::GenericsOnAssociatedType { location: path.location }); } return typ; } @@ -280,10 +264,9 @@ impl<'context> Elaborator<'context> { match self.lookup_datatype_or_error(path) { Some(data_type) => { if self.resolving_ids.contains(&data_type.borrow().id) { - self.push_err( - ResolverError::SelfReferentialType { span: data_type.borrow().name.span() }, - data_type.borrow().name.location().file, - ); + self.push_err(ResolverError::SelfReferentialType { + location: data_type.borrow().name.location(), + }); return Type::Error; } @@ -295,12 +278,9 @@ impl<'context> Elaborator<'context> { .iter() .any(|attr| matches!(attr, SecondaryAttribute::Abi(_))) { - self.push_err( - ResolverError::AbiAttributeOutsideContract { - span: data_type.borrow().name.span(), - }, - data_type.borrow().name.location().file, - ); + self.push_err(ResolverError::AbiAttributeOutsideContract { + location: data_type.borrow().name.location(), + }); } let (args, _) = self.resolve_type_args(args, data_type.borrow(), location); @@ -359,19 +339,15 @@ impl<'context> Elaborator<'context> { location: Location, allow_implicit_named_args: bool, ) -> (Vec, Vec) { - let span = location.span; let expected_kinds = item.generics(self.interner); if args.ordered_args.len() != expected_kinds.len() { - self.push_err( - TypeCheckError::GenericCountMismatch { - item: item.item_name(self.interner), - expected: expected_kinds.len(), - found: args.ordered_args.len(), - span, - }, - location.file, - ); + self.push_err(TypeCheckError::GenericCountMismatch { + item: item.item_name(self.interner), + expected: expected_kinds.len(), + found: args.ordered_args.len(), + location, + }); let error_type = UnresolvedTypeData::Error.with_location(location); args.ordered_args.resize(expected_kinds.len(), error_type); } @@ -391,7 +367,7 @@ impl<'context> Elaborator<'context> { ); } else if !args.named_args.is_empty() { let item_kind = item.item_kind(); - self.push_err(ResolverError::NamedTypeArgs { span, item_kind }, location.file); + self.push_err(ResolverError::NamedTypeArgs { location, item_kind }); } (ordered, associated) @@ -404,7 +380,6 @@ impl<'context> Elaborator<'context> { location: Location, allow_implicit_named_args: bool, ) -> Vec { - let span = location.span; let mut seen_args = HashMap::default(); let mut required_args = item.named_generics(self.interner); let mut resolved = Vec::with_capacity(required_args.len()); @@ -416,19 +391,18 @@ impl<'context> Elaborator<'context> { required_args.iter().position(|item| item.name.as_ref() == &name.0.contents); let Some(index) = index else { - let file = name.location().file; - if let Some(prev_span) = seen_args.get(&name.0.contents).copied() { - self.push_err(TypeCheckError::DuplicateNamedTypeArg { name, prev_span }, file); + if let Some(prev_location) = seen_args.get(&name.0.contents).copied() { + self.push_err(TypeCheckError::DuplicateNamedTypeArg { name, prev_location }); } else { let item = item.item_name(self.interner); - self.push_err(TypeCheckError::NoSuchNamedTypeArg { name, item }, file); + self.push_err(TypeCheckError::NoSuchNamedTypeArg { name, item }); } continue; }; // Remove the argument from the required list so we remember that we already have it let expected = required_args.remove(index); - seen_args.insert(name.0.contents.clone(), name.span()); + seen_args.insert(name.0.contents.clone(), name.location()); let typ = self.resolve_type_inner(typ, &expected.kind()); resolved.push(NamedType { name, typ }); @@ -445,10 +419,7 @@ impl<'context> Elaborator<'context> { resolved.push(NamedType { name, typ }); } else { let item = item.item_name(self.interner); - self.push_err( - TypeCheckError::MissingNamedTypeArg { item, span, name }, - location.file, - ); + self.push_err(TypeCheckError::MissingNamedTypeArg { item, location, name }); } } @@ -486,43 +457,39 @@ impl<'context> Elaborator<'context> { return self.lookup_generic_or_global_type(path); } else { let path = path.clone(); - let file = path.location.file; - self.push_err(ResolverError::NoSuchNumericTypeVariable { path }, file); + self.push_err(ResolverError::NoSuchNumericTypeVariable { path }); return None; } }; let rhs = stmt.expression; let location = self.interner.expr_location(&rhs); - let span = location.span; let GlobalValue::Resolved(global_value) = &self.interner.get_global(id).value else { - self.push_err(ResolverError::UnevaluatedGlobalType { span }, location.file); + self.push_err(ResolverError::UnevaluatedGlobalType { location }); return None; }; let Some(global_value) = global_value.to_field_element() else { let global_value = global_value.clone(); if global_value.is_integral() { - self.push_err( - ResolverError::NegativeGlobalType { span, global_value }, - location.file, - ); + self.push_err(ResolverError::NegativeGlobalType { location, global_value }); } else { - self.push_err( - ResolverError::NonIntegralGlobalType { span, global_value }, - location.file, - ); + self.push_err(ResolverError::NonIntegralGlobalType { + location, + global_value, + }); } return None; }; - let Ok(global_value) = kind.ensure_value_fits(global_value, span) else { - self.push_err( - ResolverError::GlobalLargerThanKind { span, global_value, kind }, - location.file, - ); + let Ok(global_value) = kind.ensure_value_fits(global_value, location) else { + self.push_err(ResolverError::GlobalLargerThanKind { + location, + global_value, + kind, + }); return None; }; @@ -538,7 +505,6 @@ impl<'context> Elaborator<'context> { expected_kind: &Kind, location: Location, ) -> Type { - let span = location.span; match length { UnresolvedTypeExpression::Variable(path) => { let typ = self.resolve_named_type(path, GenericTypeArgs::default()); @@ -555,24 +521,20 @@ impl<'context> Elaborator<'context> { match (lhs, rhs) { (Type::Constant(lhs, lhs_kind), Type::Constant(rhs, rhs_kind)) => { if !lhs_kind.unifies(&rhs_kind) { - self.push_err( - TypeCheckError::TypeKindMismatch { - expected_kind: lhs_kind.to_string(), - expr_kind: rhs_kind.to_string(), - expr_span: span, - }, - location.file, - ); + self.push_err(TypeCheckError::TypeKindMismatch { + expected_kind: lhs_kind.to_string(), + expr_kind: rhs_kind.to_string(), + expr_location: location, + }); return Type::Error; } - match op.function(lhs, rhs, &lhs_kind, span) { + match op.function(lhs, rhs, &lhs_kind, location) { Ok(result) => Type::Constant(result, lhs_kind), Err(err) => { let err = Box::new(err); - self.push_err( - ResolverError::BinaryOpError { lhs, op, rhs, err, span }, - location.file, - ); + let error = + ResolverError::BinaryOpError { lhs, op, rhs, err, location }; + self.push_err(error); Type::Error } } @@ -593,14 +555,11 @@ impl<'context> Elaborator<'context> { fn check_kind(&mut self, typ: Type, expected_kind: &Kind, location: Location) -> Type { if !typ.kind().unifies(expected_kind) { - self.push_err( - TypeCheckError::TypeKindMismatch { - expected_kind: expected_kind.to_string(), - expr_kind: typ.kind().to_string(), - expr_span: location.span, - }, - location.file, - ); + self.push_err(TypeCheckError::TypeKindMismatch { + expected_kind: expected_kind.to_string(), + expr_kind: typ.kind().to_string(), + expr_location: location, + }); return Type::Error; } typ @@ -642,9 +601,8 @@ impl<'context> Elaborator<'context> { Some(generic) => generic.typ.clone(), None => { let name = path.impl_item.clone(); - let file = name.location().file; let item = format!("<{} as {}>", path.typ, path.trait_path); - self.push_err(TypeCheckError::NoSuchNamedTypeArg { name, item }, file); + self.push_err(TypeCheckError::NoSuchNamedTypeArg { name, item }); Type::Error } } @@ -804,12 +762,11 @@ impl<'context> Elaborator<'context> { &mut self, actual: &Type, expected: &Type, - file: FileId, make_error: impl FnOnce() -> TypeCheckError, ) { if let Err(UnificationError) = actual.unify(expected) { let error: CompilationError = make_error().into(); - self.push_err(error, file); + self.push_err(error); } } @@ -820,13 +777,12 @@ impl<'context> Elaborator<'context> { &mut self, actual: &Type, expected: &Type, - file: fm::FileId, make_error: impl FnOnce() -> TypeCheckError, ) { let mut bindings = TypeBindings::new(); if actual.try_unify(expected, &mut bindings).is_err() { let error: CompilationError = make_error().into(); - self.push_err(error, file); + self.push_err(error); } } @@ -843,12 +799,12 @@ impl<'context> Elaborator<'context> { actual.unify_with_coercions( expected, expression, - location.span, + location, self.interner, &mut errors, make_error, ); - self.push_errors(errors.into_iter().map(|error| (error.into(), location.file))); + self.push_errors(errors.into_iter().map(|error| error.into())); } /// Return a fresh integer or field type variable and log it @@ -940,15 +896,11 @@ impl<'context> Elaborator<'context> { location: Location, ) -> Type { if fn_params.len() != callsite_args.len() { - let span = location.span; - self.push_err( - TypeCheckError::ParameterCountMismatch { - expected: fn_params.len(), - found: callsite_args.len(), - span, - }, - location.file, - ); + self.push_err(TypeCheckError::ParameterCountMismatch { + expected: fn_params.len(), + found: callsite_args.len(), + location, + }); return Type::Error; } @@ -957,7 +909,7 @@ impl<'context> Elaborator<'context> { TypeCheckError::TypeMismatch { expected_typ: param.to_string(), expr_typ: arg.to_string(), - expr_span: arg_location.span, + expr_location: *arg_location, } }); } @@ -986,8 +938,8 @@ impl<'context> Elaborator<'context> { Type::Function(args, Box::new(ret.clone()), Box::new(env_type), false); let expected_kind = expected.kind(); - if let Err(error) = binding.try_bind(expected, &expected_kind, location.span) { - self.push_err(error, location.file); + if let Err(error) = binding.try_bind(expected, &expected_kind, location) { + self.push_err(error); } ret } @@ -998,8 +950,7 @@ impl<'context> Elaborator<'context> { } Type::Error => Type::Error, found => { - let span = location.span; - self.push_err(TypeCheckError::ExpectedFunction { found, span }, location.file); + self.push_err(TypeCheckError::ExpectedFunction { found, location }); Type::Error } } @@ -1012,8 +963,6 @@ impl<'context> Elaborator<'context> { to: &Type, location: Location, ) -> Type { - let span = location.span; - let file = location.file; let from_follow_bindings = from.follow_bindings(); let from_value_opt = match self.interner.expression(from_expr_id) { @@ -1032,9 +981,9 @@ impl<'context> Elaborator<'context> { // NOTE: in reality the expected type can also include bool, but for the compiler's simplicity // we only allow integer types. If a bool is in `from` it will need an explicit type annotation. let expected = self.polymorphic_integer_or_field(); - self.unify(from, &expected, location.file, || TypeCheckError::InvalidCast { + self.unify(from, &expected, || TypeCheckError::InvalidCast { from: from.clone(), - span: location.span, + location, reason: "casting from a non-integral type is unsupported".into(), }); true @@ -1042,7 +991,7 @@ impl<'context> Elaborator<'context> { Type::Error => return Type::Error, from => { let reason = "casting from this type is unsupported".into(); - self.push_err(TypeCheckError::InvalidCast { from, span, reason }, file); + self.push_err(TypeCheckError::InvalidCast { from, location, reason }); return Type::Error; } }; @@ -1059,7 +1008,7 @@ impl<'context> Elaborator<'context> { let to = to.clone(); let reason = format!("casting untyped value ({from_value}) to a type with a maximum size ({to_maximum_size}) that's smaller than it"); // we warn that the 'to' type is too small for the value - self.push_err(TypeCheckError::DownsizingCast { from, to, span, reason }, file); + self.push_err(TypeCheckError::DownsizingCast { from, to, location, reason }); } } @@ -1069,7 +1018,7 @@ impl<'context> Elaborator<'context> { Type::Bool => Type::Bool, Type::Error => Type::Error, _ => { - self.push_err(TypeCheckError::UnsupportedCast { span }, file); + self.push_err(TypeCheckError::UnsupportedCast { location }); Type::Error } } @@ -1088,8 +1037,6 @@ impl<'context> Elaborator<'context> { ) -> Result<(Type, bool), TypeCheckError> { use Type::*; - let span = location.span; - match (lhs_type, rhs_type) { // Avoid reporting errors multiple times (Error, _) | (_, Error) => Ok((Bool, false)), @@ -1113,14 +1060,14 @@ impl<'context> Elaborator<'context> { return Err(TypeCheckError::IntegerSignedness { sign_x: *sign_x, sign_y: *sign_y, - span, + location, }); } if bit_width_x != bit_width_y { return Err(TypeCheckError::IntegerBitWidth { bit_width_x: *bit_width_x, bit_width_y: *bit_width_y, - span, + location, }); } Ok((Bool, false)) @@ -1129,7 +1076,7 @@ impl<'context> Elaborator<'context> { if op.kind.is_valid_for_field_type() { Ok((Bool, false)) } else { - Err(TypeCheckError::FieldComparison { span }) + Err(TypeCheckError::FieldComparison { location }) } } @@ -1137,10 +1084,10 @@ impl<'context> Elaborator<'context> { (Bool, Bool) => Ok((Bool, false)), (lhs, rhs) => { - self.unify(lhs, rhs, op.location.file, || TypeCheckError::TypeMismatchWithSource { + self.unify(lhs, rhs, || TypeCheckError::TypeMismatchWithSource { expected: lhs.clone(), actual: rhs.clone(), - span: op.location.span, + location: op.location, source: Source::Binary, }); Ok((Bool, true)) @@ -1158,13 +1105,11 @@ impl<'context> Elaborator<'context> { rhs_type: &Type, location: Location, ) -> bool { - let span = location.span; - - self.unify(lhs_type, rhs_type, location.file, || TypeCheckError::TypeMismatchWithSource { + self.unify(lhs_type, rhs_type, || TypeCheckError::TypeMismatchWithSource { expected: lhs_type.clone(), actual: rhs_type.clone(), source: Source::Binary, - span, + location, }); let use_impl = !lhs_type.is_numeric_value(); @@ -1178,10 +1123,10 @@ impl<'context> Elaborator<'context> { use crate::ast::BinaryOpKind::*; use TypeCheckError::*; - self.unify(lhs_type, &target, location.file, || match op.kind { - Less | LessEqual | Greater | GreaterEqual => FieldComparison { span }, - And | Or | Xor | ShiftRight | ShiftLeft => FieldBitwiseOp { span }, - Modulo => FieldModulo { span }, + self.unify(lhs_type, &target, || match op.kind { + Less | LessEqual | Greater | GreaterEqual => FieldComparison { location }, + And | Or | Xor | ShiftRight | ShiftLeft => FieldBitwiseOp { location }, + Modulo => FieldModulo { location }, other => unreachable!("Operator {other:?} should be valid for Field"), }); } @@ -1200,8 +1145,6 @@ impl<'context> Elaborator<'context> { rhs_type: &Type, location: Location, ) -> Result<(Type, bool), TypeCheckError> { - let span = location.span; - if op.kind.is_comparator() { return self.comparator_operand_type_rules(lhs_type, rhs_type, op, location); } @@ -1222,8 +1165,7 @@ impl<'context> Elaborator<'context> { self.unify( rhs_type, &Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight), - location.file, - || TypeCheckError::InvalidShiftSize { span }, + || TypeCheckError::InvalidShiftSize { location }, ); let use_impl = if lhs_type.is_numeric_value() { let integer_type = self.polymorphic_integer(); @@ -1242,7 +1184,7 @@ impl<'context> Elaborator<'context> { (Integer(sign_x, bit_width_x), Integer(sign_y, bit_width_y)) => { if op.kind == BinaryOpKind::ShiftLeft || op.kind == BinaryOpKind::ShiftRight { if *sign_y != Signedness::Unsigned || *bit_width_y != IntegerBitSize::Eight { - return Err(TypeCheckError::InvalidShiftSize { span }); + return Err(TypeCheckError::InvalidShiftSize { location }); } return Ok((Integer(*sign_x, *bit_width_x), false)); } @@ -1250,14 +1192,14 @@ impl<'context> Elaborator<'context> { return Err(TypeCheckError::IntegerSignedness { sign_x: *sign_x, sign_y: *sign_y, - span, + location, }); } if bit_width_x != bit_width_y { return Err(TypeCheckError::IntegerBitWidth { bit_width_x: *bit_width_x, bit_width_y: *bit_width_y, - span, + location, }); } Ok((Integer(*sign_x, *bit_width_x), false)) @@ -1266,9 +1208,9 @@ impl<'context> Elaborator<'context> { (FieldElement, FieldElement) => { if !op.kind.is_valid_for_field_type() { if op.kind == BinaryOpKind::Modulo { - return Err(TypeCheckError::FieldModulo { span }); + return Err(TypeCheckError::FieldModulo { location }); } else { - return Err(TypeCheckError::FieldBitwiseOp { span }); + return Err(TypeCheckError::FieldBitwiseOp { location }); } } Ok((FieldElement, false)) @@ -1281,12 +1223,12 @@ impl<'context> Elaborator<'context> { if rhs == &Type::Integer(Signedness::Unsigned, IntegerBitSize::Eight) { return Ok((lhs.clone(), true)); } - return Err(TypeCheckError::InvalidShiftSize { span }); + return Err(TypeCheckError::InvalidShiftSize { location }); } - self.unify(lhs, rhs, op.location.file, || TypeCheckError::TypeMismatchWithSource { + self.unify(lhs, rhs, || TypeCheckError::TypeMismatchWithSource { expected: lhs.clone(), actual: rhs.clone(), - span: op.location.span, + location: op.location, source: Source::Binary, }); Ok((lhs.clone(), true)) @@ -1306,8 +1248,6 @@ impl<'context> Elaborator<'context> { ) -> Result<(Type, bool), TypeCheckError> { use Type::*; - let span = location.span; - match op { crate::ast::UnaryOp::Minus | crate::ast::UnaryOp::Not => { match rhs_type { @@ -1329,8 +1269,11 @@ impl<'context> Elaborator<'context> { // type we constrain it to just (non-Field) integer types. if matches!(op, crate::ast::UnaryOp::Not) && rhs_type.is_numeric_value() { let integer_type = Type::polymorphic_integer(self.interner); - self.unify(rhs_type, &integer_type, location.file, || { - TypeCheckError::InvalidUnaryOp { kind: rhs_type.to_string(), span } + self.unify(rhs_type, &integer_type, || { + TypeCheckError::InvalidUnaryOp { + kind: rhs_type.to_string(), + location, + } }); } @@ -1340,7 +1283,7 @@ impl<'context> Elaborator<'context> { if *op == UnaryOp::Minus && *sign_x == Signedness::Unsigned { return Err(TypeCheckError::InvalidUnaryOp { kind: rhs_type.to_string(), - span, + location, }); } Ok((Integer(*sign_x, *bit_width_x), false)) @@ -1348,7 +1291,7 @@ impl<'context> Elaborator<'context> { // The result of a Field is always a witness FieldElement => { if *op == UnaryOp::Not { - return Err(TypeCheckError::FieldNot { span }); + return Err(TypeCheckError::FieldNot { location }); } Ok((FieldElement, false)) } @@ -1364,10 +1307,10 @@ impl<'context> Elaborator<'context> { crate::ast::UnaryOp::Dereference { implicitly_added: _ } => { let element_type = self.interner.next_type_variable(); let expected = Type::MutableReference(Box::new(element_type.clone())); - self.unify(rhs_type, &expected, location.file, || TypeCheckError::TypeMismatch { + self.unify(rhs_type, &expected, || TypeCheckError::TypeMismatch { expr_typ: rhs_type.to_string(), expected_typ: expected.to_string(), - expr_span: span, + expr_location: location, }); Ok((element_type, false)) } @@ -1387,7 +1330,6 @@ impl<'context> Elaborator<'context> { object_type: &Type, location: Location, ) { - let span = location.span; let the_trait = self.interner.get_trait(trait_method_id.trait_id); let method = &the_trait.methods[trait_method_id.method_index]; @@ -1398,12 +1340,10 @@ impl<'context> Elaborator<'context> { // We can cheat a bit and match against only the object type here since no operator // overload uses other generic parameters or return types aside from the object type. let expected_object_type = &args[0]; - self.unify(object_type, expected_object_type, location.file, || { - TypeCheckError::TypeMismatch { - expected_typ: expected_object_type.to_string(), - expr_typ: object_type.to_string(), - expr_span: span, - } + self.unify(object_type, expected_object_type, || TypeCheckError::TypeMismatch { + expected_typ: expected_object_type.to_string(), + expr_typ: object_type.to_string(), + expr_location: location, }); } other => { @@ -1480,20 +1420,15 @@ impl<'context> Elaborator<'context> { location: Location, check_self_param: bool, ) -> Option { - let span = location.span; - let file = location.file; match object_type.follow_bindings() { // TODO: We should allow method calls on `impl Trait`s eventually. // For now it is fine since they are only allowed on return types. Type::TraitAsType(..) => { - self.push_err( - TypeCheckError::UnresolvedMethodCall { - method_name: method_name.to_string(), - object_type: object_type.clone(), - span, - }, - file, - ); + self.push_err(TypeCheckError::UnresolvedMethodCall { + method_name: method_name.to_string(), + object_type: object_type.clone(), + location, + }); None } Type::NamedGeneric(_, _) => { @@ -1511,7 +1446,7 @@ impl<'context> Elaborator<'context> { // The type variable must be unbound at this point since follow_bindings was called Type::TypeVariable(var) if var.kind() == Kind::Normal => { - self.push_err(TypeCheckError::TypeAnnotationsNeededForMethodCall { span }, file); + self.push_err(TypeCheckError::TypeAnnotationsNeededForMethodCall { location }); None } @@ -1531,9 +1466,6 @@ impl<'context> Elaborator<'context> { location: Location, check_self_param: bool, ) -> Option { - let span = location.span; - let file = location.file; - // First search in the type methods. If there is one, that's the one. if let Some(method_id) = self.interner.lookup_direct_method(object_type, method_name, check_self_param) @@ -1569,23 +1501,17 @@ impl<'context> Elaborator<'context> { } if has_field_with_function_type { - self.push_err( - TypeCheckError::CannotInvokeStructFieldFunctionType { - method_name: method_name.to_string(), - object_type: object_type.clone(), - span, - }, - file, - ); + self.push_err(TypeCheckError::CannotInvokeStructFieldFunctionType { + method_name: method_name.to_string(), + object_type: object_type.clone(), + location, + }); } else { - self.push_err( - TypeCheckError::UnresolvedMethodCall { - method_name: method_name.to_string(), - object_type: object_type.clone(), - span, - }, - file, - ); + self.push_err(TypeCheckError::UnresolvedMethodCall { + method_name: method_name.to_string(), + object_type: object_type.clone(), + location, + }); } None } else { @@ -1606,7 +1532,7 @@ impl<'context> Elaborator<'context> { ) -> Option { let (method, error) = self.get_trait_method_in_scope(trait_methods, method_name, location); if let Some(error) = error { - self.push_err(error, location.file); + self.push_err(error); } method } @@ -1717,9 +1643,6 @@ impl<'context> Elaborator<'context> { method_name: &str, location: Location, ) -> Option { - let span = location.span; - let file = location.file; - let func_id = match self.current_item { Some(DependencyId::Function(id)) => id, _ => panic!("unexpected method outside a function: {method_name}"), @@ -1762,14 +1685,11 @@ impl<'context> Elaborator<'context> { } } - self.push_err( - TypeCheckError::UnresolvedMethodCall { - method_name: method_name.to_string(), - object_type: object_type.clone(), - span, - }, - file, - ); + self.push_err(TypeCheckError::UnresolvedMethodCall { + method_name: method_name.to_string(), + object_type: object_type.clone(), + location, + }); None } @@ -1820,10 +1740,7 @@ impl<'context> Elaborator<'context> { args: Vec<(Type, ExprId, Location)>, location: Location, ) -> Type { - let span = location.span; - let file = location.file; - - self.run_lint(file, |elaborator| { + self.run_lint(|elaborator| { lints::deprecated_function(elaborator.interner, call.func).map(Into::into) }); @@ -1842,7 +1759,7 @@ impl<'context> Elaborator<'context> { if crossing_runtime_boundary { match self.unsafe_block_status { UnsafeBlockStatus::NotInUnsafeBlock => { - self.push_err(TypeCheckError::Unsafe { span }, file); + self.push_err(TypeCheckError::Unsafe { location }); } UnsafeBlockStatus::InUnsafeBlockWithoutUnconstrainedCalls => { self.unsafe_block_status = UnsafeBlockStatus::InUnsafeBlockWithConstrainedCalls; @@ -1851,12 +1768,12 @@ impl<'context> Elaborator<'context> { } if let Some(called_func_id) = self.interner.lookup_function_from_expr(&call.func) { - self.run_lint(file, |elaborator| { + self.run_lint(|elaborator| { lints::oracle_called_from_constrained_function( elaborator.interner, &called_func_id, is_current_func_constrained, - span, + location, ) .map(Into::into) }); @@ -1864,15 +1781,15 @@ impl<'context> Elaborator<'context> { let errors = lints::unconstrained_function_args(&args); for error in errors { - self.push_err(error, file); + self.push_err(error); } } let return_type = self.bind_function_type(func_type, args, location); if crossing_runtime_boundary { - self.run_lint(file, |_| { - lints::unconstrained_function_return(&return_type, span).map(Into::into) + self.run_lint(|_| { + lints::unconstrained_function_return(&return_type, location).map(Into::into) }); } @@ -1918,8 +1835,8 @@ impl<'context> Elaborator<'context> { if matches!(expected_object_type.follow_bindings(), Type::MutableReference(_)) { if !matches!(actual_type, Type::MutableReference(_)) { - if let Err((error, file)) = verify_mutable_reference(self.interner, *object) { - self.push_err(TypeCheckError::ResolverError(error), file); + if let Err(error) = verify_mutable_reference(self.interner, *object) { + self.push_err(TypeCheckError::ResolverError(error)); } let new_type = Type::MutableReference(Box::new(actual_type)); @@ -1955,11 +1872,10 @@ impl<'context> Elaborator<'context> { } pub fn type_check_function_body(&mut self, body_type: Type, meta: &FuncMeta, body_id: ExprId) { - let (expr_span, empty_function) = self.function_info(body_id); + let (expr_location, empty_function) = self.function_info(body_id); let declared_return_type = meta.return_type(); let func_location = self.interner.expr_location(&body_id); // XXX: We could be more specific and return the span of the last stmt, however stmts do not have spans yet - let func_span = func_location.span; if let Type::TraitAsType(trait_id, _, generics) = declared_return_type { if self .interner @@ -1971,15 +1887,12 @@ impl<'context> Elaborator<'context> { ) .is_err() { - self.push_err( - TypeCheckError::TypeMismatchWithSource { - expected: declared_return_type.clone(), - actual: body_type, - span: func_span, - source: Source::Return(meta.return_type.clone(), expr_span), - }, - func_location.file, - ); + self.push_err(TypeCheckError::TypeMismatchWithSource { + expected: declared_return_type.clone(), + actual: body_type, + location: func_location, + source: Source::Return(meta.return_type.clone(), expr_location), + }); } } else { self.unify_with_coercions( @@ -1991,8 +1904,8 @@ impl<'context> Elaborator<'context> { let mut error = TypeCheckError::TypeMismatchWithSource { expected: declared_return_type.clone(), actual: body_type.clone(), - span: func_span, - source: Source::Return(meta.return_type.clone(), expr_span), + location: func_location, + source: Source::Return(meta.return_type.clone(), expr_location), }; if empty_function { @@ -2006,23 +1919,23 @@ impl<'context> Elaborator<'context> { } } - fn function_info(&self, function_body_id: ExprId) -> (noirc_errors::Span, bool) { - let (expr_span, empty_function) = + fn function_info(&self, function_body_id: ExprId) -> (noirc_errors::Location, bool) { + let (expr_location, empty_function) = if let HirExpression::Block(block) = self.interner.expression(&function_body_id) { let last_stmt = block.statements().last(); - let mut span = self.interner.expr_span(&function_body_id); + let mut location = self.interner.expr_location(&function_body_id); if let Some(last_stmt) = last_stmt { if let HirStatement::Expression(expr) = self.interner.statement(last_stmt) { - span = self.interner.expr_span(&expr); + location = self.interner.expr_location(&expr); } } - (span, last_stmt.is_none()) + (location, last_stmt.is_none()) } else { - (self.interner.expr_span(&function_body_id), false) + (self.interner.expr_location(&function_body_id), false) }; - (expr_span, empty_function) + (expr_location, empty_function) } #[allow(clippy::too_many_arguments)] @@ -2057,22 +1970,22 @@ impl<'context> Elaborator<'context> { error: ImplSearchErrorKind, location: Location, ) { - let span = location.span; - let file = location.file; match error { ImplSearchErrorKind::TypeAnnotationsNeededOnObjectType => { - self.push_err(TypeCheckError::TypeAnnotationsNeededForMethodCall { span }, file); + self.push_err(TypeCheckError::TypeAnnotationsNeededForMethodCall { location }); } ImplSearchErrorKind::Nested(constraints) => { - if let Some(error) = NoMatchingImplFoundError::new(self.interner, constraints, span) + if let Some(error) = + NoMatchingImplFoundError::new(self.interner, constraints, location) { - self.push_err(TypeCheckError::NoMatchingImplFound(error), file); + self.push_err(TypeCheckError::NoMatchingImplFound(error)); } } ImplSearchErrorKind::MultipleMatching(candidates) => { let object_type = object_type.clone(); - let err = TypeCheckError::MultipleMatchingImpls { object_type, span, candidates }; - self.push_err(err, file); + let err = + TypeCheckError::MultipleMatchingImpls { object_type, location, candidates }; + self.push_err(err); } } } @@ -2098,16 +2011,11 @@ impl<'context> Elaborator<'context> { let name = &unresolved_generic.ident().0.contents; if let Some(generic) = self.find_generic(name) { - let span = location.span; - let file = location.file; - self.push_err( - ResolverError::DuplicateDefinition { - name: name.clone(), - first_span: generic.location.span, - second_span: span, - }, - file, - ); + self.push_err(ResolverError::DuplicateDefinition { + name: name.clone(), + first_location: generic.location, + second_location: location, + }); } else { self.generics.push(resolved_generic.clone()); } @@ -2227,31 +2135,23 @@ fn bind_generic(param: &ResolvedGeneric, arg: &Type, bindings: &mut TypeBindings /// Gives an error if a user tries to create a mutable reference /// to an immutable variable. -fn verify_mutable_reference( - interner: &NodeInterner, - rhs: ExprId, -) -> Result<(), (ResolverError, FileId)> { +fn verify_mutable_reference(interner: &NodeInterner, rhs: ExprId) -> Result<(), ResolverError> { match interner.expression(&rhs) { HirExpression::MemberAccess(member_access) => { verify_mutable_reference(interner, member_access.lhs) } HirExpression::Index(_) => { let location = interner.expr_location(&rhs); - let span = location.span; - let file = location.file; - Err((ResolverError::MutableReferenceToArrayElement { span }, file)) + Err(ResolverError::MutableReferenceToArrayElement { location }) } HirExpression::Ident(ident, _) => { if let Some(definition) = interner.try_definition(ident.id) { if !definition.mutable { let location = interner.expr_location(&rhs); - let span = location.span; - let file = location.file; - let err = ResolverError::MutableReferenceToImmutableVariable { - span, - variable: definition.name.clone(), - }; - return Err((err, file)); + let variable = definition.name.clone(); + let err = + ResolverError::MutableReferenceToImmutableVariable { location, variable }; + return Err(err); } } Ok(()) diff --git a/compiler/noirc_frontend/src/hir/comptime/display.rs b/compiler/noirc_frontend/src/hir/comptime/display.rs index d4b8ee3ecb4..694db9f865c 100644 --- a/compiler/noirc_frontend/src/hir/comptime/display.rs +++ b/compiler/noirc_frontend/src/hir/comptime/display.rs @@ -10,7 +10,7 @@ use crate::{ ForBounds, ForLoopStatement, ForRange, GenericTypeArgs, IfExpression, IndexExpression, InfixExpression, LValue, Lambda, LetStatement, Literal, MatchExpression, MemberAccessExpression, MethodCallExpression, Pattern, PrefixExpression, Statement, - StatementKind, UnresolvedType, UnresolvedTypeData, WhileStatement, + StatementKind, UnresolvedType, UnresolvedTypeData, UnsafeExpression, WhileStatement, }, hir_def::traits::TraitConstraint, node_interner::{InternedStatementKind, NodeInterner}, @@ -645,10 +645,13 @@ fn remove_interned_in_expression_kind( vecmap(block.statements, |stmt| remove_interned_in_statement(interner, stmt)); ExpressionKind::Comptime(BlockExpression { statements }, span) } - ExpressionKind::Unsafe(block, span) => { + ExpressionKind::Unsafe(UnsafeExpression { block, unsafe_keyword_location }) => { let statements = vecmap(block.statements, |stmt| remove_interned_in_statement(interner, stmt)); - ExpressionKind::Unsafe(BlockExpression { statements }, span) + ExpressionKind::Unsafe(UnsafeExpression { + block: BlockExpression { statements }, + unsafe_keyword_location, + }) } ExpressionKind::AsTraitPath(mut path) => { path.typ = remove_interned_in_unresolved_type(interner, path.typ); diff --git a/compiler/noirc_frontend/src/hir/comptime/errors.rs b/compiler/noirc_frontend/src/hir/comptime/errors.rs index e7242cfb3c5..40a4f0ffe4b 100644 --- a/compiler/noirc_frontend/src/hir/comptime/errors.rs +++ b/compiler/noirc_frontend/src/hir/comptime/errors.rs @@ -11,7 +11,6 @@ use crate::{ Type, }; use acvm::{acir::AcirField, BlackBoxResolutionError, FieldElement}; -use fm::FileId; use noirc_errors::{CustomDiagnostic, Location}; /// The possible errors that can halt the interpreter. @@ -172,7 +171,6 @@ pub enum InterpreterError { }, NoMatchingImplFound { error: NoMatchingImplFoundError, - file: FileId, }, ImplMethodTypeMismatch { expected: Type, @@ -274,12 +272,7 @@ impl From for CompilationError { } impl InterpreterError { - pub fn into_compilation_error_pair(self) -> (CompilationError, fm::FileId) { - let location = self.get_location(); - (CompilationError::InterpreterError(self), location.file) - } - - pub fn get_location(&self) -> Location { + pub fn location(&self) -> Location { match self { InterpreterError::ArgumentCountMismatch { location, .. } | InterpreterError::TypeMismatch { location, .. } @@ -340,9 +333,7 @@ impl InterpreterError { | InterpreterError::LoopHaltedForUiResponsiveness { location } => *location, InterpreterError::FailedToParseMacro { error, .. } => error.location(), - InterpreterError::NoMatchingImplFound { error, file } => { - Location::new(error.span, *file) - } + InterpreterError::NoMatchingImplFound { error } => error.location, InterpreterError::Break | InterpreterError::Continue => { panic!("Tried to get the location of Break/Continue error!") } @@ -358,7 +349,7 @@ impl InterpreterError { let diagnostic = CustomDiagnostic::simple_info( "`comptime` expression ran:".to_string(), format!("After evaluation: {}", formatted_result), - location.span, + location, ); InterpreterError::DebugEvaluateComptime { diagnostic, location } } @@ -377,21 +368,21 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let few_many = if actual < expected { "few" } else { "many" }; let secondary = format!("Too {few_many} arguments"); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::TypeMismatch { expected, actual, location } => { let msg = format!("Expected `{expected}` but a value of type `{actual}` was given"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NonComptimeVarReferenced { name, location } => { let msg = format!("Non-comptime variable `{name}` referenced in comptime code"); let secondary = "Non-comptime variables can't be used in comptime code".to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::VariableNotInScope { location } => { let msg = "Variable not in scope".to_string(); let secondary = "Could not find variable".to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::IntegerOutOfRangeForType { value, typ, location } => { let int = match value.try_into_u128() { @@ -399,44 +390,44 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { None => value.to_string(), }; let msg = format!("{int} is outside the range of the {typ} type"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::ErrorNodeEncountered { location } => { let msg = "Internal Compiler Error: Error node encountered".to_string(); let secondary = "This is a bug, please report this if found!".to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonFunctionCalled { typ, location } => { let msg = "Only functions may be called".to_string(); let secondary = format!("Expression has type {typ}"); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonBoolUsedInIf { typ, location } => { let msg = format!("Expected a `bool` but found `{typ}`"); let secondary = "If conditions must be a boolean value".to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonBoolUsedInWhile { typ, location } => { let msg = format!("Expected a `bool` but found `{typ}`"); let secondary = "While conditions must be a boolean value".to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonBoolUsedInConstrain { typ, location } => { let msg = format!("Expected a `bool` but found `{typ}`"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::FailingConstraint { message, location, call_stack } => { let (primary, secondary) = match message { Some(msg) => (msg.clone(), "Assertion failed".into()), None => ("Assertion failed".into(), String::new()), }; - let diagnostic = CustomDiagnostic::simple_error(primary, secondary, location.span); + let diagnostic = CustomDiagnostic::simple_error(primary, secondary, *location); diagnostic.with_call_stack(call_stack.into_iter().copied().collect()) } InterpreterError::NoMethodFound { name, typ, location } => { let msg = format!("No method named `{name}` found for type `{typ}`"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NonIntegerUsedInLoop { typ, location } => { let msg = format!("Non-integer type `{typ}` used in for loop"); @@ -445,31 +436,31 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { } else { String::new() }; - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonPointerDereferenced { typ, location } => { let msg = format!("Only references may be dereferenced, but found `{typ}`"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NonTupleOrStructInMemberAccess { typ, location } => { let msg = format!("The type `{typ}` has no fields to access"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NonArrayIndexed { typ, location } => { let msg = format!("Expected an array or slice but found a(n) {typ}"); let secondary = "Only arrays or slices may be indexed".into(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonIntegerUsedAsIndex { typ, location } => { let msg = format!("Expected an integer but found a(n) {typ}"); let secondary = "Only integers may be indexed. Note that this excludes `field`s".into(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonIntegerIntegerLiteral { typ, location } => { let msg = format!("This integer literal somehow has the type `{typ}`"); let secondary = "This is likely a bug".into(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonIntegerArrayLength { typ, err, location } => { let msg = format!("Non-integer array length: `{typ}`"); @@ -478,59 +469,59 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { } else { "Array lengths must be integers".to_string() }; - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::NonNumericCasted { typ, location } => { let msg = "Only numeric types may be casted".into(); let secondary = format!("`{typ}` is non-numeric"); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::IndexOutOfBounds { index, length, location } => { let msg = format!("{index} is out of bounds for the array of length {length}"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::ExpectedStructToHaveField { typ, field_name, location } => { let msg = format!("The type `{typ}` has no field named `{field_name}`"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::TypeUnsupported { typ, location } => { let msg = format!("The type `{typ}` is currently unsupported in comptime expressions"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::InvalidValueForUnary { typ, operator, location } => { let msg = format!("`{typ}` cannot be used with unary {operator}"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::InvalidValuesForBinary { lhs, rhs, operator, location } => { let msg = format!("No implementation for `{lhs}` {operator} `{rhs}`",); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::CastToNonNumericType { typ, location } => { let msg = format!("Cannot cast to non-numeric type `{typ}`"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::QuoteInRuntimeCode { location } => { let msg = "`quote` may only be used in comptime code".into(); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NonStructInConstructor { typ, location } => { let msg = format!("`{typ}` is not a struct type"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NonEnumInConstructor { typ, location } => { let msg = format!("`{typ}` is not an enum type"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::CannotInlineMacro { value, typ, location } => { let msg = format!("Cannot inline values of type `{typ}` into this position"); let secondary = format!("Cannot inline value `{value}`"); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::UnquoteFoundDuringEvaluation { location } => { let msg = "Unquote found during comptime evaluation".into(); let secondary = "This is a bug".into(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::DebugEvaluateComptime { diagnostic, .. } => diagnostic.clone(), InterpreterError::FailedToParseMacro { error, tokens, rule, location } => { @@ -550,7 +541,7 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { // Given more prominence to where the parser error happened, but still show that it's // because of a failure to parse a macro's token stream, and where that happens. let message = format!("Failed to parse macro's token stream into {rule}"); - diagnostic.add_secondary_with_file(message, location.span, location.file); + diagnostic.add_secondary(message, *location); diagnostic.add_note(token_stream); diagnostic.add_note(push_the_problem_on_the_library_author); @@ -560,7 +551,7 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let msg = "Unsupported statement type to unquote".into(); let secondary = "Only functions, structs, globals, and impls can be unquoted here".into(); - let mut error = CustomDiagnostic::simple_error(msg, secondary, location.span); + let mut error = CustomDiagnostic::simple_error(msg, secondary, *location); error.add_note(format!("Unquoted item was:\n{item}")); error } @@ -568,63 +559,63 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let msg = format!("Comptime dependency cycle while resolving `{function}`"); let secondary = "This function uses comptime code internally which calls into itself".into(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::Unimplemented { item, location } => { let msg = format!("{item} is currently unimplemented"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::InvalidInComptimeContext { item, location, explanation } => { let msg = format!("{item} is invalid in comptime context"); - CustomDiagnostic::simple_error(msg, explanation.clone(), location.span) + CustomDiagnostic::simple_error(msg, explanation.clone(), *location) } InterpreterError::BreakNotInLoop { location } => { let msg = "There is no loop to break out of!".into(); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::ContinueNotInLoop { location } => { let msg = "There is no loop to continue!".into(); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NoImpl { location } => { let msg = "No impl found due to prior type error".into(); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::ImplMethodTypeMismatch { expected, actual, location } => { let msg = format!( "Impl method type {actual} does not unify with trait method type {expected}" ); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::BlackBoxError(error, location) => { - CustomDiagnostic::simple_error(error.to_string(), String::new(), location.span) + CustomDiagnostic::simple_error(error.to_string(), String::new(), *location) } InterpreterError::FailedToResolveTraitBound { trait_bound, location } => { let msg = format!("Failed to resolve trait bound `{trait_bound}`"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::NoMatchingImplFound { error, .. } => error.into(), InterpreterError::Break => unreachable!("Uncaught InterpreterError::Break"), InterpreterError::Continue => unreachable!("Uncaught InterpreterError::Continue"), InterpreterError::TraitDefinitionMustBeAPath { location } => { let msg = "Trait definition arguments must be a variable or path".to_string(); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::FailedToResolveTraitDefinition { location } => { let msg = "Failed to resolve to a trait definition".to_string(); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::FunctionAlreadyResolved { location } => { let msg = "Function already resolved".to_string(); let secondary = "The function was previously called at compile-time or is in another crate" .to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::MultipleMatchingImpls { object_type, candidates, location } => { let message = format!("Multiple trait impls match the object type `{object_type}`"); let secondary = "Ambiguous impl".to_string(); - let mut error = CustomDiagnostic::simple_error(message, secondary, location.span); + let mut error = CustomDiagnostic::simple_error(message, secondary, *location); for (i, candidate) in candidates.iter().enumerate() { error.add_note(format!("Candidate {}: `{candidate}`", i + 1)); } @@ -634,7 +625,7 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { let mut error = CustomDiagnostic::simple_error( "Object type is unknown in method call".to_string(), "Type must be known by this point to know which method to call".to_string(), - location.span, + *location, ); let message = "Try adding a type annotation for the object type before this method call"; @@ -646,19 +637,19 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { "Quoted value in index {index} of this slice is not a valid field name" ); let secondary = format!("`{value}` is not a valid field name for `set_fields`"); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::InvalidAttribute { attribute, location } => { let msg = format!("`{attribute}` is not a valid attribute"); let secondary = "Note that this method expects attribute contents, without the leading `#[` or trailing `]`".to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::GenericNameShouldBeAnIdent { name, location } => { let msg = "Generic name needs to be a valid identifier (one word beginning with a letter)" .to_string(); let secondary = format!("`{name}` is not a valid identifier"); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::DuplicateGeneric { name, @@ -668,47 +659,42 @@ impl<'a> From<&'a InterpreterError> for CustomDiagnostic { } => { let msg = format!("`{struct_name}` already has a generic named `{name}`"); let secondary = format!("`{name}` added here a second time"); - let mut error = - CustomDiagnostic::simple_error(msg, secondary, duplicate_location.span); + let mut error = CustomDiagnostic::simple_error(msg, secondary, *duplicate_location); let existing_msg = format!("`{name}` was previously defined here"); - error.add_secondary_with_file( - existing_msg, - existing_location.span, - existing_location.file, - ); + error.add_secondary(existing_msg, *existing_location); error } InterpreterError::CannotResolveExpression { location, expression } => { let msg = format!("Cannot resolve expression `{expression}`"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::CannotSetFunctionBody { location, expression } => { let msg = format!("`{expression}` is not a valid function body"); - CustomDiagnostic::simple_error(msg, String::new(), location.span) + CustomDiagnostic::simple_error(msg, String::new(), *location) } InterpreterError::UnknownArrayLength { length, err, location } => { let msg = format!("Could not determine array length `{length}`"); let secondary = format!("Evaluating the length failed with: `{err}`"); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::CannotInterpretFormatStringWithErrors { location } => { let msg = "Cannot interpret format string with errors".to_string(); let secondary = "Some of the variables to interpolate could not be evaluated".to_string(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::GlobalsDependencyCycle { location } => { let msg = "This global recursively depends on itself".to_string(); let secondary = String::new(); - CustomDiagnostic::simple_error(msg, secondary, location.span) + CustomDiagnostic::simple_error(msg, secondary, *location) } InterpreterError::LoopHaltedForUiResponsiveness { location } => { let msg = "This loop took too much time to execute so it was halted for UI responsiveness" .to_string(); let secondary = "This error doesn't happen in normal executions of `nargo`".to_string(); - CustomDiagnostic::simple_warning(msg, secondary, location.span) + CustomDiagnostic::simple_warning(msg, secondary, *location) } } } @@ -722,25 +708,26 @@ pub enum ComptimeError { ErrorAddingItemToModule { error: Box, location: Location }, } +impl ComptimeError { + pub fn location(&self) -> Location { + match self { + ComptimeError::ErrorRunningAttribute { location, .. } + | ComptimeError::ErrorAddingItemToModule { location, .. } => *location, + } + } +} + impl<'a> From<&'a ComptimeError> for CustomDiagnostic { fn from(error: &'a ComptimeError) -> Self { match error { ComptimeError::ErrorRunningAttribute { error, location } => { let mut diagnostic = CustomDiagnostic::from(&**error); - diagnostic.add_secondary_with_file( - "While running this function attribute".into(), - location.span, - location.file, - ); + diagnostic.add_secondary("While running this function attribute".into(), *location); diagnostic } ComptimeError::ErrorAddingItemToModule { error, location } => { let mut diagnostic = CustomDiagnostic::from(&**error); - diagnostic.add_secondary_with_file( - "While interpreting `Module::add_item`".into(), - location.span, - location.file, - ); + diagnostic.add_secondary("While interpreting `Module::add_item`".into(), *location); diagnostic } } diff --git a/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs b/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs index 684a2733154..5fb2b19a517 100644 --- a/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs +++ b/compiler/noirc_frontend/src/hir/comptime/hir_to_display_ast.rs @@ -6,8 +6,8 @@ use crate::ast::{ ArrayLiteral, AssignStatement, BlockExpression, CallExpression, CastExpression, ConstrainKind, ConstructorExpression, ExpressionKind, ForLoopStatement, ForRange, GenericTypeArgs, Ident, IfExpression, IndexExpression, InfixExpression, LValue, Lambda, Literal, MatchExpression, - MemberAccessExpression, MethodCallExpression, Path, PathKind, PathSegment, Pattern, - PrefixExpression, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression, WhileStatement, + MemberAccessExpression, MethodCallExpression, Path, PathSegment, Pattern, PrefixExpression, + UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression, UnsafeExpression, WhileStatement, }; use crate::ast::{ConstrainExpression, Expression, Statement, StatementKind}; use crate::hir_def::expr::{ @@ -200,9 +200,10 @@ impl HirExpression { HirExpression::Comptime(block) => { ExpressionKind::Comptime(block.to_display_ast(interner), location) } - HirExpression::Unsafe(block) => { - ExpressionKind::Unsafe(block.to_display_ast(interner), location) - } + HirExpression::Unsafe(block) => ExpressionKind::Unsafe(UnsafeExpression { + block: block.to_display_ast(interner), + unsafe_keyword_location: location, + }), HirExpression::Quote(block) => ExpressionKind::Quote(block.clone()), // A macro was evaluated here: return the quoted result @@ -215,8 +216,7 @@ impl HirExpression { let segment1 = PathSegment { ident: typ.name.clone(), location, generics: None }; let segment2 = PathSegment { ident: variant.name.clone(), location, generics: None }; - let path = - Path { segments: vec![segment1, segment2], kind: PathKind::Plain, location }; + let path = Path::plain(vec![segment1, segment2], location); let func = Box::new(Expression::new(ExpressionKind::Variable(path), location)); let arguments = vecmap(&constructor.arguments, |arg| arg.to_display_ast(interner)); let call = CallExpression { func, arguments, is_macro_call: false }; @@ -382,7 +382,7 @@ impl HirIdent { location, }; - let path = Path { segments: vec![segment], kind: crate::ast::PathKind::Plain, location }; + let path = Path::plain(vec![segment], location); ExpressionKind::Variable(path) } diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs index 12db16764be..b16adaa9ece 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter.rs @@ -3,7 +3,6 @@ use std::{collections::hash_map::Entry, rc::Rc}; use acvm::blackbox_solver::BigIntSolverWithId; use acvm::{acir::AcirField, FieldElement}; -use fm::FileId; use im::Vector; use iter_extended::try_vecmap; use noirc_errors::Location; @@ -218,11 +217,10 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { fn elaborate_in_module( &mut self, module: ModuleId, - file: FileId, f: impl FnOnce(&mut Elaborator) -> T, ) -> T { self.unbind_generics_from_previous_function(); - let result = self.elaborator.elaborate_item_from_comptime_in_module(module, file, f); + let result = self.elaborator.elaborate_item_from_comptime_in_module(module, f); self.rebind_generics_from_previous_function(); result } @@ -619,9 +617,12 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { Err(InterpreterError::NonIntegerArrayLength { typ, err: None, location }) } TypeBinding::Bound(binding) => { - let span = self.elaborator.interner.id_location(id).span; + let location = self.elaborator.interner.id_location(id); binding - .evaluate_to_field_element(&Kind::Numeric(numeric_typ.clone()), span) + .evaluate_to_field_element( + &Kind::Numeric(numeric_typ.clone()), + location, + ) .map_err(|err| { let typ = Type::TypeVariable(type_variable.clone()); let err = Some(Box::new(err)); @@ -851,8 +852,8 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { HirArrayLiteral::Repeated { repeated_element, length } => { let element = self.evaluate(repeated_element)?; - let span = self.elaborator.interner.id_location(id).span; - match length.evaluate_to_u32(span) { + let location = self.elaborator.interner.id_location(id); + match length.evaluate_to_u32(location) { Ok(length) => { let elements = (0..length).map(|_| element.clone()).collect(); Ok(Value::Array(elements, typ)) @@ -1384,11 +1385,11 @@ impl<'local, 'interner> Interpreter<'local, 'interner> { } fn unify_without_binding(&mut self, actual: &Type, expected: &Type, location: Location) { - self.elaborator.unify_without_applying_bindings(actual, expected, location.file, || { + self.elaborator.unify_without_applying_bindings(actual, expected, || { TypeCheckError::TypeMismatch { expected_typ: expected.to_string(), expr_typ: actual.to_string(), - expr_span: location.span, + expr_location: location, } }); } diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs index a8d4f93368c..8c87e9c6bad 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin.rs @@ -12,7 +12,7 @@ use builtin_helpers::{ }; use im::Vector; use iter_extended::{try_vecmap, vecmap}; -use noirc_errors::{Location, Span}; +use noirc_errors::Location; use num_bigint::BigUint; use rustc_hash::FxHashMap as HashMap; @@ -21,7 +21,7 @@ use crate::{ ArrayLiteral, BlockExpression, ConstrainKind, Expression, ExpressionKind, ForRange, FunctionKind, FunctionReturnType, Ident, IntegerBitSize, ItemVisibility, LValue, Literal, Pattern, Signedness, Statement, StatementKind, UnaryOp, UnresolvedType, UnresolvedTypeData, - Visibility, + UnsafeExpression, Visibility, }, elaborator::{ElaborateReason, Elaborator}, hir::{ @@ -247,7 +247,7 @@ impl<'local, 'context> Interpreter<'local, 'context> { "unresolved_type_is_bool" => unresolved_type_is_bool(interner, arguments, location), "unresolved_type_is_field" => unresolved_type_is_field(interner, arguments, location), "unresolved_type_is_unit" => unresolved_type_is_unit(interner, arguments, location), - "zeroed" => Ok(zeroed(return_type, location.span)), + "zeroed" => Ok(zeroed(return_type, location)), _ => { let item = format!("Comptime evaluation for builtin function '{name}'"); Err(InterpreterError::Unimplemented { item, location }) @@ -508,7 +508,7 @@ fn struct_def_generics( Kind::Numeric(numeric_type) => Some(Value::Type(*numeric_type)), _ => None, }; - let numeric_type = option(option_typ.clone(), numeric_type, location.span); + let numeric_type = option(option_typ.clone(), numeric_type, location); Value::Tuple(vec![Value::Type(generic_as_named), numeric_type]) }) .collect(); @@ -814,7 +814,7 @@ fn quoted_as_expr( }, ); - Ok(option(return_type, value, location.span)) + Ok(option(return_type, value, location)) } // fn as_module(quoted: Quoted) -> Option @@ -837,7 +837,7 @@ fn quoted_as_module( module.map(Value::ModuleDefinition) }); - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn as_trait_constraint(quoted: Quoted) -> TraitConstraint @@ -1005,7 +1005,7 @@ fn type_as_constant( // Prefer to use `evaluate_to_u32` over matching on `Type::Constant` // since arithmetic generics may be `Type::InfixExpr`s which evaluate to // constants but are not actually the `Type::Constant` variant. - match typ.evaluate_to_u32(location.span) { + match typ.evaluate_to_u32(location) { Ok(constant) => Ok(Some(Value::U32(constant))), Err(err) => { // Evaluating to a non-constant returns 'None' in user code @@ -1149,7 +1149,7 @@ where let option_value = f(typ)?; - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn type_eq(_first: Type, _second: Type) -> bool @@ -1184,7 +1184,7 @@ fn type_get_trait_impl( _ => None, }; - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn implements(self, constraint: TraitConstraint) -> bool @@ -1305,7 +1305,7 @@ fn typed_expr_as_function_definition( } else { None }; - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn get_type(self) -> Option @@ -1327,7 +1327,7 @@ fn typed_expr_get_type( } else { None }; - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn as_mutable_reference(self) -> Option @@ -1410,16 +1410,16 @@ where let typ = get_unresolved_type(interner, value)?; let option_value = f(typ); - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn zeroed() -> T -fn zeroed(return_type: Type, span: Span) -> Value { +fn zeroed(return_type: Type, location: Location) -> Value { match return_type { Type::FieldElement => Value::Field(0u128.into()), Type::Array(length_type, elem) => { - if let Ok(length) = length_type.evaluate_to_u32(span) { - let element = zeroed(elem.as_ref().clone(), span); + if let Ok(length) = length_type.evaluate_to_u32(location) { + let element = zeroed(elem.as_ref().clone(), location); let array = std::iter::repeat(element).take(length as usize).collect(); Value::Array(array, Type::Array(length_type, elem)) } else { @@ -1444,7 +1444,7 @@ fn zeroed(return_type: Type, span: Span) -> Value { }, Type::Bool => Value::Bool(false), Type::String(length_type) => { - if let Ok(length) = length_type.evaluate_to_u32(span) { + if let Ok(length) = length_type.evaluate_to_u32(location) { Value::String(Rc::new("\0".repeat(length as usize))) } else { // Assume we can resolve the length later @@ -1452,7 +1452,7 @@ fn zeroed(return_type: Type, span: Span) -> Value { } } Type::FmtString(length_type, captures) => { - let length = length_type.evaluate_to_u32(span); + let length = length_type.evaluate_to_u32(location); let typ = Type::FmtString(length_type, captures); if let Ok(length) = length { Value::FormatString(Rc::new("\0".repeat(length as usize)), typ) @@ -1462,7 +1462,7 @@ fn zeroed(return_type: Type, span: Span) -> Value { } } Type::Unit => Value::Unit, - Type::Tuple(fields) => Value::Tuple(vecmap(fields, |field| zeroed(field, span))), + Type::Tuple(fields) => Value::Tuple(vecmap(fields, |field| zeroed(field, location))), Type::DataType(data_type, generics) => { let typ = data_type.borrow(); @@ -1470,7 +1470,7 @@ fn zeroed(return_type: Type, span: Span) -> Value { let mut values = HashMap::default(); for (field_name, field_type) in fields { - let field_value = zeroed(field_type, span); + let field_value = zeroed(field_type, location); values.insert(Rc::new(field_name), field_value); } @@ -1484,7 +1484,7 @@ fn zeroed(return_type: Type, span: Span) -> Value { if !variants.is_empty() { // is_empty & swap_remove let us avoid a .clone() we'd need if we did .get(0) let (_name, params) = variants.swap_remove(0); - args = vecmap(params, |param| zeroed(param, span)); + args = vecmap(params, |param| zeroed(param, location)); } drop(typ); @@ -1494,14 +1494,14 @@ fn zeroed(return_type: Type, span: Span) -> Value { Value::Zeroed(Type::DataType(data_type, generics)) } } - Type::Alias(alias, generics) => zeroed(alias.borrow().get_type(&generics), span), - Type::CheckedCast { to, .. } => zeroed(*to, span), + Type::Alias(alias, generics) => zeroed(alias.borrow().get_type(&generics), location), + Type::CheckedCast { to, .. } => zeroed(*to, location), typ @ Type::Function(..) => { // Using Value::Zeroed here is probably safer than using FuncId::dummy_id() or similar Value::Zeroed(typ) } Type::MutableReference(element) => { - let element = zeroed(*element, span); + let element = zeroed(*element, location); Value::Pointer(Shared::new(element), false) } // Optimistically assume we can resolve this type later or that the value is unused @@ -1565,7 +1565,7 @@ fn expr_as_assert( let option_type = tuple_types.pop().unwrap(); let message = message.map(|msg| Value::expression(msg.kind)); - let message = option(option_type, message, location.span); + let message = option(option_type, message, location); Some(Value::Tuple(vec![predicate, message])) } else { @@ -1611,7 +1611,7 @@ fn expr_as_assert_eq( let option_type = tuple_types.pop().unwrap(); let message = message.map(|message| Value::expression(message.kind)); - let message = option(option_type, message, location.span); + let message = option(option_type, message, location); Some(Value::Tuple(vec![lhs, rhs, message])) } else { @@ -1787,7 +1787,7 @@ fn expr_as_constructor( None }; - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn as_for(self) -> Option<(Quoted, Expr, Expr)> @@ -1883,7 +1883,7 @@ fn expr_as_if( let alternative = option( alternative_option_type, if_expr.alternative.map(|e| Value::expression(e.kind)), - location.span, + location, ); Some(Value::Tuple(vec![ @@ -1972,7 +1972,7 @@ fn expr_as_lambda( } else { Some(Value::UnresolvedType(typ.typ)) }; - let typ = option(option_unresolved_type.clone(), typ, location.span); + let typ = option(option_unresolved_type.clone(), typ, location); Value::Tuple(vec![pattern, typ]) }) .collect(); @@ -1991,7 +1991,7 @@ fn expr_as_lambda( Some(return_type) }; let return_type = return_type.map(Value::UnresolvedType); - let return_type = option(option_unresolved_type, return_type, location.span); + let return_type = option(option_unresolved_type, return_type, location); let body = Value::expression(lambda.body.kind); @@ -2025,7 +2025,7 @@ fn expr_as_let( Some(Value::UnresolvedType(let_statement.r#type.typ)) }; - let typ = option(option_type, typ, location.span); + let typ = option(option_type, typ, location); Some(Value::Tuple(vec![ Value::pattern(let_statement.pattern), @@ -2220,8 +2220,9 @@ fn expr_as_unsafe( location: Location, ) -> IResult { expr_as(interner, arguments, return_type, location, |expr| { - if let ExprValue::Expression(ExpressionKind::Unsafe(block_expr, _)) = expr { - Some(block_expression_to_value(block_expr)) + if let ExprValue::Expression(ExpressionKind::Unsafe(UnsafeExpression { block, .. })) = expr + { + Some(block_expression_to_value(block)) } else { None } @@ -2277,7 +2278,7 @@ where let expr_value = unwrap_expr_value(interner, expr_value); let option_value = f(expr_value); - Ok(option(return_type, option_value, location.span)) + Ok(option(return_type, option_value, location)) } // fn resolve(self, in_function: Option) -> TypedExpr @@ -2765,8 +2766,7 @@ fn module_add_item( let parser = Parser::parse_top_level_items; let top_level_statements = parse(interpreter.elaborator, item, parser, "a top-level item")?; - let module_data = interpreter.elaborator.get_module(module_id); - interpreter.elaborate_in_module(module_id, module_data.location.file, |elaborator| { + interpreter.elaborate_in_module(module_id, |elaborator| { let previous_errors = elaborator .push_elaborate_reason_and_take_errors(ElaborateReason::AddingItemToModule, location); @@ -2955,12 +2955,12 @@ fn trait_def_as_trait_constraint( /// Creates a value that holds an `Option`. /// `option_type` must be a Type referencing the `Option` type. -pub(crate) fn option(option_type: Type, value: Option, span: Span) -> Value { +pub(crate) fn option(option_type: Type, value: Option, location: Location) -> Value { let t = extract_option_generic_type(option_type.clone()); let (is_some, value) = match value { Some(value) => (Value::Bool(true), value), - None => (Value::Bool(false), zeroed(t, span)), + None => (Value::Bool(false), zeroed(t, location)), }; let mut fields = HashMap::default(); @@ -3009,7 +3009,7 @@ fn derive_generators( _ => panic!("ICE: Should only have an array return type"), }; - let num_generators = size.evaluate_to_u32(location.span).map_err(|err| { + let num_generators = size.evaluate_to_u32(location).map_err(|err| { let err = Box::new(err); InterpreterError::UnknownArrayLength { length: *size, err, location } })?; diff --git a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs index 08a06ece464..0f0cd2f310f 100644 --- a/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs +++ b/compiler/noirc_frontend/src/hir/comptime/interpreter/builtin/builtin_helpers.rs @@ -509,9 +509,8 @@ where let (result, warnings) = parse_tokens(tokens, quoted, elaborator.interner, location, parser, rule)?; for warning in warnings { - let location = warning.location(); let warning: CompilationError = warning.into(); - elaborator.push_err(warning, location.file); + elaborator.push_err(warning); } Ok(result) } diff --git a/compiler/noirc_frontend/src/hir/comptime/tests.rs b/compiler/noirc_frontend/src/hir/comptime/tests.rs index 6d384860289..12de07f07bc 100644 --- a/compiler/noirc_frontend/src/hir/comptime/tests.rs +++ b/compiler/noirc_frontend/src/hir/comptime/tests.rs @@ -23,7 +23,7 @@ use crate::parse_program; /// The stdlib is not made available as a dependency. pub(crate) fn with_interpreter( src: &str, - f: impl FnOnce(&mut Interpreter, FuncId, &[(CompilationError, FileId)]) -> T, + f: impl FnOnce(&mut Interpreter, FuncId, &[CompilationError]) -> T, ) -> T { let file = FileId::default(); diff --git a/compiler/noirc_frontend/src/hir/comptime/value.rs b/compiler/noirc_frontend/src/hir/comptime/value.rs index df42913c335..aec457d1754 100644 --- a/compiler/noirc_frontend/src/hir/comptime/value.rs +++ b/compiler/noirc_frontend/src/hir/comptime/value.rs @@ -288,9 +288,8 @@ impl Value { return match parser.parse_result(Parser::parse_expression_or_error) { Ok((expr, warnings)) => { for warning in warnings { - let location = warning.location(); let warning: CompilationError = warning.into(); - elaborator.push_err(warning, location.file); + elaborator.push_err(warning); } Ok(expr) @@ -643,9 +642,8 @@ where match parser.parse_result(parsing_function) { Ok((expr, warnings)) => { for warning in warnings { - let location = warning.location(); let warning: CompilationError = warning.into(); - elaborator.push_err(warning, location.file); + elaborator.push_err(warning); } Ok(expr) } diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs index ea2ac1123d7..489b1e85a21 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_crate.rs @@ -22,8 +22,8 @@ use crate::node_interner::{ use crate::ast::{ ExpressionKind, Ident, ItemVisibility, LetStatement, Literal, NoirFunction, NoirStruct, - NoirTrait, NoirTypeAlias, Path, PathKind, PathSegment, UnresolvedGenerics, - UnresolvedTraitConstraint, UnresolvedType, UnsupportedNumericGenericType, + NoirTrait, NoirTypeAlias, Path, PathSegment, UnresolvedGenerics, UnresolvedTraitConstraint, + UnresolvedType, UnsupportedNumericGenericType, }; use crate::elaborator::FrontendOptions; @@ -190,7 +190,22 @@ pub enum CompilationError { TypeError(TypeCheckError), InterpreterError(InterpreterError), ComptimeError(ComptimeError), - DebugComptimeScopeNotFound(Vec), + DebugComptimeScopeNotFound(Vec, Location), +} + +impl CompilationError { + /// Returns the primary location where this error happened. + pub fn location(&self) -> Location { + match self { + CompilationError::ParseError(error) => error.location(), + CompilationError::DefinitionError(error) => error.location(), + CompilationError::ResolverError(error) => error.location(), + CompilationError::TypeError(error) => error.location(), + CompilationError::InterpreterError(error) => error.location(), + CompilationError::ComptimeError(error) => error.location(), + CompilationError::DebugComptimeScopeNotFound(_, location) => *location, + } + } } impl std::fmt::Display for CompilationError { @@ -201,7 +216,7 @@ impl std::fmt::Display for CompilationError { CompilationError::ResolverError(error) => write!(f, "{}", error), CompilationError::TypeError(error) => write!(f, "{}", error), CompilationError::InterpreterError(error) => write!(f, "{:?}", error), - CompilationError::DebugComptimeScopeNotFound(error) => write!(f, "{:?}", error), + CompilationError::DebugComptimeScopeNotFound(error, _) => write!(f, "{:?}", error), CompilationError::ComptimeError(error) => write!(f, "{:?}", error), } } @@ -216,15 +231,15 @@ impl<'a> From<&'a CompilationError> for CustomDiagnostic { CompilationError::TypeError(error) => error.into(), CompilationError::InterpreterError(error) => error.into(), CompilationError::ComptimeError(error) => error.into(), - CompilationError::DebugComptimeScopeNotFound(error) => { + CompilationError::DebugComptimeScopeNotFound(error, _) => { let msg = "multiple files found matching --debug-comptime path".into(); let secondary = error.iter().fold(String::new(), |mut output, path| { let _ = writeln!(output, " {}", path.display()); output }); - // NOTE: this span is empty as it is not expected to be displayed - let dummy_span = Span::default(); - CustomDiagnostic::simple_error(msg, secondary, dummy_span) + // NOTE: this location is empty as it is not expected to be displayed + let dummy_location = Location::dummy(); + CustomDiagnostic::simple_error(msg, secondary, dummy_location) } } } @@ -289,8 +304,8 @@ impl DefCollector { ast: SortedModule, root_file_id: FileId, options: FrontendOptions, - ) -> Vec<(CompilationError, FileId)> { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; + ) -> Vec { + let mut errors: Vec = vec![]; let crate_id = def_map.krate; // Recursively resolve the dependencies @@ -374,10 +389,7 @@ impl DefCollector { let has_path_resolution_error = !resolved_import.errors.is_empty(); for error in resolved_import.errors { - errors.push(( - DefCollectorErrorKind::PathResolutionError(error).into(), - file_id, - )); + errors.push(DefCollectorErrorKind::PathResolutionError(error).into()); } // Populate module namespaces according to the imports used @@ -388,14 +400,13 @@ impl DefCollector { resolved_import.namespace.iter_items() { if item_visibility < visibility { - errors.push(( + errors.push( DefCollectorErrorKind::CannotReexportItemWithLessVisibility { item_name: name.clone(), desired_visibility: visibility, } .into(), - file_id, - )); + ); } let visibility = visibility.min(item_visibility); @@ -452,15 +463,13 @@ impl DefCollector { first_def, second_def, }; - errors.push((err.into(), root_file_id)); + errors.push(err.into()); } } } Err(error) => { - let current_def_map = context.def_maps.get(&crate_id).unwrap(); - let file_id = current_def_map.file_id(collected_import.module_id); let error = DefCollectorErrorKind::PathResolutionError(error); - errors.push((error.into(), file_id)); + errors.push(error.into()); } } } @@ -468,7 +477,8 @@ impl DefCollector { let debug_comptime_in_file = options.debug_comptime_in_file.and_then(|file_suffix| { let file = context.file_manager.find_by_path_suffix(file_suffix); file.unwrap_or_else(|error| { - errors.push((CompilationError::DebugComptimeScopeNotFound(error), root_file_id)); + let location = Location::new(Span::empty(0), root_file_id); + errors.push(CompilationError::DebugComptimeScopeNotFound(error, location)); None }) }); @@ -492,7 +502,7 @@ impl DefCollector { fn check_unused_items( context: &Context, crate_id: CrateId, - errors: &mut Vec<(CompilationError, FileId)>, + errors: &mut Vec, ) { let unused_imports = context.usage_tracker.unused_items().iter(); let unused_imports = unused_imports.filter(|(module_id, _)| module_id.krate == crate_id); @@ -500,12 +510,10 @@ impl DefCollector { errors.extend(unused_imports.flat_map(|(_, usage_tracker)| { usage_tracker.iter().map(|(ident, unused_item)| { let ident = ident.clone(); - let file = ident.location().file; - let error = CompilationError::ResolverError(ResolverError::UnusedItem { + CompilationError::ResolverError(ResolverError::UnusedItem { ident, item: *unused_item, - }); - (error, file) + }) }) })); } @@ -543,11 +551,7 @@ fn inject_prelude( }) .collect(); - let path = Path { - segments: segments.clone(), - kind: crate::ast::PathKind::Plain, - location: Location::dummy(), - }; + let path = Path::plain(segments.clone(), Location::dummy()); if let Ok(resolved_import) = resolve_import( path, @@ -572,7 +576,7 @@ fn inject_prelude( ImportDirective { visibility: ItemVisibility::Private, module_id: crate_root, - path: Path { segments, kind: PathKind::Plain, location: Location::dummy() }, + path: Path::plain(segments, Location::dummy()), alias: None, is_prelude: true, }, diff --git a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs index 58abbc7761f..ec52347f882 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/dc_mod.rs @@ -58,9 +58,9 @@ pub fn collect_defs( module_id: LocalModuleId, crate_id: CrateId, context: &mut Context, -) -> Vec<(CompilationError, FileId)> { +) -> Vec { let mut collector = ModCollector { def_collector, file_id, module_id }; - let mut errors: Vec<(CompilationError, FileId)> = vec![]; + let mut errors: Vec = vec![]; // First resolve the module declarations for decl in ast.module_decls { @@ -143,7 +143,7 @@ impl<'a> ModCollector<'a> { context: &mut Context, globals: Vec<(Documented, ItemVisibility)>, crate_id: CrateId, - ) -> Vec<(CompilationError, fm::FileId)> { + ) -> Vec { let mut errors = vec![]; for (global, visibility) in globals { let (global, error) = collect_global( @@ -171,7 +171,7 @@ impl<'a> ModCollector<'a> { context: &mut Context, impls: Vec, krate: CrateId, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { let mut errors = Vec::new(); let module_id = ModuleId { krate, local_id: self.module_id }; @@ -194,7 +194,7 @@ impl<'a> ModCollector<'a> { context: &mut Context, impls: Vec, krate: CrateId, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { let mut errors = Vec::new(); for mut trait_impl in impls { @@ -212,16 +212,16 @@ impl<'a> ModCollector<'a> { for (_, func_id, noir_function) in &mut unresolved_functions.functions { if noir_function.def.attributes.is_test_function() { let error = DefCollectorErrorKind::TestOnAssociatedFunction { - span: noir_function.name_ident().span(), + location: noir_function.name_ident().location(), }; - errors.push((error.into(), self.file_id)); + errors.push(error.into()); } if noir_function.def.attributes.has_export() { let error = DefCollectorErrorKind::ExportOnAssociatedFunction { - span: noir_function.name_ident().span(), + location: noir_function.name_ident().location(), }; - errors.push((error.into(), self.file_id)); + errors.push(error.into()); } let location = noir_function.def.location; @@ -258,7 +258,7 @@ impl<'a> ModCollector<'a> { context: &mut Context, functions: Vec>, krate: CrateId, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { let mut unresolved_functions = UnresolvedFunctions { file_id: self.file_id, functions: Vec::new(), @@ -303,7 +303,7 @@ impl<'a> ModCollector<'a> { context: &mut Context, types: Vec>, krate: CrateId, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { let mut definition_errors = vec![]; for struct_definition in types { if let Some((id, the_struct)) = collect_struct( @@ -329,7 +329,7 @@ impl<'a> ModCollector<'a> { context: &mut Context, types: Vec>, krate: CrateId, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { let mut definition_errors = vec![]; for enum_definition in types { if let Some((id, the_enum)) = collect_enum( @@ -355,8 +355,8 @@ impl<'a> ModCollector<'a> { context: &mut Context, type_aliases: Vec>, krate: CrateId, - ) -> Vec<(CompilationError, FileId)> { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; + ) -> Vec { + let mut errors: Vec = vec![]; for type_alias in type_aliases { let doc_comments = type_alias.doc_comments; let type_alias = type_alias.item; @@ -375,7 +375,6 @@ impl<'a> ModCollector<'a> { &context.def_interner, &unresolved.type_alias_def.generics, &mut errors, - self.file_id, ); let type_alias_id = @@ -404,7 +403,7 @@ impl<'a> ModCollector<'a> { first_def, second_def, }; - errors.push((err.into(), self.file_id)); + errors.push(err.into()); } self.def_collector.items.type_aliases.insert(type_alias_id, unresolved); @@ -431,20 +430,20 @@ impl<'a> ModCollector<'a> { context: &mut Context, traits: Vec>, krate: CrateId, - ) -> Vec<(CompilationError, FileId)> { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; + ) -> Vec { + let mut errors: Vec = vec![]; for trait_definition in traits { let doc_comments = trait_definition.doc_comments; let trait_definition = trait_definition.item; let name = trait_definition.name.clone(); - let location = Location::new(trait_definition.name.span(), self.file_id); + let location = trait_definition.location; // Create the corresponding module for the trait namespace let trait_id = match self.push_child_module( context, &name, ItemVisibility::Public, - Location::new(name.span(), self.file_id), + name.location(), Vec::new(), Vec::new(), false, @@ -453,7 +452,7 @@ impl<'a> ModCollector<'a> { ) { Ok(module_id) => TraitId(ModuleId { krate, local_id: module_id.local_id }), Err(error) => { - errors.push((error.into(), self.file_id)); + errors.push(error.into()); continue; } }; @@ -482,7 +481,7 @@ impl<'a> ModCollector<'a> { first_def, second_def, }; - errors.push((error.into(), self.file_id)); + errors.push(error.into()); } // Add all functions that have a default implementation in the trait @@ -571,7 +570,7 @@ impl<'a> ModCollector<'a> { first_def, second_def, }; - errors.push((error.into(), self.file_id)); + errors.push(error.into()); } } } @@ -595,7 +594,7 @@ impl<'a> ModCollector<'a> { first_def, second_def, }; - errors.push((error.into(), self.file_id)); + errors.push(error.into()); } else { let type_variable_id = context.def_interner.next_type_variable_id(); let typ = self.resolve_associated_constant_type(typ, &mut errors); @@ -624,7 +623,7 @@ impl<'a> ModCollector<'a> { first_def, second_def, }; - errors.push((error.into(), self.file_id)); + errors.push(error.into()); } else { let type_variable_id = context.def_interner.next_type_variable_id(); associated_types.push(ResolvedGeneric { @@ -641,7 +640,6 @@ impl<'a> ModCollector<'a> { &context.def_interner, &trait_definition.generics, &mut errors, - self.file_id, ); let unresolved = UnresolvedTrait { @@ -682,8 +680,8 @@ impl<'a> ModCollector<'a> { parent_module_id: LocalModuleId, submodules: Vec>, file_id: FileId, - ) -> Vec<(CompilationError, FileId)> { - let mut errors: Vec<(CompilationError, FileId)> = vec![]; + ) -> Vec { + let mut errors: Vec = vec![]; for submodule in submodules { let mut doc_comments = submodule.doc_comments; let submodule = submodule.item; @@ -729,7 +727,7 @@ impl<'a> ModCollector<'a> { )); } Err(error) => { - errors.push((error.into(), file_id)); + errors.push(error.into()); } }; } @@ -747,16 +745,16 @@ impl<'a> ModCollector<'a> { crate_id: CrateId, parent_file_id: FileId, parent_module_id: LocalModuleId, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { let mut doc_comments = mod_decl.doc_comments; let mod_decl = mod_decl.item; - let mut errors: Vec<(CompilationError, FileId)> = vec![]; + let mut errors: Vec = vec![]; let child_file_id = match find_module(&context.file_manager, self.file_id, &mod_decl.ident) { Ok(child_file_id) => child_file_id, Err(err) => { - errors.push((err.into(), self.file_id)); + errors.push(err.into()); return errors; } }; @@ -766,15 +764,15 @@ impl<'a> ModCollector<'a> { if let Some(old_location) = context.visited_files.get(&child_file_id) { let error = DefCollectorErrorKind::ModuleAlreadyPartOfCrate { mod_name: mod_decl.ident.clone(), - span: location.span, + location, }; - errors.push((error.into(), location.file)); + errors.push(error.into()); let error = DefCollectorErrorKind::ModuleOriginallyDefined { mod_name: mod_decl.ident.clone(), - span: old_location.span, + location: *old_location, }; - errors.push((error.into(), old_location.file)); + errors.push(error.into()); return errors; } @@ -784,9 +782,7 @@ impl<'a> ModCollector<'a> { let (ast, parsing_errors) = context.parsed_file_results(child_file_id); let ast = ast.into_sorted(); - errors.extend( - parsing_errors.iter().map(|e| (e.clone().into(), child_file_id)).collect::>(), - ); + errors.extend(parsing_errors.iter().map(|e| e.clone().into()).collect::>()); // Add module into def collector and get a ModuleId match self.push_child_module( @@ -831,7 +827,7 @@ impl<'a> ModCollector<'a> { )); } Err(error) => { - errors.push((error.into(), child_file_id)); + errors.push(error.into()); } } errors @@ -870,15 +866,15 @@ impl<'a> ModCollector<'a> { fn resolve_associated_constant_type( &self, typ: &UnresolvedType, - errors: &mut Vec<(CompilationError, FileId)>, + errors: &mut Vec, ) -> Type { match &typ.typ { UnresolvedTypeData::FieldElement => Type::FieldElement, UnresolvedTypeData::Integer(sign, bits) => Type::Integer(*sign, *bits), _ => { - let span = typ.location.span; - let error = ResolverError::AssociatedConstantsMustBeNumeric { span }; - errors.push((error.into(), self.file_id)); + let error = + ResolverError::AssociatedConstantsMustBeNumeric { location: typ.location }; + errors.push(error.into()); Type::Error } } @@ -978,7 +974,7 @@ pub fn collect_function( function: &NoirFunction, module: ModuleId, doc_comments: Vec, - errors: &mut Vec<(CompilationError, FileId)>, + errors: &mut Vec, ) -> Option { if let Some(field) = function.attributes().get_field_attribute() { if !is_native_field(&field) { @@ -1015,13 +1011,12 @@ pub fn collect_function( // 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 file = second_def.location().file; let error = DefCollectorErrorKind::Duplicate { typ: DuplicateType::Function, first_def, second_def, }; - errors.push((error.into(), file)); + errors.push(error.into()); } Some(func_id) } @@ -1034,7 +1029,7 @@ pub fn collect_struct( struct_definition: Documented, module_id: LocalModuleId, krate: CrateId, - definition_errors: &mut Vec<(CompilationError, FileId)>, + definition_errors: &mut Vec, ) -> Option<(TypeId, UnresolvedStruct)> { let doc_comments = struct_definition.doc_comments; let struct_definition = struct_definition.item; @@ -1046,12 +1041,8 @@ pub fn collect_struct( 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, - ); + let resolved_generics = + Context::resolve_generics(interner, &unresolved.struct_def.generics, definition_errors); // Create the corresponding module for the struct namespace let location = Location::new(name.span(), file_id); @@ -1076,7 +1067,7 @@ pub fn collect_struct( interner.new_type(name, span, attributes, resolved_generics, krate, local_id, file_id) } Err(error) => { - definition_errors.push((error.into(), file_id)); + definition_errors.push(error.into()); return None; } }; @@ -1111,7 +1102,7 @@ pub fn collect_struct( first_def, second_def, }; - definition_errors.push((error.into(), file_id)); + definition_errors.push(error.into()); } if interner.is_in_lsp_mode() { @@ -1130,23 +1121,19 @@ pub fn collect_enum( file_id: FileId, module_id: LocalModuleId, krate: CrateId, - definition_errors: &mut Vec<(CompilationError, FileId)>, + definition_errors: &mut Vec, ) -> Option<(TypeId, UnresolvedEnum)> { let doc_comments = enum_def.doc_comments; let enum_def = enum_def.item; - check_duplicate_variant_names(&enum_def, file_id, definition_errors); + check_duplicate_variant_names(&enum_def, definition_errors); let name = enum_def.name.clone(); let unresolved = UnresolvedEnum { file_id, module_id, enum_def }; - let resolved_generics = Context::resolve_generics( - interner, - &unresolved.enum_def.generics, - definition_errors, - file_id, - ); + let resolved_generics = + Context::resolve_generics(interner, &unresolved.enum_def.generics, definition_errors); // Create the corresponding module for the enum namespace let location = Location::new(name.span(), file_id); @@ -1171,7 +1158,7 @@ pub fn collect_enum( interner.new_type(name, span, attributes, resolved_generics, krate, local_id, file_id) } Err(error) => { - definition_errors.push((error.into(), file_id)); + definition_errors.push(error.into()); return None; } }; @@ -1206,7 +1193,7 @@ pub fn collect_enum( first_def, second_def, }; - definition_errors.push((error.into(), file_id)); + definition_errors.push(error.into()); } if interner.is_in_lsp_mode() { @@ -1222,7 +1209,7 @@ pub fn collect_impl( r#impl: TypeImpl, file_id: FileId, module_id: ModuleId, - errors: &mut Vec<(CompilationError, FileId)>, + errors: &mut Vec, ) { let mut unresolved_functions = UnresolvedFunctions { file_id, functions: Vec::new(), trait_id: None, self_type: None }; @@ -1233,16 +1220,16 @@ pub fn collect_impl( if method.def.attributes.is_test_function() { let error = DefCollectorErrorKind::TestOnAssociatedFunction { - span: method.name_ident().span(), + location: method.name_ident().location(), }; - errors.push((error.into(), file_id)); + errors.push(error.into()); continue; } if method.def.attributes.has_export() { let error = DefCollectorErrorKind::ExportOnAssociatedFunction { - span: method.name_ident().span(), + location: method.name_ident().location(), }; - errors.push((error.into(), file_id)); + errors.push(error.into()); } let func_id = interner.push_empty_fn(); @@ -1399,7 +1386,7 @@ pub(crate) fn collect_global( file_id: FileId, module_id: LocalModuleId, crate_id: CrateId, -) -> (UnresolvedGlobal, Option<(CompilationError, FileId)>) { +) -> (UnresolvedGlobal, Option) { let doc_comments = global.doc_comments; let global = global.item; @@ -1433,7 +1420,7 @@ pub(crate) fn collect_global( let error = result.err().map(|(first_def, second_def)| { let err = DefCollectorErrorKind::Duplicate { typ: DuplicateType::Global, first_def, second_def }; - (err.into(), file_id) + err.into() }); interner.set_doc_comments(ReferenceId::Global(global_id), doc_comments); @@ -1444,7 +1431,7 @@ pub(crate) fn collect_global( fn check_duplicate_field_names( struct_definition: &NoirStruct, - definition_errors: &mut Vec<(CompilationError, FileId)>, + definition_errors: &mut Vec, ) { let mut seen_field_names = std::collections::HashSet::new(); for field in &struct_definition.fields { @@ -1460,14 +1447,13 @@ fn check_duplicate_field_names( first_def: previous_field_name.clone(), second_def: field_name.clone(), }; - definition_errors.push((error.into(), field_name.location().file)); + definition_errors.push(error.into()); } } fn check_duplicate_variant_names( enum_def: &NoirEnumeration, - file: FileId, - definition_errors: &mut Vec<(CompilationError, FileId)>, + definition_errors: &mut Vec, ) { let mut seen_variant_names = std::collections::HashSet::new(); for variant in &enum_def.variants { @@ -1483,7 +1469,7 @@ fn check_duplicate_variant_names( first_def: previous_variant_name.clone(), second_def: variant_name.clone(), }; - definition_errors.push((error.into(), file)); + definition_errors.push(error.into()); } } diff --git a/compiler/noirc_frontend/src/hir/def_collector/errors.rs b/compiler/noirc_frontend/src/hir/def_collector/errors.rs index 83776647fd0..daf30d93ad8 100644 --- a/compiler/noirc_frontend/src/hir/def_collector/errors.rs +++ b/compiler/noirc_frontend/src/hir/def_collector/errors.rs @@ -2,9 +2,8 @@ use crate::ast::{Ident, ItemVisibility, Path, UnsupportedNumericGenericType}; use crate::hir::resolution::import::PathResolutionError; use crate::hir::type_check::generics::TraitGenerics; -use noirc_errors::CustomDiagnostic as Diagnostic; use noirc_errors::FileDiagnostic; -use noirc_errors::Span; +use noirc_errors::{CustomDiagnostic as Diagnostic, Location}; use thiserror::Error; use std::fmt; @@ -38,23 +37,13 @@ pub enum DefCollectorErrorKind { #[error("Cannot re-export {item_name} because it has less visibility than this use statement")] CannotReexportItemWithLessVisibility { item_name: Ident, desired_visibility: ItemVisibility }, #[error("Non-struct type used in impl")] - NonStructTypeInImpl { span: Span }, + NonStructTypeInImpl { location: Location }, #[error("Cannot implement trait on a mutable reference type")] - MutableReferenceInTraitImpl { span: Span }, + MutableReferenceInTraitImpl { location: Location }, #[error("Impl for type `{typ}` overlaps with existing impl")] - OverlappingImpl { span: Span, typ: crate::Type }, - #[error("Previous impl defined here")] - OverlappingImplNote { span: Span }, + OverlappingImpl { typ: crate::Type, location: Location, prev_location: Location }, #[error("Cannot `impl` a type defined outside the current crate")] - ForeignImpl { span: Span, type_name: String }, - #[error("Mismatched number of generics in {location}")] - MismatchGenericCount { - actual_generic_count: usize, - expected_generic_count: usize, - location: &'static str, - origin: String, - span: Span, - }, + ForeignImpl { location: Location, type_name: String }, #[error("Method is not defined in trait")] MethodNotInTrait { trait_name: Ident, impl_method: Ident }, #[error("Only traits can be implemented")] @@ -62,36 +51,73 @@ pub enum DefCollectorErrorKind { #[error("Trait not found")] TraitNotFound { trait_path: Path }, #[error("Missing Trait method implementation")] - TraitMissingMethod { trait_name: Ident, method_name: Ident, trait_impl_span: Span }, + TraitMissingMethod { trait_name: Ident, method_name: Ident, trait_impl_location: Location }, #[error("Module is already part of the crate")] - ModuleAlreadyPartOfCrate { mod_name: Ident, span: Span }, + ModuleAlreadyPartOfCrate { mod_name: Ident, location: Location }, #[error("Module was originally declared here")] - ModuleOriginallyDefined { mod_name: Ident, span: Span }, + ModuleOriginallyDefined { mod_name: Ident, location: Location }, #[error( "Either the type or the trait must be from the same crate as the trait implementation" )] - TraitImplOrphaned { span: Span }, + TraitImplOrphaned { location: Location }, #[error("impl has stricter requirements than trait")] ImplIsStricterThanTrait { constraint_typ: crate::Type, constraint_name: String, constraint_generics: TraitGenerics, - constraint_span: Span, + constraint_location: Location, trait_method_name: String, - trait_method_span: Span, + trait_method_location: Location, }, #[error("{0}")] UnsupportedNumericGenericType(#[from] UnsupportedNumericGenericType), #[error("The `#[test]` attribute may only be used on a non-associated function")] - TestOnAssociatedFunction { span: Span }, + TestOnAssociatedFunction { location: Location }, #[error("The `#[export]` attribute may only be used on a non-associated function")] - ExportOnAssociatedFunction { span: Span }, + ExportOnAssociatedFunction { location: Location }, } impl DefCollectorErrorKind { pub fn into_file_diagnostic(&self, file: fm::FileId) -> FileDiagnostic { Diagnostic::from(self).in_file(file) } + + pub fn location(&self) -> Location { + match self { + DefCollectorErrorKind::Duplicate { first_def: ident, .. } + | DefCollectorErrorKind::UnresolvedModuleDecl { mod_name: ident, .. } + | DefCollectorErrorKind::CannotReexportItemWithLessVisibility { + item_name: ident, + .. + } + | DefCollectorErrorKind::MethodNotInTrait { impl_method: ident, .. } + | DefCollectorErrorKind::OverlappingModuleDecls { mod_name: ident, .. } => { + ident.location() + } + DefCollectorErrorKind::PathResolutionError(path_resolution_error) => { + path_resolution_error.location() + } + DefCollectorErrorKind::ImplIsStricterThanTrait { + trait_method_location: location, + .. + } + | DefCollectorErrorKind::TestOnAssociatedFunction { location } + | DefCollectorErrorKind::ExportOnAssociatedFunction { location } + | DefCollectorErrorKind::NonStructTypeInImpl { location } + | DefCollectorErrorKind::MutableReferenceInTraitImpl { location } + | DefCollectorErrorKind::OverlappingImpl { location, .. } + | DefCollectorErrorKind::ModuleAlreadyPartOfCrate { location, .. } + | DefCollectorErrorKind::ModuleOriginallyDefined { location, .. } + | DefCollectorErrorKind::TraitImplOrphaned { location } + | DefCollectorErrorKind::TraitMissingMethod { trait_impl_location: location, .. } + | DefCollectorErrorKind::ForeignImpl { location, .. } => *location, + DefCollectorErrorKind::NotATrait { not_a_trait_name: path } + | DefCollectorErrorKind::TraitNotFound { trait_path: path } => path.location, + DefCollectorErrorKind::UnsupportedNumericGenericType( + unsupported_numeric_generic_type, + ) => unsupported_numeric_generic_type.ident.location(), + } + } } impl<'a> From<&'a UnsupportedNumericGenericType> for Diagnostic { @@ -102,7 +128,7 @@ impl<'a> From<&'a UnsupportedNumericGenericType> for Diagnostic { Diagnostic::simple_error( format!("{name} has a type of {typ}. The only supported numeric generic types are `u1`, `u8`, `u16`, and `u32`."), "Unsupported numeric generic type".to_string(), - error.ident.0.span(), + error.ident.0.location(), ) } } @@ -135,35 +161,35 @@ impl<'a> From<&'a DefCollectorErrorKind> for Diagnostic { &typ, &first_def.0.contents ); { - let first_span = first_def.0.span(); - let second_span = second_def.0.span(); + let first_location = first_def.0.location(); + let second_location = second_def.0.location(); let mut diag = Diagnostic::simple_error( primary_message, format!("First {} found here", &typ), - first_span, + first_location, ); - diag.add_secondary(format!("Second {} found here", &typ), second_span); + diag.add_secondary(format!("Second {} found here", &typ), second_location); diag } } DefCollectorErrorKind::UnresolvedModuleDecl { mod_name, expected_path, alternative_path } => { - let span = mod_name.0.span(); + let location = mod_name.0.location(); let mod_name = &mod_name.0.contents; Diagnostic::simple_error( format!("No module `{mod_name}` at path `{expected_path}` or `{alternative_path}`"), String::new(), - span, + location, ) } DefCollectorErrorKind::OverlappingModuleDecls { mod_name, expected_path, alternative_path } => { - let span = mod_name.0.span(); + let location = mod_name.0.location(); let mod_name = &mod_name.0.contents; Diagnostic::simple_error( format!("Overlapping modules `{mod_name}` at path `{expected_path}` and `{alternative_path}`"), String::new(), - span, + location, ) } DefCollectorErrorKind::PathResolutionError(error) => error.into(), @@ -171,68 +197,48 @@ impl<'a> From<&'a DefCollectorErrorKind> for Diagnostic { Diagnostic::simple_error( format!("cannot re-export {item_name} because it has less visibility than this use statement"), format!("consider marking {item_name} as {desired_visibility}"), - item_name.span()) + item_name.location()) } - DefCollectorErrorKind::NonStructTypeInImpl { span } => Diagnostic::simple_error( + DefCollectorErrorKind::NonStructTypeInImpl { location } => Diagnostic::simple_error( "Non-struct type used in impl".into(), "Only struct types may have implementation methods".into(), - *span, + *location, ), - DefCollectorErrorKind::MutableReferenceInTraitImpl { span } => Diagnostic::simple_error( + DefCollectorErrorKind::MutableReferenceInTraitImpl { location } => Diagnostic::simple_error( "Trait impls are not allowed on mutable reference types".into(), "Try using a struct type here instead".into(), - *span, + *location, ), - DefCollectorErrorKind::OverlappingImpl { span, typ } => { - Diagnostic::simple_error( + DefCollectorErrorKind::OverlappingImpl { location, typ, prev_location } => { + let mut diagnostic = Diagnostic::simple_error( format!("Impl for type `{typ}` overlaps with existing impl"), "Overlapping impl".into(), - *span, - ) - } - DefCollectorErrorKind::OverlappingImplNote { span } => { - // This should be a note or part of the previous error eventually. - // This must be an error to appear next to the previous OverlappingImpl - // error since we sort warnings first. - Diagnostic::simple_error( - "Previous impl defined here".into(), - "Previous impl defined here".into(), - *span, - ) + *location, + ); + diagnostic.add_secondary("Previous impl defined here".into(), *prev_location); + diagnostic } - DefCollectorErrorKind::ForeignImpl { span, type_name } => Diagnostic::simple_error( + DefCollectorErrorKind::ForeignImpl { location, type_name } => Diagnostic::simple_error( "Cannot `impl` a type that was defined outside the current crate".into(), format!("{type_name} was defined outside the current crate"), - *span, + *location, ), DefCollectorErrorKind::TraitNotFound { trait_path } => Diagnostic::simple_error( format!("Trait {trait_path} not found"), "".to_string(), - trait_path.span(), + trait_path.location, ), - DefCollectorErrorKind::MismatchGenericCount { - actual_generic_count, - expected_generic_count, - location, - origin, - span, - } => { - let plural = if *expected_generic_count == 1 { "" } else { "s" }; - let primary_message = format!( - "`{origin}` expects {expected_generic_count} generic{plural}, but {location} has {actual_generic_count}"); - Diagnostic::simple_error(primary_message, "".to_string(), *span) - } DefCollectorErrorKind::MethodNotInTrait { trait_name, impl_method } => { let trait_name = &trait_name.0.contents; - let impl_method_span = impl_method.span(); + let impl_method_location = impl_method.location(); let impl_method_name = &impl_method.0.contents; let primary_message = format!("Method with name `{impl_method_name}` is not part of trait `{trait_name}`, therefore it can't be implemented"); - Diagnostic::simple_error(primary_message, "".to_owned(), impl_method_span) + Diagnostic::simple_error(primary_message, "".to_owned(), impl_method_location) } DefCollectorErrorKind::TraitMissingMethod { trait_name, method_name, - trait_impl_span, + trait_impl_location, } => { let trait_name = &trait_name.0.contents; let impl_method_name = &method_name.0.contents; @@ -242,53 +248,53 @@ impl<'a> From<&'a DefCollectorErrorKind> for Diagnostic { Diagnostic::simple_error( primary_message, format!("Please implement {impl_method_name} here"), - *trait_impl_span, + *trait_impl_location, ) } DefCollectorErrorKind::NotATrait { not_a_trait_name } => { - let span = not_a_trait_name.span(); + let location = not_a_trait_name.location; Diagnostic::simple_error( format!("{not_a_trait_name} is not a trait, therefore it can't be implemented"), String::new(), - span, + location, ) } - DefCollectorErrorKind::ModuleAlreadyPartOfCrate { mod_name, span } => { + DefCollectorErrorKind::ModuleAlreadyPartOfCrate { mod_name, location } => { let message = format!("Module '{mod_name}' is already part of the crate"); let secondary = String::new(); - Diagnostic::simple_error(message, secondary, *span) + Diagnostic::simple_error(message, secondary, *location) } - DefCollectorErrorKind::ModuleOriginallyDefined { mod_name, span } => { + DefCollectorErrorKind::ModuleOriginallyDefined { mod_name, location } => { let message = format!("Note: {mod_name} was originally declared here"); let secondary = String::new(); - Diagnostic::simple_error(message, secondary, *span) + Diagnostic::simple_error(message, secondary, *location) } - DefCollectorErrorKind::TraitImplOrphaned { span } => Diagnostic::simple_error( + DefCollectorErrorKind::TraitImplOrphaned { location } => Diagnostic::simple_error( "Orphaned trait implementation".into(), "Either the type or the trait must be from the same crate as the trait implementation".into(), - *span, + *location, ), - DefCollectorErrorKind::ImplIsStricterThanTrait { constraint_typ, constraint_name, constraint_generics, constraint_span, trait_method_name, trait_method_span } => { + DefCollectorErrorKind::ImplIsStricterThanTrait { constraint_typ, constraint_name, constraint_generics, constraint_location, trait_method_name, trait_method_location } => { let constraint = format!("{}{}", constraint_name, constraint_generics); let mut diag = Diagnostic::simple_error( "impl has stricter requirements than trait".to_string(), format!("impl has extra requirement `{constraint_typ}: {constraint}`"), - *constraint_span, + *constraint_location, ); - diag.add_secondary(format!("definition of `{trait_method_name}` from trait"), *trait_method_span); + diag.add_secondary(format!("definition of `{trait_method_name}` from trait"), *trait_method_location); diag } DefCollectorErrorKind::UnsupportedNumericGenericType(err) => err.into(), - DefCollectorErrorKind::TestOnAssociatedFunction { span } => Diagnostic::simple_error( + DefCollectorErrorKind::TestOnAssociatedFunction { location } => Diagnostic::simple_error( "The `#[test]` attribute is disallowed on `impl` methods".into(), String::new(), - *span, + *location, ), - DefCollectorErrorKind::ExportOnAssociatedFunction { span } => Diagnostic::simple_error( + DefCollectorErrorKind::ExportOnAssociatedFunction { location } => Diagnostic::simple_error( "The `#[export]` attribute is disallowed on `impl` methods".into(), String::new(), - *span, + *location, ), } } diff --git a/compiler/noirc_frontend/src/hir/def_map/mod.rs b/compiler/noirc_frontend/src/hir/def_map/mod.rs index 0dff7982489..4ccacc8c3b5 100644 --- a/compiler/noirc_frontend/src/hir/def_map/mod.rs +++ b/compiler/noirc_frontend/src/hir/def_map/mod.rs @@ -79,13 +79,13 @@ impl CrateDefMap { crate_id: CrateId, context: &mut Context, options: FrontendOptions, - ) -> Vec<(CompilationError, FileId)> { + ) -> Vec { // Check if this Crate has already been compiled // XXX: There is probably a better alternative for this. // Without this check, the compiler will panic as it does not // expect the same crate to be processed twice. It would not // make the implementation wrong, if the same crate was processed twice, it just makes it slow. - let mut errors: Vec<(CompilationError, FileId)> = vec![]; + let mut errors: Vec = vec![]; if context.def_map(&crate_id).is_some() { return errors; } @@ -123,9 +123,7 @@ impl CrateDefMap { options, )); - errors.extend( - parsing_errors.iter().map(|e| (e.clone().into(), root_file_id)).collect::>(), - ); + errors.extend(parsing_errors.iter().map(|e| e.clone().into()).collect::>()); errors } diff --git a/compiler/noirc_frontend/src/hir/mod.rs b/compiler/noirc_frontend/src/hir/mod.rs index 4e222ab2472..1c4e1f6e65c 100644 --- a/compiler/noirc_frontend/src/hir/mod.rs +++ b/compiler/noirc_frontend/src/hir/mod.rs @@ -232,15 +232,14 @@ impl Context<'_, '_> { pub(crate) fn resolve_generics( interner: &NodeInterner, generics: &UnresolvedGenerics, - errors: &mut Vec<(CompilationError, FileId)>, - file_id: FileId, + errors: &mut Vec, ) -> Generics { vecmap(generics, |generic| { // Map the generic to a fresh type variable let id = interner.next_type_variable_id(); let type_var_kind = generic.kind().unwrap_or_else(|err| { - errors.push((err.into(), file_id)); + errors.push(err.into()); // When there's an error, unify with any other kinds Kind::Any }); diff --git a/compiler/noirc_frontend/src/hir/resolution/errors.rs b/compiler/noirc_frontend/src/hir/resolution/errors.rs index 1e6237788c7..ea77d4dfdae 100644 --- a/compiler/noirc_frontend/src/hir/resolution/errors.rs +++ b/compiler/noirc_frontend/src/hir/resolution/errors.rs @@ -27,65 +27,65 @@ pub enum PubPosition { #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum ResolverError { #[error("Duplicate definition")] - DuplicateDefinition { name: String, first_span: Span, second_span: Span }, + DuplicateDefinition { name: String, first_location: Location, second_location: Location }, #[error("Unused variable")] UnusedVariable { ident: Ident }, #[error("Unused {}", item.item_type())] UnusedItem { ident: Ident, item: UnusedItem }, #[error("Unconditional recursion")] - UnconditionalRecursion { name: String, span: Span }, + UnconditionalRecursion { name: String, location: Location }, #[error("Could not find variable in this scope")] - VariableNotDeclared { name: String, span: Span }, + VariableNotDeclared { name: String, location: Location }, #[error("path is not an identifier")] - PathIsNotIdent { span: Span }, + PathIsNotIdent { location: Location }, #[error("could not resolve path")] PathResolutionError(#[from] PathResolutionError), #[error("Expected")] - Expected { span: Span, expected: &'static str, got: &'static str }, + Expected { location: Location, expected: &'static str, got: &'static str }, #[error("Duplicate field in constructor")] DuplicateField { field: Ident }, #[error("No such field in struct")] NoSuchField { field: Ident, struct_definition: Ident }, #[error("Missing fields from struct")] - MissingFields { span: Span, missing_fields: Vec, struct_definition: Ident }, + MissingFields { location: Location, missing_fields: Vec, struct_definition: Ident }, #[error("Unneeded 'mut', pattern is already marked as mutable")] - UnnecessaryMut { first_mut: Span, second_mut: Span }, + UnnecessaryMut { first_mut: Location, second_mut: Location }, #[error("Unneeded 'pub', function is not the main method")] UnnecessaryPub { ident: Ident, position: PubPosition }, #[error("Required 'pub', main function must return public value")] NecessaryPub { ident: Ident }, #[error("Missing expression for declared constant")] - MissingRhsExpr { name: String, span: Span }, + MissingRhsExpr { name: String, location: Location }, #[error("Expression invalid in an array length context")] - InvalidArrayLengthExpr { span: Span }, + InvalidArrayLengthExpr { location: Location }, #[error("Integer too large to be evaluated in an array length context")] - IntegerTooLarge { span: Span }, + IntegerTooLarge { location: Location }, #[error("No global or generic type parameter found with the given name")] NoSuchNumericTypeVariable { path: crate::ast::Path }, #[error("Closures cannot capture mutable variables")] - CapturedMutableVariable { span: Span }, + CapturedMutableVariable { location: Location }, #[error("Test functions are not allowed to have any parameters")] - TestFunctionHasParameters { span: Span }, + TestFunctionHasParameters { location: Location }, #[error("Only struct types can be used in constructor expressions")] - NonStructUsedInConstructor { typ: String, span: Span }, + NonStructUsedInConstructor { typ: String, location: Location }, #[error("Only struct types can have generics")] - NonStructWithGenerics { span: Span }, + NonStructWithGenerics { location: Location }, #[error("Cannot apply generics on Self type")] - GenericsOnSelfType { span: Span }, + GenericsOnSelfType { location: Location }, #[error("Cannot apply generics on an associated type")] - GenericsOnAssociatedType { span: Span }, + GenericsOnAssociatedType { location: Location }, #[error("{0}")] ParserError(Box), #[error("Cannot create a mutable reference to {variable}, it was declared to be immutable")] - MutableReferenceToImmutableVariable { variable: String, span: Span }, + MutableReferenceToImmutableVariable { variable: String, location: Location }, #[error("Mutable references to array indices are unsupported")] - MutableReferenceToArrayElement { span: Span }, + MutableReferenceToArrayElement { location: Location }, #[error("Closure environment must be a tuple or unit type")] - InvalidClosureEnvironment { typ: Type, span: Span }, + InvalidClosureEnvironment { typ: Type, location: Location }, #[error("Nested slices, i.e. slices within an array or slice, are not supported")] - NestedSlices { span: Span }, + NestedSlices { location: Location }, #[error("#[abi(tag)] attribute is only allowed in contracts")] - AbiAttributeOutsideContract { span: Span }, + AbiAttributeOutsideContract { location: Location }, #[error("Usage of the `#[foreign]` or `#[builtin]` function attributes are not allowed outside of the Noir standard library")] LowLevelFunctionOutsideOfStdlib { ident: Ident }, #[error( @@ -93,105 +93,189 @@ pub enum ResolverError { )] OracleMarkedAsConstrained { ident: Ident }, #[error("Oracle functions cannot be called directly from constrained functions")] - UnconstrainedOracleReturnToConstrained { span: Span }, + UnconstrainedOracleReturnToConstrained { location: Location }, #[error("Dependency cycle found, '{item}' recursively depends on itself: {cycle} ")] - DependencyCycle { span: Span, item: String, cycle: String }, + DependencyCycle { location: Location, item: String, cycle: String }, #[error("break/continue are only allowed in unconstrained functions")] - JumpInConstrainedFn { is_break: bool, span: Span }, + JumpInConstrainedFn { is_break: bool, location: Location }, #[error("`loop` is only allowed in unconstrained functions")] - LoopInConstrainedFn { span: Span }, + LoopInConstrainedFn { location: Location }, #[error("`loop` must have at least one `break` in it")] - LoopWithoutBreak { span: Span }, + LoopWithoutBreak { location: Location }, #[error("`while` is only allowed in unconstrained functions")] - WhileInConstrainedFn { span: Span }, + WhileInConstrainedFn { location: Location }, #[error("break/continue are only allowed within loops")] - JumpOutsideLoop { is_break: bool, span: Span }, + JumpOutsideLoop { is_break: bool, location: Location }, #[error("Only `comptime` globals can be mutable")] - MutableGlobal { span: Span }, + MutableGlobal { location: Location }, #[error("Globals must have a specified type")] - UnspecifiedGlobalType { span: Span, expected_type: Type }, + UnspecifiedGlobalType { location: Location, expected_type: Type }, #[error("Global failed to evaluate")] - UnevaluatedGlobalType { span: Span }, + UnevaluatedGlobalType { location: Location }, #[error("Globals used in a type position must be non-negative")] - NegativeGlobalType { span: Span, global_value: Value }, + NegativeGlobalType { location: Location, global_value: Value }, #[error("Globals used in a type position must be integers")] - NonIntegralGlobalType { span: Span, global_value: Value }, + NonIntegralGlobalType { location: Location, global_value: Value }, #[error("Global value `{global_value}` is larger than its kind's maximum value")] - GlobalLargerThanKind { span: Span, global_value: FieldElement, kind: Kind }, + GlobalLargerThanKind { location: Location, global_value: FieldElement, kind: Kind }, #[error("Self-referential types are not supported")] - SelfReferentialType { span: Span }, + SelfReferentialType { location: Location }, #[error("#[no_predicates] attribute is only allowed on constrained functions")] NoPredicatesAttributeOnUnconstrained { ident: Ident }, #[error("#[fold] attribute is only allowed on constrained functions")] FoldAttributeOnUnconstrained { ident: Ident }, #[error("expected type, found numeric generic parameter")] - NumericGenericUsedForType { name: String, span: Span }, + NumericGenericUsedForType { name: String, location: Location }, #[error("Invalid array length construction")] ArrayLengthInterpreter { error: InterpreterError }, #[error("The unquote operator '$' can only be used within a quote expression")] - UnquoteUsedOutsideQuote { span: Span }, + UnquoteUsedOutsideQuote { location: Location }, #[error("\"as trait path\" not yet implemented")] - AsTraitPathNotYetImplemented { span: Span }, + AsTraitPathNotYetImplemented { location: Location }, #[error("Invalid syntax in macro call")] - InvalidSyntaxInMacroCall { span: Span }, + InvalidSyntaxInMacroCall { location: Location }, #[error("Macros must be comptime functions")] - MacroIsNotComptime { span: Span }, + MacroIsNotComptime { location: Location }, #[error("Annotation name must refer to a comptime function")] - NonFunctionInAnnotation { span: Span }, + NonFunctionInAnnotation { location: Location }, #[error("Type `{typ}` was inserted into the generics list from a macro, but is not a generic")] - MacroResultInGenericsListNotAGeneric { span: Span, typ: Type }, + MacroResultInGenericsListNotAGeneric { location: Location, typ: Type }, #[error("Named type arguments aren't allowed in a {item_kind}")] - NamedTypeArgs { span: Span, item_kind: &'static str }, + NamedTypeArgs { location: Location, item_kind: &'static str }, #[error("Associated constants may only be a field or integer type")] - AssociatedConstantsMustBeNumeric { span: Span }, + AssociatedConstantsMustBeNumeric { location: Location }, #[error("Computing `{lhs} {op} {rhs}` failed with error {err}")] BinaryOpError { lhs: FieldElement, op: crate::BinaryTypeOperator, rhs: FieldElement, err: Box, - span: Span, + location: Location, }, #[error("`quote` cannot be used in runtime code")] - QuoteInRuntimeCode { span: Span }, + QuoteInRuntimeCode { location: Location }, #[error("Comptime-only type `{typ}` cannot be used in runtime code")] - ComptimeTypeInRuntimeCode { typ: String, span: Span }, + ComptimeTypeInRuntimeCode { typ: String, location: Location }, #[error("Comptime variable `{name}` cannot be mutated in a non-comptime context")] - MutatingComptimeInNonComptimeContext { name: String, span: Span }, + MutatingComptimeInNonComptimeContext { name: String, location: Location }, #[error("Failed to parse `{statement}` as an expression")] - InvalidInternedStatementInExpr { statement: String, span: Span }, + InvalidInternedStatementInExpr { statement: String, location: Location }, #[error("{0}")] UnsupportedNumericGenericType(#[from] UnsupportedNumericGenericType), #[error("Type `{typ}` is more private than item `{item}`")] - TypeIsMorePrivateThenItem { typ: String, item: String, span: Span }, + TypeIsMorePrivateThenItem { typ: String, item: String, location: Location }, #[error("Unable to parse attribute `{attribute}`")] - UnableToParseAttribute { attribute: String, span: Span }, + UnableToParseAttribute { attribute: String, location: Location }, #[error("Attribute function `{function}` is not a path")] - AttributeFunctionIsNotAPath { function: String, span: Span }, + AttributeFunctionIsNotAPath { function: String, location: Location }, #[error("Attribute function `{name}` is not in scope")] - AttributeFunctionNotInScope { name: String, span: Span }, + AttributeFunctionNotInScope { name: String, location: Location }, #[error("The trait `{missing_trait}` is not implemented for `{type_missing_trait}")] TraitNotImplemented { impl_trait: String, missing_trait: String, type_missing_trait: String, - span: Span, + location: Location, missing_trait_location: Location, }, #[error("`loop` statements are not yet implemented")] - LoopNotYetSupported { span: Span }, + LoopNotYetSupported { location: Location }, #[error("Expected a trait but found {found}")] - ExpectedTrait { found: String, span: Span }, + ExpectedTrait { found: String, location: Location }, #[error("Invalid syntax in match pattern")] - InvalidSyntaxInPattern { span: Span }, + InvalidSyntaxInPattern { location: Location }, #[error("Variable '{existing}' was already defined in the same match pattern")] - VariableAlreadyDefinedInPattern { existing: Ident, new_span: Span }, + VariableAlreadyDefinedInPattern { existing: Ident, new_location: Location }, } impl ResolverError { pub fn into_file_diagnostic(&self, file: fm::FileId) -> FileDiagnostic { Diagnostic::from(self).in_file(file) } + + pub fn location(&self) -> Location { + match self { + ResolverError::DuplicateDefinition { first_location: location, .. } + | ResolverError::UnconditionalRecursion { location, .. } + | ResolverError::PathIsNotIdent { location } + | ResolverError::Expected { location, .. } + | ResolverError::VariableNotDeclared { location, .. } + | ResolverError::MissingFields { location, .. } + | ResolverError::UnnecessaryMut { second_mut: location, .. } + | ResolverError::TypeIsMorePrivateThenItem { location, .. } + | ResolverError::UnableToParseAttribute { location, .. } + | ResolverError::AttributeFunctionIsNotAPath { location, .. } + | ResolverError::AttributeFunctionNotInScope { location, .. } + | ResolverError::TraitNotImplemented { location, .. } + | ResolverError::LoopNotYetSupported { location } + | ResolverError::ExpectedTrait { location, .. } + | ResolverError::MissingRhsExpr { location, .. } + | ResolverError::InvalidArrayLengthExpr { location } + | ResolverError::IntegerTooLarge { location } + | ResolverError::CapturedMutableVariable { location } + | ResolverError::TestFunctionHasParameters { location } + | ResolverError::NonStructUsedInConstructor { location, .. } + | ResolverError::NonStructWithGenerics { location } + | ResolverError::GenericsOnSelfType { location } + | ResolverError::GenericsOnAssociatedType { location } + | ResolverError::MutableReferenceToImmutableVariable { location, .. } + | ResolverError::MutableReferenceToArrayElement { location } + | ResolverError::InvalidClosureEnvironment { location, .. } + | ResolverError::NestedSlices { location } + | ResolverError::AbiAttributeOutsideContract { location } + | ResolverError::UnconstrainedOracleReturnToConstrained { location } + | ResolverError::DependencyCycle { location, .. } + | ResolverError::JumpInConstrainedFn { location, .. } + | ResolverError::LoopInConstrainedFn { location } + | ResolverError::LoopWithoutBreak { location } + | ResolverError::WhileInConstrainedFn { location } + | ResolverError::JumpOutsideLoop { location, .. } + | ResolverError::MutableGlobal { location } + | ResolverError::UnspecifiedGlobalType { location, .. } + | ResolverError::UnevaluatedGlobalType { location } + | ResolverError::NegativeGlobalType { location, .. } + | ResolverError::NonIntegralGlobalType { location, .. } + | ResolverError::GlobalLargerThanKind { location, .. } + | ResolverError::SelfReferentialType { location } + | ResolverError::NumericGenericUsedForType { location, .. } + | ResolverError::UnquoteUsedOutsideQuote { location } + | ResolverError::AsTraitPathNotYetImplemented { location } + | ResolverError::InvalidSyntaxInMacroCall { location } + | ResolverError::MacroIsNotComptime { location } + | ResolverError::NonFunctionInAnnotation { location } + | ResolverError::MacroResultInGenericsListNotAGeneric { location, .. } + | ResolverError::NamedTypeArgs { location, .. } + | ResolverError::AssociatedConstantsMustBeNumeric { location } + | ResolverError::BinaryOpError { location, .. } + | ResolverError::QuoteInRuntimeCode { location } + | ResolverError::ComptimeTypeInRuntimeCode { location, .. } + | ResolverError::MutatingComptimeInNonComptimeContext { location, .. } + | ResolverError::InvalidInternedStatementInExpr { location, .. } + | ResolverError::InvalidSyntaxInPattern { location } + | ResolverError::VariableAlreadyDefinedInPattern { new_location: location, .. } => { + *location + } + ResolverError::UnusedVariable { ident } + | ResolverError::UnusedItem { ident, .. } + | ResolverError::DuplicateField { field: ident } + | ResolverError::NoSuchField { field: ident, .. } + | ResolverError::UnnecessaryPub { ident, .. } + | ResolverError::NecessaryPub { ident } + | ResolverError::LowLevelFunctionOutsideOfStdlib { ident } + | ResolverError::OracleMarkedAsConstrained { ident } + | ResolverError::NoPredicatesAttributeOnUnconstrained { ident } + | ResolverError::FoldAttributeOnUnconstrained { ident } => ident.location(), + ResolverError::ArrayLengthInterpreter { error } => error.location(), + ResolverError::PathResolutionError(path_resolution_error) => { + path_resolution_error.location() + } + ResolverError::NoSuchNumericTypeVariable { path } => path.location, + ResolverError::ParserError(parser_error) => parser_error.location(), + ResolverError::UnsupportedNumericGenericType(unsupported_numeric_generic_type) => { + unsupported_numeric_generic_type.ident.location() + } + } + } } impl<'a> From<&'a ResolverError> for Diagnostic { @@ -200,13 +284,13 @@ impl<'a> From<&'a ResolverError> for Diagnostic { /// soundness of the generated program fn from(error: &'a ResolverError) -> Diagnostic { match error { - ResolverError::DuplicateDefinition { name, first_span, second_span } => { + ResolverError::DuplicateDefinition { name, first_location, second_location} => { let mut diag = Diagnostic::simple_error( format!("duplicate definitions of {name} found"), "first definition found here".to_string(), - *first_span, + *first_location, ); - diag.add_secondary("second definition found here".to_string(), *second_span); + diag.add_secondary("second definition found here".to_string(), *second_location); diag } ResolverError::UnusedVariable { ident } => { @@ -215,7 +299,7 @@ impl<'a> From<&'a ResolverError> for Diagnostic { let mut diagnostic = Diagnostic::simple_warning( format!("unused variable {name}"), "unused variable ".to_string(), - ident.span(), + ident.location(), ); diagnostic.unnecessary = true; diagnostic @@ -229,64 +313,64 @@ impl<'a> From<&'a ResolverError> for Diagnostic { Diagnostic::simple_warning( format!("{item_type} `{name}` is never constructed"), format!("{item_type} is never constructed"), - ident.span(), + ident.location(), ) } else { Diagnostic::simple_warning( format!("unused {item_type} {name}"), format!("unused {item_type}"), - ident.span(), + ident.location(), ) }; diagnostic.unnecessary = true; diagnostic } - ResolverError::UnconditionalRecursion { name, span} => { + ResolverError::UnconditionalRecursion { name, location} => { Diagnostic::simple_warning( format!("function `{name}` cannot return without recursing"), "function cannot return without recursing".to_string(), - *span, + *location, ) } - ResolverError::VariableNotDeclared { name, span } => { + ResolverError::VariableNotDeclared { name, location } => { if name == "_" { Diagnostic::simple_error( "in expressions, `_` can only be used on the left-hand side of an assignment".to_string(), "`_` not allowed here".to_string(), - *span, + *location, ) } else { Diagnostic::simple_error( format!("cannot find `{name}` in this scope"), "not found in this scope".to_string(), - *span, + *location, ) } }, - ResolverError::PathIsNotIdent { span } => Diagnostic::simple_error( + ResolverError::PathIsNotIdent { location } => Diagnostic::simple_error( "cannot use path as an identifier".to_string(), String::new(), - *span, + *location, ), ResolverError::PathResolutionError(error) => error.into(), - ResolverError::Expected { span, expected, got } => Diagnostic::simple_error( + ResolverError::Expected { location, expected, got } => Diagnostic::simple_error( format!("expected {expected} got {got}"), String::new(), - *span, + *location, ), ResolverError::DuplicateField { field } => Diagnostic::simple_error( format!("duplicate field {field}"), String::new(), - field.span(), + field.location(), ), ResolverError::NoSuchField { field, struct_definition } => { Diagnostic::simple_error( format!("no such field {field} defined in struct {struct_definition}"), String::new(), - field.span(), + field.location(), ) } - ResolverError::MissingFields { span, missing_fields, struct_definition } => { + ResolverError::MissingFields { location, missing_fields, struct_definition } => { let plural = if missing_fields.len() != 1 { "s" } else { "" }; let remaining_fields_names = match &missing_fields[..] { [field1] => field1.clone(), @@ -305,7 +389,7 @@ impl<'a> From<&'a ResolverError> for Diagnostic { Diagnostic::simple_error( format!("missing field{plural} {remaining_fields_names} in struct {struct_definition}"), String::new(), - *span, + *location, ) } ResolverError::UnnecessaryMut { first_mut, second_mut } => { @@ -326,7 +410,7 @@ impl<'a> From<&'a ResolverError> for Diagnostic { let mut diag = Diagnostic::simple_warning( format!("unnecessary pub keyword on {position} for function {name}"), format!("unnecessary pub {position}"), - ident.0.span(), + ident.0.location(), ); diag.add_note("The `pub` keyword only has effects on arguments to the entry-point function of a program. Thus, adding it to other function parameters can be deceiving and should be removed".to_owned()); @@ -338,192 +422,192 @@ impl<'a> From<&'a ResolverError> for Diagnostic { let mut diag = Diagnostic::simple_error( format!("missing pub keyword on return type of function {name}"), "missing pub on return type".to_string(), - ident.0.span(), + ident.0.location(), ); diag.add_note("The `pub` keyword is mandatory for the entry-point function return type because the verifier cannot retrieve private witness and thus the function will not be able to return a 'priv' value".to_owned()); diag } - ResolverError::MissingRhsExpr { name, span } => Diagnostic::simple_error( + ResolverError::MissingRhsExpr { name, location } => Diagnostic::simple_error( format!( "no expression specifying the value stored by the constant variable {name}" ), "expected expression to be stored for let statement".to_string(), - *span, + *location, ), - ResolverError::InvalidArrayLengthExpr { span } => Diagnostic::simple_error( + ResolverError::InvalidArrayLengthExpr { location } => Diagnostic::simple_error( "Expression invalid in an array-length context".into(), "Array-length expressions can only have simple integer operations and any variables used must be global constants".into(), - *span, + *location, ), - ResolverError::IntegerTooLarge { span } => Diagnostic::simple_error( + ResolverError::IntegerTooLarge { location } => Diagnostic::simple_error( "Integer too large to be evaluated to an array-length".into(), "Array-lengths may be a maximum size of usize::MAX, including intermediate calculations".into(), - *span, + *location, ), ResolverError::NoSuchNumericTypeVariable { path } => Diagnostic::simple_error( format!("Cannot find a global or generic type parameter named `{path}`"), "Only globals or generic type parameters are allowed to be used as an array type's length".to_string(), - path.span(), + path.location, ), - ResolverError::CapturedMutableVariable { span } => Diagnostic::simple_error( + ResolverError::CapturedMutableVariable { location } => Diagnostic::simple_error( "Closures cannot capture mutable variables".into(), "Mutable variable".into(), - *span, + *location, ), - ResolverError::TestFunctionHasParameters { span } => Diagnostic::simple_error( + ResolverError::TestFunctionHasParameters { location } => Diagnostic::simple_error( "Test functions cannot have any parameters".into(), "Try removing the parameters or moving the test into a wrapper function".into(), - *span, + *location, ), - ResolverError::NonStructUsedInConstructor { typ, span } => Diagnostic::simple_error( + ResolverError::NonStructUsedInConstructor { typ, location } => Diagnostic::simple_error( "Only struct types can be used in constructor expressions".into(), format!("{typ} has no fields to construct it with"), - *span, + *location, ), - ResolverError::NonStructWithGenerics { span } => Diagnostic::simple_error( + ResolverError::NonStructWithGenerics { location } => Diagnostic::simple_error( "Only struct types can have generic arguments".into(), "Try removing the generic arguments".into(), - *span, + *location, ), - ResolverError::GenericsOnSelfType { span } => Diagnostic::simple_error( + ResolverError::GenericsOnSelfType { location } => Diagnostic::simple_error( "Cannot apply generics to Self type".into(), "Use an explicit type name or apply the generics at the start of the impl instead".into(), - *span, + *location, ), - ResolverError::GenericsOnAssociatedType { span } => Diagnostic::simple_error( + ResolverError::GenericsOnAssociatedType { location } => Diagnostic::simple_error( "Generic Associated Types (GATs) are currently unsupported in Noir".into(), "Cannot apply generics to an associated type".into(), - *span, + *location, ), ResolverError::ParserError(error) => error.as_ref().into(), - ResolverError::MutableReferenceToImmutableVariable { variable, span } => { - Diagnostic::simple_error(format!("Cannot mutably reference the immutable variable {variable}"), format!("{variable} is immutable"), *span) + ResolverError::MutableReferenceToImmutableVariable { variable, location } => { + Diagnostic::simple_error(format!("Cannot mutably reference the immutable variable {variable}"), format!("{variable} is immutable"), *location) }, - ResolverError::MutableReferenceToArrayElement { span } => { - Diagnostic::simple_error("Mutable references to array elements are currently unsupported".into(), "Try storing the element in a fresh variable first".into(), *span) + ResolverError::MutableReferenceToArrayElement { location } => { + Diagnostic::simple_error("Mutable references to array elements are currently unsupported".into(), "Try storing the element in a fresh variable first".into(), *location) }, - ResolverError::InvalidClosureEnvironment { span, typ } => Diagnostic::simple_error( + ResolverError::InvalidClosureEnvironment { location, typ } => Diagnostic::simple_error( 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( + "Closure environment must be a tuple or unit type".to_string(), *location), + ResolverError::NestedSlices { location } => Diagnostic::simple_error( "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, + *location, ), - ResolverError::AbiAttributeOutsideContract { span } => { + ResolverError::AbiAttributeOutsideContract { location } => { Diagnostic::simple_error( "#[abi(tag)] attributes can only be used in contracts".to_string(), "misplaced #[abi(tag)] attribute".to_string(), - *span, + *location, ) }, ResolverError::LowLevelFunctionOutsideOfStdlib { ident } => Diagnostic::simple_error( "Definition of low-level function outside of standard library".into(), "Usage of the `#[foreign]` or `#[builtin]` function attributes are not allowed outside of the Noir standard library".into(), - ident.span(), + ident.location(), ), ResolverError::OracleMarkedAsConstrained { ident } => Diagnostic::simple_error( error.to_string(), "Oracle functions must have the `unconstrained` keyword applied".into(), - ident.span(), + ident.location(), ), - ResolverError::UnconstrainedOracleReturnToConstrained { span } => Diagnostic::simple_error( + ResolverError::UnconstrainedOracleReturnToConstrained { location } => Diagnostic::simple_error( error.to_string(), "This oracle call must be wrapped in a call to another unconstrained function before being returned to a constrained runtime".into(), - *span, + *location, ), - ResolverError::DependencyCycle { span, item, cycle } => { + ResolverError::DependencyCycle { location, item, cycle } => { Diagnostic::simple_error( "Dependency cycle found".into(), format!("'{item}' recursively depends on itself: {cycle}"), - *span, + *location, ) }, - ResolverError::JumpInConstrainedFn { is_break, span } => { + ResolverError::JumpInConstrainedFn { is_break, location } => { let item = if *is_break { "break" } else { "continue" }; Diagnostic::simple_error( format!("{item} is only allowed in unconstrained functions"), "Constrained code must always have a known number of loop iterations".into(), - *span, + *location, ) }, - ResolverError::LoopInConstrainedFn { span } => { + ResolverError::LoopInConstrainedFn { location } => { Diagnostic::simple_error( "`loop` is only allowed in unconstrained functions".into(), "Constrained code must always have a known number of loop iterations".into(), - *span, + *location, ) }, - ResolverError::LoopWithoutBreak { span } => { + ResolverError::LoopWithoutBreak { location } => { Diagnostic::simple_error( "`loop` must have at least one `break` in it".into(), "Infinite loops are disallowed".into(), - *span, + *location, ) }, - ResolverError::WhileInConstrainedFn { span } => { + ResolverError::WhileInConstrainedFn { location } => { Diagnostic::simple_error( "`while` is only allowed in unconstrained functions".into(), "Constrained code must always have a known number of loop iterations".into(), - *span, + *location, ) }, - ResolverError::JumpOutsideLoop { is_break, span } => { + ResolverError::JumpOutsideLoop { is_break, location } => { let item = if *is_break { "break" } else { "continue" }; Diagnostic::simple_error( format!("{item} is only allowed within loops"), "".into(), - *span, + *location, ) }, - ResolverError::MutableGlobal { span } => { + ResolverError::MutableGlobal { location } => { Diagnostic::simple_error( "Only `comptime` globals may be mutable".into(), String::new(), - *span, + *location, ) }, - ResolverError::UnspecifiedGlobalType { span, expected_type } => { + ResolverError::UnspecifiedGlobalType { location, expected_type } => { Diagnostic::simple_error( "Globals must have a specified type".to_string(), format!("Inferred type is `{expected_type}`"), - *span, + *location, ) }, - ResolverError::UnevaluatedGlobalType { span } => { + ResolverError::UnevaluatedGlobalType { location } => { Diagnostic::simple_error( "Global failed to evaluate".to_string(), String::new(), - *span, + *location, ) } - ResolverError::NegativeGlobalType { span, global_value } => { + ResolverError::NegativeGlobalType { location, global_value } => { Diagnostic::simple_error( "Globals used in a type position must be non-negative".to_string(), format!("But found value `{global_value:?}`"), - *span, + *location, ) } - ResolverError::NonIntegralGlobalType { span, global_value } => { + ResolverError::NonIntegralGlobalType { location, global_value } => { Diagnostic::simple_error( "Globals used in a type position must be integers".to_string(), format!("But found value `{global_value:?}`"), - *span, + *location, ) } - ResolverError::GlobalLargerThanKind { span, global_value, kind } => { + ResolverError::GlobalLargerThanKind { location, global_value, kind } => { Diagnostic::simple_error( format!("Global value `{global_value}` is larger than its kind's maximum value"), format!("Global's kind inferred to be `{kind}`"), - *span, + *location, ) } - ResolverError::SelfReferentialType { span } => { + ResolverError::SelfReferentialType { location } => { Diagnostic::simple_error( "Self-referential types are not supported".into(), "".into(), - *span, + *location, ) }, ResolverError::NoPredicatesAttributeOnUnconstrained { ident } => { @@ -532,7 +616,7 @@ impl<'a> From<&'a ResolverError> for Diagnostic { let mut diag = Diagnostic::simple_error( format!("misplaced #[no_predicates] attribute on unconstrained function {name}. Only allowed on constrained functions"), "misplaced #[no_predicates] attribute".to_string(), - ident.0.span(), + ident.0.location(), ); diag.add_note("The `#[no_predicates]` attribute specifies to the compiler whether it should diverge from auto-inlining constrained functions".to_owned()); @@ -544,169 +628,170 @@ impl<'a> From<&'a ResolverError> for Diagnostic { let mut diag = Diagnostic::simple_error( format!("misplaced #[fold] attribute on unconstrained function {name}. Only allowed on constrained functions"), "misplaced #[fold] attribute".to_string(), - ident.0.span(), + ident.0.location(), ); diag.add_note("The `#[fold]` attribute specifies whether a constrained function should be treated as a separate circuit rather than inlined into the program entry point".to_owned()); diag } - ResolverError::NumericGenericUsedForType { name, span } => { + ResolverError::NumericGenericUsedForType { name, location } => { Diagnostic::simple_error( format!("expected type, found numeric generic parameter {name}"), String::from("not a type"), - *span, + *location, ) } ResolverError::ArrayLengthInterpreter { error } => Diagnostic::from(error), - ResolverError::UnquoteUsedOutsideQuote { span } => { + ResolverError::UnquoteUsedOutsideQuote { location } => { Diagnostic::simple_error( "The unquote operator '$' can only be used within a quote expression".into(), "".into(), - *span, + *location, ) }, - ResolverError::AsTraitPathNotYetImplemented { span } => { + ResolverError::AsTraitPathNotYetImplemented { location } => { Diagnostic::simple_error( "\"as trait path\" not yet implemented".into(), "".into(), - *span, + *location, ) }, - ResolverError::InvalidSyntaxInMacroCall { span } => { + ResolverError::InvalidSyntaxInMacroCall { location } => { Diagnostic::simple_error( "Invalid syntax in macro call".into(), "Macro calls must call a comptime function directly, they cannot use higher-order functions".into(), - *span, + *location, ) }, - ResolverError::MacroIsNotComptime { span } => { + ResolverError::MacroIsNotComptime { location } => { Diagnostic::simple_error( "This macro call is to a non-comptime function".into(), "Macro calls must be to comptime functions".into(), - *span, + *location, ) }, - ResolverError::NonFunctionInAnnotation { span } => { + ResolverError::NonFunctionInAnnotation { location } => { Diagnostic::simple_error( "Unknown annotation".into(), "The name of an annotation must refer to a comptime function".into(), - *span, + *location, ) }, - ResolverError::MacroResultInGenericsListNotAGeneric { span, typ } => { + ResolverError::MacroResultInGenericsListNotAGeneric { location, typ } => { Diagnostic::simple_error( format!("Type `{typ}` was inserted into a generics list from a macro, but it is not a generic"), format!("Type `{typ}` is not a generic"), - *span, + *location, ) } - ResolverError::NamedTypeArgs { span, item_kind } => { + ResolverError::NamedTypeArgs { location, item_kind } => { Diagnostic::simple_error( format!("Named type arguments aren't allowed on a {item_kind}"), "Named type arguments are only allowed for associated types on traits".to_string(), - *span, + *location, ) } - ResolverError::AssociatedConstantsMustBeNumeric { span } => { + ResolverError::AssociatedConstantsMustBeNumeric { location } => { Diagnostic::simple_error( "Associated constants may only be a field or integer type".to_string(), "Only numeric constants are allowed".to_string(), - *span, + *location, ) } - ResolverError::BinaryOpError { lhs, op, rhs, err, span } => { + ResolverError::BinaryOpError { lhs, op, rhs, err, location } => { Diagnostic::simple_error( format!("Computing `{lhs} {op} {rhs}` failed with error {err}"), String::new(), - *span, + *location, ) } - ResolverError::QuoteInRuntimeCode { span } => { + ResolverError::QuoteInRuntimeCode { location } => { Diagnostic::simple_error( "`quote` cannot be used in runtime code".to_string(), "Wrap this in a `comptime` block or function to use it".to_string(), - *span, + *location, ) }, - ResolverError::ComptimeTypeInRuntimeCode { typ, span } => { + ResolverError::ComptimeTypeInRuntimeCode { typ, location } => { Diagnostic::simple_error( format!("Comptime-only type `{typ}` cannot be used in runtime code"), "Comptime-only type used here".to_string(), - *span, + *location, ) }, - ResolverError::MutatingComptimeInNonComptimeContext { name, span } => { + ResolverError::MutatingComptimeInNonComptimeContext { name, location } => { Diagnostic::simple_error( format!("Comptime variable `{name}` cannot be mutated in a non-comptime context"), format!("`{name}` mutated here"), - *span, + *location, ) }, - ResolverError::InvalidInternedStatementInExpr { statement, span } => { + ResolverError::InvalidInternedStatementInExpr { statement, location } => { Diagnostic::simple_error( format!("Failed to parse `{statement}` as an expression"), "The statement was used from a macro here".to_string(), - *span, + *location, ) }, ResolverError::UnsupportedNumericGenericType(err) => err.into(), - ResolverError::TypeIsMorePrivateThenItem { typ, item, span } => { + ResolverError::TypeIsMorePrivateThenItem { typ, item, location } => { Diagnostic::simple_error( format!("Type `{typ}` is more private than item `{item}`"), String::new(), - *span, + *location, ) }, - ResolverError::UnableToParseAttribute { attribute, span } => { + ResolverError::UnableToParseAttribute { attribute, location } => { Diagnostic::simple_error( format!("Unable to parse attribute `{attribute}`"), "Attribute should be a function or function call".into(), - *span, + *location, ) }, - ResolverError::AttributeFunctionIsNotAPath { function, span } => { + ResolverError::AttributeFunctionIsNotAPath { function, location } => { Diagnostic::simple_error( format!("Attribute function `{function}` is not a path"), "An attribute's function should be a single identifier or a path".into(), - *span, + *location, ) }, - ResolverError::AttributeFunctionNotInScope { name, span } => { + ResolverError::AttributeFunctionNotInScope { name, location } => { Diagnostic::simple_error( format!("Attribute function `{name}` is not in scope"), String::new(), - *span, + *location, ) }, - ResolverError::TraitNotImplemented { impl_trait, missing_trait: the_trait, type_missing_trait: typ, span, missing_trait_location} => { + ResolverError::TraitNotImplemented { impl_trait, missing_trait: the_trait, type_missing_trait: typ, location, missing_trait_location} => { let mut diagnostic = Diagnostic::simple_error( format!("The trait bound `{typ}: {the_trait}` is not satisfied"), format!("The trait `{the_trait}` is not implemented for `{typ}") - , *span); - diagnostic.add_secondary_with_file(format!("required by this bound in `{impl_trait}"), missing_trait_location.span, missing_trait_location.file); + , *location); + diagnostic.add_secondary(format!("required by this bound in `{impl_trait}"), *missing_trait_location); diagnostic }, - ResolverError::LoopNotYetSupported { span } => { + ResolverError::LoopNotYetSupported { location } => { let msg = "`loop` statements are not yet implemented".to_string(); - Diagnostic::simple_error(msg, String::new(), *span) + Diagnostic::simple_error(msg, String::new(), *location) } - ResolverError::ExpectedTrait { found, span } => { + ResolverError::ExpectedTrait { found, location } => { Diagnostic::simple_error( format!("Expected a trait, found {found}"), String::new(), - *span) + *location) + } - ResolverError::InvalidSyntaxInPattern { span } => { + ResolverError::InvalidSyntaxInPattern { location } => { Diagnostic::simple_error( "Invalid syntax in match pattern".into(), "Only literal, constructor, and variable patterns are allowed".into(), - *span) + *location) }, - ResolverError::VariableAlreadyDefinedInPattern { existing, new_span } => { + ResolverError::VariableAlreadyDefinedInPattern { existing, new_location } => { let message = format!("Variable `{existing}` was already defined in the same match pattern"); let secondary = format!("`{existing}` redefined here"); - let mut error = Diagnostic::simple_error(message, secondary, *new_span); - error.add_secondary(format!("`{existing}` was previously defined here"), existing.span()); + let mut error = Diagnostic::simple_error(message, secondary, *new_location); + error.add_secondary(format!("`{existing}` was previously defined here"), existing.location()); error }, } diff --git a/compiler/noirc_frontend/src/hir/resolution/import.rs b/compiler/noirc_frontend/src/hir/resolution/import.rs index 4f84b99217f..a6c9ee0cabb 100644 --- a/compiler/noirc_frontend/src/hir/resolution/import.rs +++ b/compiler/noirc_frontend/src/hir/resolution/import.rs @@ -1,5 +1,5 @@ use iter_extended::vecmap; -use noirc_errors::{CustomDiagnostic, Location, Span}; +use noirc_errors::{CustomDiagnostic, Location}; use thiserror::Error; use crate::graph::CrateId; @@ -44,9 +44,9 @@ pub enum PathResolutionError { #[error("{0} is private and not visible from the current module")] Private(Ident), #[error("There is no super module")] - NoSuper(Span), + NoSuper(Location), #[error("turbofish (`::<_>`) not allowed on {item}")] - TurbofishNotAllowedOnItem { item: String, span: Span }, + TurbofishNotAllowedOnItem { item: String, location: Location }, #[error("{ident} is a {kind}, not a module")] NotAModule { ident: Ident, kind: &'static str }, #[error("trait `{trait_name}` which provides `{ident}` is implemented but not in scope, please import it")] @@ -57,6 +57,23 @@ pub enum PathResolutionError { MultipleTraitsInScope { ident: Ident, traits: Vec }, } +impl PathResolutionError { + pub fn location(&self) -> Location { + match self { + PathResolutionError::NoSuper(location) + | PathResolutionError::TurbofishNotAllowedOnItem { location, .. } => *location, + PathResolutionError::Unresolved(ident) + | PathResolutionError::Private(ident) + | PathResolutionError::NotAModule { ident, .. } + | PathResolutionError::TraitMethodNotInScope { ident, .. } + | PathResolutionError::MultipleTraitsInScope { ident, .. } + | PathResolutionError::UnresolvedWithPossibleTraitsToImport { ident, .. } => { + ident.location() + } + } + } +} + #[derive(Debug)] pub struct ResolvedImport { // The symbol which we have resolved to @@ -75,32 +92,32 @@ impl<'a> From<&'a PathResolutionError> for CustomDiagnostic { fn from(error: &'a PathResolutionError) -> Self { match &error { PathResolutionError::Unresolved(ident) => { - CustomDiagnostic::simple_error(error.to_string(), String::new(), ident.span()) + CustomDiagnostic::simple_error(error.to_string(), String::new(), ident.location()) } // This will be upgraded to an error in future versions PathResolutionError::Private(ident) => CustomDiagnostic::simple_warning( error.to_string(), format!("{ident} is private"), - ident.span(), + ident.location(), ), - PathResolutionError::NoSuper(span) => { - CustomDiagnostic::simple_error(error.to_string(), String::new(), *span) + PathResolutionError::NoSuper(location) => { + CustomDiagnostic::simple_error(error.to_string(), String::new(), *location) } - PathResolutionError::TurbofishNotAllowedOnItem { item: _, span } => { - CustomDiagnostic::simple_error(error.to_string(), String::new(), *span) + PathResolutionError::TurbofishNotAllowedOnItem { item: _, location } => { + CustomDiagnostic::simple_error(error.to_string(), String::new(), *location) } PathResolutionError::NotAModule { ident, kind: _ } => { - CustomDiagnostic::simple_error(error.to_string(), String::new(), ident.span()) + CustomDiagnostic::simple_error(error.to_string(), String::new(), ident.location()) } PathResolutionError::TraitMethodNotInScope { ident, .. } => { - CustomDiagnostic::simple_warning(error.to_string(), String::new(), ident.span()) + CustomDiagnostic::simple_warning(error.to_string(), String::new(), ident.location()) } PathResolutionError::UnresolvedWithPossibleTraitsToImport { ident, traits } => { let traits = vecmap(traits, |trait_name| format!("`{}`", trait_name)); CustomDiagnostic::simple_error( error.to_string(), format!("The following traits which provide `{ident}` are implemented but not in scope: {}", traits.join(", ")), - ident.span(), + ident.location(), ) } PathResolutionError::MultipleTraitsInScope { ident, traits } => { @@ -111,7 +128,7 @@ impl<'a> From<&'a PathResolutionError> for CustomDiagnostic { "All these trait which provide `{ident}` are implemented and in scope: {}", traits.join(", ") ), - ident.span(), + ident.location(), ) } } @@ -227,9 +244,7 @@ impl<'def_maps, 'references_tracker> PathResolutionTargetResolver<'def_maps, 're fn resolve_super_path(&mut self, path: Path) -> Result<(Path, ModuleId), PathResolutionError> { let Some(parent_module_id) = get_module(self.def_maps, self.importing_module).parent else { - let span_start = path.location.span.start(); - let span = Span::from(span_start..span_start + 5); // 5 == "super".len() - return Err(PathResolutionError::NoSuper(span)); + return Err(PathResolutionError::NoSuper(path.kind_location)); }; let current_module = diff --git a/compiler/noirc_frontend/src/hir/type_check/errors.rs b/compiler/noirc_frontend/src/hir/type_check/errors.rs index 5f5ea112567..979a56dba17 100644 --- a/compiler/noirc_frontend/src/hir/type_check/errors.rs +++ b/compiler/noirc_frontend/src/hir/type_check/errors.rs @@ -2,7 +2,7 @@ use std::rc::Rc; use acvm::FieldElement; use noirc_errors::CustomDiagnostic as Diagnostic; -use noirc_errors::Span; +use noirc_errors::Location; use thiserror::Error; use crate::ast::{ @@ -31,190 +31,203 @@ pub enum Source { #[error("{0}")] BinOp(BinaryOpKind), #[error("Return")] - Return(FunctionReturnType, Span), + Return(FunctionReturnType, Location), } #[derive(Error, Debug, Clone, PartialEq, Eq)] pub enum TypeCheckError { #[error("Operator {op:?} cannot be used in a {place:?}")] - OpCannotBeUsed { op: HirBinaryOp, place: &'static str, span: Span }, + OpCannotBeUsed { op: HirBinaryOp, place: &'static str, location: Location }, #[error("Division by zero: {lhs} / {rhs}")] - DivisionByZero { lhs: FieldElement, rhs: FieldElement, span: Span }, + DivisionByZero { lhs: FieldElement, rhs: FieldElement, location: Location }, #[error("Modulo on Field elements: {lhs} % {rhs}")] - ModuloOnFields { lhs: FieldElement, rhs: FieldElement, span: Span }, + ModuloOnFields { lhs: FieldElement, rhs: FieldElement, location: Location }, #[error("The value `{expr:?}` cannot fit into `{ty}` which has range `{range}`")] - OverflowingAssignment { expr: FieldElement, ty: Type, range: String, span: Span }, + OverflowingAssignment { expr: FieldElement, ty: Type, range: String, location: Location }, #[error( "The value `{value}` cannot fit into `{kind}` which has a maximum size of `{maximum_size}`" )] - OverflowingConstant { value: FieldElement, kind: Kind, maximum_size: FieldElement, span: Span }, + OverflowingConstant { + value: FieldElement, + kind: Kind, + maximum_size: FieldElement, + location: Location, + }, #[error("Evaluating `{op}` on `{lhs}`, `{rhs}` failed")] - FailingBinaryOp { op: BinaryTypeOperator, lhs: i128, rhs: i128, span: Span }, + FailingBinaryOp { op: BinaryTypeOperator, lhs: i128, rhs: i128, location: Location }, #[error("Type {typ:?} cannot be used in a {place:?}")] - TypeCannotBeUsed { typ: Type, place: &'static str, span: Span }, + TypeCannotBeUsed { typ: Type, place: &'static str, location: Location }, #[error("Expected type {expected_typ:?} is not the same as {expr_typ:?}")] - TypeMismatch { expected_typ: String, expr_typ: String, expr_span: Span }, + TypeMismatch { expected_typ: String, expr_typ: String, expr_location: Location }, #[error("Expected type {expected} is not the same as {actual}")] - TypeMismatchWithSource { expected: Type, actual: Type, span: Span, source: Source }, + TypeMismatchWithSource { expected: Type, actual: Type, location: Location, source: Source }, #[error("Expected type {expected_kind:?} is not the same as {expr_kind:?}")] - TypeKindMismatch { expected_kind: String, expr_kind: String, expr_span: Span }, + TypeKindMismatch { expected_kind: String, expr_kind: String, expr_location: Location }, #[error("Evaluating {to} resulted in {to_value}, but {from_value} was expected")] TypeCanonicalizationMismatch { to: Type, from: Type, to_value: FieldElement, from_value: FieldElement, - span: Span, + location: Location, }, #[error("Expected {expected:?} found {found:?}")] - ArityMisMatch { expected: usize, found: usize, span: Span }, + ArityMisMatch { expected: usize, found: usize, location: Location }, #[error("Return type in a function cannot be public")] - PublicReturnType { typ: Type, span: Span }, + PublicReturnType { typ: Type, location: Location }, #[error("Cannot cast type {from}, 'as' is only for primitive field or integer types")] - InvalidCast { from: Type, span: Span, reason: String }, + InvalidCast { from: Type, location: Location, reason: String }, #[error("Casting value of type {from} to a smaller type ({to})")] - DownsizingCast { from: Type, to: Type, span: Span, reason: String }, + DownsizingCast { from: Type, to: Type, location: Location, reason: String }, #[error("Expected a function, but found a(n) {found}")] - ExpectedFunction { found: Type, span: Span }, + ExpectedFunction { found: Type, location: Location }, #[error("Type {lhs_type} has no member named {field_name}")] - AccessUnknownMember { lhs_type: Type, field_name: String, span: Span }, + AccessUnknownMember { lhs_type: Type, field_name: String, location: Location }, #[error("Function expects {expected} parameters but {found} were given")] - ParameterCountMismatch { expected: usize, found: usize, span: Span }, + ParameterCountMismatch { expected: usize, found: usize, location: Location }, #[error("{} expects {} or {} parameters but {found} were given", kind, kind.required_arguments_count(), kind.required_arguments_count() + 1)] - AssertionParameterCountMismatch { kind: ConstrainKind, found: usize, span: Span }, + AssertionParameterCountMismatch { kind: ConstrainKind, found: usize, location: Location }, #[error("{item} expects {expected} generics but {found} were given")] - GenericCountMismatch { item: String, expected: usize, found: usize, span: Span }, + GenericCountMismatch { item: String, expected: usize, found: usize, location: Location }, #[error("{item} has incompatible `unconstrained`")] - UnconstrainedMismatch { item: String, expected: bool, span: Span }, + UnconstrainedMismatch { item: String, expected: bool, location: Location }, #[error("Only integer and Field types may be casted to")] - UnsupportedCast { span: Span }, + UnsupportedCast { location: Location }, #[error("Index {index} is out of bounds for this tuple {lhs_type} of length {length}")] - TupleIndexOutOfBounds { index: usize, lhs_type: Type, length: usize, span: Span }, + TupleIndexOutOfBounds { index: usize, lhs_type: Type, length: usize, location: Location }, #[error("Variable `{name}` must be mutable to be assigned to")] - VariableMustBeMutable { name: String, span: Span }, + VariableMustBeMutable { name: String, location: Location }, #[error("Cannot mutate immutable variable `{name}`")] - CannotMutateImmutableVariable { name: String, span: Span }, + CannotMutateImmutableVariable { name: String, location: Location }, #[error("No method named '{method_name}' found for type '{object_type}'")] - UnresolvedMethodCall { method_name: String, object_type: Type, span: Span }, + UnresolvedMethodCall { method_name: String, object_type: Type, location: Location }, #[error("Cannot invoke function field '{method_name}' on type '{object_type}' as a method")] - CannotInvokeStructFieldFunctionType { method_name: String, object_type: Type, span: Span }, + CannotInvokeStructFieldFunctionType { + method_name: String, + object_type: Type, + location: Location, + }, #[error("Integers must have the same signedness LHS is {sign_x:?}, RHS is {sign_y:?}")] - IntegerSignedness { sign_x: Signedness, sign_y: Signedness, span: Span }, + IntegerSignedness { sign_x: Signedness, sign_y: Signedness, location: Location }, #[error("Integers must have the same bit width LHS is {bit_width_x}, RHS is {bit_width_y}")] - IntegerBitWidth { bit_width_x: IntegerBitSize, bit_width_y: IntegerBitSize, span: Span }, + IntegerBitWidth { bit_width_x: IntegerBitSize, bit_width_y: IntegerBitSize, location: Location }, #[error("{kind} cannot be used in an infix operation")] - InvalidInfixOp { kind: &'static str, span: Span }, + InvalidInfixOp { kind: &'static str, location: Location }, #[error("{kind} cannot be used in a unary operation")] - InvalidUnaryOp { kind: String, span: Span }, + InvalidUnaryOp { kind: String, location: Location }, #[error("Bitwise operations are invalid on Field types. Try casting the operands to a sized integer type first.")] - FieldBitwiseOp { span: Span }, + FieldBitwiseOp { location: Location }, #[error("Integer cannot be used with type {typ}")] - IntegerTypeMismatch { typ: Type, span: Span }, + IntegerTypeMismatch { typ: Type, location: Location }, #[error("Cannot use an integer and a Field in a binary operation, try converting the Field into an integer first")] - IntegerAndFieldBinaryOperation { span: Span }, + IntegerAndFieldBinaryOperation { location: Location }, #[error("Cannot do modulo on Fields, try casting to an integer first")] - FieldModulo { span: Span }, + FieldModulo { location: Location }, #[error("Cannot do not (`!`) on Fields, try casting to an integer first")] - FieldNot { span: Span }, + FieldNot { location: Location }, #[error("Fields cannot be compared, try casting to an integer first")] - FieldComparison { span: Span }, + FieldComparison { location: Location }, #[error("The bit count in a bit-shift operation must fit in a u8, try casting the right hand side into a u8 first")] - InvalidShiftSize { span: Span }, + InvalidShiftSize { location: Location }, #[error("The number of bits to use for this bitwise operation is ambiguous. Either the operand's type or return type should be specified")] - AmbiguousBitWidth { span: Span }, + AmbiguousBitWidth { location: Location }, #[error("Error with additional context")] Context { err: Box, ctx: &'static str }, #[error("Array is not homogeneous")] NonHomogeneousArray { - first_span: Span, + first_location: Location, first_type: String, first_index: usize, - second_span: Span, + second_location: Location, second_type: String, second_index: usize, }, #[error("Object type is unknown in method call")] - TypeAnnotationsNeededForMethodCall { span: Span }, + TypeAnnotationsNeededForMethodCall { location: Location }, #[error("Object type is unknown in field access")] - TypeAnnotationsNeededForFieldAccess { span: Span }, + TypeAnnotationsNeededForFieldAccess { location: Location }, #[error("Multiple trait impls may apply to this object type")] - MultipleMatchingImpls { object_type: Type, candidates: Vec, span: Span }, + MultipleMatchingImpls { object_type: Type, candidates: Vec, location: Location }, #[error("use of deprecated function {name}")] - CallDeprecated { name: String, note: Option, span: Span }, + CallDeprecated { name: String, note: Option, location: Location }, #[error("{0}")] ResolverError(ResolverError), #[error("Unused expression result of type {expr_type}")] - UnusedResultError { expr_type: Type, expr_span: Span }, + UnusedResultError { expr_type: Type, expr_location: Location }, #[error("Expected type {expected_typ:?} is not the same as {actual_typ:?}")] TraitMethodParameterTypeMismatch { method_name: String, expected_typ: String, actual_typ: String, - parameter_span: Span, + parameter_location: Location, parameter_index: usize, }, #[error("No matching impl found")] NoMatchingImplFound(NoMatchingImplFoundError), #[error("Constraint for `{typ}: {trait_name}` is not needed, another matching impl is already in scope")] - UnneededTraitConstraint { trait_name: String, typ: Type, span: Span }, + UnneededTraitConstraint { trait_name: String, typ: Type, location: Location }, #[error( "Expected {expected_count} generic(s) from this function, but {actual_count} were provided" )] - IncorrectTurbofishGenericCount { expected_count: usize, actual_count: usize, span: Span }, + IncorrectTurbofishGenericCount { + expected_count: usize, + actual_count: usize, + location: Location, + }, #[error( "Cannot pass a mutable reference from a constrained runtime to an unconstrained runtime" )] - ConstrainedReferenceToUnconstrained { span: Span }, + ConstrainedReferenceToUnconstrained { location: Location }, #[error( "Cannot pass a mutable reference from a unconstrained runtime to an constrained runtime" )] - UnconstrainedReferenceToConstrained { span: Span }, + UnconstrainedReferenceToConstrained { location: Location }, #[error("Slices cannot be returned from an unconstrained runtime to a constrained runtime")] - UnconstrainedSliceReturnToConstrained { span: Span }, + UnconstrainedSliceReturnToConstrained { location: Location }, #[error("Call to unconstrained function is unsafe and must be in an unconstrained function or unsafe block")] - Unsafe { span: Span }, + Unsafe { location: Location }, #[error("Converting an unconstrained fn to a non-unconstrained fn is unsafe")] - UnsafeFn { span: Span }, + UnsafeFn { location: Location }, #[error("Expected a constant, but found `{typ}`")] - NonConstantEvaluated { typ: Type, span: Span }, + NonConstantEvaluated { typ: Type, location: Location }, #[error("Slices must have constant length")] - NonConstantSliceLength { span: Span }, + NonConstantSliceLength { location: Location }, #[error("Only sized types may be used in the entry point to a program")] - InvalidTypeForEntryPoint { span: Span }, + InvalidTypeForEntryPoint { location: Location }, #[error("Mismatched number of parameters in trait implementation")] MismatchTraitImplNumParameters { actual_num_parameters: usize, expected_num_parameters: usize, trait_name: String, method_name: String, - span: Span, + location: Location, }, #[error("Strings do not support indexed assignment")] - StringIndexAssign { span: Span }, + StringIndexAssign { location: Location }, #[error("Macro calls may only return `Quoted` values")] - MacroReturningNonExpr { typ: Type, span: Span }, + MacroReturningNonExpr { typ: Type, location: Location }, #[error("`{name}` has already been specified")] - DuplicateNamedTypeArg { name: Ident, prev_span: Span }, + DuplicateNamedTypeArg { name: Ident, prev_location: Location }, #[error("`{item}` has no associated type named `{name}`")] NoSuchNamedTypeArg { name: Ident, item: String }, #[error("`{item}` is missing the associated type `{name}`")] - MissingNamedTypeArg { name: Rc, item: String, span: Span }, + MissingNamedTypeArg { name: Rc, item: String, location: Location }, #[error("Internal compiler error: type unspecified for value")] - UnspecifiedType { span: Span }, + UnspecifiedType { location: Location }, #[error("Binding `{typ}` here to the `_` inside would create a cyclic type")] - CyclicType { typ: Type, span: Span }, + CyclicType { typ: Type, location: Location }, #[error("Type annotations required before indexing this array or slice")] - TypeAnnotationsNeededForIndex { span: Span }, + TypeAnnotationsNeededForIndex { location: Location }, #[error("Unnecessary `unsafe` block")] - UnnecessaryUnsafeBlock { span: Span }, + UnnecessaryUnsafeBlock { location: Location }, #[error("Unnecessary `unsafe` block")] - NestedUnsafeBlock { span: Span }, + NestedUnsafeBlock { location: Location }, } #[derive(Debug, Clone, PartialEq, Eq)] pub struct NoMatchingImplFoundError { pub(crate) constraints: Vec<(Type, String)>, - pub span: Span, + pub location: Location, } impl TypeCheckError { @@ -225,69 +238,149 @@ impl TypeCheckError { pub(crate) fn is_non_constant_evaluated(&self) -> bool { matches!(self, TypeCheckError::NonConstantEvaluated { .. }) } + + pub fn location(&self) -> Location { + match self { + TypeCheckError::OpCannotBeUsed { location, .. } + | TypeCheckError::DivisionByZero { location, .. } + | TypeCheckError::ModuloOnFields { location, .. } + | TypeCheckError::OverflowingAssignment { location, .. } + | TypeCheckError::OverflowingConstant { location, .. } + | TypeCheckError::FailingBinaryOp { location, .. } + | TypeCheckError::TypeCannotBeUsed { location, .. } + | TypeCheckError::TypeMismatch { expr_location: location, .. } + | TypeCheckError::TypeMismatchWithSource { location, .. } + | TypeCheckError::TypeKindMismatch { expr_location: location, .. } + | TypeCheckError::TypeCanonicalizationMismatch { location, .. } + | TypeCheckError::ArityMisMatch { location, .. } + | TypeCheckError::PublicReturnType { location, .. } + | TypeCheckError::InvalidCast { location, .. } + | TypeCheckError::DownsizingCast { location, .. } + | TypeCheckError::ExpectedFunction { location, .. } + | TypeCheckError::AccessUnknownMember { location, .. } + | TypeCheckError::ParameterCountMismatch { location, .. } + | TypeCheckError::AssertionParameterCountMismatch { location, .. } + | TypeCheckError::GenericCountMismatch { location, .. } + | TypeCheckError::UnconstrainedMismatch { location, .. } + | TypeCheckError::UnsupportedCast { location } + | TypeCheckError::TupleIndexOutOfBounds { location, .. } + | TypeCheckError::VariableMustBeMutable { location, .. } + | TypeCheckError::CannotMutateImmutableVariable { location, .. } + | TypeCheckError::UnresolvedMethodCall { location, .. } + | TypeCheckError::CannotInvokeStructFieldFunctionType { location, .. } + | TypeCheckError::IntegerSignedness { location, .. } + | TypeCheckError::IntegerBitWidth { location, .. } + | TypeCheckError::InvalidInfixOp { location, .. } + | TypeCheckError::InvalidUnaryOp { location, .. } + | TypeCheckError::FieldBitwiseOp { location } + | TypeCheckError::IntegerTypeMismatch { location, .. } + | TypeCheckError::IntegerAndFieldBinaryOperation { location } + | TypeCheckError::FieldModulo { location } + | TypeCheckError::FieldNot { location } + | TypeCheckError::FieldComparison { location } + | TypeCheckError::InvalidShiftSize { location } + | TypeCheckError::AmbiguousBitWidth { location } + | TypeCheckError::NonHomogeneousArray { first_location: location, .. } + | TypeCheckError::TypeAnnotationsNeededForMethodCall { location } + | TypeCheckError::TypeAnnotationsNeededForFieldAccess { location } + | TypeCheckError::MultipleMatchingImpls { location, .. } + | TypeCheckError::CallDeprecated { location, .. } + | TypeCheckError::UnusedResultError { expr_location: location, .. } + | TypeCheckError::TraitMethodParameterTypeMismatch { + parameter_location: location, + .. + } + | TypeCheckError::UnneededTraitConstraint { location, .. } + | TypeCheckError::IncorrectTurbofishGenericCount { location, .. } + | TypeCheckError::ConstrainedReferenceToUnconstrained { location } + | TypeCheckError::UnconstrainedReferenceToConstrained { location } + | TypeCheckError::UnconstrainedSliceReturnToConstrained { location } + | TypeCheckError::Unsafe { location } + | TypeCheckError::UnsafeFn { location } + | TypeCheckError::NonConstantEvaluated { location, .. } + | TypeCheckError::NonConstantSliceLength { location } + | TypeCheckError::InvalidTypeForEntryPoint { location } + | TypeCheckError::MismatchTraitImplNumParameters { location, .. } + | TypeCheckError::StringIndexAssign { location } + | TypeCheckError::MacroReturningNonExpr { location, .. } + | TypeCheckError::MissingNamedTypeArg { location, .. } + | TypeCheckError::UnspecifiedType { location } + | TypeCheckError::CyclicType { location, .. } + | TypeCheckError::TypeAnnotationsNeededForIndex { location } + | TypeCheckError::UnnecessaryUnsafeBlock { location } + | TypeCheckError::NestedUnsafeBlock { location } => *location, + TypeCheckError::DuplicateNamedTypeArg { name: ident, .. } + | TypeCheckError::NoSuchNamedTypeArg { name: ident, .. } => ident.location(), + TypeCheckError::NoMatchingImplFound(no_matching_impl_found_error) => { + no_matching_impl_found_error.location + } + TypeCheckError::Context { err, .. } => err.location(), + TypeCheckError::ResolverError(resolver_error) => resolver_error.location(), + } + } } impl<'a> From<&'a TypeCheckError> for Diagnostic { fn from(error: &'a TypeCheckError) -> Diagnostic { match error { - TypeCheckError::TypeCannotBeUsed { typ, place, span } => Diagnostic::simple_error( + TypeCheckError::TypeCannotBeUsed { typ, place, location } => Diagnostic::simple_error( format!("The type {} cannot be used in a {}", &typ, place), String::new(), - *span, + *location, ), TypeCheckError::Context { err, ctx } => { let mut diag = Diagnostic::from(err.as_ref()); diag.add_note(ctx.to_string()); diag } - TypeCheckError::OpCannotBeUsed { op, place, span } => Diagnostic::simple_error( + TypeCheckError::OpCannotBeUsed { op, place, location } => Diagnostic::simple_error( format!("The operator {op:?} cannot be used in a {place}"), String::new(), - *span, + *location, ), - TypeCheckError::DivisionByZero { lhs, rhs, span } => Diagnostic::simple_error( + TypeCheckError::DivisionByZero { lhs, rhs, location } => Diagnostic::simple_error( format!("Division by zero: {lhs} / {rhs}"), String::new(), - *span, + *location, ), - TypeCheckError::ModuloOnFields { lhs, rhs, span } => Diagnostic::simple_error( + TypeCheckError::ModuloOnFields { lhs, rhs, location } => Diagnostic::simple_error( format!("Modulo on Field elements: {lhs} % {rhs}"), String::new(), - *span, + *location, ), - TypeCheckError::TypeMismatch { expected_typ, expr_typ, expr_span } => { + TypeCheckError::TypeMismatch { expected_typ, expr_typ, expr_location } => { Diagnostic::simple_error( format!("Expected type {expected_typ}, found type {expr_typ}"), String::new(), - *expr_span, + *expr_location, ) } - TypeCheckError::TypeKindMismatch { expected_kind, expr_kind, expr_span } => { + TypeCheckError::TypeKindMismatch { expected_kind, expr_kind, expr_location } => { Diagnostic::simple_error( format!("Expected kind {expected_kind}, found kind {expr_kind}"), String::new(), - *expr_span, + *expr_location, ) } - TypeCheckError::TypeCanonicalizationMismatch { to, from, to_value, from_value, span } => { + TypeCheckError::TypeCanonicalizationMismatch { to, from, to_value, from_value, location } => { Diagnostic::simple_error( format!("Evaluating {to} resulted in {to_value}, but {from_value} was expected"), format!("from evaluating {from} without simplifications"), - *span, + *location, ) } - TypeCheckError::TraitMethodParameterTypeMismatch { method_name, expected_typ, actual_typ, parameter_index, parameter_span } => { + TypeCheckError::TraitMethodParameterTypeMismatch { method_name, expected_typ, actual_typ, parameter_index, parameter_location } => { Diagnostic::simple_error( format!("Parameter #{parameter_index} of method `{method_name}` must be of type {expected_typ}, not {actual_typ}"), String::new(), - *parameter_span, + *parameter_location, ) } TypeCheckError::NonHomogeneousArray { - first_span, + first_location, first_type, first_index, - second_span, + second_location, second_type, second_index, } => { @@ -296,114 +389,114 @@ impl<'a> From<&'a TypeCheckError> for Diagnostic { "Non homogeneous array, different element types found at indices ({first_index},{second_index})" ), format!("Found type {first_type}"), - *first_span, + *first_location, ); - diag.add_secondary(format!("but then found type {second_type}"), *second_span); + diag.add_secondary(format!("but then found type {second_type}"), *second_location); diag } - TypeCheckError::ArityMisMatch { expected, found, span } => { + TypeCheckError::ArityMisMatch { expected, found, location } => { let plural = if *expected == 1 { "" } else { "s" }; let msg = format!("Expected {expected} argument{plural}, but found {found}"); - Diagnostic::simple_error(msg, String::new(), *span) + Diagnostic::simple_error(msg, String::new(), *location) } - TypeCheckError::ParameterCountMismatch { expected, found, span } => { + TypeCheckError::ParameterCountMismatch { expected, found, location } => { let empty_or_s = if *expected == 1 { "" } else { "s" }; let was_or_were = if *found == 1 { "was" } else { "were" }; let msg = format!("Function expects {expected} parameter{empty_or_s} but {found} {was_or_were} given"); - Diagnostic::simple_error(msg, String::new(), *span) + Diagnostic::simple_error(msg, String::new(), *location) } - TypeCheckError::AssertionParameterCountMismatch { kind, found, span } => { + TypeCheckError::AssertionParameterCountMismatch { kind, found, location } => { let was_or_were = if *found == 1 { "was" } else { "were" }; let min = kind.required_arguments_count(); let max = min + 1; let msg = format!("{kind} expects {min} or {max} parameters but {found} {was_or_were} given"); - Diagnostic::simple_error(msg, String::new(), *span) + Diagnostic::simple_error(msg, String::new(), *location) } - TypeCheckError::GenericCountMismatch { item, expected, found, span } => { + TypeCheckError::GenericCountMismatch { item, expected, found, location } => { let empty_or_s = if *expected == 1 { "" } else { "s" }; let was_or_were = if *found == 1 { "was" } else { "were" }; let msg = format!("{item} expects {expected} generic{empty_or_s} but {found} {was_or_were} given"); - Diagnostic::simple_error(msg, String::new(), *span) + Diagnostic::simple_error(msg, String::new(), *location) } - TypeCheckError::UnconstrainedMismatch { item, expected, span } => { + TypeCheckError::UnconstrainedMismatch { item, expected, location } => { let msg = if *expected { format!("{item} is expected to be unconstrained") } else { format!("{item} is not expected to be unconstrained") }; - Diagnostic::simple_error(msg, String::new(), *span) + Diagnostic::simple_error(msg, String::new(), *location) } - TypeCheckError::InvalidCast { span, reason, .. } => { - Diagnostic::simple_error(error.to_string(), reason.clone(), *span) + TypeCheckError::InvalidCast { location, reason, .. } => { + Diagnostic::simple_error(error.to_string(), reason.clone(), *location) } - TypeCheckError::DownsizingCast { span, reason, .. } => { - Diagnostic::simple_warning(error.to_string(), reason.clone(), *span) + TypeCheckError::DownsizingCast { location, reason, .. } => { + Diagnostic::simple_warning(error.to_string(), reason.clone(), *location) } - TypeCheckError::ExpectedFunction { span, .. } - | TypeCheckError::AccessUnknownMember { span, .. } - | TypeCheckError::UnsupportedCast { span } - | TypeCheckError::TupleIndexOutOfBounds { span, .. } - | TypeCheckError::VariableMustBeMutable { span, .. } - | TypeCheckError::CannotMutateImmutableVariable { span, .. } - | TypeCheckError::UnresolvedMethodCall { span, .. } - | TypeCheckError::IntegerSignedness { span, .. } - | TypeCheckError::IntegerBitWidth { span, .. } - | TypeCheckError::InvalidInfixOp { span, .. } - | TypeCheckError::InvalidUnaryOp { span, .. } - | TypeCheckError::FieldBitwiseOp { span, .. } - | TypeCheckError::IntegerTypeMismatch { span, .. } - | TypeCheckError::FieldComparison { span, .. } - | TypeCheckError::AmbiguousBitWidth { span, .. } - | TypeCheckError::IntegerAndFieldBinaryOperation { span } - | TypeCheckError::OverflowingAssignment { span, .. } - | TypeCheckError::OverflowingConstant { span, .. } - | TypeCheckError::FailingBinaryOp { span, .. } - | TypeCheckError::FieldModulo { span } - | TypeCheckError::FieldNot { span } - | TypeCheckError::ConstrainedReferenceToUnconstrained { span } - | TypeCheckError::UnconstrainedReferenceToConstrained { span } - | TypeCheckError::UnconstrainedSliceReturnToConstrained { span } - | TypeCheckError::NonConstantEvaluated { span, .. } - | TypeCheckError::NonConstantSliceLength { span } - | TypeCheckError::StringIndexAssign { span } - | TypeCheckError::InvalidShiftSize { span } => { - Diagnostic::simple_error(error.to_string(), String::new(), *span) + TypeCheckError::ExpectedFunction { location, .. } + | TypeCheckError::AccessUnknownMember { location, .. } + | TypeCheckError::UnsupportedCast { location } + | TypeCheckError::TupleIndexOutOfBounds { location, .. } + | TypeCheckError::VariableMustBeMutable { location, .. } + | TypeCheckError::CannotMutateImmutableVariable { location, .. } + | TypeCheckError::UnresolvedMethodCall { location, .. } + | TypeCheckError::IntegerSignedness { location, .. } + | TypeCheckError::IntegerBitWidth { location, .. } + | TypeCheckError::InvalidInfixOp { location, .. } + | TypeCheckError::InvalidUnaryOp { location, .. } + | TypeCheckError::FieldBitwiseOp { location, .. } + | TypeCheckError::IntegerTypeMismatch { location, .. } + | TypeCheckError::FieldComparison { location, .. } + | TypeCheckError::AmbiguousBitWidth { location, .. } + | TypeCheckError::IntegerAndFieldBinaryOperation { location } + | TypeCheckError::OverflowingAssignment { location, .. } + | TypeCheckError::OverflowingConstant { location, .. } + | TypeCheckError::FailingBinaryOp { location, .. } + | TypeCheckError::FieldModulo { location } + | TypeCheckError::FieldNot { location } + | TypeCheckError::ConstrainedReferenceToUnconstrained { location } + | TypeCheckError::UnconstrainedReferenceToConstrained { location } + | TypeCheckError::UnconstrainedSliceReturnToConstrained { location } + | TypeCheckError::NonConstantEvaluated { location, .. } + | TypeCheckError::NonConstantSliceLength { location } + | TypeCheckError::StringIndexAssign { location } + | TypeCheckError::InvalidShiftSize { location } => { + Diagnostic::simple_error(error.to_string(), String::new(), *location) } - TypeCheckError::PublicReturnType { typ, span } => Diagnostic::simple_error( + TypeCheckError::PublicReturnType { typ, location } => Diagnostic::simple_error( "Functions cannot declare a public return type".to_string(), format!("return type is {typ}"), - *span, + *location, ), - TypeCheckError::TypeAnnotationsNeededForMethodCall { span } => { + TypeCheckError::TypeAnnotationsNeededForMethodCall { location } => { let mut error = Diagnostic::simple_error( "Object type is unknown in method call".to_string(), "Type must be known by this point to know which method to call".to_string(), - *span, + *location, ); error.add_note("Try adding a type annotation for the object type before this method call".to_string()); error }, - TypeCheckError::TypeAnnotationsNeededForFieldAccess { span } => { + TypeCheckError::TypeAnnotationsNeededForFieldAccess { location } => { let mut error = Diagnostic::simple_error( "Object type is unknown in field access".to_string(), "Type must be known by this point".to_string(), - *span, + *location, ); error.add_note("Try adding a type annotation for the object type before this expression".to_string()); error }, - TypeCheckError::MultipleMatchingImpls { object_type, candidates, span } => { + TypeCheckError::MultipleMatchingImpls { object_type, candidates, location } => { let message = format!("Multiple trait impls match the object type `{object_type}`"); let secondary = "Ambiguous impl".to_string(); - let mut error = Diagnostic::simple_error(message, secondary, *span); + let mut error = Diagnostic::simple_error(message, secondary, *location); for (i, candidate) in candidates.iter().enumerate() { error.add_note(format!("Candidate {}: `{candidate}`", i + 1)); } error }, TypeCheckError::ResolverError(error) => error.into(), - TypeCheckError::TypeMismatchWithSource { expected, actual, span, source } => { + TypeCheckError::TypeMismatchWithSource { expected, actual, location, source } => { let message = match source { Source::Binary => format!("Types in a binary operation should match, but found {expected} and {actual}"), Source::Assignment => { @@ -414,125 +507,125 @@ impl<'a> From<&'a TypeCheckError> for Diagnostic { Source::StringLen => format!("Can only compare strings of the same length. Here LHS is of length {expected}, and RHS is {actual}"), Source::Comparison => format!("Unsupported types for comparison: {expected} and {actual}"), Source::BinOp(kind) => format!("Unsupported types for operator `{kind}`: {expected} and {actual}"), - Source::Return(ret_ty, expr_span) => { - let ret_ty_span = match ret_ty.clone() { - FunctionReturnType::Default(location) => location.span, - FunctionReturnType::Ty(ty) => ty.location.span, + Source::Return(ret_ty, expr_location) => { + let ret_ty_location = match ret_ty.clone() { + FunctionReturnType::Default(location) => location, + FunctionReturnType::Ty(ty) => ty.location, }; - let mut diagnostic = Diagnostic::simple_error(format!("expected type {expected}, found type {actual}"), format!("expected {expected} because of return type"), ret_ty_span); + let mut diagnostic = Diagnostic::simple_error(format!("expected type {expected}, found type {actual}"), format!("expected {expected} because of return type"), ret_ty_location); if let FunctionReturnType::Default(_) = ret_ty { diagnostic.add_note(format!("help: try adding a return type: `-> {actual}`")); } - diagnostic.add_secondary(format!("{actual} returned here"), *expr_span); + diagnostic.add_secondary(format!("{actual} returned here"), *expr_location); return diagnostic }, }; - Diagnostic::simple_error(message, String::new(), *span) + Diagnostic::simple_error(message, String::new(), *location) } - TypeCheckError::CallDeprecated { span, ref note, .. } => { + TypeCheckError::CallDeprecated { location, ref note, .. } => { let primary_message = error.to_string(); let secondary_message = note.clone().unwrap_or_default(); - let mut diagnostic = Diagnostic::simple_warning(primary_message, secondary_message, *span); + let mut diagnostic = Diagnostic::simple_warning(primary_message, secondary_message, *location); diagnostic.deprecated = true; diagnostic } - TypeCheckError::UnusedResultError { expr_type, expr_span } => { + TypeCheckError::UnusedResultError { expr_type, expr_location } => { let msg = format!("Unused expression result of type {expr_type}"); - Diagnostic::simple_warning(msg, String::new(), *expr_span) + Diagnostic::simple_warning(msg, String::new(), *expr_location) } TypeCheckError::NoMatchingImplFound(error) => error.into(), - TypeCheckError::UnneededTraitConstraint { trait_name, typ, span } => { + TypeCheckError::UnneededTraitConstraint { trait_name, typ, location } => { let msg = format!("Constraint for `{typ}: {trait_name}` is not needed, another matching impl is already in scope"); - Diagnostic::simple_warning(msg, "Unnecessary trait constraint in where clause".into(), *span) + Diagnostic::simple_warning(msg, "Unnecessary trait constraint in where clause".into(), *location) } - TypeCheckError::InvalidTypeForEntryPoint { span } => Diagnostic::simple_error( + TypeCheckError::InvalidTypeForEntryPoint { location } => Diagnostic::simple_error( "Only sized types may be used in the entry point to a program".to_string(), - "Slices, references, or any type containing them may not be used in main, contract functions, or foldable functions".to_string(), *span), + "Slices, references, or any type containing them may not be used in main, contract functions, or foldable functions".to_string(), *location), TypeCheckError::MismatchTraitImplNumParameters { expected_num_parameters, actual_num_parameters, trait_name, method_name, - span, + location, } => { let plural = if *expected_num_parameters == 1 { "" } else { "s" }; let primary_message = format!( "`{trait_name}::{method_name}` expects {expected_num_parameters} parameter{plural}, but this method has {actual_num_parameters}"); - Diagnostic::simple_error(primary_message, "".to_string(), *span) + Diagnostic::simple_error(primary_message, "".to_string(), *location) } - TypeCheckError::IncorrectTurbofishGenericCount { expected_count, actual_count, span } => { + TypeCheckError::IncorrectTurbofishGenericCount { expected_count, actual_count, location } => { let expected_plural = if *expected_count == 1 { "" } else { "s" }; let actual_plural = if *actual_count == 1 { "was" } else { "were" }; let msg = format!("Expected {expected_count} generic{expected_plural} from this function, but {actual_count} {actual_plural} provided"); - Diagnostic::simple_error(msg, "".into(), *span) + Diagnostic::simple_error(msg, "".into(), *location) }, - TypeCheckError::MacroReturningNonExpr { typ, span } => { + TypeCheckError::MacroReturningNonExpr { typ, location } => { let mut error = Diagnostic::simple_error( format!("Expected macro call to return a `Quoted` but found a(n) `{typ}`"), "Macro calls must return quoted values, otherwise there is no code to insert.".into(), - *span, + *location, ); - error.add_secondary("Hint: remove the `!` from the end of the function name.".to_string(), *span); + error.add_secondary("Hint: remove the `!` from the end of the function name.".to_string(), *location); error }, - TypeCheckError::DuplicateNamedTypeArg { name, prev_span } => { + TypeCheckError::DuplicateNamedTypeArg { name, prev_location } => { let msg = format!("`{name}` has already been specified"); - let mut error = Diagnostic::simple_error(msg.to_string(), "".to_string(), name.span()); - error.add_secondary(format!("`{name}` previously specified here"), *prev_span); + let mut error = Diagnostic::simple_error(msg.to_string(), "".to_string(), name.location()); + error.add_secondary(format!("`{name}` previously specified here"), *prev_location); error }, TypeCheckError::NoSuchNamedTypeArg { name, item } => { let msg = format!("`{item}` has no associated type named `{name}`"); - Diagnostic::simple_error(msg.to_string(), "".to_string(), name.span()) + Diagnostic::simple_error(msg.to_string(), "".to_string(), name.location()) }, - TypeCheckError::MissingNamedTypeArg { name, item, span } => { + TypeCheckError::MissingNamedTypeArg { name, item, location } => { let msg = format!("`{item}` is missing the associated type `{name}`"); - Diagnostic::simple_error(msg.to_string(), "".to_string(), *span) + Diagnostic::simple_error(msg.to_string(), "".to_string(), *location) }, - TypeCheckError::Unsafe { span } => { - Diagnostic::simple_error(error.to_string(), String::new(), *span) + TypeCheckError::Unsafe { location } => { + Diagnostic::simple_error(error.to_string(), String::new(), *location) } - TypeCheckError::UnsafeFn { span } => { - Diagnostic::simple_error(error.to_string(), String::new(), *span) + TypeCheckError::UnsafeFn { location } => { + Diagnostic::simple_error(error.to_string(), String::new(), *location) } - TypeCheckError::UnspecifiedType { span } => { - Diagnostic::simple_error(error.to_string(), String::new(), *span) + TypeCheckError::UnspecifiedType { location } => { + Diagnostic::simple_error(error.to_string(), String::new(), *location) } - TypeCheckError::CyclicType { typ: _, span } => { - Diagnostic::simple_error(error.to_string(), "Cyclic types have unlimited size and are prohibited in Noir".into(), *span) + TypeCheckError::CyclicType { typ: _, location } => { + Diagnostic::simple_error(error.to_string(), "Cyclic types have unlimited size and are prohibited in Noir".into(), *location) } - TypeCheckError::CannotInvokeStructFieldFunctionType { method_name, object_type, span } => { + TypeCheckError::CannotInvokeStructFieldFunctionType { method_name, object_type, location } => { Diagnostic::simple_error( format!("Cannot invoke function field '{method_name}' on type '{object_type}' as a method"), format!("to call the function stored in '{method_name}', surround the field access with parentheses: '(', ')'"), - *span, + *location, ) }, - TypeCheckError::TypeAnnotationsNeededForIndex { span } => { + TypeCheckError::TypeAnnotationsNeededForIndex { location } => { Diagnostic::simple_error( "Type annotations required before indexing this array or slice".into(), "Type annotations needed before this point, can't decide if this is an array or slice".into(), - *span, + *location, ) }, - TypeCheckError::UnnecessaryUnsafeBlock { span } => { + TypeCheckError::UnnecessaryUnsafeBlock { location } => { Diagnostic::simple_warning( "Unnecessary `unsafe` block".into(), "".into(), - *span, + *location, ) }, - TypeCheckError::NestedUnsafeBlock { span } => { + TypeCheckError::NestedUnsafeBlock { location } => { Diagnostic::simple_warning( "Unnecessary `unsafe` block".into(), "Because it's nested inside another `unsafe` block".into(), - *span, + *location, ) }, } @@ -542,7 +635,7 @@ impl<'a> From<&'a TypeCheckError> for Diagnostic { impl<'a> From<&'a NoMatchingImplFoundError> for Diagnostic { fn from(error: &'a NoMatchingImplFoundError) -> Self { let constraints = &error.constraints; - let span = error.span; + let span = error.location; assert!(!constraints.is_empty()); let msg = @@ -565,7 +658,7 @@ impl NoMatchingImplFoundError { pub fn new( interner: &NodeInterner, failing_constraints: Vec, - span: Span, + location: Location, ) -> Option { // Don't show any errors where try_get_trait returns None. // This can happen if a trait is used that was never declared. @@ -578,6 +671,6 @@ impl NoMatchingImplFoundError { }) .collect::>>()?; - Some(Self { constraints, span }) + Some(Self { constraints, location }) } } diff --git a/compiler/noirc_frontend/src/hir_def/expr.rs b/compiler/noirc_frontend/src/hir_def/expr.rs index e03e5f7678e..10f8eb0bbe8 100644 --- a/compiler/noirc_frontend/src/hir_def/expr.rs +++ b/compiler/noirc_frontend/src/hir_def/expr.rs @@ -249,11 +249,10 @@ impl HirMethodReference { } HirMethodReference::TraitMethodId(method_id, trait_generics, assumed) => { let id = interner.trait_method_id(method_id); - let span = location.span; let trait_id = method_id.trait_id; let constraint = TraitConstraint { typ: object_type, - trait_bound: ResolvedTraitBound { trait_id, trait_generics, span }, + trait_bound: ResolvedTraitBound { trait_id, trait_generics, location }, }; (id, ImplKind::TraitMethod(TraitMethod { method_id, constraint, assumed })) diff --git a/compiler/noirc_frontend/src/hir_def/traits.rs b/compiler/noirc_frontend/src/hir_def/traits.rs index e11903aa2e9..ea962a7bdfd 100644 --- a/compiler/noirc_frontend/src/hir_def/traits.rs +++ b/compiler/noirc_frontend/src/hir_def/traits.rs @@ -121,7 +121,7 @@ impl TraitConstraint { pub struct ResolvedTraitBound { pub trait_id: TraitId, pub trait_generics: TraitGenerics, - pub span: Span, + pub location: Location, } impl ResolvedTraitBound { @@ -198,11 +198,10 @@ impl Trait { /// Returns a TraitConstraint for this trait using Self as the object /// type and the uninstantiated generics for any trait generics. pub fn as_constraint(&self, location: Location) -> TraitConstraint { - let span = location.span; let trait_generics = self.get_trait_generics(location); TraitConstraint { typ: Type::TypeVariable(self.self_type_typevar.clone()), - trait_bound: ResolvedTraitBound { trait_generics, trait_id: self.id, span }, + trait_bound: ResolvedTraitBound { trait_generics, trait_id: self.id, location }, } } } diff --git a/compiler/noirc_frontend/src/hir_def/types.rs b/compiler/noirc_frontend/src/hir_def/types.rs index ed3af896d09..56c1e014c13 100644 --- a/compiler/noirc_frontend/src/hir_def/types.rs +++ b/compiler/noirc_frontend/src/hir_def/types.rs @@ -16,7 +16,7 @@ use crate::{ node_interner::{ExprId, NodeInterner, TraitId, TypeAliasId}, }; use iter_extended::vecmap; -use noirc_errors::{Location, Span}; +use noirc_errors::Location; use noirc_printable_type::PrintableType; use crate::{ @@ -278,7 +278,7 @@ impl Kind { pub(crate) fn ensure_value_fits( &self, value: FieldElement, - span: Span, + location: Location, ) -> Result { match self.integral_maximum_size() { None => Ok(value), @@ -287,7 +287,7 @@ impl Kind { value, kind: self.clone(), maximum_size, - span, + location, } }), } @@ -854,12 +854,17 @@ impl TypeVariable { *self.1.borrow_mut() = TypeBinding::Bound(typ); } - pub fn try_bind(&self, binding: Type, kind: &Kind, span: Span) -> Result<(), TypeCheckError> { + pub fn try_bind( + &self, + binding: Type, + kind: &Kind, + location: Location, + ) -> Result<(), TypeCheckError> { if !binding.kind().unifies(kind) { return Err(TypeCheckError::TypeKindMismatch { expected_kind: format!("{}", kind), expr_kind: format!("{}", binding.kind()), - expr_span: span, + expr_location: location, }); } @@ -871,7 +876,7 @@ impl TypeVariable { }; if binding.occurs(id) { - Err(TypeCheckError::CyclicType { span, typ: binding }) + Err(TypeCheckError::CyclicType { location, typ: binding }) } else { *self.1.borrow_mut() = TypeBinding::Bound(binding); Ok(()) @@ -1541,7 +1546,7 @@ impl Type { Type::FieldElement | Type::Integer { .. } | Type::Bool => 1, Type::Array(size, typ) => { let length = size - .evaluate_to_u32(location.span) + .evaluate_to_u32(*location) .expect("Cannot have variable sized arrays as a parameter to main"); let typ = typ.as_ref(); length * typ.field_count(location) @@ -1568,7 +1573,7 @@ impl Type { fields.iter().fold(0, |acc, field_typ| acc + field_typ.field_count(location)) } Type::String(size) => size - .evaluate_to_u32(location.span) + .evaluate_to_u32(*location) .expect("Cannot have variable sized strings as a parameter to main"), Type::FmtString(_, _) | Type::Unit @@ -1934,8 +1939,8 @@ impl Type { } (Constant(value, kind), other) | (other, Constant(value, kind)) => { - let dummy_span = Span::default(); - if let Ok(other_value) = other.evaluate_to_field_element(kind, dummy_span) { + let dummy_location = Location::dummy(); + if let Ok(other_value) = other.evaluate_to_field_element(kind, dummy_location) { if *value == other_value && kind.unifies(&other.kind()) { Ok(()) } else { @@ -2012,7 +2017,7 @@ impl Type { &self, expected: &Type, expression: ExprId, - span: Span, + location: Location, interner: &mut NodeInterner, errors: &mut Vec, make_error: impl FnOnce() -> TypeCheckError, @@ -2032,14 +2037,16 @@ impl Type { match self.try_fn_to_unconstrained_fn_coercion(expected) { FunctionCoercionResult::NoCoercion => errors.push(make_error()), FunctionCoercionResult::Coerced(coerced_self) => { - coerced_self - .unify_with_coercions(expected, expression, span, interner, errors, make_error); + coerced_self.unify_with_coercions( + expected, expression, location, interner, errors, make_error, + ); } FunctionCoercionResult::UnconstrainedMismatch(coerced_self) => { - errors.push(TypeCheckError::UnsafeFn { span }); + errors.push(TypeCheckError::UnsafeFn { location }); - coerced_self - .unify_with_coercions(expected, expression, span, interner, errors, make_error); + coerced_self.unify_with_coercions( + expected, expression, location, interner, errors, make_error, + ); } } } @@ -2104,8 +2111,8 @@ impl Type { /// If this type is a Type::Constant (used in array lengths), or is bound /// to a Type::Constant, return the constant as a u32. - pub fn evaluate_to_u32(&self, span: Span) -> Result { - self.evaluate_to_field_element(&Kind::u32(), span).map(|field_element| { + pub fn evaluate_to_u32(&self, location: Location) -> Result { + self.evaluate_to_field_element(&Kind::u32(), location).map(|field_element| { field_element .try_to_u32() .expect("ICE: size should have already been checked by evaluate_to_field_element") @@ -2117,17 +2124,17 @@ impl Type { pub(crate) fn evaluate_to_field_element( &self, kind: &Kind, - span: Span, + location: Location, ) -> Result { let run_simplifications = true; - self.evaluate_to_field_element_helper(kind, span, run_simplifications) + self.evaluate_to_field_element_helper(kind, location, run_simplifications) } /// evaluate_to_field_element with optional generic arithmetic simplifications pub(crate) fn evaluate_to_field_element_helper( &self, kind: &Kind, - span: Span, + location: Location, run_simplifications: bool, ) -> Result { if let Some((binding, binding_kind)) = self.get_inner_type_variable() { @@ -2135,7 +2142,7 @@ impl Type { if kind.unifies(&binding_kind) { return binding.evaluate_to_field_element_helper( &binding_kind, - span, + location, run_simplifications, ); } @@ -2146,12 +2153,12 @@ impl Type { match self.canonicalize_helper(could_be_checked_cast, run_simplifications) { Type::Constant(x, constant_kind) => { if kind.unifies(&constant_kind) { - kind.ensure_value_fits(x, span) + kind.ensure_value_fits(x, location) } else { Err(TypeCheckError::TypeKindMismatch { expected_kind: format!("{}", constant_kind), expr_kind: format!("{}", kind), - expr_span: span, + expr_location: location, }) } } @@ -2160,31 +2167,31 @@ impl Type { if kind.unifies(&infix_kind) { let lhs_value = lhs.evaluate_to_field_element_helper( &infix_kind, - span, + location, run_simplifications, )?; let rhs_value = rhs.evaluate_to_field_element_helper( &infix_kind, - span, + location, run_simplifications, )?; - op.function(lhs_value, rhs_value, &infix_kind, span) + op.function(lhs_value, rhs_value, &infix_kind, location) } else { Err(TypeCheckError::TypeKindMismatch { expected_kind: format!("{}", kind), expr_kind: format!("{}", infix_kind), - expr_span: span, + expr_location: location, }) } } Type::CheckedCast { from, to } => { - let to_value = to.evaluate_to_field_element(kind, span)?; + let to_value = to.evaluate_to_field_element(kind, location)?; // if both 'to' and 'from' evaluate to a constant, // return None unless they match let skip_simplifications = false; if let Ok(from_value) = - from.evaluate_to_field_element_helper(kind, span, skip_simplifications) + from.evaluate_to_field_element_helper(kind, location, skip_simplifications) { if to_value == from_value { Ok(to_value) @@ -2196,14 +2203,14 @@ impl Type { from, to_value, from_value, - span, + location, }) } } else { Ok(to_value) } } - other => Err(TypeCheckError::NonConstantEvaluated { typ: other, span }), + other => Err(TypeCheckError::NonConstantEvaluated { typ: other, location }), } } @@ -2804,7 +2811,7 @@ impl BinaryTypeOperator { a: FieldElement, b: FieldElement, kind: &Kind, - span: Span, + location: Location, ) -> Result { match kind.follow_bindings().integral_maximum_size() { None => match self { @@ -2813,16 +2820,16 @@ impl BinaryTypeOperator { BinaryTypeOperator::Multiplication => Ok(a * b), BinaryTypeOperator::Division => (b != FieldElement::zero()) .then(|| a / b) - .ok_or(TypeCheckError::DivisionByZero { lhs: a, rhs: b, span }), + .ok_or(TypeCheckError::DivisionByZero { lhs: a, rhs: b, location }), BinaryTypeOperator::Modulo => { - Err(TypeCheckError::ModuloOnFields { lhs: a, rhs: b, span }) + Err(TypeCheckError::ModuloOnFields { lhs: a, rhs: b, location }) } }, Some(_maximum_size) => { let a = a.to_i128(); let b = b.to_i128(); - let err = TypeCheckError::FailingBinaryOp { op: self, lhs: a, rhs: b, span }; + let err = TypeCheckError::FailingBinaryOp { op: self, lhs: a, rhs: b, location }; let result = match self { BinaryTypeOperator::Addition => a.checked_add(b).ok_or(err)?, BinaryTypeOperator::Subtraction => a.checked_sub(b).ok_or(err)?, @@ -2876,9 +2883,10 @@ impl From<&Type> for PrintableType { match value { Type::FieldElement => PrintableType::Field, Type::Array(size, typ) => { - let dummy_span = Span::default(); - let length = - size.evaluate_to_u32(dummy_span).expect("Cannot print variable sized arrays"); + let dummy_location = Location::dummy(); + let length = size + .evaluate_to_u32(dummy_location) + .expect("Cannot print variable sized arrays"); let typ = typ.as_ref(); PrintableType::Array { length, typ: Box::new(typ.into()) } } @@ -2903,9 +2911,10 @@ impl From<&Type> for PrintableType { }, Type::Bool => PrintableType::Boolean, Type::String(size) => { - let dummy_span = Span::default(); - let size = - size.evaluate_to_u32(dummy_span).expect("Cannot print variable sized strings"); + let dummy_location = Location::dummy(); + let size = size + .evaluate_to_u32(dummy_location) + .expect("Cannot print variable sized strings"); PrintableType::String { length: size } } Type::FmtString(_, _) => unreachable!("format strings cannot be printed"), diff --git a/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs b/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs index ce9125cd5f0..ad35e1a11bf 100644 --- a/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs +++ b/compiler/noirc_frontend/src/hir_def/types/arithmetic.rs @@ -1,7 +1,7 @@ use std::collections::BTreeMap; use acvm::{AcirField, FieldElement}; -use noirc_errors::Span; +use noirc_errors::Location; use crate::{BinaryTypeOperator, Type, TypeBindings, UnificationError}; @@ -60,16 +60,19 @@ impl Type { match self.follow_bindings() { Type::InfixExpr(lhs, op, rhs, inversion) => { let kind = lhs.infix_kind(&rhs); - let dummy_span = Span::default(); + let dummy_location = Location::dummy(); // evaluate_to_field_element also calls canonicalize so if we just called // `self.evaluate_to_field_element(..)` we'd get infinite recursion. if let Ok(lhs_value) = - lhs.evaluate_to_field_element_helper(&kind, dummy_span, run_simplifications) + lhs.evaluate_to_field_element_helper(&kind, dummy_location, run_simplifications) { - if let Ok(rhs_value) = - rhs.evaluate_to_field_element_helper(&kind, dummy_span, run_simplifications) - { - if let Ok(result) = op.function(lhs_value, rhs_value, &kind, dummy_span) { + if let Ok(rhs_value) = rhs.evaluate_to_field_element_helper( + &kind, + dummy_location, + run_simplifications, + ) { + if let Ok(result) = op.function(lhs_value, rhs_value, &kind, dummy_location) + { return Type::Constant(result, kind); } } @@ -139,9 +142,9 @@ impl Type { queue.push(*rhs_inner); } Type::Constant(new_constant, new_constant_kind) => { - let dummy_span = Span::default(); + let dummy_location = Location::dummy(); if let Ok(result) = - op.function(constant, new_constant, &new_constant_kind, dummy_span) + op.function(constant, new_constant, &new_constant_kind, dummy_location) { constant = result; } else { @@ -268,15 +271,14 @@ impl Type { rhs: &Type, ) -> Option<(Box, BinaryTypeOperator, FieldElement, FieldElement)> { let kind = lhs.infix_kind(rhs); - let dummy_span = Span::default(); - let rhs = rhs.evaluate_to_field_element(&kind, dummy_span).ok()?; + let dummy_location = Location::dummy(); + let rhs = rhs.evaluate_to_field_element(&kind, dummy_location).ok()?; let Type::InfixExpr(l_type, l_op, l_rhs, _) = lhs.follow_bindings() else { return None; }; - let dummy_span = Span::default(); - let l_rhs = l_rhs.evaluate_to_field_element(&kind, dummy_span).ok()?; + let l_rhs = l_rhs.evaluate_to_field_element(&kind, dummy_location).ok()?; Some((l_type, l_op, l_rhs, rhs)) } @@ -301,9 +303,9 @@ impl Type { if l_op == Subtraction { op = op.inverse()?; } - let dummy_span = Span::default(); + let dummy_location = Location::dummy(); let result = - op.function(l_const, r_const, &lhs.infix_kind(rhs), dummy_span).ok()?; + op.function(l_const, r_const, &lhs.infix_kind(rhs), dummy_location).ok()?; let constant = Type::Constant(result, lhs.infix_kind(rhs)); Some(Type::infix_expr(l_type, l_op, Box::new(constant))) } @@ -316,9 +318,9 @@ impl Type { if op == Division && (r_const == FieldElement::zero() || !divides_evenly) { None } else { - let dummy_span = Span::default(); + let dummy_location = Location::dummy(); let result = - op.function(l_const, r_const, &lhs.infix_kind(rhs), dummy_span).ok()?; + op.function(l_const, r_const, &lhs.infix_kind(rhs), dummy_location).ok()?; let constant = Box::new(Type::Constant(result, lhs.infix_kind(rhs))); Some(Type::infix_expr(l_type, l_op, constant)) } @@ -337,8 +339,8 @@ impl Type { if let Type::InfixExpr(lhs_a, op_a, rhs_a, _) = self { if let Some(inverse) = op_a.approx_inverse() { let kind = lhs_a.infix_kind(rhs_a); - let dummy_span = Span::default(); - if let Ok(rhs_a_value) = rhs_a.evaluate_to_field_element(&kind, dummy_span) { + let dummy_location = Location::dummy(); + if let Ok(rhs_a_value) = rhs_a.evaluate_to_field_element(&kind, dummy_location) { let rhs_a = Box::new(Type::Constant(rhs_a_value, kind)); let new_other = Type::inverted_infix_expr(Box::new(other.clone()), inverse, rhs_a); @@ -355,8 +357,8 @@ impl Type { if let Type::InfixExpr(lhs_b, op_b, rhs_b, inversion) = other { if let Some(inverse) = op_b.approx_inverse() { let kind = lhs_b.infix_kind(rhs_b); - let dummy_span = Span::default(); - if let Ok(rhs_b_value) = rhs_b.evaluate_to_field_element(&kind, dummy_span) { + let dummy_location = Location::dummy(); + if let Ok(rhs_b_value) = rhs_b.evaluate_to_field_element(&kind, dummy_location) { let rhs_b = Box::new(Type::Constant(rhs_b_value, kind)); let new_self = Type::InfixExpr(Box::new(self.clone()), inverse, rhs_b, !inversion); diff --git a/compiler/noirc_frontend/src/lexer/errors.rs b/compiler/noirc_frontend/src/lexer/errors.rs index 9f191eff18c..9adae78febd 100644 --- a/compiler/noirc_frontend/src/lexer/errors.rs +++ b/compiler/noirc_frontend/src/lexer/errors.rs @@ -6,7 +6,6 @@ use super::token::LocatedToken; use super::token::Token; use noirc_errors::CustomDiagnostic as Diagnostic; use noirc_errors::Location; -use noirc_errors::Span; use thiserror::Error; #[derive(Error, Clone, Debug, PartialEq, Eq)] @@ -82,7 +81,7 @@ impl LexerErrorKind { } } - fn parts(&self) -> (String, String, Span) { + fn parts(&self) -> (String, String, Location) { match self { LexerErrorKind::UnexpectedCharacter { location, @@ -94,7 +93,7 @@ impl LexerErrorKind { ( "An unexpected character was found".to_string(), format!("Expected {expected}, but found {found}"), - location.span, + *location, ) }, LexerErrorKind::NotADoubleChar { location, found } => ( @@ -102,47 +101,47 @@ impl LexerErrorKind { format!( " {found:?} is not a double char, this is an internal error" ), - location.span, + *location, ), LexerErrorKind::InvalidIntegerLiteral { location, found } => ( "Invalid integer literal".to_string(), format!(" {found} is not an integer"), - location.span, + *location, ), LexerErrorKind::IntegerLiteralTooLarge { location, limit } => ( "Integer literal is too large".to_string(), format!("value exceeds limit of {limit}"), - location.span, + *location, ), LexerErrorKind::MalformedFuncAttribute { location, found } => ( "Malformed function attribute".to_string(), format!(" {found} is not a valid attribute"), - location.span, + *location, ), LexerErrorKind::MalformedTestAttribute { location } => ( "Malformed test attribute".to_string(), "The test attribute can be written in one of these forms: `#[test]`, `#[test(should_fail)]` or `#[test(should_fail_with = \"message\")]`".to_string(), - location.span, + *location, ), LexerErrorKind::InvalidInnerAttribute { location, found } => ( "Invalid inner attribute".to_string(), format!(" {found} is not a valid inner attribute"), - location.span, + *location, ), LexerErrorKind::LogicalAnd { location } => ( "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(), - location.span, + *location, ), - LexerErrorKind::UnterminatedBlockComment { location } => ("Unterminated block comment".to_string(), "Unterminated block comment".to_string(), location.span), + LexerErrorKind::UnterminatedBlockComment { location } => ("Unterminated block comment".to_string(), "Unterminated block comment".to_string(), *location), LexerErrorKind::UnterminatedStringLiteral { location } => - ("Unterminated string literal".to_string(), "Unterminated string literal".to_string(), location.span), + ("Unterminated string literal".to_string(), "Unterminated string literal".to_string(), *location), LexerErrorKind::InvalidFormatString { found, location } => { if found == &'}' { ( "Invalid format string: unmatched '}}' found".to_string(), "If you intended to print '}', you can escape it using '}}'".to_string(), - location.span, + *location, ) } else { ( @@ -152,7 +151,7 @@ impl LexerErrorKind { } else { "If you intended to print '{', you can escape it using '{{'".to_string() }, - location.span, + *location, ) } } @@ -160,19 +159,19 @@ impl LexerErrorKind { ( "Invalid format string: expected letter or underscore, found '}}'".to_string(), "If you intended to print '{' or '}', you can escape them using '{{' and '}}' respectively".to_string(), - location.span, + *location, ) } LexerErrorKind::InvalidEscape { escaped, location } => - (format!("'\\{escaped}' is not a valid escape sequence. Use '\\' for a literal backslash character."), "Invalid escape sequence".to_string(), location.span), + (format!("'\\{escaped}' is not a valid escape sequence. Use '\\' for a literal backslash character."), "Invalid escape sequence".to_string(), *location), LexerErrorKind::InvalidQuoteDelimiter { delimiter } => { - (format!("Invalid quote delimiter `{delimiter}`"), "Valid delimiters are `{`, `[`, and `(`".to_string(), delimiter.span()) + (format!("Invalid quote delimiter `{delimiter}`"), "Valid delimiters are `{`, `[`, and `(`".to_string(), delimiter.location()) }, LexerErrorKind::NonAsciiComment { location } => { - ("Non-ASCII character in comment".to_string(), "Invalid comment character: only ASCII is currently supported.".to_string(), location.span) + ("Non-ASCII character in comment".to_string(), "Invalid comment character: only ASCII is currently supported.".to_string(), *location) } LexerErrorKind::UnclosedQuote { start_delim, end_delim } => { - ("Unclosed `quote` expression".to_string(), format!("Expected a `{end_delim}` to close this `{start_delim}`"), start_delim.span()) + ("Unclosed `quote` expression".to_string(), format!("Expected a `{end_delim}` to close this `{start_delim}`"), start_delim.location()) } } } diff --git a/compiler/noirc_frontend/src/monomorphization/errors.rs b/compiler/noirc_frontend/src/monomorphization/errors.rs index c137a6fc90a..86df6260ad3 100644 --- a/compiler/noirc_frontend/src/monomorphization/errors.rs +++ b/compiler/noirc_frontend/src/monomorphization/errors.rs @@ -29,7 +29,7 @@ impl MonomorphizationError { | MonomorphizationError::CheckedTransmuteFailed { location, .. } | MonomorphizationError::CheckedCastFailed { location, .. } | MonomorphizationError::NoDefaultType { location, .. } => *location, - MonomorphizationError::InterpreterError(error) => error.get_location(), + MonomorphizationError::InterpreterError(error) => error.location(), } } } @@ -61,7 +61,7 @@ impl MonomorphizationError { MonomorphizationError::NoDefaultType { location } => { let message = "Type annotation needed".into(); let secondary = "Could not determine type of generic argument".into(); - return CustomDiagnostic::simple_error(message, secondary, location.span); + return CustomDiagnostic::simple_error(message, secondary, *location); } MonomorphizationError::InterpreterError(error) => return error.into(), MonomorphizationError::InternalError { message, .. } => message.to_string(), @@ -69,16 +69,16 @@ impl MonomorphizationError { let message = format!("Comptime function {name} used in runtime code"); let secondary = "Comptime functions must be in a comptime block to be called".into(); - return CustomDiagnostic::simple_error(message, secondary, location.span); + return CustomDiagnostic::simple_error(message, secondary, *location); } MonomorphizationError::ComptimeTypeInRuntimeCode { typ, location } => { let message = format!("Comptime-only type `{typ}` used in runtime code"); let secondary = "Comptime type used here".into(); - return CustomDiagnostic::simple_error(message, secondary, location.span); + return CustomDiagnostic::simple_error(message, secondary, *location); } }; let location = self.location(); - CustomDiagnostic::simple_error(message, String::new(), location.span) + CustomDiagnostic::simple_error(message, String::new(), location) } } diff --git a/compiler/noirc_frontend/src/monomorphization/mod.rs b/compiler/noirc_frontend/src/monomorphization/mod.rs index d30229ce97d..dec2b07e02d 100644 --- a/compiler/noirc_frontend/src/monomorphization/mod.rs +++ b/compiler/noirc_frontend/src/monomorphization/mod.rs @@ -646,7 +646,7 @@ impl<'interner> Monomorphizer<'interner> { let location = self.interner.expr_location(&array); let typ = Self::convert_type(&self.interner.id_type(array), location)?; - let length = length.evaluate_to_u32(location.span).map_err(|err| { + let length = length.evaluate_to_u32(location).map_err(|err| { let location = self.interner.expr_location(&array); MonomorphizationError::UnknownArrayLength { location, err, length } })?; @@ -1027,7 +1027,7 @@ impl<'interner> Monomorphizer<'interner> { binding .evaluate_to_field_element( &Kind::Numeric(numeric_typ.clone()), - location.span, + location, ) .map_err(|err| MonomorphizationError::UnknownArrayLength { length: binding.clone(), @@ -1119,7 +1119,7 @@ impl<'interner> Monomorphizer<'interner> { HirType::Integer(sign, bits) => ast::Type::Integer(*sign, *bits), HirType::Bool => ast::Type::Bool, HirType::String(size) => { - let size = match size.evaluate_to_u32(location.span) { + let size = match size.evaluate_to_u32(location) { Ok(size) => size, // only default variable sizes to size 0 Err(TypeCheckError::NonConstantEvaluated { .. }) => 0, @@ -1135,7 +1135,7 @@ impl<'interner> Monomorphizer<'interner> { ast::Type::String(size) } HirType::FmtString(size, fields) => { - let size = match size.evaluate_to_u32(location.span) { + let size = match size.evaluate_to_u32(location) { Ok(size) => size, // only default variable sizes to size 0 Err(TypeCheckError::NonConstantEvaluated { .. }) => 0, @@ -1154,7 +1154,7 @@ impl<'interner> Monomorphizer<'interner> { HirType::Unit => ast::Type::Unit, HirType::Array(length, element) => { let element = Box::new(Self::convert_type(element.as_ref(), location)?); - let length = match length.evaluate_to_u32(location.span) { + let length = match length.evaluate_to_u32(location) { Ok(length) => length, Err(err) => { let length = length.as_ref().clone(); @@ -1402,14 +1402,11 @@ impl<'interner> Monomorphizer<'interner> { location, }); } - let to_value = to.evaluate_to_field_element(&to.kind(), location.span); + let to_value = to.evaluate_to_field_element(&to.kind(), location); if to_value.is_ok() { let skip_simplifications = false; - let from_value = from.evaluate_to_field_element_helper( - &to.kind(), - location.span, - skip_simplifications, - ); + let from_value = + from.evaluate_to_field_element_helper(&to.kind(), location, skip_simplifications); if from_value.is_err() || from_value.unwrap() != to_value.clone().unwrap() { return Err(MonomorphizationError::CheckedCastFailed { actual: HirType::Constant(to_value.unwrap(), to.kind()), @@ -2375,10 +2372,9 @@ pub fn resolve_trait_method( } Err(ImplSearchErrorKind::Nested(constraints)) => { if let Some(error) = - NoMatchingImplFoundError::new(interner, constraints, location.span) + NoMatchingImplFoundError::new(interner, constraints, location) { - let file = location.file; - return Err(InterpreterError::NoMatchingImplFound { error, file }); + return Err(InterpreterError::NoMatchingImplFound { error }); } else { return Err(InterpreterError::NoImpl { location }); } diff --git a/compiler/noirc_frontend/src/node_interner.rs b/compiler/noirc_frontend/src/node_interner.rs index a3d2441d93b..dabb940996a 100644 --- a/compiler/noirc_frontend/src/node_interner.rs +++ b/compiler/noirc_frontend/src/node_interner.rs @@ -914,11 +914,11 @@ impl NodeInterner { comptime: bool, ) -> GlobalId { let statement = self.push_stmt(HirStatement::Error); - let span = name.span(); + let location = name.location(); let id = self .push_global(name, local_id, crate_id, statement, file, attributes, mutable, comptime); - self.push_stmt_location(statement, span, file); + self.push_stmt_location(statement, location); id } @@ -1226,8 +1226,8 @@ impl NodeInterner { self.id_location(stmt_id) } - pub fn push_stmt_location(&mut self, id: StmtId, span: Span, file: FileId) { - self.id_to_location.insert(id.into(), Location::new(span, file)); + pub fn push_stmt_location(&mut self, id: StmtId, location: Location) { + self.id_to_location.insert(id.into(), location); } pub fn get_type(&self, id: TypeId) -> Shared { @@ -1517,7 +1517,7 @@ impl NodeInterner { trait_bound: ResolvedTraitBound { trait_id, trait_generics: TraitGenerics { ordered, named }, - span: Span::default(), + location: Location::dummy(), }, } }; @@ -1601,7 +1601,7 @@ impl NodeInterner { trait_bound: ResolvedTraitBound { trait_id, trait_generics, - span: Span::default(), + location: Location::dummy(), }, }; matching_impls.push((impl_kind.clone(), fresh_bindings, constraint)); @@ -1712,7 +1712,7 @@ impl NodeInterner { impl_id: TraitImplId, impl_generics: GenericTypeVars, trait_impl: Shared, - ) -> Result<(), (Location, FileId)> { + ) -> Result<(), Location> { self.trait_implementations.insert(impl_id, trait_impl.clone()); // Avoid adding error types to impls since they'll conflict with every other type. @@ -1764,7 +1764,7 @@ impl NodeInterner { ) { let existing_impl = self.get_trait_implementation(existing); let existing_impl = existing_impl.borrow(); - return Err((existing_impl.ident.location(), existing_impl.file)); + return Err(existing_impl.ident.location()); } for method in &trait_impl.borrow().methods { @@ -2036,15 +2036,14 @@ impl NodeInterner { index } - pub(crate) fn check_for_dependency_cycles(&self) -> Vec<(CompilationError, FileId)> { + pub(crate) fn check_for_dependency_cycles(&self) -> Vec { let strongly_connected_components = tarjan_scc(&self.dependency_graph); let mut errors = Vec::new(); let mut push_error = |item: String, scc: &[_], i, location: Location| { let cycle = self.get_cycle_error_string(scc, i); - let span = location.span; - let error = ResolverError::DependencyCycle { item, cycle, span }; - errors.push((error.into(), location.file)); + let error = ResolverError::DependencyCycle { item, cycle, location }; + errors.push(error.into()); }; for scc in strongly_connected_components { diff --git a/compiler/noirc_frontend/src/parser/errors.rs b/compiler/noirc_frontend/src/parser/errors.rs index 99b1f975e4a..3e25c4cf077 100644 --- a/compiler/noirc_frontend/src/parser/errors.rs +++ b/compiler/noirc_frontend/src/parser/errors.rs @@ -247,7 +247,7 @@ impl<'a> From<&'a ParserError> for Diagnostic { let mut diagnostic = Diagnostic::simple_error( "Use of deprecated keyword 'constrain'".into(), "The 'constrain' keyword is deprecated. Please use the 'assert' function instead.".into(), - error.span(), + error.location(), ); diagnostic.deprecated = true; diagnostic @@ -256,7 +256,7 @@ impl<'a> From<&'a ParserError> for Diagnostic { let mut diagnostic = Diagnostic::simple_warning( "Use of deprecated keyword 'comptime'".into(), "The 'comptime' keyword has been deprecated. It can be removed without affecting your program".into(), - error.span(), + error.location(), ) ; diagnostic.deprecated = true; diagnostic @@ -271,49 +271,51 @@ impl<'a> From<&'a ParserError> for Diagnostic { .collect::>() .join(", ") ), - error.span(), + error.location(), ), ParserErrorReason::ExperimentalFeature(feature) => { let secondary = format!( "Pass -Z{feature} to nargo to enable this feature at your own risk." ); - Diagnostic::simple_error(reason.to_string(), secondary, error.span()) + Diagnostic::simple_error(reason.to_string(), secondary, error.location()) } ParserErrorReason::TraitVisibilityIgnored => { - Diagnostic::simple_warning(reason.to_string(), "".into(), error.span()) + Diagnostic::simple_warning(reason.to_string(), "".into(), error.location()) } ParserErrorReason::TraitImplVisibilityIgnored => { - Diagnostic::simple_warning(reason.to_string(), "".into(), error.span()) + Diagnostic::simple_warning(reason.to_string(), "".into(), error.location()) } ParserErrorReason::ExpectedPatternButFoundType(ty) => Diagnostic::simple_error( format!("Expected a pattern but found a type - {ty}"), format!("{ty} is a type and cannot be used as a variable name"), - error.span(), + error.location(), ), ParserErrorReason::Lexer(error) => error.into(), ParserErrorReason::ExpectedMutAfterAmpersand { found } => Diagnostic::simple_error( format!("Expected `mut` after `&`, found `{found}`"), "Noir doesn't have immutable references, only mutable references".to_string(), - error.span(), + error.location(), ), ParserErrorReason::MissingSafetyComment => Diagnostic::simple_warning( "Unsafe block must have a safety comment above it".into(), "The comment must start with the \"Safety: \" word".into(), - error.span(), + error.location(), ), ParserErrorReason::MissingParametersForFunctionDefinition => { Diagnostic::simple_error( "Missing parameters for function definition".into(), "Add a parameter list: `()`".into(), - error.span(), + error.location(), ) } ParserErrorReason::DocCommentDoesNotDocumentAnything => { let primary = "This doc comment doesn't document anything".to_string(); let secondary = "Consider changing it to a regular `//` comment".to_string(); - Diagnostic::simple_warning(primary, secondary, error.span()) + Diagnostic::simple_warning(primary, secondary, error.location()) + } + other => { + Diagnostic::simple_error(format!("{other}"), String::new(), error.location()) } - other => Diagnostic::simple_error(format!("{other}"), String::new(), error.span()), }, None => { if matches!( @@ -322,10 +324,10 @@ impl<'a> From<&'a ParserError> for Diagnostic { ) { let primary = "This doc comment doesn't document anything".to_string(); let secondary = "Consider changing it to a regular `//` comment".to_string(); - Diagnostic::simple_warning(primary, secondary, error.span()) + Diagnostic::simple_warning(primary, secondary, error.location()) } else { let primary = error.to_string(); - Diagnostic::simple_error(primary, String::new(), error.span()) + Diagnostic::simple_error(primary, String::new(), error.location()) } } } diff --git a/compiler/noirc_frontend/src/parser/parser/expression.rs b/compiler/noirc_frontend/src/parser/parser/expression.rs index 16207bb3bcf..150d3c7abef 100644 --- a/compiler/noirc_frontend/src/parser/parser/expression.rs +++ b/compiler/noirc_frontend/src/parser/parser/expression.rs @@ -6,7 +6,7 @@ use crate::{ ArrayLiteral, BlockExpression, CallExpression, CastExpression, ConstrainExpression, ConstrainKind, ConstructorExpression, Expression, ExpressionKind, Ident, IfExpression, IndexExpression, Literal, MatchExpression, MemberAccessExpression, MethodCallExpression, - Statement, TypePath, UnaryOp, UnresolvedType, + Statement, TypePath, UnaryOp, UnresolvedType, UnsafeExpression, }, parser::{labels::ParsingRuleLabel, parser::parse_many::separated_by_comma, ParserErrorReason}, token::{Keyword, Token, TokenKind}, @@ -406,7 +406,10 @@ impl<'a> Parser<'a> { } if let Some(block) = self.parse_block() { - Some(ExpressionKind::Unsafe(block, self.location_since(start_location))) + Some(ExpressionKind::Unsafe(UnsafeExpression { + block, + unsafe_keyword_location: start_location, + })) } else { Some(ExpressionKind::Error) } @@ -1082,10 +1085,10 @@ mod tests { // Safety: test unsafe { 1 }"; let expr = parse_expression_no_errors(src); - let ExpressionKind::Unsafe(block, _) = expr.kind else { + let ExpressionKind::Unsafe(unsafe_expression) = expr.kind else { panic!("Expected unsafe expression"); }; - assert_eq!(block.statements.len(), 1); + assert_eq!(unsafe_expression.block.statements.len(), 1); } #[test] @@ -1096,10 +1099,10 @@ mod tests { let mut parser = Parser::for_str_with_dummy_file(src); let expr = parser.parse_expression().unwrap(); - let ExpressionKind::Unsafe(block, _) = expr.kind else { + let ExpressionKind::Unsafe(unsafe_expression) = expr.kind else { panic!("Expected unsafe expression"); }; - assert_eq!(block.statements.len(), 1); + assert_eq!(unsafe_expression.block.statements.len(), 1); } #[test] diff --git a/compiler/noirc_frontend/src/parser/parser/path.rs b/compiler/noirc_frontend/src/parser/parser/path.rs index 7d000a9c28a..b6262dc1352 100644 --- a/compiler/noirc_frontend/src/parser/parser/path.rs +++ b/compiler/noirc_frontend/src/parser/parser/path.rs @@ -17,11 +17,7 @@ impl<'a> Parser<'a> { } else { self.expected_label(ParsingRuleLabel::Path); - Path { - segments: Vec::new(), - kind: PathKind::Plain, - location: self.location_at_previous_token_end(), - } + Path::plain(Vec::new(), self.location_at_previous_token_end()) } } @@ -44,11 +40,7 @@ impl<'a> Parser<'a> { } else { self.expected_label(ParsingRuleLabel::Path); - Path { - segments: Vec::new(), - kind: PathKind::Plain, - location: self.location_at_previous_token_end(), - } + Path::plain(Vec::new(), self.location_at_previous_token_end()) } } @@ -151,7 +143,8 @@ impl<'a> Parser<'a> { } } - Path { segments, kind, location: self.location_since(start_location) } + let location = self.location_since(start_location); + Path { segments, kind, kind_location: start_location, location } } /// PathGenerics = GenericTypeArgs diff --git a/compiler/noirc_frontend/src/parser/parser/use_tree.rs b/compiler/noirc_frontend/src/parser/parser/use_tree.rs index d508490f283..f107387ad32 100644 --- a/compiler/noirc_frontend/src/parser/parser/use_tree.rs +++ b/compiler/noirc_frontend/src/parser/parser/use_tree.rs @@ -76,11 +76,7 @@ impl<'a> Parser<'a> { // Special case: "self" cannot be followed by anything else if self.eat_self() { return Some(UseTree { - prefix: Path { - segments: Vec::new(), - kind: PathKind::Plain, - location: start_location, - }, + prefix: Path::plain(Vec::new(), start_location), kind: UseTreeKind::Path(Ident::new("self".to_string(), start_location), None), location: start_location, }); diff --git a/compiler/noirc_frontend/src/parser/parser/where_clause.rs b/compiler/noirc_frontend/src/parser/parser/where_clause.rs index fed51995a3f..09e2f106481 100644 --- a/compiler/noirc_frontend/src/parser/parser/where_clause.rs +++ b/compiler/noirc_frontend/src/parser/parser/where_clause.rs @@ -1,5 +1,5 @@ use crate::{ - ast::{GenericTypeArgs, Path, PathKind, TraitBound, UnresolvedTraitConstraint, UnresolvedType}, + ast::{GenericTypeArgs, Path, TraitBound, UnresolvedTraitConstraint, UnresolvedType}, parser::labels::ParsingRuleLabel, token::{Keyword, Token}, }; @@ -70,11 +70,7 @@ impl<'a> Parser<'a> { self.expected_label(ParsingRuleLabel::TraitBound); TraitBound { - trait_path: Path { - kind: PathKind::Plain, - segments: Vec::new(), - location: self.location_at_previous_token_end(), - }, + trait_path: Path::plain(Vec::new(), self.location_at_previous_token_end()), trait_id: None, trait_generics: GenericTypeArgs::default(), } diff --git a/compiler/noirc_frontend/src/tests.rs b/compiler/noirc_frontend/src/tests.rs index d719e437140..3238d7106d7 100644 --- a/compiler/noirc_frontend/src/tests.rs +++ b/compiler/noirc_frontend/src/tests.rs @@ -47,12 +47,12 @@ use crate::{parse_program, ParsedModule}; use fm::FileManager; use noirc_arena::Arena; -pub(crate) fn has_parser_error(errors: &[(CompilationError, FileId)]) -> bool { - errors.iter().any(|(e, _f)| matches!(e, CompilationError::ParseError(_))) +pub(crate) fn has_parser_error(errors: &[CompilationError]) -> bool { + errors.iter().any(|e| matches!(e, CompilationError::ParseError(_))) } -pub(crate) fn remove_experimental_warnings(errors: &mut Vec<(CompilationError, FileId)>) { - errors.retain(|(error, _)| match error { +pub(crate) fn remove_experimental_warnings(errors: &mut Vec) { + errors.retain(|error| match error { CompilationError::ParseError(error) => { !matches!(error.reason(), Some(ParserErrorReason::ExperimentalFeature(..))) } @@ -60,7 +60,7 @@ pub(crate) fn remove_experimental_warnings(errors: &mut Vec<(CompilationError, F }); } -pub(crate) fn get_program(src: &str) -> (ParsedModule, Context, Vec<(CompilationError, FileId)>) { +pub(crate) fn get_program(src: &str) -> (ParsedModule, Context, Vec) { let allow_parser_errors = false; get_program_with_maybe_parser_errors(src, allow_parser_errors, FrontendOptions::test_default()) } @@ -68,7 +68,7 @@ pub(crate) fn get_program(src: &str) -> (ParsedModule, Context, Vec<(Compilation pub(crate) fn get_program_using_features( src: &str, features: &[UnstableFeature], -) -> (ParsedModule, Context<'static, 'static>, Vec<(CompilationError, FileId)>) { +) -> (ParsedModule, Context<'static, 'static>, Vec) { let allow_parser_errors = false; let mut options = FrontendOptions::test_default(); options.enabled_unstable_features = features; @@ -82,7 +82,7 @@ pub(crate) fn get_program_with_maybe_parser_errors( src: &str, allow_parser_errors: bool, options: FrontendOptions, -) -> (ParsedModule, Context<'static, 'static>, Vec<(CompilationError, FileId)>) { +) -> (ParsedModule, Context<'static, 'static>, Vec) { let root = std::path::Path::new("/"); let fm = FileManager::new(root); @@ -92,7 +92,7 @@ pub(crate) fn get_program_with_maybe_parser_errors( let root_crate_id = context.crate_graph.add_crate_root(root_file_id); let (program, parser_errors) = parse_program(src, root_file_id); - let mut errors = vecmap(parser_errors, |e| (e.into(), root_file_id)); + let mut errors = vecmap(parser_errors, |e| e.into()); remove_experimental_warnings(&mut errors); if allow_parser_errors || !has_parser_error(&errors) { @@ -139,7 +139,7 @@ pub(crate) fn get_program_with_maybe_parser_errors( (program, context, errors) } -pub(crate) fn get_program_errors(src: &str) -> Vec<(CompilationError, FileId)> { +pub(crate) fn get_program_errors(src: &str) -> Vec { get_program(src).2 } @@ -228,7 +228,7 @@ fn check_trait_implementation_duplicate_method() { assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::DefinitionError(DefCollectorErrorKind::Duplicate { typ, @@ -270,12 +270,12 @@ fn check_trait_wrong_method_return_type() { assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, - expr_span: _, + expr_location: _, }) => { assert_eq!(expected_typ, "Foo"); assert_eq!(expr_typ, "Field"); @@ -312,12 +312,12 @@ fn check_trait_wrong_method_return_type2() { assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, - expr_span: _, + expr_location: _, }) => { assert_eq!(expected_typ, "Foo"); assert_eq!(expr_typ, "Field"); @@ -357,12 +357,12 @@ fn check_trait_missing_implementation() { assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::DefinitionError(DefCollectorErrorKind::TraitMissingMethod { trait_name, method_name, - trait_impl_span: _, + trait_impl_location: _, }) => { assert_eq!(trait_name, "Default"); assert_eq!(method_name, "method2"); @@ -396,7 +396,7 @@ fn check_trait_not_in_scope() { let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::DefinitionError(DefCollectorErrorKind::TraitNotFound { trait_path, @@ -439,7 +439,7 @@ fn check_trait_wrong_method_name() { compilation_errors ); - for (err, _file_id) in compilation_errors { + for err in compilation_errors { match &err { CompilationError::DefinitionError(DefCollectorErrorKind::MethodNotInTrait { trait_name, @@ -479,7 +479,7 @@ fn check_trait_wrong_parameter() { assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::TypeError(TypeCheckError::TraitMethodParameterTypeMismatch { method_name, @@ -523,7 +523,7 @@ fn check_trait_wrong_parameter2() { assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::TypeError(TypeCheckError::TraitMethodParameterTypeMismatch { method_name, @@ -559,7 +559,7 @@ fn check_trait_wrong_parameter_type() { // In the elaborator there is no duplicate and only 1 error is issued assert!(errors.len() <= 2, "Expected 1 or 2 errors, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Unresolved(ident), @@ -597,7 +597,7 @@ fn check_trait_wrong_parameters_count() { let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::TypeError(TypeCheckError::MismatchTraitImplNumParameters { actual_num_parameters, @@ -636,7 +636,7 @@ fn check_trait_impl_for_non_type() { let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::ResolverError(ResolverError::Expected { expected, got, .. }) => { assert_eq!(*expected, "type"); @@ -676,7 +676,7 @@ fn check_impl_struct_not_trait() { let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::DefinitionError(DefCollectorErrorKind::NotATrait { not_a_trait_name, @@ -718,7 +718,7 @@ fn check_trait_duplicate_declaration() { let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::DefinitionError(DefCollectorErrorKind::Duplicate { typ, @@ -755,20 +755,11 @@ fn check_trait_duplicate_implementation() { "; let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); - assert!(errors.len() == 2, "Expected 2 errors, got: {:?}", errors); - for (err, _file_id) in errors { - match &err { - CompilationError::DefinitionError(DefCollectorErrorKind::OverlappingImpl { - .. - }) => (), - CompilationError::DefinitionError(DefCollectorErrorKind::OverlappingImplNote { - .. - }) => (), - _ => { - panic!("No other errors are expected! Found = {:?}", err); - } - }; - } + assert!(errors.len() == 1, "Expected 1 errors, got: {:?}", errors); + assert!(matches!( + errors[0], + CompilationError::DefinitionError(DefCollectorErrorKind::OverlappingImpl { .. }) + )); } #[test] @@ -794,20 +785,11 @@ fn check_trait_duplicate_implementation_with_alias() { "; let errors = get_program_errors(src); assert!(!has_parser_error(&errors)); - assert!(errors.len() == 2, "Expected 2 errors, got: {:?}", errors); - for (err, _file_id) in errors { - match &err { - CompilationError::DefinitionError(DefCollectorErrorKind::OverlappingImpl { - .. - }) => (), - CompilationError::DefinitionError(DefCollectorErrorKind::OverlappingImplNote { - .. - }) => (), - _ => { - panic!("No other errors are expected! Found = {:?}", err); - } - }; - } + assert!(errors.len() == 1, "Expected 2 errors, got: {:?}", errors); + assert!(matches!( + errors[0], + CompilationError::DefinitionError(DefCollectorErrorKind::OverlappingImpl { .. }) + )); } #[test] @@ -974,7 +956,7 @@ fn resolve_unused_var() { let errors = get_program_errors(src); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); // It should be regarding the unused variable - match &errors[0].0 { + match &errors[0] { CompilationError::ResolverError(ResolverError::UnusedVariable { ident }) => { assert_eq!(&ident.0.contents, "y"); } @@ -993,8 +975,11 @@ fn resolve_unresolved_var() { let errors = get_program_errors(src); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); // It should be regarding the unresolved var `z` (Maybe change to undeclared and special case) - match &errors[0].0 { - CompilationError::ResolverError(ResolverError::VariableNotDeclared { name, span: _ }) => { + match &errors[0] { + CompilationError::ResolverError(ResolverError::VariableNotDeclared { + name, + location: _, + }) => { assert_eq!(name, "z"); } _ => unimplemented!("we should only have an unresolved variable"), @@ -1010,7 +995,7 @@ fn unresolved_path() { "; let errors = get_program_errors(src); assert!(errors.len() == 1, "Expected 1 error, got: {:?}", errors); - for (compilation_error, _file_id) in errors { + for compilation_error in errors { match compilation_error { CompilationError::ResolverError(err) => { match err { @@ -1052,7 +1037,7 @@ fn multiple_resolution_errors() { // `a` is undeclared // `z` is unused // `foo::bar` does not exist - for (compilation_error, _file_id) in errors { + for compilation_error in errors { match compilation_error { CompilationError::ResolverError(err) => { match err { @@ -1231,7 +1216,7 @@ fn resolve_fmt_strings() { let errors = get_program_errors(src); assert!(errors.len() == 3, "Expected 5 errors, got: {:?}", errors); - for (err, _file_id) in errors { + for err in errors { match &err { CompilationError::ResolverError(ResolverError::VariableNotDeclared { name, .. @@ -1240,9 +1225,11 @@ fn resolve_fmt_strings() { } CompilationError::TypeError(TypeCheckError::UnusedResultError { expr_type: _, - expr_span, + expr_location, }) => { - let a = src.get(expr_span.start() as usize..expr_span.end() as usize).unwrap(); + let a = src + .get(expr_location.span.start() as usize..expr_location.span.end() as usize) + .unwrap(); assert!( a == "println(string)" || a == "println(f\"random_string{new_val}{new_val}\")" ); @@ -1313,7 +1300,7 @@ fn deny_cyclic_globals() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::DependencyCycle { .. }) )); } @@ -1439,7 +1426,7 @@ fn deny_inline_attribute_on_unconstrained() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::NoPredicatesAttributeOnUnconstrained { .. }) )); } @@ -1455,7 +1442,7 @@ fn deny_fold_attribute_on_unconstrained() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::FoldAttributeOnUnconstrained { .. }) )); } @@ -1555,7 +1542,7 @@ fn incorrect_turbofish_count_function_call() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::IncorrectTurbofishGenericCount { .. }), )); } @@ -1593,7 +1580,7 @@ fn incorrect_turbofish_count_method_call() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::IncorrectTurbofishGenericCount { .. }), )); } @@ -1612,7 +1599,7 @@ fn struct_numeric_generic_in_function() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::UnsupportedNumericGenericType { .. }), )); } @@ -1629,7 +1616,7 @@ fn struct_numeric_generic_in_struct() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::UnsupportedNumericGenericType(_)), )); } @@ -1648,7 +1635,7 @@ fn bool_numeric_generic() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::UnsupportedNumericGenericType { .. }), )); } @@ -1665,7 +1652,7 @@ fn numeric_generic_binary_operation_type_mismatch() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeMismatchWithSource { .. }), )); } @@ -1684,18 +1671,18 @@ fn bool_generic_as_loop_bound() { let errors = get_program_errors(src); assert_eq!(errors.len(), 3); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::UnsupportedNumericGenericType { .. }), )); assert!(matches!( - errors[1].0, + errors[1], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); let CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, .. - }) = &errors[2].0 + }) = &errors[2] else { panic!("Got an error other than a type mismatch"); }; @@ -1723,7 +1710,7 @@ fn numeric_generic_as_struct_field_type_fails() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -1739,7 +1726,7 @@ fn normal_generic_as_array_length() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -1757,17 +1744,17 @@ fn numeric_generic_as_param_type() { // Error from the parameter type assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); // Error from the let statement annotated type assert!(matches!( - errors[1].0, + errors[1], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); // Error from the return type assert!(matches!( - errors[2].0, + errors[2], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -1780,7 +1767,7 @@ fn numeric_generic_as_unused_param_type() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -1795,14 +1782,13 @@ fn numeric_generic_as_unused_trait_fn_param_type() { let errors = get_program_errors(src); assert_eq!(errors.len(), 2); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); // Foo is unused - assert!(matches!( - errors[1].0, - CompilationError::ResolverError(ResolverError::UnusedItem { .. }), - )); + assert!( + matches!(errors[1], CompilationError::ResolverError(ResolverError::UnusedItem { .. }),) + ); } #[test] @@ -1824,14 +1810,13 @@ fn numeric_generic_as_return_type() { // Error from the return type assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); // foo is unused - assert!(matches!( - errors[1].0, - CompilationError::ResolverError(ResolverError::UnusedItem { .. }), - )); + assert!( + matches!(errors[1], CompilationError::ResolverError(ResolverError::UnusedItem { .. }),) + ); } #[test] @@ -1848,7 +1833,7 @@ fn numeric_generic_used_in_nested_type_fails() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -1867,7 +1852,7 @@ fn normal_generic_used_in_nested_array_length_fail() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -1997,11 +1982,11 @@ fn numeric_generic_u16_array_size() { let errors = get_program_errors(src); assert_eq!(errors.len(), 2); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); assert!(matches!( - errors[1].0, + errors[1], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -2055,7 +2040,7 @@ fn cast_256_to_u8_size_checks() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::DownsizingCast { .. }), )); } @@ -2111,7 +2096,7 @@ fn normal_generic_used_when_numeric_expected_in_where_clause() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); @@ -2131,20 +2116,20 @@ fn normal_generic_used_when_numeric_expected_in_where_clause() { let errors = get_program_errors(src); assert_eq!(errors.len(), 4); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); assert!(matches!( - errors[1].0, + errors[1], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); assert!(matches!( - errors[2].0, + errors[2], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); // N assert!(matches!( - errors[3].0, + errors[3], CompilationError::ResolverError(ResolverError::VariableNotDeclared { .. }), )); } @@ -2171,7 +2156,7 @@ fn numeric_generics_type_kind_mismatch() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }), )); } @@ -2207,7 +2192,7 @@ fn numeric_generics_value_kind_mismatch_u32_u64() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::IntegerBitWidth { bit_width_x: IntegerBitSize::SixtyFour, bit_width_y: IntegerBitSize::ThirtyTwo, @@ -2236,7 +2221,7 @@ fn quote_code_fragments() { assert_eq!(errors.len(), 1); use InterpreterError::FailingConstraint; - assert!(matches!(&errors[0].0, CompilationError::InterpreterError(FailingConstraint { .. }))); + assert!(matches!(&errors[0], CompilationError::InterpreterError(FailingConstraint { .. }))); } #[test] @@ -2287,7 +2272,7 @@ fn impl_stricter_than_trait_no_trait_method_constraints() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::DefinitionError(DefCollectorErrorKind::ImplIsStricterThanTrait { .. }) )); } @@ -2316,11 +2301,11 @@ fn impl_stricter_than_trait_different_generics() { if let CompilationError::DefinitionError(DefCollectorErrorKind::ImplIsStricterThanTrait { constraint_typ, .. - }) = &errors[0].0 + }) = &errors[0] { assert!(matches!(constraint_typ.to_string().as_str(), "B")); } else { - panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0); + panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0]); } } @@ -2384,36 +2369,36 @@ fn impl_stricter_than_trait_different_object_generics() { constraint_typ, constraint_name, .. - }) = &errors[0].0 + }) = &errors[0] { assert!(matches!(constraint_typ.to_string().as_str(), "Option")); assert!(matches!(constraint_name.as_str(), "MyTrait")); } else { - panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0); + panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0]); } if let CompilationError::DefinitionError(DefCollectorErrorKind::ImplIsStricterThanTrait { constraint_typ, constraint_name, .. - }) = &errors[1].0 + }) = &errors[1] { assert!(matches!(constraint_typ.to_string().as_str(), "[B; 8]")); assert!(matches!(constraint_name.as_str(), "MyTrait")); } else { - panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0); + panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0]); } if let CompilationError::DefinitionError(DefCollectorErrorKind::ImplIsStricterThanTrait { constraint_typ, constraint_name, .. - }) = &errors[2].0 + }) = &errors[2] { assert!(matches!(constraint_typ.to_string().as_str(), "(Option, Option)")); assert!(matches!(constraint_name.as_str(), "MyTrait")); } else { - panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0); + panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0]); } } @@ -2449,12 +2434,12 @@ fn impl_stricter_than_trait_different_trait() { constraint_typ, constraint_name, .. - }) = &errors[0].0 + }) = &errors[0] { assert!(matches!(constraint_typ.to_string().as_str(), "Option")); assert!(matches!(constraint_name.as_str(), "OtherDefault")); } else { - panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0); + panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0]); } } @@ -2490,12 +2475,12 @@ fn trait_impl_where_clause_stricter_pass() { constraint_typ, constraint_name, .. - }) = &errors[0].0 + }) = &errors[0] { assert!(matches!(constraint_typ.to_string().as_str(), "A")); assert!(matches!(constraint_name.as_str(), "OtherTrait")); } else { - panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0); + panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0]); } } @@ -2521,13 +2506,13 @@ fn impl_stricter_than_trait_different_trait_generics() { constraint_name, constraint_generics, .. - }) = &errors[0].0 + }) = &errors[0] { assert!(matches!(constraint_typ.to_string().as_str(), "A")); assert!(matches!(constraint_name.as_str(), "T2")); assert!(matches!(constraint_generics.ordered[0].to_string().as_str(), "B")); } else { - panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0].0); + panic!("Expected DefCollectorErrorKind::ImplIsStricterThanTrait but got {:?}", errors[0]); } } @@ -2576,7 +2561,7 @@ fn impl_not_found_for_inner_impl() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::TypeError(TypeCheckError::NoMatchingImplFound { .. }) )); } @@ -2593,8 +2578,8 @@ fn cannot_call_unconstrained_function_outside_of_unsafe() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::Unsafe { .. }) = &errors[0].0 else { - panic!("Expected an 'unsafe' error, got {:?}", errors[0].0); + let CompilationError::TypeError(TypeCheckError::Unsafe { .. }) = &errors[0] else { + panic!("Expected an 'unsafe' error, got {:?}", errors[0]); }; } @@ -2619,8 +2604,8 @@ fn cannot_call_unconstrained_first_class_function_outside_of_unsafe() { assert_eq!(errors.len(), 2); for error in &errors { - let CompilationError::TypeError(TypeCheckError::Unsafe { .. }) = &error.0 else { - panic!("Expected an 'unsafe' error, got {:?}", errors[0].0); + let CompilationError::TypeError(TypeCheckError::Unsafe { .. }) = error else { + panic!("Expected an 'unsafe' error, got {:?}", errors[0]); }; } } @@ -2662,8 +2647,8 @@ fn missing_unsafe_block_when_needing_type_annotations() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::Unsafe { .. }) = &errors[0].0 else { - panic!("Expected an 'unsafe' error, got {:?}", errors[0].0); + let CompilationError::TypeError(TypeCheckError::Unsafe { .. }) = &errors[0] else { + panic!("Expected an 'unsafe' error, got {:?}", errors[0]); }; } @@ -2683,8 +2668,8 @@ fn cannot_pass_unconstrained_function_to_regular_function() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::UnsafeFn { .. }) = &errors[0].0 else { - panic!("Expected an UnsafeFn error, got {:?}", errors[0].0); + let CompilationError::TypeError(TypeCheckError::UnsafeFn { .. }) = &errors[0] else { + panic!("Expected an UnsafeFn error, got {:?}", errors[0]); }; } @@ -2701,15 +2686,15 @@ fn cannot_assign_unconstrained_and_regular_fn_to_variable() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::Context { err, .. }) = &errors[0].0 else { - panic!("Expected a context error, got {:?}", errors[0].0); + let CompilationError::TypeError(TypeCheckError::Context { err, .. }) = &errors[0] else { + panic!("Expected a context error, got {:?}", errors[0]); }; if let TypeCheckError::TypeMismatch { expected_typ, expr_typ, .. } = err.as_ref() { assert_eq!(expected_typ, "fn() -> ()"); assert_eq!(expr_typ, "unconstrained fn() -> ()"); } else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; } @@ -2743,8 +2728,8 @@ fn cannot_pass_unconstrained_function_to_constrained_function() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::UnsafeFn { .. }) = &errors[0].0 else { - panic!("Expected an UnsafeFn error, got {:?}", errors[0].0); + let CompilationError::TypeError(TypeCheckError::UnsafeFn { .. }) = &errors[0] else { + panic!("Expected an UnsafeFn error, got {:?}", errors[0]); }; } @@ -2792,9 +2777,9 @@ fn trait_impl_generics_count_mismatch() { expected, found, .. - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a generic count mismatch error, got {:?}", errors[0].0); + panic!("Expected a generic count mismatch error, got {:?}", errors[0]); }; assert_eq!(item, "Foo"); @@ -2829,9 +2814,9 @@ fn duplicate_struct_field() { typ: _, first_def, second_def, - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a 'duplicate' error, got {:?}", errors[0].0); + panic!("Expected a 'duplicate' error, got {:?}", errors[0]); }; assert_eq!(first_def.to_string(), "x"); @@ -2886,9 +2871,9 @@ fn incorrect_generic_count_on_struct_impl() { let CompilationError::TypeError(TypeCheckError::GenericCountMismatch { found, expected, .. - }) = errors[0].0 + }) = errors[0] else { - panic!("Expected an incorrect generic count mismatch error, got {:?}", errors[0].0); + panic!("Expected an incorrect generic count mismatch error, got {:?}", errors[0]); }; assert_eq!(found, 1); @@ -2910,9 +2895,9 @@ fn incorrect_generic_count_on_type_alias() { let CompilationError::TypeError(TypeCheckError::GenericCountMismatch { found, expected, .. - }) = errors[0].0 + }) = errors[0] else { - panic!("Expected an incorrect generic count mismatch error, got {:?}", errors[0].0); + panic!("Expected an incorrect generic count mismatch error, got {:?}", errors[0]); }; assert_eq!(found, 1); @@ -2992,15 +2977,15 @@ fn uses_self_type_in_trait_where_clause() { let errors = get_program_errors(src); assert_eq!(errors.len(), 2); - let CompilationError::ResolverError(ResolverError::TraitNotImplemented { .. }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::TraitNotImplemented { .. }) = &errors[0] else { - panic!("Expected a trait not implemented error, got {:?}", errors[0].0); + panic!("Expected a trait not implemented error, got {:?}", errors[0]); }; let CompilationError::TypeError(TypeCheckError::UnresolvedMethodCall { method_name, .. }) = - &errors[1].0 + &errors[1] else { - panic!("Expected an unresolved method call error, got {:?}", errors[1].0); + panic!("Expected an unresolved method call error, got {:?}", errors[1]); }; assert_eq!(method_name, "trait_func"); @@ -3037,10 +3022,7 @@ fn error_on_cast_over_type_variable() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - assert!(matches!( - errors[0].0, - CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) - )); + assert!(matches!(errors[0], CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }))); } #[test] @@ -3129,7 +3111,7 @@ fn impl_missing_associated_type() { assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::TypeError(TypeCheckError::MissingNamedTypeArg { .. }) )); } @@ -3161,8 +3143,8 @@ fn as_trait_path_syntax_resolves_outside_impl() { use CompilationError::TypeError; use TypeCheckError::TypeMismatch; - let TypeError(TypeMismatch { expected_typ, expr_typ, .. }) = errors[0].0.clone() else { - panic!("Expected TypeMismatch error, found {:?}", errors[0].0); + let TypeError(TypeMismatch { expected_typ, expr_typ, .. }) = errors[0].clone() else { + panic!("Expected TypeMismatch error, found {:?}", errors[0]); }; assert_eq!(expected_typ, "i64".to_string()); @@ -3193,7 +3175,7 @@ fn as_trait_path_syntax_no_impl() { assert_eq!(errors.len(), 1); use CompilationError::TypeError; - assert!(matches!(&errors[0].0, TypeError(TypeCheckError::NoMatchingImplFound { .. }))); + assert!(matches!(&errors[0], TypeError(TypeCheckError::NoMatchingImplFound { .. }))); } #[test] @@ -3212,13 +3194,13 @@ fn dont_infer_globals_to_u32_from_type_use() { let mut errors = get_program_errors(src); assert_eq!(errors.len(), 6); - for (error, _file_id) in errors.drain(0..3) { + for error in errors.drain(0..3) { assert!(matches!( error, CompilationError::ResolverError(ResolverError::UnspecifiedGlobalType { .. }) )); } - for (error, _file_id) in errors { + for error in errors { assert!(matches!( error, CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }) @@ -3242,7 +3224,7 @@ fn dont_infer_partial_global_types() { let errors = get_program_errors(src); assert_eq!(errors.len(), 6); - for (error, _file_id) in errors { + for error in errors { assert!(matches!( error, CompilationError::ResolverError(ResolverError::UnspecifiedGlobalType { .. }) @@ -3292,7 +3274,7 @@ fn struct_array_len() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::UnusedVariable { .. }) )); } @@ -3312,7 +3294,7 @@ fn non_u32_as_array_length() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::TypeKindMismatch { .. }) )); } @@ -3397,7 +3379,7 @@ fn error_if_attribute_not_in_scope() { assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::AttributeFunctionNotInScope { .. }) )); } @@ -3431,10 +3413,7 @@ fn arithmetic_generics_rounding_fail() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - assert!(matches!( - errors[0].0, - CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) - )); + assert!(matches!(errors[0], CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }))); } #[test] @@ -3457,10 +3436,7 @@ fn arithmetic_generics_rounding_fail_on_struct() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - assert!(matches!( - errors[0].0, - CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) - )); + assert!(matches!(errors[0], CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }))); } #[test] @@ -3539,7 +3515,7 @@ fn unconditional_recursion_fail() { "expected 'unconditional recursion' error, got nothing; src = {src}" ); - for (error, _) in errors { + for error in errors { let CompilationError::ResolverError(ResolverError::UnconditionalRecursion { .. }) = error else { @@ -3756,9 +3732,9 @@ fn errors_with_better_message_when_trying_to_invoke_struct_field_that_is_a_funct let CompilationError::TypeError(TypeCheckError::CannotInvokeStructFieldFunctionType { method_name, .. - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a 'CannotInvokeStructFieldFunctionType' error, got {:?}", errors[0].0); + panic!("Expected a 'CannotInvokeStructFieldFunctionType' error, got {:?}", errors[0]); }; assert_eq!(method_name, "wrapped"); @@ -3782,7 +3758,7 @@ fn test_disallows_attribute_on_impl_method( ); let errors = get_program_errors(&src); assert_eq!(errors.len(), 1); - check_error(&errors[0].0); + check_error(&errors[0]); } fn test_disallows_attribute_on_trait_impl_method( @@ -3807,7 +3783,7 @@ fn test_disallows_attribute_on_trait_impl_method( ); let errors = get_program_errors(&src); assert_eq!(errors.len(), 1); - check_error(&errors[0].0); + check_error(&errors[0]); } #[test] @@ -3880,9 +3856,9 @@ fn disallows_underscore_on_right_hand_side() { assert_eq!(errors.len(), 1); let CompilationError::ResolverError(ResolverError::VariableNotDeclared { name, .. }) = - &errors[0].0 + &errors[0] else { - panic!("Expected a VariableNotDeclared error, got {:?}", errors[0].0); + panic!("Expected a VariableNotDeclared error, got {:?}", errors[0]); }; assert_eq!(name, "_"); @@ -3898,11 +3874,11 @@ fn errors_on_cyclic_globals() { "#; let errors = get_program_errors(src); - assert!(errors.iter().any(|(error, _)| matches!( + assert!(errors.iter().any(|error| matches!( error, CompilationError::InterpreterError(InterpreterError::GlobalsDependencyCycle { .. }) ))); - assert!(errors.iter().any(|(error, _)| matches!( + assert!(errors.iter().any(|error| matches!( error, CompilationError::ResolverError(ResolverError::DependencyCycle { .. }) ))); @@ -3923,7 +3899,7 @@ fn warns_on_unneeded_unsafe() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::TypeError(TypeCheckError::UnnecessaryUnsafeBlock { .. }) )); } @@ -3945,10 +3921,12 @@ fn warns_on_nested_unsafe() { "#; let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - assert!(matches!( - &errors[0].0, - CompilationError::TypeError(TypeCheckError::NestedUnsafeBlock { .. }) - )); + let CompilationError::TypeError(TypeCheckError::NestedUnsafeBlock { location }) = &errors[0] + else { + panic!("Expected NestedUnsafeBlock"); + }; + + assert_eq!(&src[location.span.start() as usize..location.span.end() as usize], "unsafe"); } #[test] @@ -4248,11 +4226,11 @@ fn error_with_duplicate_enum_variant() { let errors = get_program_errors(src); assert_eq!(errors.len(), 2); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::DefinitionError(DefCollectorErrorKind::Duplicate { .. }) )); assert!(matches!( - &errors[1].0, + &errors[1], CompilationError::ResolverError(ResolverError::UnusedItem { .. }) )); } @@ -4274,7 +4252,7 @@ fn errors_on_empty_loop_no_break() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::LoopWithoutBreak { .. }) )); } @@ -4302,7 +4280,7 @@ fn errors_on_loop_without_break() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::LoopWithoutBreak { .. }) )); } @@ -4334,7 +4312,7 @@ fn errors_on_loop_without_break_with_nested_loop() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::LoopWithoutBreak { .. }) )); } @@ -4367,7 +4345,7 @@ fn errors_on_if_without_else_type_mismatch() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::Context { err, .. }) = &errors[0].0 else { + let CompilationError::TypeError(TypeCheckError::Context { err, .. }) = &errors[0] else { panic!("Expected a Context error"); }; assert!(matches!(**err, TypeCheckError::TypeMismatch { .. })); @@ -4391,7 +4369,7 @@ fn errors_if_for_body_type_is_not_unit() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) = &errors[0].0 else { + let CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) = &errors[0] else { panic!("Expected a TypeMismatch error"); }; } @@ -4410,7 +4388,7 @@ fn errors_if_loop_body_type_is_not_unit() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) = &errors[0].0 else { + let CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) = &errors[0] else { panic!("Expected a TypeMismatch error"); }; } @@ -4427,7 +4405,7 @@ fn errors_if_while_body_type_is_not_unit() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) = &errors[0].0 else { + let CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) = &errors[0] else { panic!("Expected a TypeMismatch error"); }; } @@ -4447,7 +4425,7 @@ fn errors_on_unspecified_unstable_enum() { let errors = get_program_using_features(src, no_features).2; assert_eq!(errors.len(), 1); - let CompilationError::ParseError(error) = &errors[0].0 else { + let CompilationError::ParseError(error) = &errors[0] else { panic!("Expected a ParseError experimental feature error"); }; @@ -4469,7 +4447,7 @@ fn errors_on_unspecified_unstable_match() { let errors = get_program_using_features(src, no_features).2; assert_eq!(errors.len(), 1); - let CompilationError::ParseError(error) = &errors[0].0 else { + let CompilationError::ParseError(error) = &errors[0] else { panic!("Expected a ParseError experimental feature error"); }; @@ -4490,7 +4468,7 @@ fn errors_on_repeated_match_variables_in_pattern() { assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::VariableAlreadyDefinedInPattern { .. }) )); } @@ -4511,7 +4489,7 @@ fn check_impl_duplicate_method_without_self() { assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::DuplicateDefinition { .. }) )); } @@ -4536,7 +4514,7 @@ struct Foo { assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::DuplicateField { .. }) )); } @@ -4561,7 +4539,7 @@ struct Foo { assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::MissingFields { .. }) )); } @@ -4586,7 +4564,7 @@ struct Foo { assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::NoSuchField { .. }) )); } diff --git a/compiler/noirc_frontend/src/tests/bound_checks.rs b/compiler/noirc_frontend/src/tests/bound_checks.rs index 05669bda411..3a9efd716de 100644 --- a/compiler/noirc_frontend/src/tests/bound_checks.rs +++ b/compiler/noirc_frontend/src/tests/bound_checks.rs @@ -11,13 +11,13 @@ fn overflowing_u8() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - if let CompilationError::TypeError(error) = &errors[0].0 { + if let CompilationError::TypeError(error) = &errors[0] { assert_eq!( error.to_string(), "The value `256` cannot fit into `u8` which has range `0..=255`" ); } else { - panic!("Expected OverflowingAssignment error, got {:?}", errors[0].0); + panic!("Expected OverflowingAssignment error, got {:?}", errors[0]); } } @@ -30,13 +30,13 @@ fn underflowing_u8() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - if let CompilationError::TypeError(error) = &errors[0].0 { + if let CompilationError::TypeError(error) = &errors[0] { assert_eq!( error.to_string(), "The value `-1` cannot fit into `u8` which has range `0..=255`" ); } else { - panic!("Expected OverflowingAssignment error, got {:?}", errors[0].0); + panic!("Expected OverflowingAssignment error, got {:?}", errors[0]); } } @@ -49,13 +49,13 @@ fn overflowing_i8() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - if let CompilationError::TypeError(error) = &errors[0].0 { + if let CompilationError::TypeError(error) = &errors[0] { assert_eq!( error.to_string(), "The value `128` cannot fit into `i8` which has range `-128..=127`" ); } else { - panic!("Expected OverflowingAssignment error, got {:?}", errors[0].0); + panic!("Expected OverflowingAssignment error, got {:?}", errors[0]); } } @@ -68,12 +68,12 @@ fn underflowing_i8() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - if let CompilationError::TypeError(error) = &errors[0].0 { + if let CompilationError::TypeError(error) = &errors[0] { assert_eq!( error.to_string(), "The value `-129` cannot fit into `i8` which has range `-128..=127`" ); } else { - panic!("Expected OverflowingAssignment error, got {:?}", errors[0].0); + panic!("Expected OverflowingAssignment error, got {:?}", errors[0]); } } diff --git a/compiler/noirc_frontend/src/tests/imports.rs b/compiler/noirc_frontend/src/tests/imports.rs index 8598d8296e5..dafc5b098de 100644 --- a/compiler/noirc_frontend/src/tests/imports.rs +++ b/compiler/noirc_frontend/src/tests/imports.rs @@ -28,14 +28,14 @@ fn no_super() { assert_eq!(errors.len(), 1); let CompilationError::DefinitionError(DefCollectorErrorKind::PathResolutionError( - PathResolutionError::NoSuper(span), - )) = &errors[0].0 + PathResolutionError::NoSuper(location), + )) = &errors[0] else { - panic!("Expected a 'no super' error, got {:?}", errors[0].0); + panic!("Expected a 'no super' error, got {:?}", errors[0]); }; - assert_eq!(span.start(), 4); - assert_eq!(span.end(), 9); + assert_eq!(location.span.start(), 4); + assert_eq!(location.span.end(), 9); } #[test] @@ -76,7 +76,7 @@ fn warns_on_use_of_private_exported_item() { assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Private(..), )) @@ -121,7 +121,7 @@ fn warns_on_re_export_of_item_with_less_visibility() { assert_eq!(errors.len(), 1); assert!(matches!( - &errors[0].0, + &errors[0], CompilationError::DefinitionError( DefCollectorErrorKind::CannotReexportItemWithLessVisibility { .. } ) @@ -146,9 +146,9 @@ fn errors_if_using_alias_in_import() { let CompilationError::DefinitionError(DefCollectorErrorKind::PathResolutionError( PathResolutionError::NotAModule { ident, kind }, - )) = &errors[0].0 + )) = &errors[0] else { - panic!("Expected a 'not a module' error, got {:?}", errors[0].0); + panic!("Expected a 'not a module' error, got {:?}", errors[0]); }; assert_eq!(ident.to_string(), "bar"); diff --git a/compiler/noirc_frontend/src/tests/metaprogramming.rs b/compiler/noirc_frontend/src/tests/metaprogramming.rs index fb27cac6c96..1ea23b4301c 100644 --- a/compiler/noirc_frontend/src/tests/metaprogramming.rs +++ b/compiler/noirc_frontend/src/tests/metaprogramming.rs @@ -36,7 +36,7 @@ fn comptime_code_rejects_dynamic_variable() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - match &errors[0].0 { + match &errors[0] { CompilationError::InterpreterError(InterpreterError::NonComptimeVarReferenced { name, .. @@ -53,7 +53,7 @@ fn comptime_type_in_runtime_code() { let errors = get_program_errors(source); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::ComptimeTypeInRuntimeCode { .. }) )); } @@ -75,10 +75,7 @@ fn macro_result_type_mismatch() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - assert!(matches!( - errors[0].0, - CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) - )); + assert!(matches!(errors[0], CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }))); } #[test] @@ -154,9 +151,9 @@ fn errors_if_macros_inject_functions_with_name_collisions() { assert_eq!(errors.len(), 1); let CompilationError::ComptimeError(ComptimeError::ErrorRunningAttribute { error, .. }) = - errors.remove(0).0 + errors.remove(0) else { - panic!("Expected a ComptimeError, got {:?}", errors[0].0); + panic!("Expected a ComptimeError, got {:?}", errors[0]); }; assert!(matches!( @@ -214,8 +211,8 @@ fn does_not_fail_to_parse_macro_on_parser_warning() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ParseError(parser_error) = &errors[0].0 else { - panic!("Expected a ParseError, got {:?}", errors[0].0); + let CompilationError::ParseError(parser_error) = &errors[0] else { + panic!("Expected a ParseError, got {:?}", errors[0]); }; assert!(matches!(parser_error.reason(), Some(ParserErrorReason::MissingSafetyComment))); diff --git a/compiler/noirc_frontend/src/tests/references.rs b/compiler/noirc_frontend/src/tests/references.rs index 5dbc395eb59..236b22b9e90 100644 --- a/compiler/noirc_frontend/src/tests/references.rs +++ b/compiler/noirc_frontend/src/tests/references.rs @@ -20,7 +20,7 @@ fn cannot_mutate_immutable_variable() { assert_eq!(errors.len(), 1); let CompilationError::TypeError(TypeCheckError::CannotMutateImmutableVariable { name, .. }) = - &errors[0].0 + &errors[0] else { panic!("Expected a CannotMutateImmutableVariable error"); }; @@ -49,7 +49,7 @@ fn cannot_mutate_immutable_variable_on_member_access() { assert_eq!(errors.len(), 1); let CompilationError::TypeError(TypeCheckError::CannotMutateImmutableVariable { name, .. }) = - &errors[0].0 + &errors[0] else { panic!("Expected a CannotMutateImmutableVariable error"); }; @@ -73,7 +73,7 @@ fn does_not_crash_when_passing_mutable_undefined_variable() { assert_eq!(errors.len(), 1); let CompilationError::ResolverError(ResolverError::VariableNotDeclared { name, .. }) = - &errors[0].0 + &errors[0] else { panic!("Expected a VariableNotDeclared error"); }; @@ -105,7 +105,7 @@ fn constrained_reference_to_unconstrained() { assert_eq!(errors.len(), 1); let CompilationError::TypeError(TypeCheckError::ConstrainedReferenceToUnconstrained { .. }) = - &errors[0].0 + &errors[0] else { panic!("Expected an error about passing a constrained reference to unconstrained"); }; diff --git a/compiler/noirc_frontend/src/tests/traits.rs b/compiler/noirc_frontend/src/tests/traits.rs index 78cda330cf1..e5b19e695d4 100644 --- a/compiler/noirc_frontend/src/tests/traits.rs +++ b/compiler/noirc_frontend/src/tests/traits.rs @@ -116,7 +116,7 @@ fn trait_inheritance_dependency_cycle() { assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::ResolverError(ResolverError::DependencyCycle { .. }) )); } @@ -144,9 +144,9 @@ fn trait_inheritance_missing_parent_implementation() { missing_trait: the_trait, type_missing_trait: typ, .. - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a TraitNotImplemented error, got {:?}", &errors[0].0); + panic!("Expected a TraitNotImplemented error, got {:?}", &errors[0]); }; assert_eq!(the_trait, "Foo"); @@ -257,9 +257,9 @@ fn errors_if_impl_trait_constraint_is_not_satisfied() { missing_trait: the_trait, type_missing_trait: typ, .. - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a TraitNotImplemented error, got {:?}", &errors[0].0); + panic!("Expected a TraitNotImplemented error, got {:?}", &errors[0]); }; assert_eq!(the_trait, "Greeter"); @@ -473,7 +473,7 @@ fn trait_alias_polymorphic_where_clause() { let errors = get_program_errors(src); assert_eq!(errors.len(), 2); - match &errors[0].0 { + match &errors[0] { CompilationError::TypeError(TypeCheckError::UnresolvedMethodCall { method_name, .. }) => { @@ -484,7 +484,7 @@ fn trait_alias_polymorphic_where_clause() { } } - match &errors[1].0 { + match &errors[1] { CompilationError::TypeError(TypeCheckError::NoMatchingImplFound(err)) => { assert_eq!(err.constraints.len(), 2); assert_eq!(err.constraints[0].1, "Baz"); @@ -548,7 +548,7 @@ fn trait_alias_with_where_clause_has_equivalent_errors() { assert_eq!(errors.len(), 1); assert_eq!(alias_errors.len(), 1); - match (&errors[0].0, &alias_errors[0].0) { + match (&errors[0], &alias_errors[0]) { ( CompilationError::TypeError(TypeCheckError::UnresolvedMethodCall { method_name, @@ -685,7 +685,7 @@ fn warns_if_trait_is_not_in_scope_for_function_call_and_there_is_only_one_trait_ let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::TraitMethodNotInScope { ident, trait_name }, - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a 'trait method not in scope' error"); }; @@ -824,7 +824,7 @@ fn errors_if_trait_is_not_in_scope_for_function_call_and_there_are_multiple_cand let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::UnresolvedWithPossibleTraitsToImport { ident, mut traits }, - )) = errors.remove(0).0 + )) = errors.remove(0) else { panic!("Expected a 'trait method not in scope' error"); }; @@ -873,7 +873,7 @@ fn errors_if_multiple_trait_methods_are_in_scope_for_function_call() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::MultipleTraitsInScope { ident, mut traits }, - )) = errors.remove(0).0 + )) = errors.remove(0) else { panic!("Expected a 'trait method not in scope' error"); }; @@ -911,7 +911,7 @@ fn warns_if_trait_is_not_in_scope_for_method_call_and_there_is_only_one_trait_me let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::TraitMethodNotInScope { ident, trait_name }, - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a 'trait method not in scope' error"); }; @@ -987,7 +987,7 @@ fn errors_if_trait_is_not_in_scope_for_method_call_and_there_are_multiple_candid let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::UnresolvedWithPossibleTraitsToImport { ident, mut traits }, - )) = errors.remove(0).0 + )) = errors.remove(0) else { panic!("Expected a 'trait method not in scope' error"); }; @@ -1038,7 +1038,7 @@ fn errors_if_multiple_trait_methods_are_in_scope_for_method_call() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::MultipleTraitsInScope { ident, mut traits }, - )) = errors.remove(0).0 + )) = errors.remove(0) else { panic!("Expected a 'trait method not in scope' error"); }; @@ -1099,9 +1099,9 @@ fn type_checks_trait_default_method_and_errors() { expected, actual, .. - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; assert_eq!(expected.to_string(), "i32"); @@ -1166,7 +1166,7 @@ fn warns_if_trait_is_not_in_scope_for_primitive_function_call_and_there_is_only_ let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::TraitMethodNotInScope { ident, trait_name }, - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a 'trait method not in scope' error"); }; @@ -1199,7 +1199,7 @@ fn warns_if_trait_is_not_in_scope_for_primitive_method_call_and_there_is_only_on let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::TraitMethodNotInScope { ident, trait_name }, - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a 'trait method not in scope' error"); }; @@ -1232,7 +1232,7 @@ fn warns_if_trait_is_not_in_scope_for_generic_function_call_and_there_is_only_on let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::TraitMethodNotInScope { ident, trait_name }, - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a 'trait method not in scope' error"); }; @@ -1259,14 +1259,12 @@ fn error_on_duplicate_impl_with_associated_type() { "#; // Expect "Impl for type `i32` overlaps with existing impl" - // and "Previous impl defined here" let errors = get_program_errors(src); - assert_eq!(errors.len(), 2); + assert_eq!(errors.len(), 1); use CompilationError::DefinitionError; use DefCollectorErrorKind::*; - assert!(matches!(&errors[0].0, DefinitionError(OverlappingImpl { .. }))); - assert!(matches!(&errors[1].0, DefinitionError(OverlappingImplNote { .. }))); + assert!(matches!(&errors[0], DefinitionError(OverlappingImpl { .. }))); } #[test] @@ -1288,14 +1286,12 @@ fn error_on_duplicate_impl_with_associated_constant() { "#; // Expect "Impl for type `i32` overlaps with existing impl" - // and "Previous impl defined here" let errors = get_program_errors(src); - assert_eq!(errors.len(), 2); + assert_eq!(errors.len(), 1); use CompilationError::DefinitionError; use DefCollectorErrorKind::*; - assert!(matches!(&errors[0].0, DefinitionError(OverlappingImpl { .. }))); - assert!(matches!(&errors[1].0, DefinitionError(OverlappingImplNote { .. }))); + assert!(matches!(&errors[0], DefinitionError(OverlappingImpl { .. }))); } // See https://github.com/noir-lang/noir/issues/6530 @@ -1391,8 +1387,5 @@ fn calls_trait_method_using_struct_name_when_multiple_impls_exist_and_errors_tur "#; let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - assert!(matches!( - errors[0].0, - CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }) - )); + assert!(matches!(errors[0], CompilationError::TypeError(TypeCheckError::TypeMismatch { .. }))); } diff --git a/compiler/noirc_frontend/src/tests/turbofish.rs b/compiler/noirc_frontend/src/tests/turbofish.rs index 3e34ea9521b..bda590533cf 100644 --- a/compiler/noirc_frontend/src/tests/turbofish.rs +++ b/compiler/noirc_frontend/src/tests/turbofish.rs @@ -72,7 +72,7 @@ fn turbofish_in_constructor_generics_mismatch() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::TypeError(TypeCheckError::GenericCountMismatch { .. }), )); } @@ -95,9 +95,9 @@ fn turbofish_in_constructor() { let CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, .. - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; assert_eq!(expected_typ, "i32"); @@ -137,9 +137,9 @@ fn turbofish_in_struct_pattern_errors_if_type_mismatch() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::TypeError(TypeCheckError::TypeMismatchWithSource { .. }) = &errors[0].0 + let CompilationError::TypeError(TypeCheckError::TypeMismatchWithSource { .. }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; } @@ -165,9 +165,9 @@ fn turbofish_in_struct_pattern_generic_count_mismatch() { expected, found, .. - }) = &errors[0].0 + }) = &errors[0] else { - panic!("Expected a generic count mismatch error, got {:?}", errors[0].0); + panic!("Expected a generic count mismatch error, got {:?}", errors[0]); }; assert_eq!(item, "struct Foo"); @@ -210,9 +210,9 @@ fn errors_if_turbofish_after_module() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::TurbofishNotAllowedOnItem { item, .. }, - )) = &errors[0].0 + )) = &errors[0] else { - panic!("Expected a turbofish not allowed on item error, got {:?}", errors[0].0); + panic!("Expected a turbofish not allowed on item error, got {:?}", errors[0]); }; assert_eq!(item, "module `moo`"); } @@ -260,10 +260,10 @@ fn turbofish_in_type_before_call_errors() { let CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, - expr_span: _, - }) = &errors[0].0 + expr_location: _, + }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; assert_eq!(expected_typ, "i32"); @@ -320,10 +320,10 @@ fn use_generic_type_alias_with_turbofish_in_method_call_errors() { let CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, - expr_span: _, - }) = &errors[0].0 + expr_location: _, + }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; assert_eq!(expected_typ, "i32"); @@ -379,10 +379,10 @@ fn use_generic_type_alias_with_partial_generics_with_turbofish_in_method_call_er let CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, - expr_span: _, - }) = &errors[0].0 + expr_location: _, + }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; assert_eq!(expected_typ, "bool"); @@ -415,10 +415,10 @@ fn use_generic_type_alias_with_partial_generics_with_turbofish_in_method_call_er let CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, - expr_span: _, - }) = &errors[0].0 + expr_location: _, + }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; assert_eq!(expected_typ, "i32"); @@ -448,10 +448,10 @@ fn trait_function_with_turbofish_on_trait_gives_error() { let CompilationError::TypeError(TypeCheckError::TypeMismatch { expected_typ, expr_typ, - expr_span: _, - }) = &errors[0].0 + expr_location: _, + }) = &errors[0] else { - panic!("Expected a type mismatch error, got {:?}", errors[0].0); + panic!("Expected a type mismatch error, got {:?}", errors[0]); }; assert_eq!(expected_typ, "bool"); diff --git a/compiler/noirc_frontend/src/tests/unused_items.rs b/compiler/noirc_frontend/src/tests/unused_items.rs index c38e604f2c3..0840eb18a38 100644 --- a/compiler/noirc_frontend/src/tests/unused_items.rs +++ b/compiler/noirc_frontend/src/tests/unused_items.rs @@ -31,7 +31,7 @@ fn errors_on_unused_private_import() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0] else { panic!("Expected an unused item error"); }; @@ -66,7 +66,7 @@ fn errors_on_unused_pub_crate_import() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0] else { panic!("Expected an unused item error"); }; @@ -97,7 +97,7 @@ fn errors_on_unused_function() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0] else { panic!("Expected an unused item error"); }; @@ -120,7 +120,7 @@ fn errors_on_unused_struct() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0] else { panic!("Expected an unused item error"); }; @@ -147,7 +147,7 @@ fn errors_on_unused_trait() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0] else { panic!("Expected an unused item error"); }; @@ -179,7 +179,7 @@ fn errors_on_unused_type_alias() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0] else { panic!("Expected an unused item error"); }; @@ -202,7 +202,7 @@ fn warns_on_unused_global() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); - let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0].0 + let CompilationError::ResolverError(ResolverError::UnusedItem { ident, item }) = &errors[0] else { panic!("Expected an unused item warning"); }; diff --git a/compiler/noirc_frontend/src/tests/visibility.rs b/compiler/noirc_frontend/src/tests/visibility.rs index 0826e804b3b..ce41141b8d8 100644 --- a/compiler/noirc_frontend/src/tests/visibility.rs +++ b/compiler/noirc_frontend/src/tests/visibility.rs @@ -23,7 +23,7 @@ fn errors_once_on_unused_import_that_is_not_accessible() { let errors = get_program_errors(src); assert_eq!(errors.len(), 1); assert!(matches!( - errors[0].0, + errors[0], CompilationError::DefinitionError(DefCollectorErrorKind::PathResolutionError( PathResolutionError::Private { .. } )) @@ -34,7 +34,7 @@ fn assert_type_is_more_private_than_item_error(src: &str, private_typ: &str, pub let errors = get_program_errors(src); assert!(!errors.is_empty(), "expected visibility error, got nothing"); - for (error, _) in &errors { + for error in &errors { let CompilationError::ResolverError(ResolverError::TypeIsMorePrivateThenItem { typ, item, @@ -271,7 +271,7 @@ fn errors_if_trying_to_access_public_function_inside_private_module() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Private(ident), - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a private error"); }; @@ -304,7 +304,7 @@ fn warns_if_calling_private_struct_method() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Private(ident), - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a private error"); }; @@ -396,7 +396,7 @@ fn error_when_accessing_private_struct_field() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Private(ident), - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a private error"); }; @@ -463,7 +463,7 @@ fn error_when_using_private_struct_field_in_constructor() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Private(ident), - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a private error"); }; @@ -494,7 +494,7 @@ fn error_when_using_private_struct_field_in_struct_pattern() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Private(ident), - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a private error"); }; @@ -573,7 +573,7 @@ fn errors_if_accessing_private_struct_member_inside_comptime_context() { let CompilationError::ResolverError(ResolverError::PathResolutionError( PathResolutionError::Private(ident), - )) = &errors[0].0 + )) = &errors[0] else { panic!("Expected a private error"); }; @@ -614,9 +614,9 @@ fn errors_if_accessing_private_struct_member_inside_function_generated_at_compti assert_eq!(errors.len(), 1); let CompilationError::ComptimeError(ComptimeError::ErrorRunningAttribute { error, .. }) = - errors.remove(0).0 + errors.remove(0) else { - panic!("Expected a ComptimeError, got {:?}", errors[0].0); + panic!("Expected a ComptimeError, got {:?}", errors[0]); }; let CompilationError::ResolverError(ResolverError::PathResolutionError( diff --git a/compiler/wasm/src/errors.rs b/compiler/wasm/src/errors.rs index ef56dcfc911..c2e51162d3f 100644 --- a/compiler/wasm/src/errors.rs +++ b/compiler/wasm/src/errors.rs @@ -96,8 +96,8 @@ impl Diagnostic { .iter() .map(|label| DiagnosticLabel { message: label.message.clone(), - start: label.span.start(), - end: label.span.end(), + start: label.location.span.start(), + end: label.location.span.end(), }) .collect(); diff --git a/tooling/lsp/src/notifications/mod.rs b/tooling/lsp/src/notifications/mod.rs index ac8bf730979..c6b0f110ec3 100644 --- a/tooling/lsp/src/notifications/mod.rs +++ b/tooling/lsp/src/notifications/mod.rs @@ -6,7 +6,7 @@ use crate::{ insert_all_files_for_workspace_into_file_manager, PackageCacheData, WorkspaceCacheData, }; use async_lsp::{ErrorCode, LanguageClient, ResponseError}; -use fm::{FileId, FileManager, FileMap}; +use fm::{FileManager, FileMap}; use fxhash::FxHashMap as HashMap; use lsp_types::{DiagnosticRelatedInformation, DiagnosticTag, Url}; use noirc_driver::check_crate; @@ -245,7 +245,7 @@ fn file_diagnostic_to_diagnostic( return None; } - let span = diagnostic.secondaries.first().unwrap().span; + let span = diagnostic.secondaries.first().unwrap().location.span; let range = byte_span_to_range(files, file_id, span.into())?; let severity = match diagnostic.kind { @@ -266,7 +266,7 @@ fn file_diagnostic_to_diagnostic( let secondaries = diagnostic .secondaries .into_iter() - .filter_map(|secondary| secondary_to_related_information(secondary, file_id, files, fm)); + .filter_map(|secondary| secondary_to_related_information(secondary, files, fm)); let notes = diagnostic.notes.into_iter().map(|message| DiagnosticRelatedInformation { location: lsp_types::Location { uri: uri.clone(), range }, message, @@ -293,14 +293,13 @@ fn file_diagnostic_to_diagnostic( fn secondary_to_related_information( secondary: CustomLabel, - file_id: FileId, files: &FileMap, fm: &FileManager, ) -> Option { - let secondary_file = secondary.file.unwrap_or(file_id); + let secondary_file = secondary.location.file; let path = fm.path(secondary_file)?; let uri = Url::from_file_path(path).ok()?; - let range = byte_span_to_range(files, secondary_file, secondary.span.into())?; + let range = byte_span_to_range(files, secondary_file, secondary.location.span.into())?; let message = secondary.message; Some(DiagnosticRelatedInformation { location: lsp_types::Location { uri, range }, message }) } diff --git a/tooling/lsp/src/with_file.rs b/tooling/lsp/src/with_file.rs index ac6fc1b0a85..62fd8d0e850 100644 --- a/tooling/lsp/src/with_file.rs +++ b/tooling/lsp/src/with_file.rs @@ -13,7 +13,7 @@ use noirc_frontend::{ PrefixExpression, Statement, StatementKind, StructField, TraitBound, TraitImplItem, TraitImplItemKind, TraitItem, TypeImpl, TypePath, UnresolvedGeneric, UnresolvedTraitConstraint, UnresolvedType, UnresolvedTypeData, UnresolvedTypeExpression, - UseTree, UseTreeKind, WhileStatement, + UnsafeExpression, UseTree, UseTreeKind, WhileStatement, }, parser::{Item, ItemKind, ParsedSubModule}, token::{ @@ -426,6 +426,7 @@ fn path_with_file(path: Path, file: FileId) -> Path { Path { segments: vecmap(path.segments, |segment| path_segment_with_file(segment, file)), kind: path.kind, + kind_location: location_with_file(path.kind_location, file), location: location_with_file(path.location, file), } } @@ -670,10 +671,12 @@ fn expression_kind_with_file(kind: ExpressionKind, file: FileId) -> ExpressionKi block_expression_with_file(block_expression, file), location_with_file(location, file), ), - ExpressionKind::Unsafe(block_expression, location) => ExpressionKind::Unsafe( - block_expression_with_file(block_expression, file), - location_with_file(location, file), - ), + ExpressionKind::Unsafe(UnsafeExpression { block, unsafe_keyword_location }) => { + ExpressionKind::Unsafe(UnsafeExpression { + block: block_expression_with_file(block, file), + unsafe_keyword_location: location_with_file(unsafe_keyword_location, file), + }) + } ExpressionKind::AsTraitPath(as_trait_path) => { ExpressionKind::AsTraitPath(as_trait_path_with_file(as_trait_path, file)) } diff --git a/tooling/nargo/src/errors.rs b/tooling/nargo/src/errors.rs index 00c411bf7e4..0f27eb3124e 100644 --- a/tooling/nargo/src/errors.rs +++ b/tooling/nargo/src/errors.rs @@ -241,6 +241,6 @@ pub fn try_to_diagnose_runtime_error( // of the call stack (the last item in the Vec). let location = *source_locations.last()?; let message = extract_message_from_error(&abi.error_types, nargo_err); - let error = CustomDiagnostic::simple_error(message, String::new(), location.span); + let error = CustomDiagnostic::simple_error(message, String::new(), location); Some(error.with_call_stack(source_locations).in_file(location.file)) } diff --git a/tooling/nargo_fmt/src/formatter/expression.rs b/tooling/nargo_fmt/src/formatter/expression.rs index 924b2307418..56c4374dd77 100644 --- a/tooling/nargo_fmt/src/formatter/expression.rs +++ b/tooling/nargo_fmt/src/formatter/expression.rs @@ -98,9 +98,9 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { false, // force multiple lines )); } - ExpressionKind::Unsafe(block_expression, _span) => { + ExpressionKind::Unsafe(unsafe_xpression) => { group.group(self.format_unsafe_expression( - block_expression, + unsafe_xpression.block, false, // force multiple lines )); } diff --git a/tooling/nargo_fmt/src/formatter/statement.rs b/tooling/nargo_fmt/src/formatter/statement.rs index 20c3b374366..18b553c4534 100644 --- a/tooling/nargo_fmt/src/formatter/statement.rs +++ b/tooling/nargo_fmt/src/formatter/statement.rs @@ -52,9 +52,10 @@ impl<'a, 'b> ChunkFormatter<'a, 'b> { ExpressionKind::Block(block) => group.group(self.format_block_expression( block, true, // force multiple lines )), - ExpressionKind::Unsafe(block, _) => { + ExpressionKind::Unsafe(unsafe_expression) => { group.group(self.format_unsafe_expression( - block, true, // force multiple lines + unsafe_expression.block, + true, // force multiple lines )); } ExpressionKind::If(if_expression) => { diff --git a/tooling/profiler/src/errors.rs b/tooling/profiler/src/errors.rs index c49b0b335dd..6a028931f5e 100644 --- a/tooling/profiler/src/errors.rs +++ b/tooling/profiler/src/errors.rs @@ -1,5 +1,5 @@ use fm::FileMap; -use noirc_errors::{CustomDiagnostic, Span}; +use noirc_errors::{CustomDiagnostic, Location}; use thiserror::Error; #[derive(Debug, Error)] @@ -10,7 +10,7 @@ pub(crate) enum CliError { /// Report an error from the CLI that is not reliant on a stack trace. pub(crate) fn report_error(message: String) -> Result<(), CliError> { - let error = CustomDiagnostic::simple_error(message.clone(), String::new(), Span::default()); - noirc_errors::reporter::report(&FileMap::default(), &error, None, false); + let error = CustomDiagnostic::simple_error(message.clone(), String::new(), Location::dummy()); + noirc_errors::reporter::report(&FileMap::default(), &error, false); Err(CliError::Generic) } From f0c1c7ba3feaaa28905bb0813d14acc6673ca797 Mon Sep 17 00:00:00 2001 From: noirwhal <163862677+noirwhal@users.noreply.github.com> Date: Tue, 25 Feb 2025 20:31:29 +0000 Subject: [PATCH 4/4] chore: bump external pinned commits (#7515) Co-authored-by: noirwhal Co-authored-by: Tom French <15848336+TomAFrench@users.noreply.github.com> Co-authored-by: Tom French --- .github/benchmark_projects.yml | 6 +++--- EXTERNAL_NOIR_LIBRARIES.yml | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/benchmark_projects.yml b/.github/benchmark_projects.yml index cabc53d38bb..ba0c598c25a 100644 --- a/.github/benchmark_projects.yml +++ b/.github/benchmark_projects.yml @@ -1,4 +1,4 @@ -define: &AZ_COMMIT f7a8f6be5c4b9c9aa9f59b4b99104b30b7bbff4c +define: &AZ_COMMIT 17e79f42c0a1895dc87a74e4155591e38c45f09b projects: private-kernel-inner: repo: AztecProtocol/aztec-packages @@ -66,7 +66,7 @@ projects: num_runs: 1 timeout: 60 compilation-timeout: 100 - compilation-memory-limit: 7000 + compilation-memory-limit: 8000 rollup-block-root: repo: AztecProtocol/aztec-packages ref: *AZ_COMMIT @@ -75,7 +75,7 @@ projects: timeout: 60 compilation-timeout: 110 execution-timeout: 40 - compilation-memory-limit: 7000 + compilation-memory-limit: 8000 execution-memory-limit: 1500 rollup-merge: repo: AztecProtocol/aztec-packages diff --git a/EXTERNAL_NOIR_LIBRARIES.yml b/EXTERNAL_NOIR_LIBRARIES.yml index 9232e5ac4ce..ddc7a27ee14 100644 --- a/EXTERNAL_NOIR_LIBRARIES.yml +++ b/EXTERNAL_NOIR_LIBRARIES.yml @@ -1,4 +1,4 @@ -define: &AZ_COMMIT f7a8f6be5c4b9c9aa9f59b4b99104b30b7bbff4c +define: &AZ_COMMIT 17e79f42c0a1895dc87a74e4155591e38c45f09b libraries: noir_check_shuffle: repo: noir-lang/noir_check_shuffle @@ -23,10 +23,10 @@ libraries: timeout: 2 noir-bignum: repo: noir-lang/noir-bignum - timeout: 380 + timeout: 90 noir_bigcurve: repo: noir-lang/noir_bigcurve - timeout: 330 + timeout: 250 noir_base64: repo: noir-lang/noir_base64 timeout: 3