Skip to content

Commit

Permalink
chore(docs): Docs for turbofish operator (noir-lang#5555)
Browse files Browse the repository at this point in the history
# Description

## Problem\*

Resolves noir-lang#5254 

## Summary\*



## Additional Context



## Documentation\*

Check one:
- [ ] No documentation needed.
- [X] Documentation included in this PR.
- [ ] **[For Experimental Features]** Documentation to be submitted in a
separate PR.

# PR Checklist\*

- [X] I have tested the changes locally.
- [X] I have formatted the changes with [Prettier](https://prettier.io/)
and/or `cargo fmt` on default settings.

---------

Co-authored-by: jfecher <[email protected]>
  • Loading branch information
vezenovm and jfecher authored Jul 18, 2024
1 parent ece033f commit 63babcf
Showing 1 changed file with 57 additions and 0 deletions.
57 changes: 57 additions & 0 deletions docs/docs/noir/concepts/generics.md
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,60 @@ impl Eq for MyStruct {
```

You can find more details on traits and trait implementations on the [traits page](../concepts/traits.md).

## Manually Specifying Generics with the Turbofish Operator

There are times when the compiler cannot reasonably infer what type should be used for a generic, or when the developer themselves may want to manually distinguish generic type parameters. This is where the `::<>` turbofish operator comes into play.

The `::<>` operator can follow a variable or path and can be used to manually specify generic arguments within the angle brackets.
The name "turbofish" comes from that `::<>` looks like a little fish.

Examples:
```rust
fn main() {
let mut slice = [];
slice = slice.push_back(1);
slice = slice.push_back(2);
// Without turbofish a type annotation would be needed on the left hand side
let array = slice.as_array::<2>();
}
```
```rust
fn double<let N: u32>() -> u32 {
N * 2
}
fn example() {
assert(double::<9>() == 18);
assert(double::<7 + 8>() == 30);
}
```
```rust
trait MyTrait {
fn ten() -> Self;
}

impl MyTrait for Field {
fn ten() -> Self { 10 }
}

struct Foo<T> {
inner: T
}

impl<T> Foo<T> {
fn generic_method<U>(_self: Self) -> U where U: MyTrait {
U::ten()
}
}

fn example() {
let foo: Foo<Field> = Foo { inner: 1 };
// Using a type other than `Field` here (e.g. u32) would fail as
// there is no matching impl for `u32: MyTrait`.
//
// Substituting the `10` on the left hand side of this assert
// with `10 as u32` would also fail with a type mismatch as we
// are expecting a `Field` from the right hand side.
assert(10 as u32 == foo.generic_method::<Field>());
}
```

0 comments on commit 63babcf

Please sign in to comment.