Skip to content

feat: Make arrays and slices polymorphic over each other#2070

Merged
jfecher merged 16 commits intomasterfrom
jf/merge-array-and-slice-types
Jul 28, 2023
Merged

feat: Make arrays and slices polymorphic over each other#2070
jfecher merged 16 commits intomasterfrom
jf/merge-array-and-slice-types

Conversation

@jfecher
Copy link
Contributor

@jfecher jfecher commented Jul 27, 2023

Description

Problem*

Resolves #1963
Resolves #1931
Resolves #1842
Resolves #1354

Summary*

Instead of representing Type::Array(size, elem) as a separate type from Type::Slice(elem) and allowing them to intermingle via subtyping, this PR removes the subtyping relationship and the Type::Slice variant entirely. Now, array literals have a polymorphic "MaybeConstant" size that can later be resolved to either a Constant size (array) or a NotConstant size (slice). This also means we no longer need type annotations to create slice literals.

BREAKING CHANGES:
- Arrays and slices are no longer subtypes of each other. So if you have an array and you need to pass it to a function that only accepts a slice, you now need to add an explicit .as_slice().

  • I've added an array to slice coercion so there should no longer be any breaking changes.

Documentation

  • This PR requires documentation updates when merged.

    • I will submit a noir-lang/docs PR.
    • I will request for and support Dev Rel's help in documenting this PR.
      • An array literal [a, b, c, ..] can now resolve to either an array or a slice depending on how it is used.
      • This is just like how an integer literal can resolve to any integer type depending on how it is used.
      • Just like integer literals, if you want to convert between arrays and slices you now need an explicit conversion function.
      • Users wishing to write a function that is polymorphic over arrays and slices can still use the fn foo<T, N>(array_or_slice: [T; N]) syntax since slices are considered to be arrays internally of a non-constant size (implementation detail).

Additional Context

I'm putting this PR out a bit early for visibility and because I need the CI to help find which tests need a .as_slice() to be added.

PR Checklist*

  • I have tested the changes locally.
  • I have formatted the changes with Prettier and/or cargo fmt on default settings.

@jfecher
Copy link
Contributor Author

jfecher commented Jul 27, 2023

I think I'll try to add rust's implicit coercion of array to slice. This should no longer be a breaking change afterward.

Edit: Added

@jfecher jfecher mentioned this pull request Jul 27, 2023
5 tasks
@jfecher
Copy link
Contributor Author

jfecher commented Jul 27, 2023

This PR is currently held up by an error in brillig_slices:

the application panicked (crashed).
Message:  internal error: entered unreachable code: ICE: Expected array, got HeapVector(HeapVector { pointer: RegisterIndex(6), size: RegisterIndex(7) })
Location: crates/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs:114

