Skip to content

Commit d9188da

Browse files
committed
Auto merge of #3589 - RalfJung:io-error, r=RalfJung
io::Error handling: keep around the full io::Error for longer so we can give better errors This should help with the error message in #3587.
2 parents 28ab963 + 9bea173 commit d9188da

File tree

6 files changed

+31
-34
lines changed

6 files changed

+31
-34
lines changed

src/helpers.rs

+8-11
Original file line numberDiff line numberDiff line change
@@ -751,26 +751,23 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
751751

752752
/// This function tries to produce the most similar OS error from the `std::io::ErrorKind`
753753
/// as a platform-specific errnum.
754-
fn io_error_to_errnum(
755-
&self,
756-
err_kind: std::io::ErrorKind,
757-
) -> InterpResult<'tcx, Scalar<Provenance>> {
754+
fn io_error_to_errnum(&self, err: std::io::Error) -> InterpResult<'tcx, Scalar<Provenance>> {
758755
let this = self.eval_context_ref();
759756
let target = &this.tcx.sess.target;
760757
if target.families.iter().any(|f| f == "unix") {
761758
for &(name, kind) in UNIX_IO_ERROR_TABLE {
762-
if err_kind == kind {
759+
if err.kind() == kind {
763760
return Ok(this.eval_libc(name));
764761
}
765762
}
766-
throw_unsup_format!("io error {:?} cannot be translated into a raw os error", err_kind)
763+
throw_unsup_format!("unsupported io error: {err}")
767764
} else if target.families.iter().any(|f| f == "windows") {
768765
for &(name, kind) in WINDOWS_IO_ERROR_TABLE {
769-
if err_kind == kind {
766+
if err.kind() == kind {
770767
return Ok(this.eval_windows("c", name));
771768
}
772769
}
773-
throw_unsup_format!("io error {:?} cannot be translated into a raw os error", err_kind);
770+
throw_unsup_format!("unsupported io error: {err}");
774771
} else {
775772
throw_unsup_format!(
776773
"converting io::Error into errnum is unsupported for OS {}",
@@ -812,8 +809,8 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
812809
}
813810

814811
/// Sets the last OS error using a `std::io::ErrorKind`.
815-
fn set_last_error_from_io_error(&mut self, err_kind: std::io::ErrorKind) -> InterpResult<'tcx> {
816-
self.set_last_error(self.io_error_to_errnum(err_kind)?)
812+
fn set_last_error_from_io_error(&mut self, err: std::io::Error) -> InterpResult<'tcx> {
813+
self.set_last_error(self.io_error_to_errnum(err)?)
817814
}
818815

819816
/// Helper function that consumes an `std::io::Result<T>` and returns an
@@ -829,7 +826,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
829826
match result {
830827
Ok(ok) => Ok(ok),
831828
Err(e) => {
832-
self.eval_context_mut().set_last_error_from_io_error(e.kind())?;
829+
self.eval_context_mut().set_last_error_from_io_error(e)?;
833830
Ok((-1).into())
834831
}
835832
}

src/shims/unix/env.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -228,7 +228,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
228228

229229
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
230230
this.reject_in_isolation("`getcwd`", reject_with)?;
231-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
231+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
232232
return Ok(Pointer::null());
233233
}
234234

@@ -241,7 +241,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
241241
let erange = this.eval_libc("ERANGE");
242242
this.set_last_error(erange)?;
243243
}
244-
Err(e) => this.set_last_error_from_io_error(e.kind())?,
244+
Err(e) => this.set_last_error_from_io_error(e)?,
245245
}
246246

247247
Ok(Pointer::null())
@@ -255,15 +255,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
255255

256256
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
257257
this.reject_in_isolation("`chdir`", reject_with)?;
258-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
258+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
259259

260260
return Ok(-1);
261261
}
262262

263263
match env::set_current_dir(path) {
264264
Ok(()) => Ok(0),
265265
Err(e) => {
266-
this.set_last_error_from_io_error(e.kind())?;
266+
this.set_last_error_from_io_error(e)?;
267267
Ok(-1)
268268
}
269269
}

src/shims/unix/fd.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -312,7 +312,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
312312
// Reject if isolation is enabled.
313313
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
314314
this.reject_in_isolation("`fcntl`", reject_with)?;
315-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
315+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
316316
return Ok(-1);
317317
}
318318

@@ -394,7 +394,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
394394
Ok(read_bytes)
395395
}
396396
Err(e) => {
397-
this.set_last_error_from_io_error(e.kind())?;
397+
this.set_last_error_from_io_error(e)?;
398398
Ok(-1)
399399
}
400400
}

src/shims/unix/fs.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -378,7 +378,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
378378
// Reject if isolation is enabled.
379379
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
380380
this.reject_in_isolation("`open`", reject_with)?;
381-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
381+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
382382
return Ok(-1);
383383
}
384384

