@@ -537,10 +537,6 @@ impl Stream for Timer {
537537/// For higher-level primitives built on top of [`Async`], look into [`async-net`] or
538538/// [`async-process`] (on Unix).
539539///
540- /// The most notable caveat is that it is unsafe to access the inner I/O source mutably
541- /// using this primitive. Traits likes [`AsyncRead`] and [`AsyncWrite`] are not implemented by
542- /// default unless it is guaranteed that the resource won't be invalidated by reading or writing.
543- /// See the [`IoSafe`] trait for more information.
544540///
545541/// [`async-net`]: https://github.com/smol-rs/async-net
546542/// [`async-process`]: https://github.com/smol-rs/async-process
@@ -680,9 +676,7 @@ impl<T: AsFd> Async<T> {
680676 /// it is not set. If not set to non-blocking mode, I/O operations may block the current thread
681677 /// and cause a deadlock in an asynchronous context.
682678 pub fn new_nonblocking ( io : T ) -> io:: Result < Async < T > > {
683- // SAFETY: It is impossible to drop the I/O source while it is registered through
684- // this type.
685- let registration = unsafe { Registration :: new ( io. as_fd ( ) ) } ;
679+ let registration = Registration :: new ( io. as_fd ( ) ) ;
686680
687681 Ok ( Async {
688682 source : Reactor :: get ( ) . insert_io ( registration) ?,
@@ -839,10 +833,6 @@ impl<T> Async<T> {
839833
840834 /// Gets a mutable reference to the inner I/O handle.
841835 ///
842- /// # Safety
843- ///
844- /// The underlying I/O source must not be dropped using this function.
845- ///
846836 /// # Examples
847837 ///
848838 /// ```
@@ -851,10 +841,10 @@ impl<T> Async<T> {
851841 ///
852842 /// # futures_lite::future::block_on(async {
853843 /// let mut listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 0))?;
854- /// let inner = unsafe { listener.get_mut() } ;
844+ /// let inner = listener.get_mut();
855845 /// # std::io::Result::Ok(()) });
856846 /// ```
857- pub unsafe fn get_mut ( & mut self ) -> & mut T {
847+ pub fn get_mut ( & mut self ) -> & mut T {
858848 self . io . as_mut ( ) . unwrap ( )
859849 }
860850
@@ -1044,10 +1034,6 @@ impl<T> Async<T> {
10441034 ///
10451035 /// The closure receives a mutable reference to the I/O handle.
10461036 ///
1047- /// # Safety
1048- ///
1049- /// In the closure, the underlying I/O source must not be dropped.
1050- ///
10511037 /// # Examples
10521038 ///
10531039 /// ```no_run
@@ -1058,10 +1044,10 @@ impl<T> Async<T> {
10581044 /// let mut listener = Async::<TcpListener>::bind(([127, 0, 0, 1], 0))?;
10591045 ///
10601046 /// // Accept a new client asynchronously.
1061- /// let (stream, addr) = unsafe { listener.read_with_mut(|l| l.accept()).await? } ;
1047+ /// let (stream, addr) = listener.read_with_mut(|l| l.accept()).await?;
10621048 /// # std::io::Result::Ok(()) });
10631049 /// ```
1064- pub async unsafe fn read_with_mut < R > (
1050+ pub async fn read_with_mut < R > (
10651051 & mut self ,
10661052 op : impl FnMut ( & mut T ) -> io:: Result < R > ,
10671053 ) -> io:: Result < R > {
@@ -1116,11 +1102,6 @@ impl<T> Async<T> {
11161102 /// [`io::ErrorKind::WouldBlock`]. In between iterations of the loop, it waits until the OS
11171103 /// sends a notification that the I/O handle is writable.
11181104 ///
1119- /// # Safety
1120- ///
1121- /// The closure receives a mutable reference to the I/O handle. In the closure, the underlying
1122- /// I/O source must not be dropped.
1123- ///
11241105 /// # Examples
11251106 ///
11261107 /// ```no_run
@@ -1132,10 +1113,10 @@ impl<T> Async<T> {
11321113 /// socket.get_ref().connect("127.0.0.1:9000")?;
11331114 ///
11341115 /// let msg = b"hello";
1135- /// let len = unsafe { socket.write_with_mut(|s| s.send(msg)).await? } ;
1116+ /// let len = socket.write_with_mut(|s| s.send(msg)).await?;
11361117 /// # std::io::Result::Ok(()) });
11371118 /// ```
1138- pub async unsafe fn write_with_mut < R > (
1119+ pub async fn write_with_mut < R > (
11391120 & mut self ,
11401121 op : impl FnMut ( & mut T ) -> io:: Result < R > ,
11411122 ) -> io:: Result < R > {
@@ -1170,19 +1151,9 @@ impl<T> Drop for Async<T> {
11701151
11711152/// Types whose I/O trait implementations do not drop the underlying I/O source.
11721153///
1173- /// The resource contained inside of the [`Async`] cannot be invalidated. This invalidation can
1174- /// happen if the inner resource (the [`TcpStream`], [`UnixListener`] or other `T`) is moved out
1175- /// and dropped before the [`Async`]. Because of this, functions that grant mutable access to
1176- /// the inner type are unsafe, as there is no way to guarantee that the source won't be dropped
1177- /// and a dangling handle won't be left behind.
1178- ///
1179- /// Unfortunately this extends to implementations of [`Read`] and [`Write`]. Since methods on those
1180- /// traits take `&mut`, there is no guarantee that the implementor of those traits won't move the
1181- /// source out while the method is being run.
1182- ///
1183- /// This trait is an antidote to this predicament. By implementing this trait, the user pledges
1184- /// that using any I/O traits won't destroy the source. This way, [`Async`] can implement the
1185- /// `async` version of these I/O traits, like [`AsyncRead`] and [`AsyncWrite`].
1154+ /// Previously, this constraint was used to ensure only certain I/O sources could
1155+ /// be used with [`Async`]. But this constraint no longer applies, so this trait is
1156+ /// now deprecated.
11861157///
11871158/// # Safety
11881159///
@@ -1201,6 +1172,7 @@ impl<T> Drop for Async<T> {
12011172///
12021173/// [`AsyncRead`]: https://docs.rs/futures-io/latest/futures_io/trait.AsyncRead.html
12031174/// [`AsyncWrite`]: https://docs.rs/futures-io/latest/futures_io/trait.AsyncWrite.html
1175+ #[ deprecated = "this trait is now no longer required" ]
12041176pub unsafe trait IoSafe { }
12051177
12061178/// Reference types can't be mutated.
@@ -1234,46 +1206,67 @@ pub unsafe trait IoSafe {}
12341206///
12351207/// We solve this problem by only calling `as_fd()` once to get the original source. Implementations
12361208/// like this are considered buggy (but not unsound) and are thus not really supported by `async-io`.
1209+ #[ allow( deprecated) ]
12371210unsafe impl < T : ?Sized > IoSafe for & T { }
12381211
12391212// Can be implemented on top of libstd types.
1213+ #[ allow( deprecated) ]
12401214unsafe impl IoSafe for std:: fs:: File { }
1215+ #[ allow( deprecated) ]
12411216unsafe impl IoSafe for std:: io:: Stderr { }
1217+ #[ allow( deprecated) ]
12421218unsafe impl IoSafe for std:: io:: Stdin { }
1219+ #[ allow( deprecated) ]
12431220unsafe impl IoSafe for std:: io:: Stdout { }
1221+ #[ allow( deprecated) ]
12441222unsafe impl IoSafe for std:: io:: StderrLock < ' _ > { }
1223+ #[ allow( deprecated) ]
12451224unsafe impl IoSafe for std:: io:: StdinLock < ' _ > { }
1225+ #[ allow( deprecated) ]
12461226unsafe impl IoSafe for std:: io:: StdoutLock < ' _ > { }
1227+ #[ allow( deprecated) ]
12471228unsafe impl IoSafe for std:: net:: TcpStream { }
1229+ #[ allow( deprecated) ]
12481230unsafe impl IoSafe for std:: process:: ChildStdin { }
1231+ #[ allow( deprecated) ]
12491232unsafe impl IoSafe for std:: process:: ChildStdout { }
1233+ #[ allow( deprecated) ]
12501234unsafe impl IoSafe for std:: process:: ChildStderr { }
12511235
12521236#[ cfg( unix) ]
1237+ #[ allow( deprecated) ]
12531238unsafe impl IoSafe for std:: os:: unix:: net:: UnixStream { }
12541239
12551240// PipeReader & PipeWriter require std >= 1.87, our MSRV is 1.71, hence
12561241// conditional on cfg()s, generated from build.rs
12571242#[ cfg( not( async_io_no_pipe) ) ]
1243+ #[ allow( deprecated) ]
12581244unsafe impl IoSafe for std:: io:: PipeReader { }
12591245#[ cfg( not( async_io_no_pipe) ) ]
1246+ #[ allow( deprecated) ]
12601247unsafe impl IoSafe for std:: io:: PipeWriter { }
12611248
1249+ #[ allow( deprecated) ]
12621250unsafe impl < T : IoSafe + Read > IoSafe for std:: io:: BufReader < T > { }
1251+ #[ allow( deprecated) ]
12631252unsafe impl < T : IoSafe + Write > IoSafe for std:: io:: BufWriter < T > { }
1253+ #[ allow( deprecated) ]
12641254unsafe impl < T : IoSafe + Write > IoSafe for std:: io:: LineWriter < T > { }
1255+ #[ allow( deprecated) ]
12651256unsafe impl < T : IoSafe + ?Sized > IoSafe for & mut T { }
1257+ #[ allow( deprecated) ]
12661258unsafe impl < T : IoSafe + ?Sized > IoSafe for Box < T > { }
1259+ #[ allow( deprecated) ]
12671260unsafe impl < T : Clone + IoSafe > IoSafe for std:: borrow:: Cow < ' _ , T > { }
12681261
1269- impl < T : IoSafe + Read > AsyncRead for Async < T > {
1262+ impl < T : Read > AsyncRead for Async < T > {
12701263 fn poll_read (
12711264 mut self : Pin < & mut Self > ,
12721265 cx : & mut Context < ' _ > ,
12731266 buf : & mut [ u8 ] ,
12741267 ) -> Poll < io:: Result < usize > > {
12751268 loop {
1276- match unsafe { ( * self ) . get_mut ( ) } . read ( buf) {
1269+ match ( * self ) . get_mut ( ) . read ( buf) {
12771270 Err ( err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => { }
12781271 res => return Poll :: Ready ( res) ,
12791272 }
@@ -1287,7 +1280,7 @@ impl<T: IoSafe + Read> AsyncRead for Async<T> {
12871280 bufs : & mut [ IoSliceMut < ' _ > ] ,
12881281 ) -> Poll < io:: Result < usize > > {
12891282 loop {
1290- match unsafe { ( * self ) . get_mut ( ) } . read_vectored ( bufs) {
1283+ match ( * self ) . get_mut ( ) . read_vectored ( bufs) {
12911284 Err ( err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => { }
12921285 res => return Poll :: Ready ( res) ,
12931286 }
@@ -1331,14 +1324,14 @@ where
13311324 }
13321325}
13331326
1334- impl < T : IoSafe + Write > AsyncWrite for Async < T > {
1327+ impl < T : Write > AsyncWrite for Async < T > {
13351328 fn poll_write (
13361329 mut self : Pin < & mut Self > ,
13371330 cx : & mut Context < ' _ > ,
13381331 buf : & [ u8 ] ,
13391332 ) -> Poll < io:: Result < usize > > {
13401333 loop {
1341- match unsafe { ( * self ) . get_mut ( ) } . write ( buf) {
1334+ match ( * self ) . get_mut ( ) . write ( buf) {
13421335 Err ( err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => { }
13431336 res => return Poll :: Ready ( res) ,
13441337 }
@@ -1352,7 +1345,7 @@ impl<T: IoSafe + Write> AsyncWrite for Async<T> {
13521345 bufs : & [ IoSlice < ' _ > ] ,
13531346 ) -> Poll < io:: Result < usize > > {
13541347 loop {
1355- match unsafe { ( * self ) . get_mut ( ) } . write_vectored ( bufs) {
1348+ match ( * self ) . get_mut ( ) . write_vectored ( bufs) {
13561349 Err ( err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => { }
13571350 res => return Poll :: Ready ( res) ,
13581351 }
@@ -1362,7 +1355,7 @@ impl<T: IoSafe + Write> AsyncWrite for Async<T> {
13621355
13631356 fn poll_flush ( mut self : Pin < & mut Self > , cx : & mut Context < ' _ > ) -> Poll < io:: Result < ( ) > > {
13641357 loop {
1365- match unsafe { ( * self ) . get_mut ( ) } . flush ( ) {
1358+ match ( * self ) . get_mut ( ) . flush ( ) {
13661359 Err ( err) if err. kind ( ) == io:: ErrorKind :: WouldBlock => { }
13671360 res => return Poll :: Ready ( res) ,
13681361 }
0 commit comments