@@ -1261,34 +1261,38 @@ impl<'b, T: ?Sized> Ref<'b, T> {
12611261 Ref { value : f ( orig. value ) , borrow : orig. borrow }
12621262 }
12631263
1264- /// Makes a new `Ref` for an optional component of the borrowed data.
1264+ /// Makes a new `Ref` for an optional component of the borrowed data. The
1265+ /// original guard is returned as an `Err(..)` if the closure returns
1266+ /// `None`.
12651267 ///
12661268 /// The `RefCell` is already immutably borrowed, so this cannot fail.
12671269 ///
12681270 /// This is an associated function that needs to be used as
1269- /// `Ref::try_map (...)`. A method would interfere with methods of the same
1271+ /// `Ref::filter_map (...)`. A method would interfere with methods of the same
12701272 /// name on the contents of a `RefCell` used through `Deref`.
12711273 ///
12721274 /// # Examples
12731275 ///
12741276 /// ```
1275- /// #![feature(cell_try_map )]
1277+ /// #![feature(cell_filter_map )]
12761278 ///
12771279 /// use std::cell::{RefCell, Ref};
12781280 ///
12791281 /// let c = RefCell::new(vec![1, 2, 3]);
12801282 /// let b1: Ref<Vec<u32>> = c.borrow();
1281- /// let b2: Option <Ref<u32>> = Ref::try_map (b1, |v| v.get(1));
1282- /// assert_eq!(b2.as_deref (), Some(&2))
1283+ /// let b2: Result <Ref<u32>, _ > = Ref::filter_map (b1, |v| v.get(1));
1284+ /// assert_eq!(* b2.unwrap (), 2);
12831285 /// ```
1284- #[ unstable( feature = "cell_try_map " , reason = "recently added" , issue = "none" ) ]
1286+ #[ unstable( feature = "cell_filter_map " , reason = "recently added" , issue = "none" ) ]
12851287 #[ inline]
1286- pub fn try_map < U : ?Sized , F > ( orig : Ref < ' b , T > , f : F ) -> Option < Ref < ' b , U > >
1288+ pub fn filter_map < U : ?Sized , F > ( orig : Ref < ' b , T > , f : F ) -> Result < Ref < ' b , U > , Self >
12871289 where
12881290 F : FnOnce ( & T ) -> Option < & U > ,
12891291 {
1290- let value = f ( orig. value ) ?;
1291- Some ( Ref { value, borrow : orig. borrow } )
1292+ match f ( orig. value ) {
1293+ Some ( value) => Ok ( Ref { value, borrow : orig. borrow } ) ,
1294+ None => Err ( orig) ,
1295+ }
12921296 }
12931297
12941298 /// Splits a `Ref` into multiple `Ref`s for different components of the
@@ -1402,44 +1406,56 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
14021406 RefMut { value : f ( value) , borrow }
14031407 }
14041408
1405- /// Makes a new `RefMut` for an optional component of the borrowed data.
1409+ /// Makes a new `RefMut` for an optional component of the borrowed data. The
1410+ /// original guard is returned as an `Err(..)` if the closure returns
1411+ /// `None`.
14061412 ///
14071413 /// The `RefCell` is already mutably borrowed, so this cannot fail.
14081414 ///
14091415 /// This is an associated function that needs to be used as
1410- /// `RefMut::try_map (...)`. A method would interfere with methods of the
1416+ /// `RefMut::filter_map (...)`. A method would interfere with methods of the
14111417 /// same name on the contents of a `RefCell` used through `Deref`.
14121418 ///
14131419 /// # Examples
14141420 ///
14151421 /// ```
1416- /// #![feature(cell_try_map )]
1422+ /// #![feature(cell_filter_map )]
14171423 ///
14181424 /// use std::cell::{RefCell, RefMut};
14191425 ///
14201426 /// let c = RefCell::new(vec![1, 2, 3]);
14211427 ///
14221428 /// {
14231429 /// let b1: RefMut<Vec<u32>> = c.borrow_mut();
1424- /// let mut b2: Option <RefMut<u32>> = RefMut::try_map (b1, |v| v.get_mut(1));
1430+ /// let mut b2: Result <RefMut<u32>, _ > = RefMut::filter_map (b1, |v| v.get_mut(1));
14251431 ///
1426- /// if let Some (mut b2) = b2 {
1432+ /// if let Ok (mut b2) = b2 {
14271433 /// *b2 += 2;
14281434 /// }
14291435 /// }
14301436 ///
14311437 /// assert_eq!(*c.borrow(), vec![1, 4, 3]);
14321438 /// ```
1433- #[ unstable( feature = "cell_try_map " , reason = "recently added" , issue = "none" ) ]
1439+ #[ unstable( feature = "cell_filter_map " , reason = "recently added" , issue = "none" ) ]
14341440 #[ inline]
1435- pub fn try_map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> Option < RefMut < ' b , U > >
1441+ pub fn filter_map < U : ?Sized , F > ( orig : RefMut < ' b , T > , f : F ) -> Result < RefMut < ' b , U > , Self >
14361442 where
14371443 F : FnOnce ( & mut T ) -> Option < & mut U > ,
14381444 {
14391445 // FIXME(nll-rfc#40): fix borrow-check
14401446 let RefMut { value, borrow } = orig;
1441- let value = f ( value) ?;
1442- Some ( RefMut { value, borrow } )
1447+ let value = value as * mut T ;
1448+ // SAFETY: function holds onto an exclusive reference for the duration
1449+ // of its call through `orig`, and the pointer is only de-referenced
1450+ // inside of the function call never allowing the exclusive reference to
1451+ // escape.
1452+ match f ( unsafe { & mut * value } ) {
1453+ Some ( value) => Ok ( RefMut { value, borrow } ) ,
1454+ None => {
1455+ // SAFETY: same as above.
1456+ Err ( RefMut { value : unsafe { & mut * value } , borrow } )
1457+ }
1458+ }
14431459 }
14441460
14451461 /// Splits a `RefMut` into multiple `RefMut`s for different components of the
0 commit comments