@@ -1261,34 +1261,38 @@ impl<'b, T: ?Sized> Ref<'b, T> {
1261
1261
Ref { value : f ( orig. value ) , borrow : orig. borrow }
1262
1262
}
1263
1263
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`.
1265
1267
///
1266
1268
/// The `RefCell` is already immutably borrowed, so this cannot fail.
1267
1269
///
1268
1270
/// 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
1270
1272
/// name on the contents of a `RefCell` used through `Deref`.
1271
1273
///
1272
1274
/// # Examples
1273
1275
///
1274
1276
/// ```
1275
- /// #![feature(cell_try_map )]
1277
+ /// #![feature(cell_filter_map )]
1276
1278
///
1277
1279
/// use std::cell::{RefCell, Ref};
1278
1280
///
1279
1281
/// let c = RefCell::new(vec![1, 2, 3]);
1280
1282
/// 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);
1283
1285
/// ```
1284
- #[ unstable( feature = "cell_try_map " , reason = "recently added" , issue = "none" ) ]
1286
+ #[ unstable( feature = "cell_filter_map " , reason = "recently added" , issue = "none" ) ]
1285
1287
#[ 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 >
1287
1289
where
1288
1290
F : FnOnce ( & T ) -> Option < & U > ,
1289
1291
{
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
+ }
1292
1296
}
1293
1297
1294
1298
/// Splits a `Ref` into multiple `Ref`s for different components of the
@@ -1402,44 +1406,56 @@ impl<'b, T: ?Sized> RefMut<'b, T> {
1402
1406
RefMut { value : f ( value) , borrow }
1403
1407
}
1404
1408
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`.
1406
1412
///
1407
1413
/// The `RefCell` is already mutably borrowed, so this cannot fail.
1408
1414
///
1409
1415
/// 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
1411
1417
/// same name on the contents of a `RefCell` used through `Deref`.
1412
1418
///
1413
1419
/// # Examples
1414
1420
///
1415
1421
/// ```
1416
- /// #![feature(cell_try_map )]
1422
+ /// #![feature(cell_filter_map )]
1417
1423
///
1418
1424
/// use std::cell::{RefCell, RefMut};
1419
1425
///
1420
1426
/// let c = RefCell::new(vec![1, 2, 3]);
1421
1427
///
1422
1428
/// {
1423
1429
/// 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));
1425
1431
///
1426
- /// if let Some (mut b2) = b2 {
1432
+ /// if let Ok (mut b2) = b2 {
1427
1433
/// *b2 += 2;
1428
1434
/// }
1429
1435
/// }
1430
1436
///
1431
1437
/// assert_eq!(*c.borrow(), vec![1, 4, 3]);
1432
1438
/// ```
1433
- #[ unstable( feature = "cell_try_map " , reason = "recently added" , issue = "none" ) ]
1439
+ #[ unstable( feature = "cell_filter_map " , reason = "recently added" , issue = "none" ) ]
1434
1440
#[ 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 >
1436
1442
where
1437
1443
F : FnOnce ( & mut T ) -> Option < & mut U > ,
1438
1444
{
1439
1445
// FIXME(nll-rfc#40): fix borrow-check
1440
1446
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
+ }
1443
1459
}
1444
1460
1445
1461
/// Splits a `RefMut` into multiple `RefMut`s for different components of the
0 commit comments