Skip to content

Move std::io::Error into core#155625

Open
bushrat011899 wants to merge 13 commits into
rust-lang:mainfrom
bushrat011899:core_io_error
Open

Move std::io::Error into core#155625
bushrat011899 wants to merge 13 commits into
rust-lang:mainfrom
bushrat011899:core_io_error

Conversation

@bushrat011899

@bushrat011899 bushrat011899 commented Apr 21, 2026

Copy link
Copy Markdown
Contributor

View all comments

ACP: rust-lang/libs-team#755
Tracking issue: #154046
Related: #155574
Related: #152918

Description

Moves std::io::Error into core, deferring Box-adjacent methods to incoherent implementations in alloc, and RawOsError methods to std. This requires some substantial changes to the internals of Error, but none of them are breaking changes or externally visible.

Notably, I've replaced usage of Box with a wrapper around a pointer and an appropriate drop function. This requires the addition of quite a few lines of unsafe, but is required to work around Box only being accessible from alloc. Additionally, an atomic pointer to a VTable is used for working with RawOsError in core, since we cannot know the required implementations without std.

As mention in this comment, there may be concern around having a static AtomicPtr in core for certain users. I've added a configuration option no_io_statics which (similar to no_sync/etc. in alloc) can be used to prevent their inclusion in core. When active, the fallback default implementation will always be used.


Notes

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Apr 21, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

Comment thread library/core/src/io/error/os_functions_atomic.rs
@bushrat011899 bushrat011899 force-pushed the core_io_error branch 2 times, most recently from 93b1fa3 to d3835aa Compare April 22, 2026 03:06
Comment thread library/core/src/io/error.rs Outdated
@rust-log-analyzer

This comment has been minimized.

@programmerjake

Copy link
Copy Markdown
Member

example of how to link from core's docs to std: https://doc.rust-lang.org/1.95.0/src/core/str/mod.rs.html#200

@rustbot rustbot added the O-unix Operating system: Unix-like label Apr 22, 2026
@bushrat011899

Copy link
Copy Markdown
Contributor Author

example of how to link from core's docs to std: https://doc.rust-lang.org/1.95.0/src/core/str/mod.rs.html#200

That's a clever trick I never knew about! Looks like it's also required for linking to incoherent implementations even within the file that creates them too.

@bushrat011899

This comment has been minimized.

@rustbot rustbot removed the O-unix Operating system: Unix-like label Apr 22, 2026
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added the O-unix Operating system: Unix-like label Apr 22, 2026
@bushrat011899

This comment has been minimized.

@rustbot rustbot removed the O-unix Operating system: Unix-like label Apr 22, 2026
@rust-log-analyzer

This comment has been minimized.

@rustbot rustbot added the O-unix Operating system: Unix-like label Apr 22, 2026
@bushrat011899

This comment has been minimized.

@rustbot rustbot removed the O-unix Operating system: Unix-like label Apr 22, 2026
@programmerjake

Copy link
Copy Markdown
Member

label -O-unix
See

maybe just leave it until you get the PR to work, that way there's less comment spam.

@programmerjake