@@ -434,7 +434,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
434434
// Reject if isolation is enabled.
435435
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
436436
this.reject_in_isolation("`unlink`", reject_with)?;
437-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
437+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
438438
return Ok(-1);
439439
}
440440

@@ -465,7 +465,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
465465
// Reject if isolation is enabled.
466466
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
467467
this.reject_in_isolation("`symlink`", reject_with)?;
468-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
468+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
469469
return Ok(-1);
470470
}
471471

@@ -766,7 +766,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
766766
// Reject if isolation is enabled.
767767
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
768768
this.reject_in_isolation("`rename`", reject_with)?;
769-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
769+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
770770
return Ok(-1);
771771
}
772772

@@ -794,7 +794,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
794794
// Reject if isolation is enabled.
795795
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
796796
this.reject_in_isolation("`mkdir`", reject_with)?;
797-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
797+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
798798
return Ok(-1);
799799
}
800800

@@ -822,7 +822,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
822822
// Reject if isolation is enabled.
823823
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
824824
this.reject_in_isolation("`rmdir`", reject_with)?;
825-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
825+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
826826
return Ok(-1);
827827
}
828828

@@ -859,7 +859,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
859859
Ok(Scalar::from_target_usize(id, this))
860860
}
861861
Err(e) => {
862-
this.set_last_error_from_io_error(e.kind())?;
862+
this.set_last_error_from_io_error(e)?;
863863
Ok(Scalar::null_ptr(this))
864864
}
865865
}
@@ -947,7 +947,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
947947
None
948948
}
949949
Some(Err(e)) => {
950-
this.set_last_error_from_io_error(e.kind())?;
950+
this.set_last_error_from_io_error(e)?;
951951
None
952952
}
953953
};
@@ -1299,7 +1299,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
12991299
Ok(path_bytes.len().try_into().unwrap())
13001300
}
13011301
Err(e) => {
1302-
this.set_last_error_from_io_error(e.kind())?;
1302+
this.set_last_error_from_io_error(e)?;
13031303
Ok(-1)
13041304
}
13051305
}
@@ -1382,7 +1382,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
13821382
Ok(Scalar::from_maybe_pointer(dest, this))
13831383
}
13841384
Err(e) => {
1385-
this.set_last_error_from_io_error(e.kind())?;
1385+
this.set_last_error_from_io_error(e)?;
13861386
Ok(Scalar::from_target_usize(0, this))
13871387
}
13881388
}
@@ -1503,7 +1503,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
15031503
_ => {
15041504
// "On error, -1 is returned, and errno is set to
15051505
// indicate the error"
1506-
this.set_last_error_from_io_error(e.kind())?;
1506+
this.set_last_error_from_io_error(e)?;
15071507
return Ok(-1);
15081508
}
15091509
},
@@ -1582,7 +1582,7 @@ impl FileMetadata {
15821582
let metadata = match metadata {
15831583
Ok(metadata) => metadata,
15841584
Err(e) => {
1585-
ecx.set_last_error_from_io_error(e.kind())?;
1585+
ecx.set_last_error_from_io_error(e)?;
15861586
return Ok(None);
15871587
}
15881588
};

src/shims/windows/env.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
153153

154154
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
155155
this.reject_in_isolation("`GetCurrentDirectoryW`", reject_with)?;
156-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
156+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
157157
return Ok(Scalar::from_u32(0));
158158
}
159159

@@ -166,7 +166,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
166166
this.write_path_to_wide_str(&cwd, buf, size)?,
167167
)));
168168
}
169-
Err(e) => this.set_last_error_from_io_error(e.kind())?,
169+
Err(e) => this.set_last_error_from_io_error(e)?,
170170
}
171171
Ok(Scalar::from_u32(0))
172172
}
@@ -185,15 +185,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
185185

186186
if let IsolatedOp::Reject(reject_with) = this.machine.isolated_op {
187187
this.reject_in_isolation("`SetCurrentDirectoryW`", reject_with)?;
188-
this.set_last_error_from_io_error(ErrorKind::PermissionDenied)?;
188+
this.set_last_error_from_io_error(ErrorKind::PermissionDenied.into())?;
189189

190190
return Ok(this.eval_windows("c", "FALSE"));
191191
}
192192

193193
match env::set_current_dir(path) {
194194
Ok(()) => Ok(this.eval_windows("c", "TRUE")),
195195
Err(e) => {
196-
this.set_last_error_from_io_error(e.kind())?;
196+
this.set_last_error_from_io_error(e)?;
197197
Ok(this.eval_windows("c", "FALSE"))
198198
}
199199
}

src/shims/windows/foreign_items.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
225225
let filename = this.read_path_from_wide_str(filename)?;
226226
let result = match win_absolute(&filename)? {
227227
Err(err) => {
228-
this.set_last_error_from_io_error(err.kind())?;
228+
this.set_last_error_from_io_error(err)?;
229229
Scalar::from_u32(0) // return zero upon failure
230230
}
231231
Ok(abs_filename) => {

0 commit comments

Comments
 (0)