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

feat(ssa refactor): Implement first-class references #1849

Merged
merged 13 commits into from
Jul 5, 2023
Merged

Conversation

jfecher
Copy link
Contributor

@jfecher jfecher commented Jul 3, 2023

Description

Problem*

Resolves #1702 - although I opted for first-class references instead of second-class references. These turned out to be easier/cleaner to add since adding second-class references would require some restrictions in how users are allowed to pass these around which are non-trivial to implement.

Summary*

Implements first-class references:

  • A new type &mut T is now added representing mutable references.
    • Unlike rust, there are no lifetimes on references types in noir.
  • New unary operators have been added:
    • Create a mutable reference via &mut expr
    • Dereference via *expr
  • Dereferencing is also valid in the "lvalue" of an assignment.
    • In other words, the * in *foo = bar; is now allowed on the left hand side of the =.
    • This is required if foo : &mut T.
  • An error is issued if:
    • Users use &mut v where v is an immutable variable or field of one.
    • Users use &mut v[i] where v[i] is an array access. Since arrays are immutable in the ssa refactor, this is somewhat more difficult to add so I opted to leave it as an error for now. Note that this is a user-facing error rather than a panic. The error message suggests storing the array element in another variable as a work around.

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.
      • We should mention noir has mutable references.
      • Users can create mutable references via &mut value where value is either an existing (mutable) variable, or a literal value.
        • If it is an existing mutable variable, the reference will be aliased to the same variable
        • If it is to a literal value, a fresh reference will be created.
        • If it is to an immutable value, an error will be issued.
      • Mutable references have the type &mut T where T is the element type. For example, a mutable reference to a Field will have the type &mut Field.
      • Mutable references can be dereferenced to access their inner value: *my_ref. We can think of the unary * operation as having the type fn(&mut T) -> T.
      • Mutable references can be passed to functions to have functions mutate values visible to the caller.

Additional Context

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 4, 2023

Found and fixed a bug with assignments and the mem2reg pass where we would produce incorrect code when codegening a let mut variable with nested &mut references. Only the &mut was dereferenced, and the outer reference from the let mut would not.

@jfecher
Copy link
Contributor Author

jfecher commented Jul 5, 2023

This PR is passing again

@jfecher
Copy link
Contributor Author

jfecher commented Jul 5, 2023

All of the outdated code has been removed

@jfecher jfecher added this pull request to the merge queue Jul 5, 2023
Merged via the queue into master with commit e5773e4 Jul 5, 2023
@jfecher jfecher deleted the jf/references branch July 5, 2023 14:02
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.

Add second-class references to Noir
2 participants