Skip to content

Conversation

alexcrichton
Copy link
Member

This commit is a large change to the implementation of filesystem and other system-related operations on WASI targets. Previously the standard library explicitly used the wasi crate at the 0.11.x version track which means that it used WASIp1 APIs directly. This meant that std was hard-coded to use WASIp1 syscalls and there was no separate implementation for the WASIp{2,3} targets, for example. The high-level goal of this commit is to decouple this interaction and avoid the use of the wasi crate on the WASIp2 target.

Historically when WASIp1 was originally added to Rust the wasi-libc library was in a much different position than it is today. Nowadays Rust already depends on wasi-libc on WASI targets for things like memory allocation and environment variable management. As a libc library it also has all the functions necessary to implement all filesystem operations Rust wants. Recently wasi-libc additionally was updated to use WASIp2 APIs directly on the wasm32-wasip2 target instead of using wasm32-wasip1 APIs. This commit is leveraging this work by enabling Rust to completely sever the dependence on WASIp1 APIs when compiling for wasm32-wasip2. This is also intended to make it easier to migrate to wasm32-wasip3 internally in the future where now only libc need be updated and Rust doesn't need to explicitly change as well.

This commit fairly heavily changes the internals of the implementation of WASI filesystem operations. The basis of implementation is now libc-style APIs as opposed to WASIp1-style-APIs which necessitated a number of changes throughout. Additionally the std::os::wasi::fs module has had a few API-breaking changes as well, but this module is also unstable. While this module has been "stable" since inception in the sense that it hasn't changed, this PR is what the unstable status was sort of trying to buy in terms of future flexibility to make changes. For users of stable std::fs interfaces this is not intended to be a breaking change but there nevertheless may be minor issues here and there.

Concrete changes here are:

  • std for wasm32-wasip2 no longer depends on wasi 0.11.x
  • The implementation of std::os::wasi::fs, which was previously unstable and still is, is now only available on wasm32-wasip1 and is implemented largely directly in terms of WASIp1 APIs by directly using the wasi 0.11.x crate.
  • std::os::wasi::fs::MetadataExt, which was previously unstable and still is, has removed methods that duplicate functionality in std::fs::Metadata as there's no point in having them.
  • std::os::wasi::fs::FileTypeExt, which was previously unstable and still is, lost the ability to distinguish between dgram/stream sockets. WASIp1 sockets were never really supported, though, so this isn't much of a loss.
  • The internal WasiFd type has been "gutted" to have far fewer methods internally. This still represents a file descriptor owned by wasi-libc, however.
  • The std::sys::fs::wasi implementation is overhauled to largely use the libc crate and its APIs directly (which go to wasi-libc). This drastically changes the ReadDir implementation, for example.
  • The std::sys::fs::wasi::OpenOptions API now has two ways of opening files. By default libc::open is used but of std::os::wasi::fs::OpenOptionsExt is used then a WASIp1-specific API is used to open a file.
  • Types like FileAttr and FileType now use libc representations at-rest instead of WASIp1 internals.
  • Various transmutations for iovec-style APIs are consolidated into a WASI-specific module close to the definition of the IoSlice{,Mut} types to make it easier to audit unsafe guarantees.
  • The wasip2 OS module gained a custom implementation of the helpers module as the WASIp1 version of this module is no longer applicable.

I'd like to do follow-up PRs after this one to reorganize std::os::wasi* a bit to be more amenable for WASIp{2,3} targets as well, but that'll come in a future PR. For now this is tasked with the high-level goal of removing the dependency on WASIp1 APIs in the standard library by relying on wasi-libc to natively use WASIp2 APIs.

@rustbot rustbot added O-wasi Operating system: Wasi, Webassembly System Interface O-wasm Target: WASM (WebAssembly), http://webassembly.org/ 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. labels Oct 10, 2025
@rustbot
Copy link
Collaborator

rustbot commented Oct 10, 2025

r? @Mark-Simulacrum

rustbot has assigned @Mark-Simulacrum.
They will have a look at your PR within the next two weeks and either review your PR or reassign to another reviewer.

Use r? to explicitly pick a reviewer

@rust-log-analyzer

This comment has been minimized.

