-
Notifications
You must be signed in to change notification settings - Fork 5.4k
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
Implement References RFC #5063
Labels
enhancement
New feature or request
language feature
Core language features visible to end users
Needs RFC
Features that require an RFC before proceeding with an implementation
Comments
IGI-111
added
enhancement
New feature or request
language feature
Core language features visible to end users
Needs RFC
Features that require an RFC before proceeding with an implementation
labels
Aug 31, 2023
Closed
ironcev
added a commit
that referenced
this issue
Jan 4, 2024
## Description This PR brings [references](https://github.com/FuelLabs/sway-rfcs/blob/ironcev/amend-references/files/0010-references.sw) 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_ptr`s 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](https://github.com/FuelLabs/sway/assets/4142833/0d1a3576-3725-4a70-abf2-e5e11625f429) ## Checklist - [x] I have linked to any relevant issues. - [x] 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). - [x] 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. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
ironcev
added a commit
that referenced
this issue
Jan 31, 2024
## Description This PR implements index operator `[]` for [references](https://github.com/FuelLabs/sway-rfcs/blob/ironcev/amend-references/files/0010-references.sw). The overall effort related to references is tracked in #5063. `[]` is defined for references using this recursive definition: `<reference>[<index>] := (*<reference>)[<index>]`. This eliminates the need for the dereferencing operator `*` when working with references to arrays: ```Sway let array = [1, 2, 3]; let r = &&&array; assert((***r)[0] == r[0]); ``` ```Sway let r = &&&[ &&[1, 2, 3], &&[4, 5, 6] ]; assert(r[0][2] == 3); assert(r[1][0] == 4); ``` Additionally, the PR fixes two previously existing issues (see below screenshots): - the misleading error message on type not implementing the "index" method when indexing a non-indexable type. - the broken error span and expression text when indexing a non-indexable type in reassignments. Before: ![No method named index found for type](https://github.com/FuelLabs/sway/assets/4142833/4693510d-bcb4-45ca-8f41-7988a8d87b3e) ![Not an indexable expression - Before](https://github.com/FuelLabs/sway/assets/4142833/6b8f28f0-25db-4ba8-b6a5-3d5468c70cdc) After: ![Type is not indexable](https://github.com/FuelLabs/sway/assets/4142833/df160b3b-312e-40dc-b32f-71786ee382ea) ## Checklist - [x] I have linked to any relevant issues. - [x] 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). - [x] 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. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
7 tasks
ironcev
added a commit
that referenced
this issue
Feb 4, 2024
## Description This PR implements struct field access operator `.` for [references](https://github.com/FuelLabs/sway-rfcs/blob/ironcev/amend-references/files/0010-references.sw). The overall effort related to references is tracked in #5063. `.` is defined for references to structs using this recursive definition: `<reference>.<field name> := (*<reference>).<field name>`. This eliminates the need for the dereferencing operator `*` when working with references to structs: ```Sway let s = Struct { x: 0 }; let r = &&&s; assert((***r).x == r.x); ``` ```Sway let r = &&&Struct { r_a: &&A { x: 1 }, &B { y: 2 } ]; assert(r.r_a.x == 1); assert(r.r_b.y == 2); ``` Additionally, the PR adds a `Diagnostic` for the `StorageFieldDoesNotExist` error and aligns it with the `StructFieldDoesNotExist` error. ## Demo ![Field access requires a struct - On expression](https://github.com/FuelLabs/sway/assets/4142833/6dcad917-2a91-47ba-8ff7-aa13dc681bcb)) ![Field access requires a struct - Storage variable](https://github.com/FuelLabs/sway/assets/4142833/ab3fc2d4-bc87-48dd-855c-b4001c43199e) ![Storage field does not exist](https://github.com/FuelLabs/sway/assets/4142833/6a7f1800-dbad-4e0a-af4a-ed5f9f393f70) ## Checklist - [x] I have linked to any relevant issues. - [x] 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). - [x] 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. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
7 tasks
IGI-111
pushed a commit
that referenced
this issue
Feb 5, 2024
## Description This PR implements tuple element access operator `.` for [references](https://github.com/FuelLabs/sway-rfcs/blob/ironcev/amend-references/files/0010-references.sw). The overall effort related to references is tracked in #5063. `.` is defined for references to tuples using this recursive definition: `<reference>.<element index> := (*<reference>).<element index>`. This eliminates the need for the dereferencing operator `*` when working with references to tuples: ```Sway let t = (1, 2, 3); let r = &&&t; assert((***r).0 == r.0); ``` ```Sway let r = &&& ( &&(1, 2), &(3, 4) ); assert(r.0.0 == 1); assert(r.1.1 == 4); ``` Additionally, the PR: - creates `Diagnostic` for the `TupleIndexOutOfBounds` error. - harmonizes the appearance of the `TupleIndexOutOfBounds` error in the element access and reassignments. ## Demo `TupleIndexOutOfBounds` in element access and reassignments before: ![Tuple index out of bounds - Before](https://github.com/FuelLabs/sway/assets/4142833/38dc610e-c9c2-4ae9-a638-d3da3fc38ada) New errors: ![Tuple index out of bounds - After](https://github.com/FuelLabs/sway/assets/4142833/d1668f7d-15b6-4d76-8644-301d3871568d) ![Tuple element access requires a tuple](https://github.com/FuelLabs/sway/assets/4142833/15c41cea-ccac-417c-9b7b-758dccbc43f8) ## Checklist - [x] I have linked to any relevant issues. - [x] 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). - [x] 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. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
ironcev
added a commit
that referenced
this issue
Mar 11, 2024
## Description This PR implements references to mutable values, `&mut T`, as defined in [references](https://github.com/FuelLabs/sway-rfcs/blob/ironcev/amend-references/files/0010-references.sw). The overall effort related to references is tracked in #5063. References to mutable values: - can be created using `&mut` - can be used in type system wherever a type is expected - coerce to references (`&mut T` -> `&T`) and thus can be used wherever "regular" references are expected - can be passed to and returned from functions The last point is a step in direction of replacing `ref mut` function parameters with either `&` or `&mut`. References to mutable values cannot be taken on constants and immutable variables (see errors below). (Note that we slightly departure from the Rust counterparts here. Rust allows `&mut` on constants but issues a warning.) Additionally, the PR implements `Diagnostic` for the `ConflictingImplsForTraitAndType` and shows the already existing, conflicting implementation of the trait. ## Demo For more demos, see the tests in this PR. ```Sway let mut x = 123u32; let r_m_x: &mut u32 = &mut x; fn fun(p: &mut T) -> &mut T { ... } impl Foo for &mut &mut T { ... } type RefMutRefMut = &mut &mut u64; ``` ![References to mutable values cannot reference constants](https://github.com/FuelLabs/sway/assets/4142833/207a859b-4876-4320-9e65-57b37093f384) ![Trait is already implemented for type](https://github.com/FuelLabs/sway/assets/4142833/4c10902e-ffce-40bb-b9f5-2e9c0e971fcf) ## Checklist - [x] I have linked to any relevant issues. - [x] 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). - [x] 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. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
IGI-111
pushed a commit
that referenced
this issue
Apr 30, 2024
## Description This PR implements dereferencing in reassignment targets, as defined in [references](https://github.com/FuelLabs/sway-rfcs/blob/ironcev/amend-references/files/0010-references.sw). The overall effort related to references is tracked in #5063. Up to now, it was only possible to read the values references refer to. This PR allows values to be written over `&mut` references. In other words, any `*<expression that results in &mut>`is now an l-values and can be used in left-hand sides (LHS) of assignments. In most of the cases, the `<expression>` will very likely be just a reference variable, but any expression that results in `&mut` is allowed and supported. E.g.; ```Sway *mut_ref_to_u64 = 42; *if condition { &mut x } else { &mut y } = 42; *max_mut(&mut x, &mut y) = 42; ``` Additionally, the PR: - fixes #5736 by properly replacing decls in reassignment LHSs. - fixes #5737 by properly substituting types in reassignment LHSs. - fixes #5920 by properly connecting expressions in array indices to the DCA graph. - fixes #5922 by type-cheking the array indices in reassignment LHSs and forcing them to be `u64`. - improves misplaced and misleading error messages when assigning to constants and other items (see demo below). - improves error message when assigning to immutable variables by pointing to variable declaration. - improves error message when expression cannot be assigned to by pointing to the problematic part of the expression. Since Sway is more restrictive here then Rust, the restrictions, without being explained, could cause confusion. That's why special attention was given to point to the exact issue and explain what is actually supported in Sway (see demo below). - reduces number of expected warnings in references E2E tests that were previously set high because of DCA issues that are fixed in the meantime. The PR also brings additional analysis and checks to IR optimizations. Among other things, it explicitly points out the cases in which a potential usage of a symbol cannot be deterministically confirmed or denied. In this PR properly reacting for such cases is done in some optimizations. Rolling it out fully will be done in a follow up PR #5924. More advanced escape analysis will be done later on, as a part of allocating values on the heap in case of referencing. This PR implements only dereferencing in LHS. Support for referenced elements in the element based access (without dereferencing) will be done in a separate step as an ongoing work on implementing #5063. Closes #5736, #5737, #5920, #5922. ## Demo Before: ![Assignment to constant - Before](https://github.com/FuelLabs/sway/assets/4142833/e6b29d31-8e29-4ffa-acfe-a844ac50887b) ![Assignment to decl - Before](https://github.com/FuelLabs/sway/assets/4142833/ef5f025e-3dcc-4cb0-b52f-d735e2ee451e) After: ![Assignment to constant - After](https://github.com/FuelLabs/sway/assets/4142833/f3dfdbd9-2123-4a96-98a7-b3c7a3f3e7f9) ![Assignment to decl - After](https://github.com/FuelLabs/sway/assets/4142833/ae765d61-41b2-478c-96c0-d476604deec6) Expression cannot be assigned to: ![Expression cannot be assigned to](https://github.com/FuelLabs/sway/assets/4142833/384d0bb7-34a1-446a-acd5-6c8f66dc4ed5) ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [x] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [ ] If my change requires substantial documentation changes, I have [requested support from the DevRel team](https://github.com/FuelLabs/devrel-requests/issues/new/choose) - [x] 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. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Labels
enhancement
New feature or request
language feature
Core language features visible to end users
Needs RFC
Features that require an RFC before proceeding with an implementation
Tracking issue for https://github.com/FuelLabs/sway-rfcs/blob/master/rfcs/0010-references.md
match
expressionlet
statementref mut
#5064self
parametert: &T
mut t: &T
t: &mut T
mut t: &mut T
&Self
&mut Self
&T
&mut T
const
referencescore::ops::Eq
)__addr_of
for referencesmain
methods (TODO: Re-discuss this decision.)*mut
typed pointer #5066raw_ptr
#5067__ptr_cast
intrinsic #5068__slice
intrinsic #5070__slice_elem
intrinsic #5071str
slices #5072raw_slice
#5073The text was updated successfully, but these errors were encountered: