# Type and Lifetime Parameters

> **Syntax**\
> _Generics_ :\
>    `<` _GenericParams_ `>`
>
> _GenericParams_ :\
>       _LifetimeParams_\
>    | ( _LifetimeParam_ `,` )\* _TypeParams_
>
> _LifetimeParams_ :\
>    ( _LifetimeParam_ `,` )\* _LifetimeParam_?
>
> _LifetimeParam_ :\
>    [_OuterAttribute_]? [LIFETIME_OR_LABEL] ( `:` [_LifetimeBounds_] )?
>
> _TypeParams_:\
>    ( _TypeParam_ `,` )\* _TypeParam_?
>
> _TypeParam_ :\
>    [_OuterAttribute_]? [IDENTIFIER] ( `:` [_TypeParamBounds_]? )? ( `=` [_Type_] )?

Functions, type aliases, structs, enumerations, unions, traits and
implementations may be *parameterized* by types and lifetimes. These parameters
are listed in angle brackets (`<...>`),
usually immediately after and before its definition the name of the item. For
implementations, which don't have a name, they come directly after `impl`.
Lifetime parameters must be declared before type parameters. Some examples of
items with type and lifetime parameters:

```rust
fn foo<'a, T>() {}
trait A<U> {}
struct Ref<'a, T> where T: 'a { r: &'a T }
```

[References], [raw pointers], [arrays], [slices][arrays], [tuples] and
[function pointers] have lifetime or type parameters as well, but are not
referred to with path syntax.

## Where clauses

> **Syntax**\
> _WhereClause_ :\
>    `where` ( _WhereClauseItem_ `,` )\* _WhereClauseItem_ ?
>
> _WhereClauseItem_ :\
>       _LifetimeWhereClauseItem_\
>    | _TypeBoundWhereClauseItem_
>
> _LifetimeWhereClauseItem_ :\
>    [_Lifetime_] `:` [_LifetimeBounds_]
>
> _TypeBoundWhereClauseItem_ :\
>    _ForLifetimes_? [_Type_] `:` [_TypeParamBounds_]?
>
> _ForLifetimes_ :\
>    `for` `<` [_LifetimeParams_](#type-and-lifetime-parameters) `>`

*Where clauses* provide an another way to specify bounds on type and lifetime
parameters as well as a way to specify bounds on types that aren't type
parameters.

Bounds that don't use the item's parameters or higher-ranked lifetimes are
checked when the item is defined. It is an error for such a bound to be false.

[`Copy`], [`Clone`] and [`Sized`] bounds are also checked for certain generic
types when defining the item. It is an error to have `Copy` or `Clone`as a
bound on a mutable reference, [trait object] or [slice][arrays] or `Sized` as a
bound on a trait object or slice.

```rust,ignore
struct A<T>
where
    T: Iterator,            // Could use A<T: Iterator> instead
    T::Item: Copy,
    String: PartialEq<T>,
    i32: Default,           // Allowed, but not useful
    i32: Iterator,          // Error: the trait bound is not satisfied
    [T]: Copy,              // Error: the trait bound is not satisfied
{
    f: T,
}
```

## Attributes

Generic lifetime and type parameters allow [attributes] on them. There are no
built-in attributes that do anything in this position, although custom derive
attributes may give meaning to it.

This example shows using a custom derive attribute to modify the meaning of a
generic parameter.

```ignore
// Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as
// an attribute it understands.
#[derive(MyFlexibleClone)] struct Foo<#[my_flexible_clone(unbounded)] H> {
    a: *const H
}
```

[IDENTIFIER]: identifiers.html
[LIFETIME_OR_LABEL]: tokens.html#lifetimes-and-loop-labels

[_LifetimeBounds_]: trait-bounds.html
[_Lifetime_]: trait-bounds.html
[_OuterAttribute_]: attributes.html
[_Type_]: types.html#type-expressions
[_TypeParamBounds_]: trait-bounds.html

[arrays]: types/array.html
[function pointers]: types/function-pointer.html
[references]: types/pointer.html#shared-references-
[raw pointers]: types/pointer.html#raw-pointers-const-and-mut
[`Clone`]: special-types-and-traits.html#clone
[`Copy`]: special-types-and-traits.html#copy
[`Sized`]: special-types-and-traits.html#sized
[tuples]: types/tuple.html
[trait object]: types/trait-object.html
[attributes]: attributes.html
