Syntax
Generics :
< GenericParams >

GenericParams :
| ( LifetimeParam , )* TypeParams

( 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 the name of the item and before its definition. 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)]
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 :
| TypeBoundWhereClauseItem

Lifetime : LifetimeBounds

TypeBoundWhereClauseItem :
ForLifetimes? Type : TypeParamBounds?

for < LifetimeParams >

Where clauses provide 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 Cloneas a bound on a mutable reference, trait object or slice or Sized as a bound on a trait object or slice.


#![allow(unused)]
fn main() {
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
}