@@ -78,6 +78,17 @@ const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = {
7878 ( "EAGAIN" , WouldBlock ) ,
7979 ]
8080} ;
81+ // This mapping should match `decode_error_kind` in
82+ // <https://github.com/rust-lang/rust/blob/master/library/std/src/sys/pal/windows/mod.rs>.
83+ const WINDOWS_IO_ERROR_TABLE : & [ ( & str , std:: io:: ErrorKind ) ] = {
84+ use std:: io:: ErrorKind :: * ;
85+ // FIXME: this is still incomplete.
86+ & [
87+ ( "ERROR_ACCESS_DENIED" , PermissionDenied ) ,
88+ ( "ERROR_FILE_NOT_FOUND" , NotFound ) ,
89+ ( "ERROR_INVALID_PARAMETER" , InvalidInput ) ,
90+ ]
91+ } ;
8192
8293/// Gets an instance for a path.
8394///
@@ -712,20 +723,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
712723 }
713724 throw_unsup_format ! ( "io error {:?} cannot be translated into a raw os error" , err_kind)
714725 } else if target. families . iter ( ) . any ( |f| f == "windows" ) {
715- // FIXME: we have to finish implementing the Windows equivalent of this.
716- use std:: io:: ErrorKind :: * ;
717- Ok ( this. eval_windows (
718- "c" ,
719- match err_kind {
720- NotFound => "ERROR_FILE_NOT_FOUND" ,
721- PermissionDenied => "ERROR_ACCESS_DENIED" ,
722- _ =>
723- throw_unsup_format ! (
724- "io error {:?} cannot be translated into a raw os error" ,
725- err_kind
726- ) ,
727- } ,
728- ) )
726+ for & ( name, kind) in WINDOWS_IO_ERROR_TABLE {
727+ if err_kind == kind {
728+ return Ok ( this. eval_windows ( "c" , name) ) ;
729+ }
730+ }
731+ throw_unsup_format ! ( "io error {:?} cannot be translated into a raw os error" , err_kind) ;
729732 } else {
730733 throw_unsup_format ! (
731734 "converting io::Error into errnum is unsupported for OS {}" ,
@@ -749,8 +752,14 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
749752 return Ok ( Some ( kind) ) ;
750753 }
751754 }
752- // Our table is as complete as the mapping in std, so we are okay with saying "that's a
753- // strange one" here.
755+ return Ok ( None ) ;
756+ } else if target. families . iter ( ) . any ( |f| f == "windows" ) {
757+ let errnum = errnum. to_u32 ( ) ?;
758+ for & ( name, kind) in WINDOWS_IO_ERROR_TABLE {
759+ if errnum == this. eval_windows ( "c" , name) . to_u32 ( ) ? {
760+ return Ok ( Some ( kind) ) ;
761+ }
762+ }
754763 return Ok ( None ) ;
755764 } else {
756765 throw_unsup_format ! (
0 commit comments