]>
Commit | Line | Data |
---|---|---|
94b46f34 XL |
1 | # Type and Lifetime Parameters |
2 | ||
8faf50e0 XL |
3 | > **<sup>Syntax</sup>**\ |
4 | > _Generics_ :\ | |
5 | > `<` _GenericParams_ `>` | |
6 | > | |
7 | > _GenericParams_ :\ | |
8 | > _LifetimeParams_\ | |
9 | > | ( _LifetimeParam_ `,` )<sup>\*</sup> _TypeParams_ | |
10 | > | |
11 | > _LifetimeParams_ :\ | |
12 | > ( _LifetimeParam_ `,` )<sup>\*</sup> _LifetimeParam_<sup>?</sup> | |
13 | > | |
14 | > _LifetimeParam_ :\ | |
13cf67c4 | 15 | > [_OuterAttribute_]<sup>?</sup> [LIFETIME_OR_LABEL] ( `:` [_LifetimeBounds_] )<sup>?</sup> |
8faf50e0 XL |
16 | > |
17 | > _TypeParams_:\ | |
13cf67c4 | 18 | > ( _TypeParam_ `,` )<sup>\*</sup> _TypeParam_<sup>?</sup> |
8faf50e0 XL |
19 | > |
20 | > _TypeParam_ :\ | |
13cf67c4 | 21 | > [_OuterAttribute_]<sup>?</sup> [IDENTIFIER] ( `:` [_TypeParamBounds_]<sup>?</sup> )<sup>?</sup> ( `=` [_Type_] )<sup>?</sup> |
94b46f34 | 22 | |
e1599b0c | 23 | Functions, type aliases, structs, enumerations, unions, traits, and |
94b46f34 XL |
24 | implementations may be *parameterized* by types and lifetimes. These parameters |
25 | are listed in angle <span class="parenthetical">brackets (`<...>`)</span>, | |
532ac7d7 | 26 | usually immediately after the name of the item and before its definition. For |
94b46f34 XL |
27 | implementations, which don't have a name, they come directly after `impl`. |
28 | Lifetime parameters must be declared before type parameters. Some examples of | |
29 | items with type and lifetime parameters: | |
30 | ||
31 | ```rust | |
32 | fn foo<'a, T>() {} | |
33 | trait A<U> {} | |
34 | struct Ref<'a, T> where T: 'a { r: &'a T } | |
35 | ``` | |
36 | ||
e1599b0c | 37 | [References], [raw pointers], [arrays], [slices][arrays], [tuples], and |
94b46f34 XL |
38 | [function pointers] have lifetime or type parameters as well, but are not |
39 | referred to with path syntax. | |
40 | ||
41 | ## Where clauses | |
42 | ||
8faf50e0 XL |
43 | > **<sup>Syntax</sup>**\ |
44 | > _WhereClause_ :\ | |
45 | > `where` ( _WhereClauseItem_ `,` )<sup>\*</sup> _WhereClauseItem_ <sup>?</sup> | |
46 | > | |
47 | > _WhereClauseItem_ :\ | |
48 | > _LifetimeWhereClauseItem_\ | |
49 | > | _TypeBoundWhereClauseItem_ | |
50 | > | |
51 | > _LifetimeWhereClauseItem_ :\ | |
52 | > [_Lifetime_] `:` [_LifetimeBounds_] | |
53 | > | |
54 | > _TypeBoundWhereClauseItem_ :\ | |
55 | > _ForLifetimes_<sup>?</sup> [_Type_] `:` [_TypeParamBounds_]<sup>?</sup> | |
56 | > | |
57 | > _ForLifetimes_ :\ | |
58 | > `for` `<` [_LifetimeParams_](#type-and-lifetime-parameters) `>` | |
94b46f34 | 59 | |
532ac7d7 | 60 | *Where clauses* provide another way to specify bounds on type and lifetime |
94b46f34 XL |
61 | parameters as well as a way to specify bounds on types that aren't type |
62 | parameters. | |
63 | ||
64 | Bounds that don't use the item's parameters or higher-ranked lifetimes are | |
65 | checked when the item is defined. It is an error for such a bound to be false. | |
66 | ||
e1599b0c | 67 | [`Copy`], [`Clone`], and [`Sized`] bounds are also checked for certain generic |
94b46f34 XL |
68 | types when defining the item. It is an error to have `Copy` or `Clone`as a |
69 | bound on a mutable reference, [trait object] or [slice][arrays] or `Sized` as a | |
70 | bound on a trait object or slice. | |
71 | ||
60c5eb7d | 72 | ```rust,compile_fail |
94b46f34 XL |
73 | struct A<T> |
74 | where | |
75 | T: Iterator, // Could use A<T: Iterator> instead | |
76 | T::Item: Copy, | |
77 | String: PartialEq<T>, | |
78 | i32: Default, // Allowed, but not useful | |
79 | i32: Iterator, // Error: the trait bound is not satisfied | |
80 | [T]: Copy, // Error: the trait bound is not satisfied | |
81 | { | |
82 | f: T, | |
83 | } | |
84 | ``` | |
85 | ||
86 | ## Attributes | |
87 | ||
88 | Generic lifetime and type parameters allow [attributes] on them. There are no | |
89 | built-in attributes that do anything in this position, although custom derive | |
90 | attributes may give meaning to it. | |
91 | ||
92 | This example shows using a custom derive attribute to modify the meaning of a | |
93 | generic parameter. | |
94 | ||
60c5eb7d | 95 | <!-- ignore: requires proc macro derive --> |
e74abb32 | 96 | ```rust,ignore |
94b46f34 XL |
97 | // Assume that the derive for MyFlexibleClone declared `my_flexible_clone` as |
98 | // an attribute it understands. | |
e74abb32 XL |
99 | #[derive(MyFlexibleClone)] |
100 | struct Foo<#[my_flexible_clone(unbounded)] H> { | |
94b46f34 XL |
101 | a: *const H |
102 | } | |
103 | ``` | |
104 | ||
416331ca XL |
105 | [IDENTIFIER]: ../identifiers.md |
106 | [LIFETIME_OR_LABEL]: ../tokens.md#lifetimes-and-loop-labels | |
107 | ||
108 | [_LifetimeBounds_]: ../trait-bounds.md | |
109 | [_Lifetime_]: ../trait-bounds.md | |
110 | [_OuterAttribute_]: ../attributes.md | |
111 | [_Type_]: ../types.md#type-expressions | |
112 | [_TypeParamBounds_]: ../trait-bounds.md | |
113 | ||
114 | [arrays]: ../types/array.md | |
115 | [function pointers]: ../types/function-pointer.md | |
116 | [references]: ../types/pointer.md#shared-references- | |
117 | [raw pointers]: ../types/pointer.md#raw-pointers-const-and-mut | |
118 | [`Clone`]: ../special-types-and-traits.md#clone | |
119 | [`Copy`]: ../special-types-and-traits.md#copy | |
120 | [`Sized`]: ../special-types-and-traits.md#sized | |
121 | [tuples]: ../types/tuple.md | |
122 | [trait object]: ../types/trait-object.md | |
123 | [attributes]: ../attributes.md |