-
Notifications
You must be signed in to change notification settings - Fork 12
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
RFC for const generics #42
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
@@ -0,0 +1,299 @@ | ||||||||||||||||||||||||||||||||||||||||
- Feature Name: const_generics | ||||||||||||||||||||||||||||||||||||||||
- Start Date: 2024-10-27 | ||||||||||||||||||||||||||||||||||||||||
- RFC PR: [FuelLabs/sway-rfcs#42](https://github.com/FuelLabs/sway-rfcs/pull/42) | ||||||||||||||||||||||||||||||||||||||||
- Sway Issue: [FueLabs/sway#0000](https://github.com/FuelLabs/sway/issues/001) | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Summary | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[summary]: #summary | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Allows constant values as generic arguments. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Motivation | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[motivation]: #motivation | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Some types have constants, specifically unsigned integers, as their definition (e.g. arrays and string arrays). Without `const generics` it is impossible to have `impl` items for all instances of these types. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Guide-level explanation | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[guide-level-explanation]: #guide-level-explanation | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
`const generics` refer to the language syntax where generic parameters are defined as constant values, instead of types. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
A simple example would be: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
fn id<const SIZE: usize>(array: [u64; SIZE]) -> [u64; SIZE] { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In most of the code samples Even in that case, the proposal would be to go with Or to mention on the top of the Guide-level explanation that Still, in this particular example even that is misleading because currently array size must be
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
array | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
This also allows `impl` items such as | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
impl<const N: usize> AbiEncode for str[N] { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
... | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
This constant can be inferred or explicitly specified. When inferred, the syntax is no different than just using the item: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
id([1u8]) | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
In the example above, the Sway compiler will infer `SIZE` to be one, because `id` parameter will be infered to be `[u8; 1]`. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
For the cases where the compiler cannot infer this value, or this value comes from an expression, it is possible to do: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
id::<1>([1u8]); | ||||||||||||||||||||||||||||||||||||||||
id::<{1 + 1}>([1u8, 2u8]); | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
When the value is not a literal, but an expression, it is named "const generic expression" and it needs to be enclosed by curly braces. This will fail if the expression cannot be evaluated as `const`. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Reference-level explanation | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[reference-level-explanation]: #reference-level-explanation | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
This new syntax has three forms: declarations, instantiations and references. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
"const generics declarations" can appear anywhere all other generic arguments declarations are valid: | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. Function/method declaration; | ||||||||||||||||||||||||||||||||||||||||
1. Struct/Enum declaration; | ||||||||||||||||||||||||||||||||||||||||
1. `impl` declarations. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
// 1 | ||||||||||||||||||||||||||||||||||||||||
fn id<const N: usize>(...) { ... } | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// 2 | ||||||||||||||||||||||||||||||||||||||||
struct SpecialArray<const N: usize> { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
inner: [u8; N], | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
//3 | ||||||||||||||||||||||||||||||||||||||||
impl<const N: usize> AbiEncode for str[N] { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
... | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
"const generics instantiations" can appear anywhere all other generic argument instantiations are valid: | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. Function/method reference; | ||||||||||||||||||||||||||||||||||||||||
1. Struct/Enum reference; | ||||||||||||||||||||||||||||||||||||||||
1. Fully qualified call paths. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
// 1 | ||||||||||||||||||||||||||||||||||||||||
id::<1>([1u8]); | ||||||||||||||||||||||||||||||||||||||||
special_array.do_something::<1>(); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// 2 | ||||||||||||||||||||||||||||||||||||||||
SpecialArray::<1>::new(); | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// 3 | ||||||||||||||||||||||||||||||||||||||||
<SpecialArray::<1> as SpecialArrayTrait::<1>>::f(); | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
"const generics references" can appear anywhere any other identifier appears. For semantic purposes, there is no difference between the reference of a "const generics" and a "normal" const. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
fn f<const I: usize>() { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
__log(I); | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Different from type generics, const generics cannot appear at: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. constraints; | ||||||||||||||||||||||||||||||||||||||||
1. where types are expected. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
// 1 - INVALID | ||||||||||||||||||||||||||||||||||||||||
fn f<const I: usize>() where I > 10 { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Supporting constraints can be added to future possibilities. One case I see as interesting, is ensuring that an array size is greater then zero. Or for small vec implementations to ensure the upper bound is not to high. |
||||||||||||||||||||||||||||||||||||||||
... | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
// 2 - INVALID | ||||||||||||||||||||||||||||||||||||||||
fn f<const I: usize>() -> Vec<I> { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
Vec::<I>::new() | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
## Const Value Specialization | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
By the nature of `impl` declarations, it is possible to specialize for some specific types. For example: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
impl SomeStruct<bool> { | ||||||||||||||||||||||||||||||||||||||||
fn f() { | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
In the example above, `f` only is available when the generic argument of `SomeStruct` is known to be `bool`. This will not be supported for "const generics", which means that the example below will not be supported: | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
impl SomeIntegerStruct<1> { | ||||||||||||||||||||||||||||||||||||||||
... | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
impl SomeBoolStruct<false> { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned, we should explicitly specify which types are supported. Out of this example with |
||||||||||||||||||||||||||||||||||||||||
... | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
The main reason for forbidding this is that apart from `bool`, which only needs two values, all other constants would demand complex syntax to guarantee the completeness and uniqueness of all implementations, the same way that `match` expressions do. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
## Monomorphization | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
As with other generic arguments, `const generics` monormorphize functions, which means that a new "TyFunctionDecl", for example, will be created for which value that is instantiated. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Prevention of code bloat will be the responsability of the optimizer. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Monomorphization for const generics has one extra complexity to support arbitrary expressions it is needed to "solve" an equation. For example, | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
if a variable is typed as `[u64; 1]` and a method with its `self` type as `[u64; N + 1]` is called, the monomorphization process needs to know that `N` needs to be valued as `0` and if the variable is `[u64; 2]`, `N` will be `1`. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
## Type Engine changes | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
By the nature of `const generics`, it will be possible to write expressions inside types. Initially, only simple references will be | ||||||||||||||||||||||||||||||||||||||||
supported, but at some point, more complex expressions will be needed, for example: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```sway | ||||||||||||||||||||||||||||||||||||||||
fn len<T, const N: u64>(a: [T; N]) { ... } | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
fn bigger<const N: usize>(a: [u64; N]) -> [u64; N + 1] { | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
[0; N + 1] | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
This poses the challenge of having an expression tree inside the type system. Currently `sway` already | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
has three expression trees: `Expr`, `ExpressionKind` and `TyExpressionVariant`. This demands a new one, | ||||||||||||||||||||||||||||||||||||||||
given that the first two allow much more complex expressions than what `const generics` wants to support; | ||||||||||||||||||||||||||||||||||||||||
and last one is only create after some `TypeInfo` already exist, and thus cannot be used. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
At the same time, the parser should be able to parse any expression and return a friendly error that such expression, | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
is not supported. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
So, in case of a unsupported expression the parser will parser the `const generic` expression as it does for normal `Expr`and will lower it to the type system expression enum, but in the place of the unsupported expression will return a `TypeInfo::ErrorRecovery`. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
These expressions will also increase the complexity of all types related algorithms such as: | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. Unification | ||||||||||||||||||||||||||||||||||||||||
2. PartialEq | ||||||||||||||||||||||||||||||||||||||||
3. Hash | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
In the simplest case, it is very clear how to unify `TypeInfo::Array(..., Length::Literal(1))` and `TypeInfo::Array(..., Length::Expression("N"))`. | ||||||||||||||||||||||||||||||||||||||||
But more complex cases such as `TypeInfo::Array(..., Length::Expression("N"))` and `TypeInfo::Array(..., Length::Expression("N + 1"))`, is not clear | ||||||||||||||||||||||||||||||||||||||||
if these types are unifiable, equal or simply different. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
## Method call search algorithm | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
When a method is called, the algorithm that searches which method is called uses the method `TraitMap::get_impls`. | ||||||||||||||||||||||||||||||||||||||||
Currently, this method does an `O(1)` search to find all methods applicable to a type. For example: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```sway | ||||||||||||||||||||||||||||||||||||||||
impl [u64; 1] { | ||||||||||||||||||||||||||||||||||||||||
fn len_for_size_one(&self) { ... } | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
would create a map with something like | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
Placeholder -> [...] | ||||||||||||||||||||||||||||||||||||||||
... | ||||||||||||||||||||||||||||||||||||||||
[u64; 1] -> [..., len_for_size_one,...] | ||||||||||||||||||||||||||||||||||||||||
... | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
The algorithms first create a `TypeRootFilter`, which is very similar to `TypeInfo`. And uses this `enum` to search the hash table. | ||||||||||||||||||||||||||||||||||||||||
After that, it "generalizes" the filter and searches for `TypeRootFilter::Placeholder`. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
To fully support `const generics` and `const value specialization`, the compiler will now keep generalizing the | ||||||||||||||||||||||||||||||||||||||||
searched type until it hits `Placeholder`. For example, searching for `[u64; 1]` will actually search for: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. [u64; 1]; | ||||||||||||||||||||||||||||||||||||||||
1. [u64; Placeholder]; | ||||||||||||||||||||||||||||||||||||||||
1. Placeholder; | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
The initial implementation will do this generalization only for `const generics`, but it also makes sense to | ||||||||||||||||||||||||||||||||||||||||
generalize this with other types such as `Vec<u64>`. | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. Vec\<u64>; | ||||||||||||||||||||||||||||||||||||||||
1. Vec\<Placeholder>; | ||||||||||||||||||||||||||||||||||||||||
1. Placeholder; | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
This gets more complex as the number of `generics` and `const generics` increases. For example: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
```sway | ||||||||||||||||||||||||||||||||||||||||
struct VecWithSmallVecOptimization<T, const N: u64> { ... } | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
Searching for this type would search: | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. VecWithSmallVecOptimization\<u64, 1> | ||||||||||||||||||||||||||||||||||||||||
1. VecWithSmallVecOptimization\<Placeholder, 1> | ||||||||||||||||||||||||||||||||||||||||
1. VecWithSmallVecOptimization\<u64, Placeholder> | ||||||||||||||||||||||||||||||||||||||||
1. VecWithSmallVecOptimization\<Placeholder, Placeholder> | ||||||||||||||||||||||||||||||||||||||||
1. Placeholder | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Perhaps to explicitly mention that the insertion into trait map must already search for conflicting implementations in regard to const generic arguments.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
More research is needed to understand if this change can potentially change the semantics of any program written in `sway`. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Implementation Roadmap | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. Creation of the feature flag `const-generics`; | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
1. Implementation of "const generics references"; | ||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
fn f<const I: usize>() { __log(I); } | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
3. The compiler will be able to encode arrays of any size; Which means being able to implement the following in the "core" lib and using arrays of any size as "configurables"; | ||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
impl<T, const N: usize> AbiEncode for [T; N] { ... } | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
4. Being able to `encode` arrays of any size; | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
fn f<T, const N: usize>(s: [T; N]) -> raw_slice { | ||||||||||||||||||||||||||||||||||||||||
<[T; N] as AbiEncode>::abi_encode(...); | ||||||||||||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||||||||||||
f::<1>([1]) | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
5. Inference of the example above | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
```rust | ||||||||||||||||||||||||||||||||||||||||
f([1]); | ||||||||||||||||||||||||||||||||||||||||
core::encode([1]); | ||||||||||||||||||||||||||||||||||||||||
``` | ||||||||||||||||||||||||||||||||||||||||
6. Struct/enum support for const generics | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
7. Function/method declaration; | ||||||||||||||||||||||||||||||||||||||||
8. `impl` declarations. | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
9. Function/method reference; | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Drawbacks | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[drawbacks]: #drawbacks | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
None | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Rationale and alternatives | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[rationale-and-alternatives]: #rationale-and-alternatives | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Prior art | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[prior-art]: #prior-art | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
This RFC is partially based on Rust's own const generic system: https://doc.rust-lang.org/reference/items/generics.html#const-generics, https://blog.rust-lang.org/inside-rust/2021/09/06/Splitting-const-generics.html, https://rust-lang.github.io/rfcs/2000-const-generics.html, https://doc.rust-lang.org/beta/unstable-book/language-features/generic-const-exprs.html | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Unresolved questions | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[unresolved-questions]: #unresolved-questions | ||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
1. What is the impact of changing the "method called algorithm"? | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
# Future possibilities | ||||||||||||||||||||||||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As mentioned above, implementing constraints like |
||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||
[future-possibilities]: #future-possibilities |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.