@@ -698,14 +698,14 @@ impl<T, const N: usize> Cell<[T; N]> {
698
698
/// # Examples
699
699
///
700
700
/// ```
701
- /// #![feature(as_array_of_cells)]
702
701
/// use std::cell::Cell;
703
702
///
704
703
/// let mut array: [i32; 3] = [1, 2, 3];
705
704
/// let cell_array: &Cell<[i32; 3]> = Cell::from_mut(&mut array);
706
705
/// let array_cell: &[Cell<i32>; 3] = cell_array.as_array_of_cells();
707
706
/// ```
708
- #[ unstable( feature = "as_array_of_cells" , issue = "88248" ) ]
707
+ #[ stable( feature = "as_array_of_cells" , since = "CURRENT_RUSTC_VERSION" ) ]
708
+ #[ rustc_const_stable( feature = "as_array_of_cells" , since = "CURRENT_RUSTC_VERSION" ) ]
709
709
pub const fn as_array_of_cells ( & self ) -> & [ Cell < T > ; N ] {
710
710
// SAFETY: `Cell<T>` has the same memory layout as `T`.
711
711
unsafe { & * ( self as * const Cell < [ T ; N ] > as * const [ Cell < T > ; N ] ) }
@@ -1573,6 +1573,47 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1573
1573
}
1574
1574
}
1575
1575
1576
+ /// Tries to makes a new `Ref` for a component of the borrowed data.
1577
+ /// On failure, the original guard is returned alongside with the error
1578
+ /// returned by the closure.
1579
+ ///
1580
+ /// The `RefCell` is already immutably borrowed, so this cannot fail.
1581
+ ///
1582
+ /// This is an associated function that needs to be used as
1583
+ /// `Ref::try_map(...)`. A method would interfere with methods of the same
1584
+ /// name on the contents of a `RefCell` used through `Deref`.
1585
+ ///
1586
+ /// # Examples
1587
+ ///
1588
+ /// ```
1589
+ /// #![feature(refcell_try_map)]
1590
+ /// use std::cell::{RefCell, Ref};
1591
+ /// use std::str::{from_utf8, Utf8Error};
1592
+ ///
1593
+ /// let c = RefCell::new(vec![0xF0, 0x9F, 0xA6 ,0x80]);
1594
+ /// let b1: Ref<'_, Vec<u8>> = c.borrow();
1595
+ /// let b2: Result<Ref<'_, str>, _> = Ref::try_map(b1, |v| from_utf8(v));
1596
+ /// assert_eq!(&*b2.unwrap(), "🦀");
1597
+ ///
1598
+ /// let c = RefCell::new(vec![0xF0, 0x9F, 0xA6]);
1599
+ /// let b1: Ref<'_, Vec<u8>> = c.borrow();
1600
+ /// let b2: Result<_, (Ref<'_, Vec<u8>>, Utf8Error)> = Ref::try_map(b1, |v| from_utf8(v));
1601
+ /// let (b3, e) = b2.unwrap_err();
1602
+ /// assert_eq!(*b3, vec![0xF0, 0x9F, 0xA6]);
1603
+ /// assert_eq!(e.valid_up_to(), 0);
1604
+ /// ```
1605
+ #[ unstable( feature = "refcell_try_map" , issue = "143801" ) ]
1606
+ #[ inline]
1607
+ pub fn try_map < U : ?Sized , E > (
1608
+ orig : Ref < ' b , T > ,
1609
+ f : impl FnOnce ( & T ) -> Result < & U , E > ,
1610
+ ) -> Result < Ref < ' b , U > , ( Self , E ) > {
1611
+ match f( & * orig) {
1612
+ Ok ( value) => Ok ( Ref { value: NonNull :: from( value) , borrow : orig. borrow } ) ,
1613
+ Err ( e) => Err ( ( orig , e ) ) ,
1614
+ }
1615
+ }
1616
+
1576
1617
/// Splits a `Ref` into multiple `Ref`s for different components of the
1577
1618
/// borrowed data.
1578
1619
///
@@ -1734,6 +1775,58 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1734
1775
}
1735
1776
}
1736
1777
1778
+ /// Tries to makes a new `RefMut` for a component of the borrowed data.
1779
+ /// On failure, the original guard is returned alongside with the error
1780
+ /// returned by the closure.
1781
+ ///
1782
+ /// The `RefCell` is already mutably borrowed, so this cannot fail.
1783
+ ///
1784
+ /// This is an associated function that needs to be used as
1785
+ /// `RefMut::try_map(...)`. A method would interfere with methods of the same
1786
+ /// name on the contents of a `RefCell` used through `Deref`.
1787
+ ///
1788
+ /// # Examples
1789
+ ///
1790
+ /// ```
1791
+ /// #![feature(refcell_try_map)]
1792
+ /// use std::cell::{RefCell, RefMut};
1793
+ /// use std::str::{from_utf8_mut, Utf8Error};
1794
+ ///
1795
+ /// let c = RefCell::new(vec![0x68, 0x65, 0x6C, 0x6C, 0x6F]);
1796
+ /// {
1797
+ /// let b1: RefMut<'_, Vec<u8>> = c.borrow_mut();
1798
+ /// let b2: Result<RefMut<'_, str>, _> = RefMut::try_map(b1, |v| from_utf8_mut(v));
1799
+ /// let mut b2 = b2.unwrap();
1800
+ /// assert_eq!(&*b2, "hello");
1801
+ /// b2.make_ascii_uppercase();
1802
+ /// }
1803
+ /// assert_eq!(*c.borrow(), "HELLO".as_bytes());
1804
+ ///
1805
+ /// let c = RefCell::new(vec![0xFF]);
1806
+ /// let b1: RefMut<'_, Vec<u8>> = c.borrow_mut();
1807
+ /// let b2: Result<_, (RefMut<'_, Vec<u8>>, Utf8Error)> = RefMut::try_map(b1, |v| from_utf8_mut(v));
1808
+ /// let (b3, e) = b2.unwrap_err();
1809
+ /// assert_eq!(*b3, vec![0xFF]);
1810
+ /// assert_eq!(e.valid_up_to(), 0);
1811
+ /// ```
1812
+ #[ unstable( feature = "refcell_try_map" , issue = "143801" ) ]
1813
+ #[ inline]
1814
+ pub fn try_map < U : ?Sized , E > (
1815
+ mut orig : RefMut < ' b , T > ,
1816
+ f : impl FnOnce ( & mut T ) -> Result < & mut U , E > ,
1817
+ ) -> Result < RefMut < ' b , U > , ( Self , E ) > {
1818
+ // SAFETY: function holds onto an exclusive reference for the duration
1819
+ // of its call through `orig`, and the pointer is only de-referenced
1820
+ // inside of the function call never allowing the exclusive reference to
1821
+ // escape.
1822
+ match f( & mut * orig) {
1823
+ Ok ( value) => {
1824
+ Ok ( RefMut { value: NonNull :: from( value) , borrow : orig. borrow, marker : PhantomData } )
1825
+ }
1826
+ Err ( e) => Err ( ( orig, e) ) ,
1827
+ }
1828
+ }
1829
+
1737
1830
/// Splits a `RefMut` into multiple `RefMut`s for different components of the
1738
1831
/// borrowed data.
1739
1832
///
0 commit comments