# Associated Items

> **<sup>Syntax</sup>**\
> _AssociatedItem_ :\
> &nbsp;&nbsp; [_OuterAttribute_]<sup>\*</sup> (\
> &nbsp;&nbsp; &nbsp;&nbsp; &nbsp;&nbsp; [_MacroInvocationSemi_]\
> &nbsp;&nbsp; &nbsp;&nbsp; | ( [_Visibility_]<sup>?</sup> ( [_TypeAlias_] | [_ConstantItem_] | [_Function_] ) )\
> &nbsp;&nbsp; )

*Associated Items* are the items declared in [traits] or defined in
[implementations]. They are called this because they are defined on an associate
type &mdash; the type in the implementation. They are a subset of the kinds of
items you can declare in a module. Specifically, there are [associated
functions] (including methods), [associated types], and [associated constants].

[associated functions]: #associated-functions-and-methods
[associated types]: #associated-types
[associated constants]: #associated-constants

Associated items are useful when the associated item logically is related to the
associating item. For example, the `is_some` method on `Option` is intrinsically
related to Options, so should be associated.

Every associated item kind comes in two varieties: definitions that contain the
actual implementation and declarations that declare signatures for
definitions.

It is the declarations that make up the contract of traits and what is available
on generic types.

## Associated functions and methods

*Associated functions* are [functions] associated with a type.

An *associated function declaration* declares a signature for an associated
function definition. It is written as a function item, except the
function body is replaced with a `;`.

The identifier is the name of the function. The generics, parameter list,
return type, and where clause of the associated function must be the same as the
associated function declarations's.

An *associated function definition* defines a function associated with another
type. It is written the same as a [function item].

An example of a common associated function is a `new` function that returns
a value of the type the associated function is associated with.

```rust
struct Struct {
    field: i32
}

impl Struct {
    fn new() -> Struct {
        Struct {
            field: 0i32
        }
    }
}

fn main () {
    let _struct = Struct::new();
}
```

When the associated function is declared on a trait, the function can also be
called with a [path] that is a path to the trait appended by the name of the
trait. When this happens, it is substituted for `<_ as Trait>::function_name`.

```rust
trait Num {
    fn from_i32(n: i32) -> Self;
}

impl Num for f64 {
    fn from_i32(n: i32) -> f64 { n as f64 }
}

// These 4 are all equivalent in this case.
let _: f64 = Num::from_i32(42);
let _: f64 = <_ as Num>::from_i32(42);
let _: f64 = <f64 as Num>::from_i32(42);
let _: f64 = f64::from_i32(42);
```

### Methods

Associated functions whose first parameter is named `self` are called *methods*
and may be invoked using the [method call operator], for example, `x.foo()`, as
well as the usual function call notation.

If the type of the `self` parameter is specified, it is limited to types resolving
to one generated by the following grammar (where `'lt` denotes some arbitrary
lifetime):

```text
P = &'lt S | &'lt mut S | Box<S> | Rc<S> | Arc<S> | Pin<P>
S = Self | P
```

The `Self` terminal in this grammar denotes a type resolving to the implementing type.
This can also include the contextual type alias `Self`, other type aliases,
or associated type projections resolving to the implementing type.

```rust
# use std::rc::Rc;
# use std::sync::Arc;
# use std::pin::Pin;
// Examples of methods implemented on struct `Example`.
struct Example;
type Alias = Example;
trait Trait { type Output; }
impl Trait for Example { type Output = Example; }
impl Example {
    fn by_value(self: Self) {}
    fn by_ref(self: &Self) {}
    fn by_ref_mut(self: &mut Self) {}
    fn by_box(self: Box<Self>) {}
    fn by_rc(self: Rc<Self>) {}
    fn by_arc(self: Arc<Self>) {}
    fn by_pin(self: Pin<&Self>) {}
    fn explicit_type(self: Arc<Example>) {}
    fn with_lifetime<'a>(self: &'a Self) {}
    fn nested<'a>(self: &mut &'a Arc<Rc<Box<Alias>>>) {}
    fn via_projection(self: <Example as Trait>::Output) {}
}
```

Shorthand syntax can be used without specifying a type, which have the
following equivalents:

Shorthand             | Equivalent
----------------------|-----------
`self`                | `self: Self`
`&'lifetime self`     | `self: &'lifetime Self`
`&'lifetime mut self` | `self: &'lifetime mut Self`

> **Note**: Lifetimes can be, and usually are, elided with this shorthand.

If the `self` parameter is prefixed with `mut`, it becomes a mutable variable,
similar to regular parameters using a `mut` [identifier pattern]. For example:

```rust
trait Changer: Sized {
    fn change(mut self) {}
    fn modify(mut self: Box<Self>) {}
}
```

As an example of methods on a trait, consider the following:

```rust
# type Surface = i32;
# type BoundingBox = i32;
trait Shape {
    fn draw(&self, surface: Surface);
    fn bounding_box(&self) -> BoundingBox;
}
```