This is a bug. We may have already fixed this in newer versions of Nargo so try searching for similar issues at https://github.com/noir-lang/noir/issues/.
If there isn't an open issue for this bug, consider opening one at https://github.com/noir-lang/noir/issues/new?labels=bug&template=bug_report.yml

  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ BACKTRACE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
                                ⋮ 13 frames hidden ⋮                              
  14: noirc_evaluator::brillig::brillig_gen::brillig_fn::FunctionContext::extract_heap_array::h612d83e614e579d9
      at /.../noir/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_fn.rs:114
  15: noirc_evaluator::brillig::brillig_gen::brillig_block::BrilligBlock::convert_ssa_value::h03347b8489e010ae
      at /.../noir/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs:803
  16: noirc_evaluator::brillig::brillig_gen::brillig_block::BrilligBlock::convert_ssa_instruction::h435b587b3c58d1e0
      at /.../noir/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs:236
  17: noirc_evaluator::brillig::brillig_gen::brillig_block::BrilligBlock::convert_block::h3079b65c1c7e2aaa
      at /.../noir/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs:61
  18: noirc_evaluator::brillig::brillig_gen::brillig_block::BrilligBlock::compile::h4903fe94bd90897c
      at /.../noir/crates/noirc_evaluator/src/brillig/brillig_gen/brillig_block.rs:47
  19: noirc_evaluator::brillig::brillig_gen::convert_ssa_function::h6239c1d6fcb032a1
      at /.../noir/crates/noirc_evaluator/src/brillig/brillig_gen.rs:28
  20: noirc_evaluator::brillig::Brillig::compile::h3cd51d3807fe3513
      at /.../noir/crates/noirc_evaluator/src/brillig/mod.rs:28
  21: noirc_evaluator::brillig::<impl noirc_evaluator::ssa_refactor::ssa_gen::program::Ssa>::to_brillig::h58acb38d118edfdd
      at /.../noir/crates/noirc_evaluator/src/brillig/mod.rs:99
  22: noirc_evaluator::ssa_refactor::optimize_into_acir::h96fd7ea2cbc06f17
      at /.../noir/crates/noirc_evaluator/src/ssa_refactor.rs:48
  23: noirc_evaluator::ssa_refactor::create_circuit::h3221b5c03c1245cd
      at /.../noir/crates/noirc_evaluator/src/ssa_refactor.rs:81
  24: noirc_driver::compile_no_check::ha192bac6b09f9ae5
      at /.../noir/crates/noirc_driver/src/lib.rs:306
  25: noirc_driver::compile_main::h159318b5103cbeb1
      at /.../noir/crates/noirc_driver/src/lib.rs:195
  26: nargo_cli::cli::compile_cmd::compile_circuit::h750de128d64d5da7
      at /.../noir/crates/nargo_cli/src/cli/compile_cmd.rs:128
  27: nargo_cli::cli::prove_cmd::prove_with_path::hc2b46b42c1fbf6f9
      at /.../noir/crates/nargo_cli/src/cli/prove_cmd.rs:112
  28: nargo_cli::cli::prove_cmd::run::h9a42555316685c8e
      at /.../noir/crates/nargo_cli/src/cli/prove_cmd.rs:68
  29: nargo_cli::cli::start_cli::hafb3033a71756cdf
      at /.../noir/crates/nargo_cli/src/cli/mod.rs:80
  30: nargo::main::hb051dd85bb9ddb14
      at /.../noir/crates/nargo_cli/src/main.rs:14
  31: core::ops::function::FnOnce::call_once::he90185e242af6ac8
      at /rustc/69f9c33d71c871fc16ac445211281c6e7a340943/library/core/src/ops/function.rs:251
                                ⋮ 13 frames hidden ⋮                              
exit 101

Any insight into this @sirasistant?

@sirasistant
Copy link
Contributor

Yes, fixed in #2080. The problem was that it was previously assumed that a Value::Array was always had Type::Array, which is no longer the case. Also improved a bit the brillig_slices test now that references have coherent typing!

@sirasistant sirasistant mentioned this pull request Jul 28, 2023
5 tasks
sirasistant and others added 2 commits July 28, 2023 08:12
* fix: Initialize Value::Array of type Slice

* test: improved brillig test after bug fix
sirasistant
sirasistant previously approved these changes Jul 28, 2023
Copy link
Contributor

@sirasistant sirasistant left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks a lot for this! 🚀

@jfecher jfecher changed the title feat!: Make arrays and slices polymorphic over each other feat: Make arrays and slices polymorphic over each other Jul 28, 2023
@jfecher
Copy link
Contributor Author

jfecher commented Jul 28, 2023

@sirasistant I've pushed an array -> slice coercion so that this is no longer a breaking change. I think this recovers the lost ergonomics as well. It works by implicitly adding a .as_slice() call when needed, so the backend does not have to worry about values changing types.

