@@ -15,6 +15,8 @@ use crate::prelude::*;
1515use crate :: task:: { spawn_blocking, Context , Poll , Waker } ;
1616use crate :: utils:: Context as _;
1717
18+ const ARC_TRY_UNWRAP_EXPECT : & str = "cannot acquire ownership of the file handle after drop" ;
19+ 1820/// An open file on the filesystem.
1921///
2022/// Depending on what options the file was opened with, this type can be used for reading and/or
@@ -415,6 +417,15 @@ impl From<std::fs::File> for File {
415417cfg_unix ! {
416418 use crate :: os:: unix:: io:: { AsRawFd , FromRawFd , IntoRawFd , RawFd } ;
417419
420+ impl File {
421+ fn into_std_file( self ) -> std:: fs:: File {
422+ let file = self . file. clone( ) ;
423+ drop( self ) ;
424+ Arc :: try_unwrap( file)
425+ . expect( ARC_TRY_UNWRAP_EXPECT )
426+ }
427+ }
428+ 418429 impl AsRawFd for File {
419430 fn as_raw_fd( & self ) -> RawFd {
420431 self . file. as_raw_fd( )
@@ -429,11 +440,29 @@ cfg_unix! {
429440
430441 impl IntoRawFd for File {
431442 fn into_raw_fd( self ) -> RawFd {
432- let file = self . file. clone( ) ;
433- drop( self ) ;
434- Arc :: try_unwrap( file)
435- . expect( "cannot acquire ownership of the file handle after drop" )
436- . into_raw_fd( )
443+ self . into_std_file( ) . into_raw_fd( )
444+ }
445+ }
446+ 447+ cfg_io_safety! {
448+ use crate :: os:: unix:: io:: { AsFd , BorrowedFd , OwnedFd } ;
449+ 450+ impl AsFd for File {
451+ fn as_fd( & self ) -> BorrowedFd <' _> {
452+ self . file. as_fd( )
453+ }
454+ }
455+ 456+ impl From <OwnedFd > for File {
457+ fn from( fd: OwnedFd ) -> Self {
458+ std:: fs:: File :: from( fd) . into( )
459+ }
460+ }
461+ 462+ impl From <File > for OwnedFd {
463+ fn from( val: File ) -> OwnedFd {
464+ self . into_std_file( ) . into( )
465+ }
437466 }
438467 }
439468}
@@ -458,10 +487,36 @@ cfg_windows! {
458487 let file = self . file. clone( ) ;
459488 drop( self ) ;
460489 Arc :: try_unwrap( file)
461- . expect( "cannot acquire ownership of the file handle after drop" )
490+ . expect( ARC_TRY_UNWRAP_EXPECT )
462491 . into_raw_handle( )
463492 }
464493 }
494+ 495+ cfg_io_safety! {
496+ use crate :: os:: windows:: io:: { AsHandle , BorrowedHandle , OwnedHandle } ;
497+ 498+ impl AsHandle for File {
499+ fn as_handle( & self ) -> BorrowedHandle <' _> {
500+ self . file. as_handle( )
501+ }
502+ }
503+ 504+ impl From <OwnedHandle > for File {
505+ fn from( handle: OwnedHandle ) -> Self {
506+ std:: fs:: File :: from( handle) . into( )
507+ }
508+ }
509+ 510+ impl From <File > for OwnedHandle {
511+ fn from( val: File ) -> OwnedHandle {
512+ let file = val. file. clone( ) ;
513+ drop( val) ;
514+ Arc :: try_unwrap( file)
515+ . expect( ARC_TRY_UNWRAP_EXPECT )
516+ . into( )
517+ }
518+ }
519+ }
465520}
466521
467522/// An async mutex with non-borrowing lock guards.
0 commit comments