Repository: rust
Issue: Tracking Issue for `sync_nonpoison` and `nonpoison_{condvar,mutex,once,rwlock}`
Labels: E-hard,T-libs-api,E-help-wanted,C-tracking-issue

Feature gates: 

- `#![feature(sync_nonpoison)]`
- `#![feature(nonpoison_condvar)]`
- `#![feature(nonpoison_mutex)]`
- `#![feature(nonpoison_once)]`
- `#![feature(nonpoison_rwlock)]`

This is a tracking issue for versions of synchronization primitives that do not not need to worry about poison.

### Public API

#### `sync_nonpoison`

The module itself and common types will be gated by this feature:

```rust
// std::sync

mod nonpoison {
    pub type TryLockResult<Guard> = Result<Guard, WouldBlock>;
    
    // Error type for failed locking
    pub struct WouldBlock;
}
```

#### `nonpoison_condvar`

```rust
// std::sync::nonpoison

pub struct Condvar { /* ... */ }

impl Condvar {
    pub const fn new() -> Self;
    pub fn wait<'a, T>(&self, guard: MutexGuard<'a, T>) -> MutexGuard<'a, T>;
    pub fn notify_one(&self);
    pub fn notify_all(&self);

    pub fn wait_while<'a, T, F>(
        &self,
        guard: MutexGuard<'a, T>,
        condition: F,
    ) -> MutexGuard<'a, T>
    where
        F: FnMut(&mut T) -> bool;

    pub fn wait_timeout<'a, T>(
        &self,
        guard: MutexGuard<'a, T>,
        dur: Duration,
    ) -> (MutexGuard<'a, T>, WaitTimeoutResult);

    pub fn wait_timeout_while<'a, T, F>(
        &self,
        guard: MutexGuard<'a, T>,
        dur: Duration,
        condition: F,
    ) -> (MutexGuard<'a, T>, WaitTimeoutResult)
    where
        F: FnMut(&mut T) -> bool;
}

/* trait implementations from `std::sync::poison::Condvar` */
```

#### `nonpoison_mutex`

```rust
// std::sync::nonpoison

pub struct Mutex<T: ?Sized> { /* ... */ }

impl<T> Mutex<T> {
    pub const fn new(t: T) -> Self;
}

impl<T: ?Sized> Mutex<T> {
    pub fn lock(&self) -> MutexGuard<'_, T>;
    pub fn try_lock(&self) -> TryLockResult<MutexGuard<'_, T>>;
    pub fn get_mut(&mut self) -> &mut T;
    pub fn into_inner(self) -> T
    where
        T: Sized;
}

/* trait implementations from `std::sync::poison::Mutex` */

pub struct MutexGuard<'a, T: ?Sized + 'a> { /* ... */ }

impl<'a, T: ?Sized> MutexGuard<'a, T> {
    // Unstable API from `mapped_lock_guards`
}

/* trait implementations from `std::sync::poison::MutexGuard` */

// Currently unstable under `mapped_lock_guards`, see that tracking issue for more
pub struct MappedMutexGuard<'a, T: ?Sized + 'a> { /* ... */ }
```

#### `nonpoison_once`

```rust
// std::sync::nonpoison

pub struct Once { /* ... */ }

impl Once {
    pub const fn new() -> Self;
    pub fn call_once<F: FnOnce()>(&self, f: F);
    pub fn call_once_force<F: FnOnce(&OnceState)>(&self, f: F)
    pub fn is_completed(&self) -> bool
   
    // Currently unstable from `once_wait`
    pub fn wait(&self);
}

/* trait implementations from `std::sync::poison::Once` */
```

#### `nonpoison_rwlock`

```rust
// std::sync::nonpoison

pub struct RwLock<T: ?Sized> { /* ... */ }

impl<T> RwLock<T> {
    pub const fn new(t: T) -> Self;
}

impl<T: ?Sized> RwLock<T> {
    pub fn read(&self) -> RwLockReadGuard<'_, T>;
    pub fn try_read(&self) -> TryLockResult<RwLockReadGuard<'_, T>>;
    pub fn write(&self) -> RwLockWriteGuard<'_, T>;
    pub fn try_write(&self) -> TryLockResult<RwLockWriteGuard<'_, T>>;
    pub fn get_mut(&mut self) -> &mut T;
    pub fn into_inner(self) -> T
    where
        T: Sized;
}

/* trait implementations from `std::sync::poison::RwLock` */

pub struct RwLockReadGuard<'a, T: ?Sized + 'a> { /* private fields */ }

impl<'a, T: ?Sized> RwLockReadGuard<'a, T> {
    // Unstable API from `mapped_lock_guards`
}

/* trait implementations from `std::sync::poison::RwLockReadGuard` */

impl<'a, T: ?Sized> RwLockWriteGuard<'a, T> {
    // Unstable API from `mapped_lock_guards`
}

/* trait implementations from `std::sync::poison::RwLockWriteGuard` */

// Currently unstable under `mapped_lock_guards`, see that tracking issue for more
pub struct MappedRwLockReadGuard<'a, T: ?Sized + 'a> { /* ... */ }
pub struct MappedRwLockReadGuard<'a, T: ?Sized + 'a> { /* ... */ }
```

### Steps / History

- [ ] ACP: https://github.com/rust-lang/libs-team/issues/169
- [ ] Implementation: #...
- [ ] Final comment period (FCP)[^1]
- [ ] Stabilization PR

### Unresolved Questions

- Should existing types without poison be moved to this module? `Barrier`, `LazyLock`, `OnceLock`, `ReentrantLock` 

### Related

- Move all existing poisonable types to `std::sync::poison` and reexport them https://github.com/rust-lang/rust/issues/134646
- The unstable `ReentrantLock` currently does not support poisoning https://github.com/rust-lang/rust/issues/121440
- `mapped_lock_guards` adds API to the guard types https://github.com/rust-lang/rust/issues/117108

[^1]: https://std-dev-guide.rust-lang.org/feature-lifecycle/stabilization.html