Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(frontend)!: Restrict capturing mutable variable in lambdas #7488

Merged
merged 15 commits into from
Mar 3, 2025

Conversation

vezenovm
Copy link
Contributor

@vezenovm vezenovm commented Feb 21, 2025

Description

Problem*

Resolves #4795

Summary*

We now restrict capturing mutable variables that are not mutable references in lambdas.
This is now banned:

fn main() {
    let mut x = 3;

    let f = || {
        x += 2;
    };

    f();
    assert(x == 5);
}

A mutable reference must be used for x instead.

We can still capture a mutable variable if it is only ever used immutably.
e.g. this code is still allowed:

fn main() {
        let mut x = 3;
        let f = || x;
        let _x2 = f();
        assert(x == 3);
   }

Additional Context

Documentation*

Check one:

  • No documentation needed.
  • Documentation included in this PR.
  • [For Experimental Features] Documentation to be submitted in a separate PR.

PR Checklist*

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

@vezenovm vezenovm requested a review from a team February 21, 2025 20:34
@vezenovm vezenovm marked this pull request as draft February 26, 2025 19:25
@vezenovm
Copy link
Contributor Author

vezenovm commented Feb 26, 2025

Looks like the dispatch aztec-nr macro is going to need updating.

Fix here: AztecProtocol/aztec-packages#12311

@asterite
Copy link
Collaborator

I think this doesn't completely solve the issue, though it solves one case of it.

For example I think this code should also be banned:

fn main() {
    let mut x = 3;

    let f = || mutate(&mut x);

    f();
    assert(x == 3);
}

fn mutate(x: &mut Field) {
    *x = 5;
}

And this one:

struct Foo {
    value: Field,
}

impl Foo {
    fn mutate(&mut self) {
        self.value = 2;
    }
}

fn main() {
    let mut foo = Foo { value: 1 };

    let f = || foo.mutate();

    f();

    println(foo);
}

(no need to fix those in this PR, though!)

TomAFrench pushed a commit to AztecProtocol/aztec-packages that referenced this pull request Feb 27, 2025
)

Post noir-lang/noir#7488 aztec-nr is going to
fail to compile as we now explicitly error when attempting to use a
capture mutably (lambda captures are meant to be entirely immutable).
The current code only worked because it was done at comptime.
AztecBot pushed a commit to AztecProtocol/aztec-nr that referenced this pull request Feb 28, 2025
…311)

Post noir-lang/noir#7488 aztec-nr is going to
fail to compile as we now explicitly error when attempting to use a
capture mutably (lambda captures are meant to be entirely immutable).
The current code only worked because it was done at comptime.
@vezenovm
Copy link
Contributor Author

vezenovm commented Mar 3, 2025

(no need to fix those in this PR, though!)

With the PR updates I just pushed, these are also banned now. I have added tests for these cases as well as nested lambdas.

@vezenovm vezenovm requested review from jfecher and asterite March 3, 2025 18:53
Copy link
Contributor

@github-actions github-actions bot left a comment

Choose a reason for hiding this comment

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

⚠️ Performance Alert ⚠️

Possible performance regression was detected for benchmark 'Test Suite Duration'.
Benchmark result of this commit is worse than the previous benchmark result exceeding threshold 1.20.

Benchmark suite Current: 10e4639 Previous: c2022f4 Ratio
noir-lang_noir_bigcurve_ 243 s 199 s 1.22

This comment was automatically generated by workflow using github-action-benchmark.

CC: @TomAFrench

Copy link
Contributor

@jfecher jfecher left a comment

Choose a reason for hiding this comment

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

LGTM. Thank you!

@jfecher jfecher enabled auto-merge March 3, 2025 20:06
@jfecher jfecher added this pull request to the merge queue Mar 3, 2025
Merged via the queue into master with commit 899e8c8 Mar 3, 2025
102 checks passed
@jfecher jfecher deleted the mv/restrict-mut-captures branch March 3, 2025 20:33
AztecBot added a commit to AztecProtocol/aztec-packages that referenced this pull request Mar 4, 2025
…r-lang/noir#7477)

