Syntax
Generics :
<
GenericParams>
GenericParams :
LifetimeParams
| ( LifetimeParam,
)* TypeParamsLifetimeParams :
( 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 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:
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.
Syntax
WhereClause :
where
( WhereClauseItem,
)* WhereClauseItem ?WhereClauseItem :
LifetimeWhereClauseItem
| TypeBoundWhereClauseItemLifetimeWhereClauseItem :
Lifetime:
LifetimeBoundsTypeBoundWhereClauseItem :
ForLifetimes? Type:
TypeParamBounds?ForLifetimes :
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 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,
}
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
}