Skip to content

Commit ea3a4bc

Browse files
committed
Add more documentation to IoSafe
Signed-off-by: John Nunley <[email protected]>
1 parent a28d13c commit ea3a4bc

File tree

1 file changed

+34
-2
lines changed

1 file changed

+34
-2
lines changed

src/lib.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -536,10 +536,14 @@ impl Stream for Timer {
536536
/// [`async-process`] (on Unix).
537537
///
538538
/// The most notable caveat is that it is unsafe to access the inner I/O source mutably
539-
/// using this function.
539+
/// using this primitive. Traits likes [`AsyncRead`] and [`AsyncWrite`] are not implemented by
540+
/// default unless it is guaranteed that the resource won't be invalidated by reading or writing.
541+
/// See the [`IoSafe`] trait for more information.
540542
///
541543
/// [`async-net`]: https://github.com/smol-rs/async-net
542544
/// [`async-process`]: https://github.com/smol-rs/async-process
545+
/// [`AsyncRead`]: https://docs.rs/futures-io/latest/futures_io/trait.AsyncRead.html
546+
/// [`AsyncWrite`]: https://docs.rs/futures-io/latest/futures_io/trait.AsyncWrite.html
543547
///
544548
/// ### Supported types
545549
///
@@ -1145,9 +1149,37 @@ impl<T> Drop for Async<T> {
11451149

11461150
/// Types whose I/O trait implementations do not drop the underlying I/O source.
11471151
///
1152+
/// The resource contained inside of the [`Async`] cannot be invalidated. This invalidation can
1153+
/// happen if the inner resource (the [`TcpStream`], [`UnixListener`] or other `T`) is moved out
1154+
/// and dropped before the [`Async`]. Because of this, functions that grant mutable access to
1155+
/// the inner type are unsafe, as there is no way to guarantee that the source won't be dropped
1156+
/// and a dangling pointer won't be left behind.
1157+
///
1158+
/// Unfortunately this extends to implementations of [`Read`] and [`Write`]. Since methods on those
1159+
/// traits take `&mut`, there is no guarantee that the implementor of those traits won't move the
1160+
/// source out while the method is being run.
1161+
///
1162+
/// This trait is an antidote to this predicament. By implementing this trait, it is guaranteed
1163+
/// that using any I/O traits won't desroy the source. This way, [`Async`] can implement the
1164+
/// `async` version of these I/O traits, like [`AsyncRead`], [`AsyncWrite`] and [`AsyncSeek`].
1165+
///
11481166
/// # Safety
11491167
///
1150-
/// Any I/O trait implementations for this type must not drop the underlying I/O source.
1168+
/// Any I/O trait implementations for this type must not drop the underlying I/O source. Traits
1169+
/// affected by this trait include [`Read`], [`Write`] and [`Seek`].
1170+
///
1171+
/// This trait is implemented by default on top of `libstd` types. In addition, it is implemented
1172+
/// for immutable reference types, as it is impossible to invalidate any outstanding references
1173+
/// while holding an immutable reference, even with interior mutability. As Rust's current pinning
1174+
/// system relies on similar guarantees, I believe that this approach is robust.
1175+
///
1176+
/// [`Read`]: https://doc.rust-lang.org/std/io/trait.Read.html
1177+
/// [`Seek`]: https://doc.rust-lang.org/std/io/trait.Seek.html
1178+
/// [`Write`]: https://doc.rust-lang.org/std/io/trait.Write.html
1179+
///
1180+
/// [`AsyncRead`]: https://docs.rs/futures-io/latest/futures_io/trait.AsyncRead.html
1181+
/// [`AsyncSeek`]: https://docs.rs/futures-io/latest/futures_io/trait.AsyncSeek.html
1182+
/// [`AsyncWrite`]: https://docs.rs/futures-io/latest/futures_io/trait.AsyncWrite.html
11511183
pub unsafe trait IoSafe {}
11521184

11531185
// Reference types can't be mutated.

0 commit comments

Comments
 (0)