Skip to content

Rename *Guard::try_map to filter_map. #140536

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 3, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 10 additions & 12 deletions library/std/src/sync/poison/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,11 +253,11 @@ unsafe impl<T: ?Sized + Sync> Sync for MutexGuard<'_, T> {}
/// The data protected by the mutex can be accessed through this guard via its
/// [`Deref`] and [`DerefMut`] implementations.
///
/// This structure is created by the [`map`] and [`try_map`] methods on
/// This structure is created by the [`map`] and [`filter_map`] methods on
/// [`MutexGuard`].
///
/// [`map`]: MutexGuard::map
/// [`try_map`]: MutexGuard::try_map
/// [`filter_map`]: MutexGuard::filter_map
/// [`Condvar`]: crate::sync::Condvar
#[must_use = "if unused the Mutex will immediately unlock"]
#[must_not_suspend = "holding a MappedMutexGuard across suspend \
Expand Down Expand Up @@ -718,7 +718,7 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
U: ?Sized,
{
// SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
Expand All @@ -739,17 +739,16 @@ impl<'a, T: ?Sized> MutexGuard<'a, T> {
/// The `Mutex` is already locked, so this cannot fail.
///
/// This is an associated function that needs to be used as
/// `MutexGuard::try_map(...)`. A method would interfere with methods of the
/// `MutexGuard::filter_map(...)`. A method would interfere with methods of the
/// same name on the contents of the `MutexGuard` used through `Deref`.
#[doc(alias = "filter_map")]
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
where
F: FnOnce(&mut T) -> Option<&mut U>,
U: ?Sized,
{
// SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
match f(unsafe { &mut *orig.lock.data.get() }) {
Expand Down Expand Up @@ -826,7 +825,7 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
U: ?Sized,
{
// SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
Expand All @@ -847,17 +846,16 @@ impl<'a, T: ?Sized> MappedMutexGuard<'a, T> {
/// The `Mutex` is already locked, so this cannot fail.
///
/// This is an associated function that needs to be used as
/// `MappedMutexGuard::try_map(...)`. A method would interfere with methods of the
/// `MappedMutexGuard::filter_map(...)`. A method would interfere with methods of the
/// same name on the contents of the `MutexGuard` used through `Deref`.
#[doc(alias = "filter_map")]
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub fn try_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedMutexGuard<'a, U>, Self>
where
F: FnOnce(&mut T) -> Option<&mut U>,
U: ?Sized,
{
// SAFETY: the conditions of `MutexGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
match f(unsafe { orig.data.as_mut() }) {
Expand Down
54 changes: 25 additions & 29 deletions library/std/src/sync/poison/rwlock.rs
Original file line number Diff line number Diff line change
Expand Up @@ -147,11 +147,11 @@ unsafe impl<T: ?Sized + Sync> Sync for RwLockWriteGuard<'_, T> {}
/// RAII structure used to release the shared read access of a lock when
/// dropped, which can point to a subfield of the protected data.
///
/// This structure is created by the [`map`] and [`try_map`] methods
/// This structure is created by the [`map`] and [`filter_map`] methods
/// on [`RwLockReadGuard`].
///
/// [`map`]: RwLockReadGuard::map
/// [`try_map`]: RwLockReadGuard::try_map
/// [`filter_map`]: RwLockReadGuard::filter_map
#[must_use = "if unused the RwLock will immediately unlock"]
#[must_not_suspend = "holding a MappedRwLockReadGuard across suspend \
points can cause deadlocks, delays, \
Expand All @@ -176,11 +176,11 @@ unsafe impl<T: ?Sized + Sync> Sync for MappedRwLockReadGuard<'_, T> {}
/// RAII structure used to release the exclusive write access of a lock when
/// dropped, which can point to a subfield of the protected data.
///
/// This structure is created by the [`map`] and [`try_map`] methods
/// This structure is created by the [`map`] and [`filter_map`] methods
/// on [`RwLockWriteGuard`].
///
/// [`map`]: RwLockWriteGuard::map
/// [`try_map`]: RwLockWriteGuard::try_map
/// [`filter_map`]: RwLockWriteGuard::filter_map
#[must_use = "if unused the RwLock will immediately unlock"]
#[must_not_suspend = "holding a MappedRwLockWriteGuard across suspend \
points can cause deadlocks, delays, \
Expand Down Expand Up @@ -788,7 +788,7 @@ impl<T: ?Sized> Deref for MappedRwLockReadGuard<'_, T> {

fn deref(&self) -> &T {
// SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
unsafe { self.data.as_ref() }
}
}
Expand All @@ -799,7 +799,7 @@ impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {

fn deref(&self) -> &T {
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
unsafe { self.data.as_ref() }
}
}
Expand All @@ -808,7 +808,7 @@ impl<T: ?Sized> Deref for MappedRwLockWriteGuard<'_, T> {
impl<T: ?Sized> DerefMut for MappedRwLockWriteGuard<'_, T> {
fn deref_mut(&mut self) -> &mut T {
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
unsafe { self.data.as_mut() }
}
}
Expand Down Expand Up @@ -838,7 +838,7 @@ impl<T: ?Sized> Drop for RwLockWriteGuard<'_, T> {
impl<T: ?Sized> Drop for MappedRwLockReadGuard<'_, T> {
fn drop(&mut self) {
// SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
unsafe {
self.inner_lock.read_unlock();
}
Expand All @@ -850,7 +850,7 @@ impl<T: ?Sized> Drop for MappedRwLockWriteGuard<'_, T> {
fn drop(&mut self) {
self.poison_flag.done(&self.poison);
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
unsafe {
self.inner_lock.write_unlock();
}
Expand Down Expand Up @@ -878,7 +878,7 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
U: ?Sized,
{
// SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
Expand All @@ -893,22 +893,21 @@ impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
/// The `RwLock` is already locked for reading, so this cannot fail.
///
/// This is an associated function that needs to be used as
/// `RwLockReadGuard::try_map(...)`. A method would interfere with methods
/// `RwLockReadGuard::filter_map(...)`. A method would interfere with methods
/// of the same name on the contents of the `RwLockReadGuard` used through
/// `Deref`.
///
/// # Panics
///
/// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
#[doc(alias = "filter_map")]
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
where
F: FnOnce(&T) -> Option<&U>,
U: ?Sized,
{
// SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
match f(unsafe { orig.data.as_ref() }) {
Expand Down Expand Up @@ -943,7 +942,7 @@ impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
U: ?Sized,
{
// SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
let data = NonNull::from(f(unsafe { orig.data.as_ref() }));
Expand All @@ -958,22 +957,21 @@ impl<'a, T: ?Sized> MappedRwLockReadGuard<'a, T> {
/// The `RwLock` is already locked for reading, so this cannot fail.
///
/// This is an associated function that needs to be used as
/// `MappedRwLockReadGuard::try_map(...)`. A method would interfere with
/// `MappedRwLockReadGuard::filter_map(...)`. A method would interfere with
/// methods of the same name on the contents of the `MappedRwLockReadGuard`
/// used through `Deref`.
///
/// # Panics
///
/// If the closure panics, the guard will be dropped (unlocked) and the RwLock will not be poisoned.
#[doc(alias = "filter_map")]
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockReadGuard<'a, U>, Self>
where
F: FnOnce(&T) -> Option<&U>,
U: ?Sized,
{
// SAFETY: the conditions of `RwLockReadGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
match f(unsafe { orig.data.as_ref() }) {
Expand Down Expand Up @@ -1008,7 +1006,7 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
U: ?Sized,
{
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
let data = NonNull::from(f(unsafe { &mut *orig.lock.data.get() }));
Expand All @@ -1029,22 +1027,21 @@ impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
/// The `RwLock` is already locked for writing, so this cannot fail.
///
/// This is an associated function that needs to be used as
/// `RwLockWriteGuard::try_map(...)`. A method would interfere with methods
/// `RwLockWriteGuard::filter_map(...)`. A method would interfere with methods
/// of the same name on the contents of the `RwLockWriteGuard` used through
/// `Deref`.
///
/// # Panics
///
/// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
#[doc(alias = "filter_map")]
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub fn try_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
pub fn filter_map<U, F>(orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
where
F: FnOnce(&mut T) -> Option<&mut U>,
U: ?Sized,
{
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
match f(unsafe { &mut *orig.lock.data.get() }) {
Expand Down Expand Up @@ -1147,7 +1144,7 @@ impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
U: ?Sized,
{
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
let data = NonNull::from(f(unsafe { orig.data.as_mut() }));
Expand All @@ -1168,22 +1165,21 @@ impl<'a, T: ?Sized> MappedRwLockWriteGuard<'a, T> {
/// The `RwLock` is already locked for writing, so this cannot fail.
///
/// This is an associated function that needs to be used as
/// `MappedRwLockWriteGuard::try_map(...)`. A method would interfere with
/// `MappedRwLockWriteGuard::filter_map(...)`. A method would interfere with
/// methods of the same name on the contents of the `MappedRwLockWriteGuard`
/// used through `Deref`.
///
/// # Panics
///
/// If the closure panics, the guard will be dropped (unlocked) and the RwLock will be poisoned.
#[doc(alias = "filter_map")]
#[unstable(feature = "mapped_lock_guards", issue = "117108")]
pub fn try_map<U, F>(mut orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
pub fn filter_map<U, F>(mut orig: Self, f: F) -> Result<MappedRwLockWriteGuard<'a, U>, Self>
where
F: FnOnce(&mut T) -> Option<&mut U>,
U: ?Sized,
{
// SAFETY: the conditions of `RwLockWriteGuard::new` were satisfied when the original guard
// was created, and have been upheld throughout `map` and/or `try_map`.
// was created, and have been upheld throughout `map` and/or `filter_map`.
// The signature of the closure guarantees that it will not "leak" the lifetime of the reference
// passed to it. If the closure panics, the guard will be dropped.
match f(unsafe { orig.data.as_mut() }) {
Expand Down
14 changes: 8 additions & 6 deletions library/std/tests/sync/mutex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,13 +409,13 @@ fn panic_while_mapping_unlocked_poison() {

let _ = panic::catch_unwind(|| {
let guard = lock.lock().unwrap();
let _guard = MutexGuard::try_map::<(), _>(guard, |_| panic!());
let _guard = MutexGuard::filter_map::<(), _>(guard, |_| panic!());
});

match lock.try_lock() {
Ok(_) => panic!("panicking in a MutexGuard::try_map closure should poison the Mutex"),
Ok(_) => panic!("panicking in a MutexGuard::filter_map closure should poison the Mutex"),
Err(TryLockError::WouldBlock) => {
panic!("panicking in a MutexGuard::try_map closure should unlock the mutex")
panic!("panicking in a MutexGuard::filter_map closure should unlock the mutex")
}
Err(TryLockError::Poisoned(_)) => {}
}
Expand All @@ -437,13 +437,15 @@ fn panic_while_mapping_unlocked_poison() {
let _ = panic::catch_unwind(|| {
let guard = lock.lock().unwrap();
let guard = MutexGuard::map::<(), _>(guard, |val| val);
let _guard = MappedMutexGuard::try_map::<(), _>(guard, |_| panic!());
let _guard = MappedMutexGuard::filter_map::<(), _>(guard, |_| panic!());
});

match lock.try_lock() {
Ok(_) => panic!("panicking in a MappedMutexGuard::try_map closure should poison the Mutex"),
Ok(_) => {
panic!("panicking in a MappedMutexGuard::filter_map closure should poison the Mutex")
}
Err(TryLockError::WouldBlock) => {
panic!("panicking in a MappedMutexGuard::try_map closure should unlock the mutex")
panic!("panicking in a MappedMutexGuard::filter_map closure should unlock the mutex")
}
Err(TryLockError::Poisoned(_)) => {}
}
Expand Down
Loading
Loading