1
1
use crate :: ops:: ControlFlow ;
2
2
3
- /// The trait used for a variety of operations related to short-circuits,
4
- /// such as the `?` operator, `try {}` blocks, and `try_*` methods.
3
+ /// The `?` operator and `try {}` blocks.
4
+ ///
5
+ /// `try_*` methods typically involve a type implementing this trait. For
6
+ /// example, the closures passed to [`Iterator::try_fold`] and
7
+ /// [`Iterator::try_for_each`] must return such a type.
8
+ ///
9
+ /// `Try` types are typically those containing two or more categories of values,
10
+ /// some subset of which are so commonly handled via early returns that it's
11
+ /// worth providing a terse (but still visible) syntax to make that easy.
12
+ ///
13
+ /// This is most often seen for error handling with [`Result`] and [`Option`].
14
+ /// The quintessential implementation of this trait is on [`ControlFlow`].
5
15
///
6
16
/// # Using `Try` in Generic Code
7
17
///
@@ -42,8 +52,8 @@ use crate::ops::ControlFlow;
42
52
/// }
43
53
/// ```
44
54
///
45
- /// `Try` is also the trait we need to get the updated accumulator from `f`'s return
46
- /// value and return the result if we manage to get through the entire iterator :
55
+ /// If we get through the entire iterator, we need to wrap up the accumulator
56
+ /// into the return type using [`Try::from_output`] :
47
57
/// ```
48
58
/// # #![feature(try_trait_v2)]
49
59
/// # #![feature(try_trait_transition)]
@@ -65,9 +75,9 @@ use crate::ops::ControlFlow;
65
75
/// }
66
76
/// ```
67
77
///
68
- /// We'll also need `FromResidual::from_residual` to turn the residual back into
69
- /// the original type. But because it's a supertrait of `Try`, we don't need to
70
- /// mention it in the bounds. All types which implement `Try` can always be
78
+ /// We'll also need [ `FromResidual::from_residual`] to turn the residual back
79
+ /// into the original type. But because it's a supertrait of `Try`, we don't
80
+ /// need to mention it in the bounds. All types which implement `Try` can be
71
81
/// recreated from their corresponding residual, so we'll just call it:
72
82
/// ```
73
83
/// # #![feature(try_trait_v2)]
@@ -131,14 +141,18 @@ pub trait Try: FromResidual {
131
141
/// That way it's distinct from `ControlFlow<E>::Residual`, for example,
132
142
/// and thus `?` on `ControlFlow` cannot be used in a method returning `Result`.
133
143
///
134
- /// In a type that's generic on a parameter that's used as the ` Output` type ,
135
- /// call it `Foo<T> : Try` where `Foo<T>::Output == T`, it's typically easiest
136
- /// to make the corresponding `Residual` type by filling in that generic
137
- /// with an uninhabited type: `type Residual = Foo<Infallible>;` .
144
+ /// If you're making a generic type `Foo<T>` that implements `Try< Output = T>` ,
145
+ /// then typically you can use `Foo<std::convert::Infallible>` as its `Residual`
146
+ /// type: that type will have a "hole" in the correct place, and will maintain the
147
+ /// "foo-ness" of the residual so other types need to opt-in to interconversion .
138
148
#[ unstable( feature = "try_trait_v2" , issue = "84277" ) ]
139
149
type Residual ;
140
150
141
- /// Wraps up a value such that `?` on the value will produce the original value.
151
+ /// Constructs the type from its `Output` type.
152
+ ///
153
+ /// This should be implemented consistently with the `branch` method
154
+ /// such that applying the `?` operator will get back the original value:
155
+ /// `Try::from_output(x).branch() --> ControlFlow::Continue(x)`.
142
156
///
143
157
/// # Examples
144
158
///
@@ -203,8 +217,12 @@ pub trait Try: FromResidual {
203
217
/// to support interconversion with other `Try` types.
204
218
#[ unstable( feature = "try_trait_v2" , issue = "84277" ) ]
205
219
pub trait FromResidual < R = <Self as Try >:: Residual > {
206
- /// Produces the return value of the function from the residual
207
- /// when the `?` operator results in an early exit.
220
+ /// Constructs the type from a compatible `Residual` type.
221
+ ///
222
+ /// This should be implemented consistently with the `branch` method such
223
+ /// that applying the `?` operator will get back an equivalent residual:
224
+ /// `FromResidual::from_residual(r).branch() --> ControlFlow::Break(r)`.
225
+ /// (It may not be an *identical* residual when interconversion is involved.)
208
226
///
209
227
/// # Examples
210
228
///
0 commit comments