@@ -87,10 +87,40 @@ 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+ /// #![feature(once_cell_try_insert)]
108+ ///
109+ /// use std::cell::OnceCell;
110+ ///
111+ /// let cell = OnceCell::new();
112+ /// assert!(cell.get().is_none());
113+ ///
114+ /// assert_eq!(cell.try_insert(92), Ok(&92));
115+ /// assert_eq!(cell.try_insert(62), Err((&92, 62)));
116+ ///
117+ /// assert!(cell.get().is_some());
118+ /// ```
119+ #[ inline]
120+ #[ unstable( feature = "once_cell_try_insert" , issue = "116693" ) ]
121+ pub fn try_insert ( & self , value : T ) -> Result < & T , ( & T , T ) > {
122+ if let Some ( old) = self . get ( ) {
123+ return Err ( ( old, value) ) ;
94124 }
95125
96126 // SAFETY: This is the only place where we set the slot, no races
@@ -99,7 +129,7 @@ impl<T> OnceCell<T> {
99129 // maintains the `inner`'s invariant.
100130 let slot = unsafe { & mut * self . inner . get ( ) } ;
101131 * slot = Some ( value) ;
102- Ok ( ( ) )
132+ Ok ( self . get ( ) . unwrap ( ) )
103133 }
104134
105135 /// Gets the contents of the cell, initializing it with `f`
0 commit comments