@@ -87,10 +87,38 @@ 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
+ /// 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) ) ;
94
122
}
95
123
96
124
// SAFETY: This is the only place where we set the slot, no races
@@ -99,7 +127,7 @@ impl<T> OnceCell<T> {
99
127
// maintains the `inner`'s invariant.
100
128
let slot = unsafe { & mut * self . inner . get ( ) } ;
101
129
* slot = Some ( value) ;
102
- Ok ( ( ) )
130
+ Ok ( self . get ( ) . unwrap ( ) )
103
131
}
104
132
105
133
/// Gets the contents of the cell, initializing it with `f`
0 commit comments