# 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:

    # #![allow(unused_variables)]
    #fn main() {
    fn foo<'a, T>() {}
    trait A<U> {}
    struct Ref<'a, T> where T: 'a { r: &'a T }
    #}

References, raw pointers, arrays, slices, 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 `>`

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 or `Sized` as a bound on a trait object or slice.

    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.

    // 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
    }