This defines a trait with two methods. All values that have [implementations]
of this trait while the trait is in scope can have their `draw` and
`bounding_box` methods called.

```rust
# type Surface = i32;
# type BoundingBox = i32;
# trait Shape {
#     fn draw(&self, surface: Surface);
#     fn bounding_box(&self) -> BoundingBox;
# }
#
struct Circle {
    // ...
}

impl Shape for Circle {
    // ...
#   fn draw(&self, _: Surface) {}
#   fn bounding_box(&self) -> BoundingBox { 0i32 }
}

# impl Circle {
#     fn new() -> Circle { Circle{} }
# }
#
let circle_shape = Circle::new();
let bounding_box = circle_shape.bounding_box();
```

> **Edition differences**: In the 2015 edition, it is possible to declare trait
> methods with anonymous parameters (e.g. `fn foo(u8)`). This is deprecated and
> an error as of the 2018 edition. All parameters must have an argument name.

#### Attributes on method parameters

Attributes on method parameters follow the same rules and restrictions as
[regular function parameters].

## Associated Types

*Associated types* are [type aliases] associated with another type. Associated
types cannot be defined in [inherent implementations] nor can they be given a
default implementation in traits.

An *associated type declaration* declares a signature for associated type
definitions. It is written in one of the following forms, where `Assoc` is the
name of the associated type, `Params` is a comma-separated list of type,
lifetime or const parameters, `Bounds` is a plus-separated list of trait bounds
that the associated type must meet, and `WhereBounds` is a comma-separated list
of bounds that the parameters must meet:

<!-- ignore: illustrative example forms -->
```rust,ignore
type Assoc;
type Assoc: Bounds;
type Assoc<Params>;
type Assoc<Params>: Bounds;
type Assoc<Params> where WhereBounds;
type Assoc<Params>: Bounds where WhereBounds;
```

The identifier is the name of the declared type alias. The optional trait bounds
must be fulfilled by the implementations of the type alias.
There is an implicit [`Sized`] bound on associated types that can be relaxed using the special `?Sized` bound.

An *associated type definition* defines a type alias for the implementation
of a trait on a type. They are written similarly to an *associated type declaration*,
but cannot contain `Bounds`, but instead must contain a `Type`:

<!-- ignore: illustrative example forms -->
```rust,ignore
type Assoc = Type;
type Assoc<Params> = Type; // the type `Type` here may reference `Params`
type Assoc<Params> = Type where WhereBounds;
type Assoc<Params> where WhereBounds = Type; // deprecated, prefer the form above
```

If a type `Item` has an associated type `Assoc` from a trait `Trait`, then
`<Item as Trait>::Assoc` is a type that is an alias of the type specified in the
associated type definition. Furthermore, if `Item` is a type parameter, then
`Item::Assoc` can be used in type parameters.

Associated types may include [generic parameters] and [where clauses]; these are
often referred to as *generic associated types*, or *GATs*. If the type `Thing`
has an 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 {
    // Associated type declaration
    type Assoc;
}

struct Struct;

struct OtherStruct;

impl AssociatedType for Struct {
    // Associated type definition
    type Assoc = OtherStruct;
}

impl OtherStruct {
    fn new() -> OtherStruct {
        OtherStruct
    }
}

fn main() {
    // Usage of the associated type to refer to OtherStruct as <Struct as AssociatedType>::Assoc
    let _other_struct: OtherStruct = <Struct as AssociatedType>::Assoc::new();
}
```

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
available for use in the method signatures:

```rust
trait Container {
    type E;
    fn empty() -> Self;
    fn insert(&mut self, elem: Self::E);
}
```

In order for a type to implement this trait, it must not only provide
implementations for every method, but it must specify the type `E`. Here's an
implementation of `Container` for the standard library type `Vec`:

```rust
# trait Container {
#     type E;
#     fn empty() -> Self;
#     fn insert(&mut self, elem: Self::E);
# }
impl<T> Container for Vec<T> {
    type E = T;
    fn empty() -> Vec<T> { Vec::new() }
    fn insert(&mut self, x: T) { self.push(x); }
}
```

### Relationship between `Bounds` and `WhereBounds`

In this example:

```rust
# use std::fmt::Debug;
trait Example {
    type Output<T>: Ord where T: Debug;
}
```

Given a reference to the associated type like `<X as Example>::Output<Y>`, the associated type itself must be `Ord`, and the type `Y` must be `Debug`.

### Required where clauses on generic associated types

Generic associated type declarations on traits currently may require a list of
where clauses, dependent on functions in the trait and how the GAT is used. These
rules may be loosened in the future; updates can be found [on the generic
associated types initiative repository](https://rust-lang.github.io/generic-associated-types-initiative/explainer/required_bounds.html).

In a few words, these where clauses are required in order to maximize the allowed
definitions of the associated type in impls. To do this, any clauses that *can be
proven to hold* on functions (using the parameters of the function or trait)
where a GAT appears as an input or output must also be written on the GAT itself.

```rust
trait LendingIterator {
    type Item<'x> where Self: 'x;
    fn next<'a>(&'a mut self) -> Self::Item<'a>;
}
```

In the above, on the `next` function, we can prove that `Self: 'a`, because of
the implied bounds from `&'a mut self`; therefore, we must write the equivalent
bound on the GAT itself: `where Self: 'x`.

