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 basic GATs reference information #1265

Merged
merged 11 commits into from
Oct 19, 2022
38 changes: 37 additions & 1 deletion src/items/associated-items.md
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,12 @@ If a type `Item` has an associated type `Assoc` from a trait `Trait`, then
associated type definition. Furthermore, if `Item` is a type parameter, then
`Item::Assoc` can be used in type parameters.

Associated types must not include [generic parameters] or [where clauses].
Associated types may include [generic parameters] or [where clauses]; these may
jackh726 marked this conversation as resolved.
Show resolved Hide resolved
be referred to generic associated types, or GATs. If the type `Thing` has an
jackh726 marked this conversation as resolved.
Show resolved Hide resolved
jackh726 marked this conversation as resolved.
Show resolved Hide resolved
associated type `Item` from a trait `Trait` with the generics `<'a>` , the type
can be named like `<Thing as Trait>::Item<'x>`, where `'x` is some lifetime in
scope. In this case, `'x` will be used wherever `'a` appears in the associated
type definitions on impls.

```rust
trait AssociatedType {
Expand Down Expand Up @@ -249,6 +254,37 @@ fn main() {
}
```

An example of associated types with generics and where clauses:

```rust
struct ArrayLender<'a, T>(&'a mut [T; 16]);

trait Lend {
// Generic associated type declaration
type Lender<'a> where Self: 'a;
fn lend<'a>(&'a mut self) -> Self::Lender<'a>;
}

impl<T> Lend for [T; 16] {
// Generic associated type definition
type Lender<'a> = ArrayLender<'a, T> where Self: 'a;

fn lend<'a>(&'a mut self) -> Self::Lender<'a> {
ArrayLender(self)
}
}

fn borrow<'a, T: Lend>(array: &'a mut T) -> <T as Lend>::Lender<'a> {
array.lend()
}


fn main() {
let mut array = [0usize; 16];
let lender = borrow(&mut array);
}
```

### Associated Types Container Example

Consider the following example of a `Container` trait. Notice that the type is
Expand Down
6 changes: 5 additions & 1 deletion src/items/type-aliases.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
> _TypeAlias_ :\
> &nbsp;&nbsp; `type` [IDENTIFIER]&nbsp;[_GenericParams_]<sup>?</sup>
> ( `:` [_TypeParamBounds_] )<sup>?</sup>
> [_WhereClause_]<sup>?</sup> ( `=` [_Type_] )<sup>?</sup> `;`
> [_WhereClause_]<sup>?</sup> ( `=` [_Type_] )<sup>?</sup> [_WhereClause_]<sup>?</sup> `;`
jackh726 marked this conversation as resolved.
Show resolved Hide resolved

A _type alias_ defines a new name for an existing [type]. Type aliases are
declared with the keyword `type`. Every value has a single, specific type, but
Expand Down Expand Up @@ -37,6 +37,9 @@ A type alias without the [_Type_] specification may only appear as an
A type alias with [_TypeParamBounds_] may only specified when used as
an [associated type] in a [trait].

A type alias with where clauses after the equals sign may only appear as an
[associated type] in a [trait] or a [trait impl].
jackh726 marked this conversation as resolved.
Show resolved Hide resolved

[IDENTIFIER]: ../identifiers.md
[_GenericParams_]: generics.md
[_TypeParamBounds_]: ../trait-bounds.md
Expand All @@ -45,3 +48,4 @@ an [associated type] in a [trait].
[associated type]: associated-items.md#associated-types
[trait]: traits.md
[type]: ../types.md
[trait impl]: implementations.md#trait-implementations