11use crate :: ops:: ControlFlow ;
22
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`].
515///
616/// # Using `Try` in Generic Code
717///
@@ -42,8 +52,8 @@ use crate::ops::ControlFlow;
4252/// }
4353/// ```
4454///
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`] :
4757/// ```
4858/// # #![feature(try_trait_v2)]
4959/// # #![feature(try_trait_transition)]
@@ -65,9 +75,9 @@ use crate::ops::ControlFlow;
6575/// }
6676/// ```
6777///
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
7181/// recreated from their corresponding residual, so we'll just call it:
7282/// ```
7383/// # #![feature(try_trait_v2)]
@@ -131,14 +141,18 @@ pub trait Try: FromResidual {
131141 /// That way it's distinct from `ControlFlow<E>::Residual`, for example,
132142 /// and thus `?` on `ControlFlow` cannot be used in a method returning `Result`.
133143 ///
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 .
138148 #[ unstable( feature = "try_trait_v2" , issue = "84277" ) ]
139149 type Residual ;
140150
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)`.
142156 ///
143157 /// # Examples
144158 ///
@@ -203,8 +217,12 @@ pub trait Try: FromResidual {
203217/// to support interconversion with other `Try` types.
204218#[ unstable( feature = "try_trait_v2" , issue = "84277" ) ]
205219pub 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.)
208226 ///
209227 /// # Examples
210228 ///
0 commit comments