Skip to content

Commit 344aa2a

Browse files
committed
Implement RefCell::{try_replace, try_replace_with, try_swap}
Resolves #54493.
1 parent 3ec4308 commit 344aa2a

File tree

1 file changed

+119
-0
lines changed

1 file changed

+119
-0
lines changed

library/core/src/cell.rs

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -899,6 +899,43 @@ impl<T> RefCell<T> {
899899
mem::replace(&mut *self.borrow_mut(), t)
900900
}
901901

902+
/// Replaces the wrapped value with a new one, returning the old value,
903+
/// without deinitializing either one.
904+
///
905+
/// This function corresponds to [`std::mem::replace`](../mem/fn.replace.html).
906+
///
907+
/// This is the non-panicking variant of [`replace`](#method.replace).
908+
///
909+
/// # Examples
910+
///
911+
/// ```
912+
/// #![feature(refcell_try_replace)]
913+
/// use std::cell::RefCell;
914+
///
915+
/// let cell = RefCell::new(5);
916+
///
917+
/// {
918+
/// let borrowed_five = cell.borrow();
919+
/// let replace_result = cell.try_replace(6);
920+
/// assert!(replace_result.is_err());
921+
/// assert_eq!(cell, RefCell::new(5));
922+
///
923+
/// }
924+
///
925+
/// {
926+
/// let replace_result = cell.try_replace(6);
927+
/// assert!(replace_result.is_ok());
928+
/// assert_eq!(cell, RefCell::new(6));
929+
/// }
930+
/// ```
931+
#[inline]
932+
#[unstable(feature = "refcell_try_replace", issue = "none")]
933+
#[track_caller]
934+
#[rustc_confusables("try_swap")]
935+
pub fn try_replace(&self, t: T) -> Result<T, BorrowMutError> {
936+
Ok(mem::replace(&mut *self.try_borrow_mut()?, t))
937+
}
938+
902939
/// Replaces the wrapped value with a new one computed from `f`, returning
903940
/// the old value, without deinitializing either one.
904941
///
@@ -924,6 +961,42 @@ impl<T> RefCell<T> {
924961
mem::replace(mut_borrow, replacement)
925962
}
926963

964+
/// Replaces the wrapped value with a new one computed from `f`, returning
965+
/// the old value, without deinitializing either one.
966+
///
967+
/// This is the non-panicking variant of [`replace_with`](#method.replace_with).
968+
///
969+
/// # Examples
970+
///
971+
/// ```
972+
/// #![feature(refcell_try_replace)]
973+
/// use std::cell::RefCell;
974+
///
975+
/// let cell = RefCell::new(5);
976+
///
977+
/// {
978+
/// let borrowed_five = cell.borrow();
979+
/// let replace_result = cell.try_replace_with(|&mut old| old + 1);
980+
/// assert!(replace_result.is_err());
981+
/// assert_eq!(cell, RefCell::new(5));
982+
///
983+
/// }
984+
///
985+
/// {
986+
/// let replace_result = cell.try_replace_with(|&mut old| old + 1);
987+
/// assert!(replace_result.is_ok());
988+
/// assert_eq!(cell, RefCell::new(6));
989+
/// }
990+
/// ```
991+
#[inline]
992+
#[unstable(feature = "refcell_try_replace", issue = "none")]
993+
#[track_caller]
994+
pub fn try_replace_with<F: FnOnce(&mut T) -> T>(&self, f: F) -> Result<T, BorrowMutError> {
995+
let mut_borrow = &mut *self.try_borrow_mut()?;
996+
let replacement = f(mut_borrow);
997+
Ok(mem::replace(mut_borrow, replacement))
998+
}
999+
9271000
/// Swaps the wrapped value of `self` with the wrapped value of `other`,
9281001
/// without deinitializing either one.
9291002
///
@@ -949,6 +1022,52 @@ impl<T> RefCell<T> {
9491022
pub fn swap(&self, other: &Self) {
9501023
mem::swap(&mut *self.borrow_mut(), &mut *other.borrow_mut())
9511024
}
1025+
1026+
/// Swaps the wrapped value of `self` with the wrapped value of `other`,
1027+
/// without deinitializing either one.
1028+
///
1029+
/// This function corresponds to [`std::mem::swap`](../mem/fn.swap.html).
1030+
///
1031+
/// This is the non-panicking variant of [`swap`](#method.swap).
1032+
///
1033+
/// # Examples
1034+
///
1035+
/// ```
1036+
/// #![feature(refcell_try_replace)]
1037+
/// use std::cell::RefCell;
1038+
///
1039+
/// let c = RefCell::new(5);
1040+
/// let d = RefCell::new(6);
1041+
///
1042+
/// {
1043+
/// let borrowed_c = c.borrow();
1044+
/// let swap_result = c.try_swap(&d);
1045+
/// assert!(swap_result.is_err());
1046+
/// assert_eq!(c, RefCell::new(5));
1047+
/// assert_eq!(d, RefCell::new(6));
1048+
/// }
1049+
///
1050+
/// {
1051+
/// let borrowed_d = d.borrow();
1052+
/// let swap_result = c.try_swap(&d);
1053+
/// assert!(swap_result.is_err());
1054+
/// assert_eq!(c, RefCell::new(5));
1055+
/// assert_eq!(d, RefCell::new(6));
1056+
/// }
1057+
///
1058+
/// {
1059+
/// let swap_result = c.try_swap(&d);
1060+
/// assert!(swap_result.is_ok());
1061+
/// assert_eq!(c, RefCell::new(6));
1062+
/// assert_eq!(d, RefCell::new(5));
1063+
/// }
1064+
/// ```
1065+
#[inline]
1066+
#[unstable(feature = "refcell_try_replace", issue = "none")]
1067+
#[track_caller]
1068+
pub fn try_swap(&self, other: &Self) -> Result<(), BorrowMutError> {
1069+
Ok(mem::swap(&mut *self.try_borrow_mut()?, &mut *other.try_borrow_mut()?))
1070+
}
9521071
}
9531072

9541073
impl<T: ?Sized> RefCell<T> {

0 commit comments

Comments
 (0)