library/std/src/sys/io/error/ has a separate hand-written decode_error_kind (raw OS errno → io::ErrorKind) for each platform. Three of them, unix.rs, wasi.rs, and teeos.rs, decode the POSIX/libc errno space and are near-identical copies; the rest (windows.rs, uefi.rs, and the smaller targets) have their own error namespaces.
The three POSIX copies are maintained by hand, and they have drifted. There seem to be two parts to this: a few missing mappings, and a question about whether the drift is worth preventing.
The gaps
teeos.rs states at the top of its table that it is a copy of unix:
// library/std/src/sys/io/error/teeos.rs
// Note: code below is 1:1 copied from unix/mod.rs
The copies have since drifted apart, each in its own way. Taking unix.rs as the reference (current master):
| errno → kind |
unix.rs |
wasi.rs |
teeos.rs |
ENOTEMPTY → DirectoryNotEmpty |
yes (cfg(not(aix))) |
missing |
yes |
EINPROGRESS → InProgress |
yes |
yes |
missing |
EMFILE/ENFILE → TooManyOpenFiles |
yes |
yes |
missing |
EOPNOTSUPP → Unsupported |
yes |
yes |
missing |
So teeos.rs is missing three of unix's arms and wasi.rs is missing a different one. On each affected target the errno decodes to Uncategorized instead of its specific kind, which a caller can only recover with raw_os_error(). As far as I can tell nothing in the test suite asserts these mappings, so the drift isn't caught by CI.
These look like straightforward parity fixes: add the missing arms, each already present in the other POSIX tables. I can put up a PR for them if that's useful.
The open question
This is not the first time the copies have drifted:
Every new errno mapping has to be added to each POSIX copy separately, and a missed one is a silent per-platform difference that no test catches. Would it be worth having the POSIX targets share one decode core, with each supplying only its real deltas (errnos that differ or do not exist there, like the existing cfg(not(aix)) on ENOTEMPTY)? A new mapping would then be written once and inherited everywhere.
I wanted to ask first rather than send a PR for that, since the tricky part is real: not every errno constant exists on every target (libc gates them), so a shared table would need careful per-target cfg/feature handling, which may be why the copies exist today. There is also in-flight work moving io::Error into core (#153915, #155625) that a change here should stay clear of.
If the split is deliberate, that's a fine answer; the missing arms are probably worth adding either way.
@rustbot label +T-libs +A-io
library/std/src/sys/io/error/has a separate hand-writtendecode_error_kind(raw OS errno →io::ErrorKind) for each platform. Three of them,unix.rs,wasi.rs, andteeos.rs, decode the POSIX/libc errno space and are near-identical copies; the rest (windows.rs,uefi.rs, and the smaller targets) have their own error namespaces.The three POSIX copies are maintained by hand, and they have drifted. There seem to be two parts to this: a few missing mappings, and a question about whether the drift is worth preventing.
The gaps
teeos.rsstates at the top of its table that it is a copy of unix:The copies have since drifted apart, each in its own way. Taking
unix.rsas the reference (currentmaster):unix.rswasi.rsteeos.rsENOTEMPTY→DirectoryNotEmptycfg(not(aix)))EINPROGRESS→InProgressEMFILE/ENFILE→TooManyOpenFilesEOPNOTSUPP→UnsupportedSo
teeos.rsis missing three of unix's arms andwasi.rsis missing a different one. On each affected target the errno decodes toUncategorizedinstead of its specific kind, which a caller can only recover withraw_os_error(). As far as I can tell nothing in the test suite asserts these mappings, so the drift isn't caught by CI.These look like straightforward parity fixes: add the missing arms, each already present in the other POSIX tables. I can put up a PR for them if that's useful.
The open question
This is not the first time the copies have drifted:
io_error_moreon WASI #114709 had to bring wasi back in line after Tracking Issue for io_error_more #86442 (io_error_more) added variants to unix only.io::ErrorKind::TooManyOpenFiles#158326 (TooManyOpenFiles) updated three of these tables; teeos was not one of them, which is why teeos is missing that arm above.Every new errno mapping has to be added to each POSIX copy separately, and a missed one is a silent per-platform difference that no test catches. Would it be worth having the POSIX targets share one decode core, with each supplying only its real deltas (errnos that differ or do not exist there, like the existing
cfg(not(aix))onENOTEMPTY)? A new mapping would then be written once and inherited everywhere.I wanted to ask first rather than send a PR for that, since the tricky part is real: not every errno constant exists on every target (
libcgates them), so a shared table would need careful per-targetcfg/feature handling, which may be why the copies exist today. There is also in-flight work movingio::Errorintocore(#153915, #155625) that a change here should stay clear of.If the split is deliberate, that's a fine answer; the missing arms are probably worth adding either way.
@rustbot label +T-libs +A-io