1
1
use crate :: cell:: UnsafeCell ;
2
2
use crate :: fmt;
3
3
use crate :: mem;
4
+ use crate :: ops:: Residual ;
5
+ use crate :: ops:: Try ;
4
6
5
7
/// A cell which can be written to only once.
6
8
///
@@ -136,8 +138,12 @@ impl<T> OnceCell<T> {
136
138
}
137
139
138
140
/// Gets the contents of the cell, initializing it with `f` if
139
- /// the cell was empty. If the cell was empty and `f` failed, an
140
- /// error is returned.
141
+ /// the cell was empty. If the cell was empty and `f` short-circuits,
142
+ /// the residual is returned.
143
+ ///
144
+ /// The return type of this method depends on the return type of the
145
+ /// closure. If it returns `Result<T, E>`, the output is `Result<&T, E>`.
146
+ /// If it returns `Option<T>`, the output is `Option<&T>`.
141
147
///
142
148
/// # Panics
143
149
///
@@ -156,6 +162,7 @@ impl<T> OnceCell<T> {
156
162
///
157
163
/// let cell = OnceCell::new();
158
164
/// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
165
+ /// assert_eq!(cell.get_or_try_init(|| None), None);
159
166
/// assert!(cell.get().is_none());
160
167
/// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
161
168
/// Ok(92)
@@ -164,19 +171,21 @@ impl<T> OnceCell<T> {
164
171
/// assert_eq!(cell.get(), Some(&92))
165
172
/// ```
166
173
#[ unstable( feature = "once_cell_try" , issue = "109737" ) ]
167
- pub fn get_or_try_init < F , E > ( & self , f : F ) -> Result < & T , E >
174
+ pub fn get_or_try_init < ' a , F , R > ( & ' a self , f : F ) -> < R :: Residual as Residual < & T > > :: TryType
168
175
where
169
- F : FnOnce ( ) -> Result < T , E > ,
176
+ F : FnOnce ( ) -> R ,
177
+ R : Try < Output = T > ,
178
+ R :: Residual : Residual < & ' a T > ,
170
179
{
171
180
if let Some ( val) = self . get ( ) {
172
- return Ok ( val) ;
181
+ return Try :: from_output ( val) ;
173
182
}
174
183
/// Avoid inlining the initialization closure into the common path that fetches
175
184
/// the already initialized value
176
185
#[ cold]
177
- fn outlined_call < F , T , E > ( f : F ) -> Result < T , E >
186
+ fn outlined_call < F , R > ( f : F ) -> R
178
187
where
179
- F : FnOnce ( ) -> Result < T , E > ,
188
+ F : FnOnce ( ) -> R ,
180
189
{
181
190
f ( )
182
191
}
@@ -186,7 +195,7 @@ impl<T> OnceCell<T> {
186
195
// `assert`, while keeping `set/get` would be sound, but it seems
187
196
// better to panic, rather than to silently use an old value.
188
197
assert ! ( self . set( val) . is_ok( ) , "reentrant init" ) ;
189
- Ok ( self . get ( ) . unwrap ( ) )
198
+ Try :: from_output ( self . get ( ) . unwrap ( ) )
190
199
}
191
200
192
201
/// Consumes the cell, returning the wrapped value.
0 commit comments