This commit is a large change to the implementation of filesystem and
other system-related operations on WASI targets. Previously the standard
library explicitly used the `wasi` crate at the 0.11.x version track
which means that it used WASIp1 APIs directly. This meant that `std` was
hard-coded to use WASIp1 syscalls and there was no separate
implementation for the WASIp{2,3} targets, for example. The high-level
goal of this commit is to decouple this interaction and avoid the use of
the `wasi` crate on the WASIp2 target.

Historically when WASIp1 was originally added to Rust the wasi-libc
library was in a much different position than it is today. Nowadays Rust
already depends on wasi-libc on WASI targets for things like memory
allocation and environment variable management. As a libc library it
also has all the functions necessary to implement all filesystem
operations Rust wants. Recently wasi-libc additionally was updated to
use WASIp2 APIs directly on the `wasm32-wasip2` target instead of using
`wasm32-wasip1` APIs. This commit is leveraging this work by enabling
Rust to completely sever the dependence on WASIp1 APIs when compiling
for `wasm32-wasip2`. This is also intended to make it easier to migrate
to `wasm32-wasip3` internally in the future where now only libc need be
updated and Rust doesn't need to explicitly change as well.

This commit fairly heavily changes the internals of the implementation
of WASI filesystem operations. The basis of implementation is now
libc-style APIs as opposed to WASIp1-style-APIs which necessitated a
number of changes throughout. Additionally the `std::os::wasi::fs`
module has had a few API-breaking changes as well, but this module is
also unstable. While this module has been "stable" since inception in
the sense that it hasn't changed, this PR is what the unstable status
was sort of trying to buy in terms of future flexibility to make
changes. For users of stable `std::fs` interfaces this is not intended
to be a breaking change but there nevertheless may be minor issues here
and there.

Concrete changes here are:

* `std` for `wasm32-wasip2` no longer depends on `wasi 0.11.x`
* The implementation of `std::os::wasi::fs`, which was previously
  unstable and still is, is now only available on `wasm32-wasip1` and is
  implemented largely directly in terms of WASIp1 APIs by directly using
  the `wasi 0.11.x` crate.
* `std::os::wasi::fs::MetadataExt`, which was previously unstable and
  still is, has removed methods that duplicate functionality in
  `std::fs::Metadata` as there's no point in having them.
* `std::os::wasi::fs::FileTypeExt`, which was previously unstable and
  still is, lost the ability to distinguish between dgram/stream
  sockets. WASIp1 sockets were never really supported, though, so this
  isn't much of a loss.
* The internal `WasiFd` type has been "gutted" to have far fewer methods
  internally. This still represents a file descriptor owned by
  `wasi-libc`, however.
* The `std::sys::fs::wasi` implementation is overhauled to largely use
  the `libc` crate and its APIs directly (which go to wasi-libc). This
  drastically changes the `ReadDir` implementation, for example.
* The `std::sys::fs::wasi::OpenOptions` API now has two ways of opening
  files. By default `libc::open` is used but of
  `std::os::wasi::fs::OpenOptionsExt` is used then a WASIp1-specific API
  is used to open a file.
* Types like `FileAttr` and `FileType` now use libc representations
  at-rest instead of WASIp1 internals.
* Various transmutations for iovec-style APIs are consolidated into a
  WASI-specific module close to the definition of the `IoSlice{,Mut}`
  types to make it easier to audit unsafe guarantees.
* The `wasip2` OS module gained a custom implementation of the `helpers`
  module as the WASIp1 version of this module is no longer applicable.

I'd like to do follow-up PRs after this one to reorganize
`std::os::wasi*` a bit to be more amenable for WASIp{2,3} targets as
well, but that'll come in a future PR. For now this is tasked with the
high-level goal of removing the dependency on WASIp1 APIs in the
standard library by relying on wasi-libc to natively use WASIp2 APIs.
@rustbot rustbot added A-rustdoc-search Area: Rustdoc's search feature T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output. labels Oct 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-rustdoc-search Area: Rustdoc's search feature O-wasi Operating system: Wasi, Webassembly System Interface O-wasm Target: WASM (WebAssembly), http://webassembly.org/ 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. T-rustdoc-frontend Relevant to the rustdoc-frontend team, which will review and decide on the web UI/UX output.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants