@@ -87,10 +87,40 @@ impl<T> OnceCell<T> {
87
87
#[ inline]
88
88
#[ stable( feature = "once_cell" , since = "1.70.0" ) ]
89
89
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) ) ;
94
124
}
95
125
96
126
// SAFETY: This is the only place where we set the slot, no races
@@ -99,7 +129,7 @@ impl<T> OnceCell<T> {
99
129
// maintains the `inner`'s invariant.
100
130
let slot = unsafe { & mut * self . inner . get ( ) } ;
101
131
* slot = Some ( value) ;
102
- Ok ( ( ) )
132
+ Ok ( self . get ( ) . unwrap ( ) )
103
133
}
104
134
105
135
/// Gets the contents of the cell, initializing it with `f`
0 commit comments