fix(frontend)!: Restrict capturing mutable variable in lambdas (noir-lang/noir#7488)
feat: perform constant sha256 compressions at compile-time (noir-lang/noir#7566)
chore: bump external pinned commits (noir-lang/noir#7565)
chore(ssa): Turn the Brillig constraints check back on by default (noir-lang/noir#7404)
chore: bump external pinned commits (noir-lang/noir#7561)
chore: address some frontend tests TODOs (noir-lang/noir#7554)
fix: shift right overflow in ACIR with unknown var now returns zero (noir-lang/noir#7509)
chore(cli): Forward `nargo execute` to `noir_artifact_cli` (noir-lang/noir#7406)
feat: Support `<Type as Trait>::method` in expressions (noir-lang/noir#7551)
chore: remove FileDiagnostic (noir-lang/noir#7546)
chore: add some extra tests (noir-lang/noir#7544)
fix: fix a few cases where safety comment wasn't correctly identified (noir-lang/noir#7548)
chore!: remove U128 struct from stdlib (noir-lang/noir#7529)
feat: simplify simple conditionals for brillig (noir-lang/noir#7205)
chore: put RcTracker as part of the DIE context (noir-lang/noir#7309)
AztecBot added a commit to AztecProtocol/aztec-packages that referenced this pull request Mar 5, 2025
chore!: remove deprecated hash functions from stdlib (noir-lang/noir#7477)
fix(frontend)!: Restrict capturing mutable variable in lambdas (noir-lang/noir#7488)
feat: perform constant sha256 compressions at compile-time (noir-lang/noir#7566)
chore: bump external pinned commits (noir-lang/noir#7565)
chore(ssa): Turn the Brillig constraints check back on by default (noir-lang/noir#7404)
chore: bump external pinned commits (noir-lang/noir#7561)
chore: address some frontend tests TODOs (noir-lang/noir#7554)
fix: shift right overflow in ACIR with unknown var now returns zero (noir-lang/noir#7509)
chore(cli): Forward `nargo execute` to `noir_artifact_cli` (noir-lang/noir#7406)
feat: Support `<Type as Trait>::method` in expressions (noir-lang/noir#7551)
chore: remove FileDiagnostic (noir-lang/noir#7546)
chore: add some extra tests (noir-lang/noir#7544)
fix: fix a few cases where safety comment wasn't correctly identified (noir-lang/noir#7548)
chore!: remove U128 struct from stdlib (noir-lang/noir#7529)
feat: simplify simple conditionals for brillig (noir-lang/noir#7205)
chore: put RcTracker as part of the DIE context (noir-lang/noir#7309)
AztecBot added a commit to AztecProtocol/aztec-packages that referenced this pull request Mar 5, 2025
chore!: remove deprecated hash functions from stdlib (noir-lang/noir#7477)
fix(frontend)!: Restrict capturing mutable variable in lambdas (noir-lang/noir#7488)
feat: perform constant sha256 compressions at compile-time (noir-lang/noir#7566)
chore: bump external pinned commits (noir-lang/noir#7565)
chore(ssa): Turn the Brillig constraints check back on by default (noir-lang/noir#7404)
chore: bump external pinned commits (noir-lang/noir#7561)
chore: address some frontend tests TODOs (noir-lang/noir#7554)
fix: shift right overflow in ACIR with unknown var now returns zero (noir-lang/noir#7509)
chore(cli): Forward `nargo execute` to `noir_artifact_cli` (noir-lang/noir#7406)
feat: Support `<Type as Trait>::method` in expressions (noir-lang/noir#7551)
chore: remove FileDiagnostic (noir-lang/noir#7546)
chore: add some extra tests (noir-lang/noir#7544)
fix: fix a few cases where safety comment wasn't correctly identified (noir-lang/noir#7548)
chore!: remove U128 struct from stdlib (noir-lang/noir#7529)
feat: simplify simple conditionals for brillig (noir-lang/noir#7205)
chore: put RcTracker as part of the DIE context (noir-lang/noir#7309)
AztecBot added a commit to AztecProtocol/aztec-packages that referenced this pull request Mar 6, 2025
chore!: bump bb version to v0.77.0 (noir-lang/noir#7599)
chore: bump external pinned commits (noir-lang/noir#7601)
feat(cli): Log and replay oracle transcript (noir-lang/noir#7417)
chore: some SSA improvements (noir-lang/noir#7588)
chore(profiler): Add option to only get the total sample count for the `execution-opcodes` command (noir-lang/noir#7578)
feat(experimental): Issue errors for unreachable match branches (noir-lang/noir#7556)
fix: Log to `stderr` (noir-lang/noir#7585)
chore!: remove merkle module from stdlib (noir-lang/noir#7582)
fix: Display causes but not stack trace in CLI error report (noir-lang/noir#7584)
chore: bump `light-poseidon` (noir-lang/noir#7568)
chore: bump external pinned commits (noir-lang/noir#7581)
chore!: remove deprecated hash functions from stdlib (noir-lang/noir#7477)
fix(frontend)!: Restrict capturing mutable variable in lambdas (noir-lang/noir#7488)
feat: perform constant sha256 compressions at compile-time (noir-lang/noir#7566)
chore: bump external pinned commits (noir-lang/noir#7565)
chore(ssa): Turn the Brillig constraints check back on by default (noir-lang/noir#7404)
chore: bump external pinned commits (noir-lang/noir#7561)
chore: address some frontend tests TODOs (noir-lang/noir#7554)
fix: shift right overflow in ACIR with unknown var now returns zero (noir-lang/noir#7509)
chore(cli): Forward `nargo execute` to `noir_artifact_cli` (noir-lang/noir#7406)
feat: Support `<Type as Trait>::method` in expressions (noir-lang/noir#7551)
chore: remove FileDiagnostic (noir-lang/noir#7546)
chore: add some extra tests (noir-lang/noir#7544)
fix: fix a few cases where safety comment wasn't correctly identified (noir-lang/noir#7548)
chore!: remove U128 struct from stdlib (noir-lang/noir#7529)
feat: simplify simple conditionals for brillig (noir-lang/noir#7205)
chore: put RcTracker as part of the DIE context (noir-lang/noir#7309)
AztecBot added a commit to AztecProtocol/aztec-packages that referenced this pull request Mar 6, 2025
chore!: bump bb version to v0.77.0 (noir-lang/noir#7599)
chore: bump external pinned commits (noir-lang/noir#7601)
feat(cli): Log and replay oracle transcript (noir-lang/noir#7417)
chore: some SSA improvements (noir-lang/noir#7588)
chore(profiler): Add option to only get the total sample count for the `execution-opcodes` command (noir-lang/noir#7578)
feat(experimental): Issue errors for unreachable match branches (noir-lang/noir#7556)
fix: Log to `stderr` (noir-lang/noir#7585)
chore!: remove merkle module from stdlib (noir-lang/noir#7582)
fix: Display causes but not stack trace in CLI error report (noir-lang/noir#7584)
chore: bump `light-poseidon` (noir-lang/noir#7568)
chore: bump external pinned commits (noir-lang/noir#7581)
chore!: remove deprecated hash functions from stdlib (noir-lang/noir#7477)
fix(frontend)!: Restrict capturing mutable variable in lambdas (noir-lang/noir#7488)
feat: perform constant sha256 compressions at compile-time (noir-lang/noir#7566)
chore: bump external pinned commits (noir-lang/noir#7565)
chore(ssa): Turn the Brillig constraints check back on by default (noir-lang/noir#7404)
chore: bump external pinned commits (noir-lang/noir#7561)
chore: address some frontend tests TODOs (noir-lang/noir#7554)
fix: shift right overflow in ACIR with unknown var now returns zero (noir-lang/noir#7509)
chore(cli): Forward `nargo execute` to `noir_artifact_cli` (noir-lang/noir#7406)
feat: Support `<Type as Trait>::method` in expressions (noir-lang/noir#7551)
chore: remove FileDiagnostic (noir-lang/noir#7546)
chore: add some extra tests (noir-lang/noir#7544)
fix: fix a few cases where safety comment wasn't correctly identified (noir-lang/noir#7548)
chore!: remove U128 struct from stdlib (noir-lang/noir#7529)
feat: simplify simple conditionals for brillig (noir-lang/noir#7205)
chore: put RcTracker as part of the DIE context (noir-lang/noir#7309)
TomAFrench added a commit to AztecProtocol/aztec-packages that referenced this pull request Mar 6, 2025
Automated pull of development from the
[noir](https://github.com/noir-lang/noir) programming language, a
dependency of Aztec.
BEGIN_COMMIT_OVERRIDE
chore!: remove deprecated hash functions from stdlib
(noir-lang/noir#7477)
fix(frontend)!: Restrict capturing mutable variable in lambdas
(noir-lang/noir#7488)
feat: perform constant sha256 compressions at compile-time
(noir-lang/noir#7566)
chore: bump external pinned commits
(noir-lang/noir#7565)
chore(ssa): Turn the Brillig constraints check back on by default
(noir-lang/noir#7404)
chore: bump external pinned commits
(noir-lang/noir#7561)
chore: address some frontend tests TODOs
(noir-lang/noir#7554)
fix: shift right overflow in ACIR with unknown var now returns zero
(noir-lang/noir#7509)
chore(cli): Forward `nargo execute` to `noir_artifact_cli`
(noir-lang/noir#7406)
feat: Support `<Type as Trait>::method` in expressions
(noir-lang/noir#7551)
chore: remove FileDiagnostic
(noir-lang/noir#7546)
chore: add some extra tests
(noir-lang/noir#7544)
fix: fix a few cases where safety comment wasn't correctly identified
(noir-lang/noir#7548)
chore!: remove U128 struct from stdlib
(noir-lang/noir#7529)
feat: simplify simple conditionals for brillig
(noir-lang/noir#7205)
chore: put RcTracker as part of the DIE context
(noir-lang/noir#7309)
END_COMMIT_OVERRIDE

---------

Co-authored-by: Tom French <tom@tomfren.ch>
TomAFrench added a commit that referenced this pull request Mar 6, 2025
* master: (65 commits)
  feat: Compare bincode to CBOR, FlexBuffers and Protobuf - implement best (#7513)
  chore: track more critical libraries (#7604)
  chore!: bump bb version to v0.77.0 (#7599)
  chore: bump external pinned commits (#7601)
  feat(cli): Log and replay oracle transcript (#7417)
  chore: some SSA improvements (#7588)
  chore(profiler): Add option to only get the total sample count for the `execution-opcodes` command (#7578)
  feat(experimental): Issue errors for unreachable match branches (#7556)
  fix: Log to `stderr` (#7585)
  chore!: remove merkle module from stdlib (#7582)
  fix: Display causes but not stack trace in CLI error report (#7584)
  chore: bump `light-poseidon` (#7568)
  chore: bump external pinned commits (#7581)
  chore!: remove deprecated hash functions from stdlib (#7477)
  fix(frontend)!: Restrict capturing mutable variable in lambdas (#7488)
  feat: perform constant sha256 compressions at compile-time (#7566)
  chore: bump external pinned commits (#7565)
  chore(ssa): Turn the Brillig constraints check back on by default (#7404)
  chore: bump external pinned commits (#7561)
  chore: address some frontend tests TODOs (#7554)
  ...
rahul-kothari pushed a commit to AztecProtocol/aztec-packages that referenced this pull request Mar 7, 2025
🤖 I have created a new Aztec Packages release
---


##
[0.78.0](v0.77.1...v0.78.0)
(2025-03-07)


### ⚠ BREAKING CHANGES

* convert `TraitMethodNotInScope` to error
(noir-lang/noir#7427)
* bump bb version to v0.77.0
(noir-lang/noir#7599)
* remove merkle module from stdlib
(noir-lang/noir#7582)
* remove deprecated hash functions from stdlib
(noir-lang/noir#7477)
* **frontend:** Restrict capturing mutable variable in lambdas
(noir-lang/noir#7488)
* remove U128 struct from stdlib
(noir-lang/noir#7529)

### Features

* **barretenberg:** Graph methods for circuit analysis (part 2)
([#12130](#12130))
([ec4c0c4](ec4c0c4))
* **cli:** Log and replay oracle transcript
(noir-lang/noir#7417)
([f13b729](f13b729))
* Compare bincode to CBOR, FlexBuffers and Protobuf - implement best
(noir-lang/noir#7513)
([8eb727c](8eb727c))
* **experimental:** Enable ownership syntax
(noir-lang/noir#7603)
([1a3c112](1a3c112))
* **experimental:** Issue errors for unreachable match branches
(noir-lang/noir#7556)
([f13b729](f13b729))
* nullify just-added notes
([#12552](#12552))
([dcba7a4](dcba7a4))
* perform constant sha256 compressions at compile-time
(noir-lang/noir#7566)
([f13b729](f13b729))
* relate errors to macro built-ins errors
(noir-lang/noir#7609)
([fbaa634](fbaa634))
* simplify simple conditionals for brillig
(noir-lang/noir#7205)
([f13b729](f13b729))
* Support `&lt;Type as Trait&gt;::method` in expressions
(noir-lang/noir#7551)
([f13b729](f13b729))
* Sync from aztec-packages (noir-lang/noir#7606)
([8eb727c](8eb727c))
* teardown in call interface
([#12499](#12499))
([062df02](062df02))
* translation evaluations with zk
([#12222](#12222))
([568982d](568982d))


### Bug Fixes

* **avm:** use the correct number of rows in check_interaction
([#12519](#12519))
([b1284ef](b1284ef))
* aztec-up
([#12509](#12509))
([3ddb6de](3ddb6de))
* bbup
([#12555](#12555))
([e7b5353](e7b5353))
* Bitwise lookup
([#12471](#12471))
([a38f353](a38f353))
* **ci:** remove regex - transfer explicitly
([#12525](#12525))
([352bb1d](352bb1d))
* Cl/fix arm anvil
([#12565](#12565))
([e4bfbd1](e4bfbd1))
* compare Quoted by expanding interned values
(noir-lang/noir#7602)
([1a3c112](1a3c112))
* Display causes but not stack trace in CLI error report
(noir-lang/noir#7584)
([f13b729](f13b729))
* **experimental:** Fix execution of match expressions with multiple
branches (noir-lang/noir#7570)
([1a3c112](1a3c112))
* fix a few cases where safety comment wasn't correctly identified
(noir-lang/noir#7548)
([f13b729](f13b729))
* fix bbup and add CI
([#12541](#12541))
([1b2604c](1b2604c))
* Fix the config
([#12513](#12513))
([fb9fac6](fb9fac6))
* **frontend:** Restrict capturing mutable variable in lambdas
(noir-lang/noir#7488)
([f13b729](f13b729))
* FunctionDefinition::as_typed_expr didn't work well for trait imp…
(noir-lang/noir#7611)
([1a3c112](1a3c112))
* Log to `stderr` (noir-lang/noir#7585)
([f13b729](f13b729))
* **LSP:** references/rename only when underlying span has the correct…
(noir-lang/noir#7598)
([8eb727c](8eb727c))
* make vk metadata actual witnesses
([#12459](#12459))
([dada06f](dada06f))
* no fast deployments when the boot node needs to restart.
([#12557](#12557))
([866582e](866582e))
* **node:** drop log level of handler not registered
([#12523](#12523))
([cb7e42d](cb7e42d))
* override bb path in cli-wallet PXE config
([#12511](#12511))
([0c3024e](0c3024e))
* publish-bb-mac.yml version replace
([#12554](#12554))
([7e89dfb](7e89dfb))
* release bb-mac
([fac5fb5](fac5fb5))
* Revert "make vk metadata actual witnesses"
([#12534](#12534))
([ed46a3c](ed46a3c))
* shift right overflow in ACIR with unknown var now returns zero
(noir-lang/noir#7509)
([f13b729](f13b729))
* TokensPrettyPrinter was missing some spaces between tokens
(noir-lang/noir#7607)
([1a3c112](1a3c112))
* yarn-project e2e bench
([#12547](#12547))
([b40b904](b40b904))


### Miscellaneous

* add some extra tests (noir-lang/noir#7544)
([f13b729](f13b729))
* add underscore parameter documentation
(noir-lang/noir#7562)
([1a3c112](1a3c112))
* add yaml aliases in .test_patterns.yml
([#12516](#12516))
([3ee8d51](3ee8d51))
* address some frontend tests TODOs
(noir-lang/noir#7554)
([f13b729](f13b729))
* addressing remaining feedback in PR 12182
([#12494](#12494))
([f733879](f733879)),
closes
[#12193](#12193)
* bump `light-poseidon` (noir-lang/noir#7568)
([f13b729](f13b729))
* bump bb version to v0.77.0
(noir-lang/noir#7599)
([f13b729](f13b729))
* bump external pinned commits
(noir-lang/noir#7561)
([f13b729](f13b729))
* bump external pinned commits
(noir-lang/noir#7565)
([f13b729](f13b729))
* bump external pinned commits
(noir-lang/noir#7581)
([f13b729](f13b729))
* bump external pinned commits
(noir-lang/noir#7601)
([f13b729](f13b729))
* bump external pinned commits
(noir-lang/noir#7618)
([fbaa634](fbaa634))
* bump ring to address advisory
(noir-lang/noir#7619)
([fbaa634](fbaa634))
* Cleaner PXE
([#12515](#12515))
([a69f416](a69f416))
* cleanup committing and masking utility
([#12514](#12514))
([9f57048](9f57048))
* **cli:** exclude kind smoke test from flake list
([#12518](#12518))
([778bfa6](778bfa6))
* **cli:** Forward `nargo execute` to `noir_artifact_cli`
(noir-lang/noir#7406)
([f13b729](f13b729))
* convert `TraitMethodNotInScope` to error
(noir-lang/noir#7427)
([fbaa634](fbaa634))
* explode aliases when looking up owners in `.test_patterns.yml`
([#12526](#12526))
([2e0d791](2e0d791))
* fix trait import issues
([#12500](#12500))
([fd9f145](fd9f145))
* Fix yarn install immutable issues
([#12539](#12539))
([fb9ada3](fb9ada3)),
closes
[#12538](#12538)
* More config defaults and forward p2p ports
([#12529](#12529))
([2c45fb9](2c45fb9))
* **node:** return correct node version
([#12520](#12520))
([5502901](5502901))
* **profiler:** Add option to only get the total sample count for the
`execution-opcodes` command
(noir-lang/noir#7578)
([f13b729](f13b729))
* put RcTracker as part of the DIE context
(noir-lang/noir#7309)
([f13b729](f13b729))
* remove deprecated hash functions from stdlib
(noir-lang/noir#7477)
([f13b729](f13b729))
* remove FileDiagnostic (noir-lang/noir#7546)
([f13b729](f13b729))
* remove merkle module from stdlib
(noir-lang/noir#7582)
([f13b729](f13b729))
* Remove scope interpolation from env vars
([#12522](#12522))
([70942e9](70942e9))
* remove U128 struct from stdlib
(noir-lang/noir#7529)
([f13b729](f13b729))
* replace relative paths to noir-protocol-circuits
([f20c0dd](f20c0dd))
* replace relative paths to noir-protocol-circuits
([4365064](4365064))
* restore bb --version
([#12542](#12542))
([ab13d43](ab13d43))
* restore method syntax on `get_storage_slot` calls
([#12532](#12532))
([8e9f594](8e9f594))
* rm unused methods
([#12544](#12544))
([ed1dbdc](ed1dbdc))
* some SSA improvements (noir-lang/noir#7588)
([f13b729](f13b729))
* **spartan:** kind test speedup
([#12478](#12478))
([8ede7b1](8ede7b1))
* **ssa:** Turn the Brillig constraints check back on by default
(noir-lang/noir#7404)
([f13b729](f13b729))
* track more critical libraries
(noir-lang/noir#7604)
([f13b729](f13b729))
* update and lock AVM's lockfile
([#12533](#12533))
([2babc50](2babc50))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Closure environments are treated as mutable when they actually aren't
3 participants