@@ -87,10 +87,38 @@ impl<T> OnceCell<T> {
8787 #[ inline]
8888 #[ stable( feature = "once_cell" , since = "1.70.0" ) ]
8989 pub fn set ( & self , value : T ) -> Result < ( ) , T > {
90- // SAFETY: Safe because we cannot have overlapping mutable borrows
91- let slot = unsafe { & * self . inner . get ( ) } ;
92- if slot. is_some ( ) {
93- return Err ( value) ;
90+ match self . try_insert ( value) {
91+ Ok ( _) => Ok ( ( ) ) ,
92+ Err ( ( _, value) ) => Err ( value) ,
93+ }
94+ }
95+
96+ /// Sets the contents of the cell to `value` if the cell was empty, then
97+ /// returns a reference to it.
98+ ///
99+ /// # Errors
100+ ///
101+ /// This method returns `Ok(&value)` if the cell was empty and
102+ /// `Err(¤t_value, value)` if it was full.
103+ ///
104+ /// # Examples
105+ ///
106+ /// ```
107+ /// use std::cell::OnceCell;
108+ ///
109+ /// let cell = OnceCell::new();
110+ /// assert!(cell.get().is_none());
111+ ///
112+ /// assert_eq!(cell.try_insert(92), Ok(&92));
113+ /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
114+ ///
115+ /// assert!(cell.get().is_some());
116+ /// ```
117+ #[ inline]
118+ #[ stable( feature = "once_cell" , since = "CURRENT_RUSTC_VERSION" ) ]
119+ pub fn try_insert ( & self , value : T ) -> Result < & T , ( & T , T ) > {
120+ if let Some ( old) = self . get ( ) {
121+ return Err ( ( old, value) ) ;
94122 }
95123
96124 // SAFETY: This is the only place where we set the slot, no races
@@ -99,7 +127,7 @@ impl<T> OnceCell<T> {
99127 // maintains the `inner`'s invariant.
100128 let slot = unsafe { & mut * self . inner . get ( ) } ;
101129 * slot = Some ( value) ;
102- Ok ( ( ) )
130+ Ok ( self . get ( ) . unwrap ( ) )
103131 }
104132
105133 /// Gets the contents of the cell, initializing it with `f`
0 commit comments