11use crate :: cell:: UnsafeCell ;
22use crate :: fmt;
33use crate :: mem;
4+ use crate :: ops:: Residual ;
5+ use crate :: ops:: Try ;
46
57/// A cell which can be written to only once.
68///
@@ -136,8 +138,12 @@ impl<T> OnceCell<T> {
136138 }
137139
138140 /// 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>`.
141147 ///
142148 /// # Panics
143149 ///
@@ -156,6 +162,7 @@ impl<T> OnceCell<T> {
156162 ///
157163 /// let cell = OnceCell::new();
158164 /// assert_eq!(cell.get_or_try_init(|| Err(())), Err(()));
165+ /// assert_eq!(cell.get_or_try_init(|| None), None);
159166 /// assert!(cell.get().is_none());
160167 /// let value = cell.get_or_try_init(|| -> Result<i32, ()> {
161168 /// Ok(92)
@@ -164,19 +171,21 @@ impl<T> OnceCell<T> {
164171 /// assert_eq!(cell.get(), Some(&92))
165172 /// ```
166173 #[ 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
168175 where
169- F : FnOnce ( ) -> Result < T , E > ,
176+ F : FnOnce ( ) -> R ,
177+ R : Try < Output = T > ,
178+ R :: Residual : Residual < & ' a T > ,
170179 {
171180 if let Some ( val) = self . get ( ) {
172- return Ok ( val) ;
181+ return Try :: from_output ( val) ;
173182 }
174183 /// Avoid inlining the initialization closure into the common path that fetches
175184 /// the already initialized value
176185 #[ cold]
177- fn outlined_call < F , T , E > ( f : F ) -> Result < T , E >
186+ fn outlined_call < F , R > ( f : F ) -> R
178187 where
179- F : FnOnce ( ) -> Result < T , E > ,
188+ F : FnOnce ( ) -> R ,
180189 {
181190 f ( )
182191 }
@@ -186,7 +195,7 @@ impl<T> OnceCell<T> {
186195 // `assert`, while keeping `set/get` would be sound, but it seems
187196 // better to panic, rather than to silently use an old value.
188197 assert ! ( self . set( val) . is_ok( ) , "reentrant init" ) ;
189- Ok ( self . get ( ) . unwrap ( ) )
198+ Try :: from_output ( self . get ( ) . unwrap ( ) )
190199 }
191200
192201 /// Consumes the cell, returning the wrapped value.
0 commit comments