When there are multiple functions in a trait that use the GAT, then the
*intersection* of the bounds from the different functions are used, rather than
the union.

```rust
trait Check<T> {
    type Checker<'x>;
    fn create_checker<'a>(item: &'a T) -> Self::Checker<'a>;
    fn do_check(checker: Self::Checker<'_>);
}
```

In this example, no bounds are required on the `type Checker<'a>;`. While we
know that `T: 'a` on `create_checker`, we do not know that on `do_check`. However,
if `do_check` was commented out, then the `where T: 'x` bound would be required
on `Checker`.

The bounds on associated types also propagate required where clauses.

```rust
trait Iterable {
    type Item<'a> where Self: 'a;
    type Iterator<'a>: Iterator<Item = Self::Item<'a>> where Self: 'a;
    fn iter<'a>(&'a self) -> Self::Iterator<'a>;
}
```

Here, `where Self: 'a` is required on `Item` because of `iter`. However, `Item`
is used in the bounds of `Iterator`, the `where Self: 'a` clause is also required
there.

Finally, any explicit uses of `'static` on GATs in the trait do not count towards
the required bounds.

```rust
trait StaticReturn {
    type Y<'a>;
    fn foo(&self) -> Self::Y<'static>;
}
```

## Associated Constants

*Associated constants* are [constants] associated with a type.

An *associated constant declaration* declares a signature for associated
constant definitions. It is written as `const`, then an identifier,
then `:`, then a type, finished by a `;`.

The identifier is the name of the constant used in the path. The type is the
type that the definition has to implement.

An *associated constant definition* defines a constant associated with a
type. It is written the same as a [constant item].

Associated constant definitions undergo [constant evaluation] only when
referenced. Further, definitions that include [generic parameters] are
evaluated after monomorphization.

```rust,compile_fail
struct Struct;
struct GenericStruct<const ID: i32>;

impl Struct {
    // Definition not immediately evaluated
    const PANIC: () = panic!("compile-time panic");
}

impl<const ID: i32> GenericStruct<ID> {
    // Definition not immediately evaluated
    const NON_ZERO: () = if ID == 0 {
        panic!("contradiction")
    };
}

fn main() {
    // Referencing Struct::PANIC causes compilation error
    let _ = Struct::PANIC;

    // Fine, ID is not 0
    let _ = GenericStruct::<1>::NON_ZERO;

    // Compilation error from evaluating NON_ZERO with ID=0
    let _ = GenericStruct::<0>::NON_ZERO;
}
```

### Associated Constants Examples

A basic example:

```rust
trait ConstantId {
    const ID: i32;
}

struct Struct;

impl ConstantId for Struct {
    const ID: i32 = 1;
}

fn main() {
    assert_eq!(1, Struct::ID);
}
```

Using default values:

```rust
trait ConstantIdDefault {
    const ID: i32 = 1;
}

struct Struct;
struct OtherStruct;

impl ConstantIdDefault for Struct {}

impl ConstantIdDefault for OtherStruct {
    const ID: i32 = 5;
}

fn main() {
    assert_eq!(1, Struct::ID);
    assert_eq!(5, OtherStruct::ID);
}
```

[_ConstantItem_]: constant-items.md
[_Function_]: functions.md
[_MacroInvocationSemi_]: ../macros.md#macro-invocation
[_OuterAttribute_]: ../attributes.md
[_TypeAlias_]: type-aliases.md
[_Visibility_]: ../visibility-and-privacy.md
[`Arc<Self>`]: ../special-types-and-traits.md#arct
[`Box<Self>`]: ../special-types-and-traits.md#boxt
[`Pin<P>`]: ../special-types-and-traits.md#pinp
[`Rc<Self>`]: ../special-types-and-traits.md#rct
[`Sized`]: ../special-types-and-traits.md#sized
[traits]: traits.md
[type aliases]: type-aliases.md
[inherent implementations]: implementations.md#inherent-implementations
[identifier]: ../identifiers.md
[identifier pattern]: ../patterns.md#identifier-patterns
[implementations]: implementations.md
[type]: ../types.md#type-expressions
[constants]: constant-items.md
[constant item]: constant-items.md
[functions]: functions.md
[function item]: ../types/function-item.md
[method call operator]: ../expressions/method-call-expr.md
[path]: ../paths.md
[regular function parameters]: functions.md#attributes-on-function-parameters
[generic parameters]: generics.md
[where clauses]: generics.md#where-clauses
[constant evaluation]: ../const_eval.md