Copy link
Copy Markdown
Member
fn is_interrupted(_code: RawOsError) -> bool {
    cfg_select! {
        target_os = "solid_asp3" => {
            _code == -2004
        }
        any(
            target_os = "hermit",
            all(target_vendor = "fortanix", target_env = "sgx"),
            target_os = "teeos",
            target_family = "unix",
            target_os = "wasi",
        ) => {
            _code == 4

not all unixes have EINTR = 4:
https://github.com/search?q=repo%3Arust-lang%2Flibc+%2Fconst+EINTR%2F&type=code

@bushrat011899

Copy link
Copy Markdown
Contributor Author

not all unixes have EINTR = 4: https://github.com/search?q=repo%3Arust-lang%2Flibc+%2Fconst+EINTR%2F&type=code

That's exactly the kind of thing I was worried about. I've updated that particular commit to use the correct value on WASI. All other configurations should be correct. I've left the cfg_select! statement unchanged to ensure the implicit selection behaviour doesn't change.

Comment thread library/core/src/io/error.rs Outdated
@rustbot rustbot removed the S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. label Jun 11, 2026
@rustbot

rustbot commented Jun 11, 2026

Copy link
Copy Markdown
Collaborator

Reminder, once the PR becomes ready for a review, use @rustbot ready.

@rustbot rustbot added the S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. label Jun 11, 2026
Viewing internals wont be possible from `std` once moved into `core`.
Adjust `Error` documentation

`core` is more restrictive with documentation quality and linking to other items.

Methods that will be implemented through incoherence must also be explicitly linked.
Personal preference that will be used for another module in a later commit. Purely stylistic.
They'll be moved into `core` but must be accessible from `std`.
Incoherence is required to define inherit methods on `Error` from `alloc` and `std` once it is moved into `core`. This is required because:

1. `Box` is part of `Error`'s public API and that is only accessible from `alloc`.
2. `RawOsError` methods must ensure the `OsFunctions` atomic pointer is appropriately set, which can only be done from `std`.
Required to allow `std` access from `core`
This allows `Error` to be moved into `core` while still retaining the ability to store custom error data. This may have performance implications!
Stored in a `static` `AtomicPtr` to allow definition in `core` and setting in `std`. Should be replaced with Externally Implemented Items (EII) or similar once stable.
Now that `Error` lives in `core::io`, doc links to it from `core` can be simplified.
@rustbot

rustbot commented Jun 12, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@bushrat011899

Copy link
Copy Markdown
Contributor Author

@rustbot ready

I don't believe the OsFunctions static can be reduced in this PR without substantially increasing the risk for a change in behaviour. Even the relatively simple is_interrupted function requires considering many different targets for exceptions. Without access to libc in core, that's very difficult to keep in sync. If we want to go down that path, I think it should be in its own PR so it can be given the focus I think it needs.

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jun 12, 2026
@Amanieu

Amanieu commented Jun 18, 2026

Copy link
Copy Markdown
Member

This was discussed in the libs meeting last week. We're happy to use atomics as a workaround for now, but ideally we would want this to be resolved using the compiler's EII support.

@jdonszelmann Are EIIs with defaults in a sufficiently usable state right? We essentially need callbacks from core into std for io::Error, but we want to have an unreachable!() default when std is not linked in to avoid linker errors. This is completely internal to the standard library and not user-exposed.

@clarfonthey

Copy link
Copy Markdown
Contributor

Also just resurfacing the comments on it since I can't find the appropriate review thread and it was kind of hidden in the meeting notes: as far as we're aware, the Rust for Linux folks would rather not have any static writable data in core+alloc and this would technically change that, even if it's in unstable stuff that might get LTO'd out. This isn't necessarily an API guarantee, but an implementation detail they're trying to avoid, and so the impression was that we'd use Externally Implementable Items on targets that support it, which would satisfy this for now in the cases RFL wants, and then longer-term we could maybe gate stabilisation on EII being available more broadly (at least unstably) so that we can try and retain this property longer term.

I feel like this is maybe the kind of thing that longer-term should be tracked using a dedicated lint, maybe, but at least for now this is the impression I have of the situation and why EII is desirable currently. Feel free to correct me depending on how accurate this is.

@programmerjake

programmerjake commented Jun 18, 2026

Copy link
Copy Markdown
Member

for the linux kernel, since that won't support std, we could follow my earlier suggestion of only having the EII/atomic on targets that actually have std and hardwire core to use the fallback on targets without std. this would need a cfg.

Allows disabling the use of a static `AtomicPtr` as an implementation detail of `core::io`, regardless of the platform.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

I-libs-nominated Nominated for discussion during a libs team meeting. O-unix Operating system: Unix-like perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-libs Relevant to the library team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.