@@ -536,10 +536,14 @@ impl Stream for Timer {
536
536
/// [`async-process`] (on Unix).
537
537
///
538
538
/// 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.
540
542
///
541
543
/// [`async-net`]: https://github.com/smol-rs/async-net
542
544
/// [`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
543
547
///
544
548
/// ### Supported types
545
549
///
@@ -1145,9 +1149,37 @@ impl<T> Drop for Async<T> {
1145
1149
1146
1150
/// Types whose I/O trait implementations do not drop the underlying I/O source.
1147
1151
///
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
+ ///
1148
1166
/// # Safety
1149
1167
///
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
1151
1183
pub unsafe trait IoSafe { }
1152
1184
1153
1185
// Reference types can't be mutated.
0 commit comments