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

Add references to Sway #5406

Merged
merged 27 commits into from
Jan 4, 2024
Merged

Add references to Sway #5406

merged 27 commits into from
Jan 4, 2024

Conversation

ironcev
Copy link
Member

@ironcev ironcev commented Dec 18, 2023

Description

This PR brings references to the language. The overall effort is tracked in #5063.

In the below description, when talking about references we mean &T references - references to immutable values. &mut T will be implemented in upcoming PRs.

The PR implements the following features:

  • References exist in the type system and can be declared, aliased, dereferenced using * operator, etc.
  • Reference expressions (referencing) are fully supported on all expressions including the nonsensical one like e.g. &return;
  • Semantic analysis and checks are implemented for the current functionality.
  • References can be embedded in aggregates.
  • References can reference parts of aggreagates.
  • References can be passed to and returned from ASM blocks.
  • References can be passed to and returned from functions.
  • References can be mutable: let mut r_x = &x
  • Impls can be implemented for non-generic reference types.
  • Traits can be implemented for non-generic reference types.
  • References work with generics, means &T works as expected.
  • References can reference references.
  • References can be dereferenced using the * operator.
  • Dereference expressions (dereferencing) are fully supported on all expressions including the nonsensical one like e.g. *&return;

Known limitations:

  • When declaring references on references, currently a space (' ') is mandatory between two ampersands. E.g., &&a emits error and must be written as & &a. Extending parser to support, e.g., arbitrary &&...&&a will be done in upcoming PRs.
  • Referencing function parameters for copy types works but not with 100% proper semantics (creates a copy of the parameter).

On the IR level, references are pointers stored as u64 and do not exist as a separate concept. They play well with all the existing IR optimizations.

Since core::ops::Eq and __addr_of() are still not implemented for references, checking for equality in tests is done by converting references to raw_ptrs and checking raw pointers. This is essentially fine and will one day be turned into converting references to typed pointers which are tests we will anyhow want to have.

Next steps are listed in #5063.

The documentation will be done in a separate PR and provided separately once feature is considered ready for public usage.

There are several todos in code marked as TODO-IG. They will be resolved in upcoming PRs.

Demo

For extensive demos of implemented features, see the tests in this PR.

An example of a semantic check:

Expression cannot be dereferenced

Checklist

  • I have linked to any relevant issues.
  • I have commented my code, particularly in hard-to-understand areas.
  • I have updated the documentation where relevant (API docs, the reference, and the Sway book).
  • I have added tests that prove my fix is effective or that my feature works.
  • I have added (or requested a maintainer to add) the necessary Breaking* or New Feature labels where relevant.
  • I have done my best to ensure that my PR adheres to the Fuel Labs Code Review Standards.
  • I have requested a review from the relevant team or maintainers.

@ironcev ironcev requested a review from a team December 18, 2023 15:48
@ironcev ironcev self-assigned this Dec 18, 2023
@ironcev ironcev added compiler General compiler. Should eventually become more specific as the issue is triaged compiler: ir IRgen and sway-ir including optimization passes compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler: parser Everything to do with the parser compiler: codegen Everything to do with IR->ASM, register allocation, etc. compiler: ui Mostly compiler messages labels Dec 18, 2023
@Voxelot
Copy link
Member

Voxelot commented Dec 19, 2023

References can be passed to and returned from functions.

What about ABI methods - are there any special considerations we've taken into account for those? (i.e. no mutable references)

@ironcev
Copy link
Member Author

ironcev commented Dec 19, 2023

What about ABI methods - are there any special considerations we've taken into account for those? (i.e. no mutable references)

Good question! I am also asking it in one of the open todos: // TODO-IG: No references in ABIs according to the RFC. Or we want to have them?

The current proposal goes for forbidding references altogether on the boundaries. But if we support raw_ptr on the boundaries, and we do, I see no reason not to support references.

Having some good examples for use cases where raw_ptr is used in ABIs would be great. I am sure such use cases would get easier to support with references.

Long story short, current proposal bans references on the boundaries, but we will re-discuss it. Any concrete examples in dapps that would be helpful to understand the use cases are appreciated.

xunilrj
xunilrj previously approved these changes Dec 20, 2023
@xunilrj
Copy link
Contributor

xunilrj commented Dec 20, 2023

I left some comments but I am in favor of merging this and avoid merge/rebase issues.

@xunilrj
Copy link
Contributor

xunilrj commented Dec 20, 2023

I am also curious to know what would happen to references to locals being returned

fn f(v: u64) -> &u64 {
    return &v;
}

@ironcev
Copy link
Member Author

ironcev commented Dec 20, 2023

I am also curious to know what would happen to references to locals being returned

The locals will be placed on heap and the returned reference will contain a heap pointer. This is meant by "Allocating values on the heap when using references" in #5063. Knowing we never free heap allocations this is fine and is a first step. BDW we discussed garbage collection at the offsite and there should not be anything in the reference concept what will stop us one day from implementing garbage collection if we want.

xunilrj
xunilrj previously approved these changes Dec 22, 2023
@ironcev ironcev requested review from xunilrj and a team December 24, 2023 21:07
@ironcev ironcev enabled auto-merge (squash) December 24, 2023 21:08
xunilrj
xunilrj previously approved these changes Dec 27, 2023
@ironcev ironcev requested review from xunilrj and a team January 4, 2024 12:38
Copy link
Member

@JoshuaBatty JoshuaBatty left a comment

Choose a reason for hiding this comment

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

So cool to see this finally land in sway. Awesome work!

@ironcev ironcev merged commit bae4be8 into master Jan 4, 2024
34 checks passed
@ironcev ironcev deleted the ironcev/declare-references branch January 4, 2024 22:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
compiler: codegen Everything to do with IR->ASM, register allocation, etc. compiler: frontend Everything to do with type checking, control flow analysis, and everything between parsing and IRgen compiler: ir IRgen and sway-ir including optimization passes compiler: parser Everything to do with the parser compiler: ui Mostly compiler messages compiler General compiler. Should eventually become more specific as the issue is triaged
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants