Skip to content

Commit bab007c

Browse files
authored
Merge pull request #1631 from chorman0773/spec-add-identifiers-trait-bounds
Add identifier syntax to trait-bounds.md
2 parents 889a660 + 14d9df2 commit bab007c

File tree

1 file changed

+30
-0
lines changed

1 file changed

+30
-0
lines changed

src/trait-bounds.md

+30
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
# Trait and lifetime bounds
22

3+
r[bound]
4+
5+
r[bound.syntax]
36
> **<sup>Syntax</sup>**\
47
> _TypeParamBounds_ :\
58
> &nbsp;&nbsp; _TypeParamBound_ ( `+` _TypeParamBound_ )<sup>\*</sup> `+`<sup>?</sup>
@@ -35,6 +38,7 @@
3538
> &nbsp;&nbsp; | [IDENTIFIER][] \
3639
> &nbsp;&nbsp; | `Self`
3740
41+
r[bound.intro]
3842
[Trait] and lifetime bounds provide a way for [generic items][generic] to
3943
restrict which types and lifetimes are used as their parameters. Bounds can be
4044
provided on any type in a [where clause]. There are also shorter forms for
@@ -48,6 +52,7 @@ certain common cases:
4852
`trait A { type B: Copy; }` is equivalent to
4953
`trait A where Self::B: Copy { type B; }`.
5054

55+
r[bound.satisfaction]
5156
Bounds on an item must be satisfied when using the item. When type checking and
5257
borrow checking a generic item, the bounds can be used to determine that a
5358
trait is implemented for a type. For example, given `Ty: Trait`
@@ -87,9 +92,11 @@ fn name_figure<U: Shape>(
8792
}
8893
```
8994

95+
r[bound.trivial]
9096
Bounds that don't use the item's parameters or [higher-ranked lifetimes] are checked when the item is defined.
9197
It is an error for such a bound to be false.
9298

99+
r[bound.special]
93100
[`Copy`], [`Clone`], and [`Sized`] bounds are also checked for certain generic types when using the item, even if the use does not provide a concrete type.
94101
It is an error to have `Copy` or `Clone` as a bound on a mutable reference, [trait object], or [slice].
95102
It is an error to have `Sized` as a bound on a trait object or slice.
@@ -107,16 +114,24 @@ where
107114
struct UsesA<'a, T>(A<'a, T>);
108115
```
109116

117+
r[bound.trait-object]
110118
Trait and lifetime bounds are also used to name [trait objects].
111119

112120
## `?Sized`
113121

122+
r[bound.sized]
123+
114124
`?` is only used to relax the implicit [`Sized`] trait bound for [type parameters] or [associated types].
115125
`?Sized` may not be used as a bound for other types.
116126

117127
## Lifetime bounds
118128

129+
r[bound.lifetime]
130+
131+
r[bound.lifetime.intro]
119132
Lifetime bounds can be applied to types or to other lifetimes.
133+
134+
r[bound.lifetime.outlive-lifetime]
120135
The bound `'a: 'b` is usually read as `'a` *outlives* `'b`.
121136
`'a: 'b` means that `'a` lasts at least as long as `'b`, so a reference `&'a ()` is valid whenever `&'b ()` is valid.
122137

@@ -127,14 +142,19 @@ fn f<'a, 'b>(x: &'a i32, mut y: &'b i32) where 'a: 'b {
127142
}
128143
```
129144

145+
r[bound.lifetime.outlive-type]
130146
`T: 'a` means that all lifetime parameters of `T` outlive `'a`.
131147
For example, if `'a` is an unconstrained lifetime parameter, then `i32: 'static` and `&'static str: 'a` are satisfied, but `Vec<&'a ()>: 'static` is not.
132148

133149
## Higher-ranked trait bounds
134150

151+
r[bound.higher-ranked]
152+
153+
r[bound.higher-ranked.syntax]
135154
> _ForLifetimes_ :\
136155
> &nbsp;&nbsp; `for` [_GenericParams_]
137156
157+
r[bound.higher-ranked.intro]
138158
Trait bounds may be *higher ranked* over lifetimes. These bounds specify a bound
139159
that is true *for all* lifetimes. For example, a bound such as `for<'a> &'a T:
140160
PartialEq<i32>` would require an implementation like
@@ -158,6 +178,7 @@ fn call_on_ref_zero<F>(f: F) where for<'a> F: Fn(&'a i32) {
158178
}
159179
```
160180

181+
r[bound.higher-ranked.trait]
161182
Higher-ranked lifetimes may also be specified just before the trait: the only
162183
difference is the [scope][hrtb-scopes] of the lifetime parameter, which extends only to the
163184
end of the following trait instead of the whole bound. This function is
@@ -172,15 +193,20 @@ fn call_on_ref_zero<F>(f: F) where F: for<'a> Fn(&'a i32) {
172193

173194
## Implied bounds
174195

196+
r[bound.implied]
197+
198+
r[bound.implied.intro]
175199
Lifetime bounds required for types to be well-formed are sometimes inferred.
176200

177201
```rust
178202
fn requires_t_outlives_a<'a, T>(x: &'a T) {}
179203
```
204+
180205
The type parameter `T` is required to outlive `'a` for the type `&'a T` to be well-formed.
181206
This is inferred because the function signature contains the type `&'a T` which is
182207
only valid if `T: 'a` holds.
183208

209+
r[bound.implied.context]
184210
Implied bounds are added for all parameters and outputs of functions. Inside of `requires_t_outlives_a`
185211
you can assume `T: 'a` to hold even if you don't explicitly specify this:
186212

@@ -203,6 +229,7 @@ fn not_implied<'a, T>() {
203229
}
204230
```
205231

232+
r[bound.implied.trait]
206233
Only lifetime bounds are implied, trait bounds still have to be explicitly added.
207234
The following example therefore causes an error:
208235

@@ -213,6 +240,7 @@ struct IsDebug<T: Debug>(T);
213240
fn doesnt_specify_t_debug<T>(x: IsDebug<T>) {}
214241
```
215242

243+
r[bound.implied.def]
216244
Lifetime bounds are also inferred for type definitions and impl blocks for any type:
217245

218246
```rust
@@ -244,6 +272,8 @@ impl<'a, T> Trait<'a, T> for &'a T {}
244272

245273
## Use bounds
246274

275+
r[bound.use]
276+
247277
Certain bounds lists may include a `use<..>` bound to control which generic parameters are captured by the `impl Trait` [abstract return type]. See [precise capturing] for more details.
248278

249279
[IDENTIFIER]: identifiers.html

0 commit comments

Comments
 (0)