sirasistant
sirasistant previously approved these changes Jul 28, 2023
@jfecher jfecher enabled auto-merge July 28, 2023 17:20
@jfecher jfecher added this pull request to the merge queue Jul 28, 2023
Merged via the queue into master with commit ef91286 Jul 28, 2023
@jfecher jfecher deleted the jf/merge-array-and-slice-types branch July 28, 2023 17:43
TomAFrench added a commit that referenced this pull request Aug 1, 2023
* master: (53 commits)
  chore: Update `noir-source-resolver` to v1.1.3 (#1912)
  chore: Document `GeneratedAcir::more_than_eq_comparison` (#2085)
  chore: refresh ACIR test artifacts (#2091)
  feat: Add `deprecated` attribute (#2041)
  chore(ssa refactor): Implement `acir_gen` errors (#2071)
  chore: use witnesses from the generated acir in the ABI (#2095)
  fix: Fix methods not mutating fields (#2087)
  chore(nargo): Use Display impl for InputValue (#1990)
  feat: Make arrays and slices polymorphic over each other (#2070)
  feat: Remove an unnecessary witness in `mul_with_witness` (#2078)
  chore: document truncate (#2082)
  fix: avoid potential panic in `two_complement` (#2081)
  chore: Cleanup integration tests (#2074)
  chore: replace `Type::TypeVariable`, `Type::PolymorphicInteger`, and … (#2065)
  chore!: Require package names in `Nargo.toml` files (#2056)
  fix: Avoid non-determinism in defunctionalization (#2069)
  chore: change 'unnecessary pub' error to a warning (#2064)
  feat!: Update to ACVM 0.21.0 (#2051)
  chore: Rename execute tests for an accurate description (#2063)
  chore: Restore lost integration test (#2062)
  ...
TomAFrench added a commit that referenced this pull request Aug 1, 2023
* master: (75 commits)
  fix: Mutating a variable no longer mutates its copy (#2057)
  fix: Implement `.len()` in Acir-Gen (#2077)
  chore: clippy fixes (#2101)
  chore: Update `noir-source-resolver` to v1.1.3 (#1912)
  chore: Document `GeneratedAcir::more_than_eq_comparison` (#2085)
  chore: refresh ACIR test artifacts (#2091)
  feat: Add `deprecated` attribute (#2041)
  chore(ssa refactor): Implement `acir_gen` errors (#2071)
  chore: use witnesses from the generated acir in the ABI (#2095)
  fix: Fix methods not mutating fields (#2087)
  chore(nargo): Use Display impl for InputValue (#1990)
  feat: Make arrays and slices polymorphic over each other (#2070)
  feat: Remove an unnecessary witness in `mul_with_witness` (#2078)
  chore: document truncate (#2082)
  fix: avoid potential panic in `two_complement` (#2081)
  chore: Cleanup integration tests (#2074)
  chore: replace `Type::TypeVariable`, `Type::PolymorphicInteger`, and … (#2065)
  chore!: Require package names in `Nargo.toml` files (#2056)
  fix: Avoid non-determinism in defunctionalization (#2069)
  chore: change 'unnecessary pub' error to a warning (#2064)
  ...
TomAFrench added a commit that referenced this pull request Aug 1, 2023
* master: (75 commits)
  fix: Mutating a variable no longer mutates its copy (#2057)
  fix: Implement `.len()` in Acir-Gen (#2077)
  chore: clippy fixes (#2101)
  chore: Update `noir-source-resolver` to v1.1.3 (#1912)
  chore: Document `GeneratedAcir::more_than_eq_comparison` (#2085)
  chore: refresh ACIR test artifacts (#2091)
  feat: Add `deprecated` attribute (#2041)
  chore(ssa refactor): Implement `acir_gen` errors (#2071)
  chore: use witnesses from the generated acir in the ABI (#2095)
  fix: Fix methods not mutating fields (#2087)
  chore(nargo): Use Display impl for InputValue (#1990)
  feat: Make arrays and slices polymorphic over each other (#2070)
  feat: Remove an unnecessary witness in `mul_with_witness` (#2078)
  chore: document truncate (#2082)
  fix: avoid potential panic in `two_complement` (#2081)
  chore: Cleanup integration tests (#2074)
  chore: replace `Type::TypeVariable`, `Type::PolymorphicInteger`, and … (#2065)
  chore!: Require package names in `Nargo.toml` files (#2056)
  fix: Avoid non-determinism in defunctionalization (#2069)
  chore: change 'unnecessary pub' error to a warning (#2064)
  ...
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

2 participants