From e2ce8a3c267f206918df970ba3a9b8f82fb602da Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 31 Oct 2025 11:36:17 +0000 Subject: [PATCH 01/43] build-std: explicit dependencies --- text/0000-build-std-explicit-dependencies.md | 1111 ++++++++++++++++++ 1 file changed, 1111 insertions(+) create mode 100644 text/0000-build-std-explicit-dependencies.md diff --git a/text/0000-build-std-explicit-dependencies.md b/text/0000-build-std-explicit-dependencies.md new file mode 100644 index 00000000000..0aef6c68141 --- /dev/null +++ b/text/0000-build-std-explicit-dependencies.md @@ -0,0 +1,1111 @@ +- Feature Name: `build-std-explicit-dependencies` +- Start Date: 2025-06-05 +- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) + +# Summary +[summary]: #summary + +Allow users to add explicit dependencies on standard library crates in the +`Cargo.toml`. This enables Cargo to determine which standard library crates are +required by the crate graph without `build-std-crates` being set and for +different crates to require different standard library crates. + +**This RFC is is part of the [build-std project goal] and a series of build-std +RFCs:** + +1. build-std context ([rfcs#3873]) + - [Background][background] + - [History][history] + - [Motivation][motivation] +2. `build-std="always"` ([rfcs#3874]) + - [Proposal][rfcs#3874-proposal] + - [Rationale and alternatives][rfcs#3874-rationale-and-alternatives] + - [Unresolved questions][rfcs#3874-unresolved-questions] + - [Future possibilities][rfcs#3874-future-possibilities] +3. Explicit standard library dependencies (this RFC) + - [Proposal][proposal] + - [Rationale and alternatives][rationale-and-alternatives] + - [Unresolved questions][unresolved-questions] + - [Future possibilities][future-possibilities] +4. `build-std="compatible"` (RFC not opened yet) +5. `build-std="match-profile"` (RFC not opened yet) + +# Motivation +[motivation]: #motivation + +This RFC builds on a large collection of prior art collated in the +[`build-std-context`][build-std-context] RFC. It does not directly address the +main [motivations] it identifies but supports +later proposals. + +The main motivation for this proposal is to support future extensions to +build-std which allow public/private standard library dependencies or enabling +features of the standard library. Allowing the standard library to behave +similarly to other dependencies also reduces user friction and can improve build +times. + +# Proposal +[proposal]: #proposal + +Users can now optionally declare explicit dependencies on the standard library +in their `Cargo.toml` files ([?][rationale-why-explicit-deps]): + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true } +``` + +`builtin` is a new source of dependency, like registry dependencies (with the +`version` key and optionally the `registry` key), `path` dependencies or `git` +dependencies. `builtin` can only be set to `true` and cannot be combined with +any other dependency source for a given dependency +([?][rationale-builtin-other-sources]). + +`builtin` can only be used with crates named `core`, `alloc` or `std` +([?][rationale-no-builtin-other-crates]) on stable. This set could be expanded +with new crates in future. + +Use with any other crate name is gated on a perma-unstable `cargo-feature` +([?][rationale-unstable-builtin-crates]). If a builtin dependency on a unstable +crate name exists but is not used due to cfgs, then Cargo will still require the +Cargo feature. + +> [!NOTE] +> +> Explicit dependencies are passed to rustc without the `noprelude` modifier +> ([?][rationale-explicit-noprelude]). When adding an explicit dependency, users +> may need to adjust their code (removing extraneous `extern crate` statements +> or root-relative paths, like `::std`). + +Crates without an explicit dependency on the standard library now have a +implicit dependency ([?][rationale-no-migration]) on that target's default set +of standard library crates (see [build-std-always][standard-library-crate-stability]). +Any explicit `builtin` dependency present in any dependency table will disable +the implicit dependencies. + +> [!NOTE] +> +> Implicit dependencies are passed to rustc with the `noprelude` modifier to +> ensure backwards compatibility as in [`build-std=always`][always-noprelude]. + +When a `std` dependency is present an additional implicit dependency on the +`test` crate is added for crates that are being tested with the default test +harness. The `test` crate's name, but not its interface, will be stabilised so +Cargo can refer to it. + +crates.io will accept crates published which have `builtin` dependencies. + +Standard library dependencies can be marked as `optional` and be enabled +conditionally by a feature in the crate: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true, optional = true } +core = { builtin = true } + +[features] +default = ["std"] +std = ["dep:std"] +``` + +If there is an optional dependency on the standard library then Cargo will +validate that there is at least one non-optional dependency on the standard +library (e.g. an optional `std` and non-optional `core` or `alloc`, or an +optional `alloc` and non-optional `core`). `core` cannot be optional. For +example, the following example will error as it could result in a build without +`core` (if the `std` feature were disabled): + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true, optional = true } +# error: must have a non-optional dependency on core + +[features] +default = ["std"] +std = ["dep:std"] +``` + +However, in this example, a build for the `x86-64-pc-windows-gnu` target would +have an explicit dependency on `alloc` (and indirectly on `core`), while a build +for any other target would have implicit dependencies on `std`, `alloc` and +`core`: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +# implicit deps on `core`, `alloc` and `std` unless target='x86_64-pc-windows-gnu' + +[target.x86_64-pc-windows-gnu.dependencies] +alloc.builtin = true +``` + +Dependencies with `builtin = true` cannot be renamed with the `package` key +([?][rationale-package-key]). It is not possible to perform source replacement +on the `builtin` source using the `[source]` Cargo config table +([?][rationale-source-replacement]), and nor is it possible to override +`builtin` dependencies with the `[replace]` sections or `paths` overrides +([?][rationale-overriding-builtins]), though [patching][patches] is permitted. + +Dependencies with `builtin = true` can be specified as platform-specific +dependencies: + +```toml +[target.'cfg(unix)'.dependencies] +std = { builtin = true} +``` + +Implicit and explicit standard library dependencies are added to `Cargo.lock` +files ([?][rationale-cargo-lock]). + +> [!NOTE] +> +> A new version of the `Cargo.lock` file will be introduced to add support for +> packages with a `builtin` source: +> +> ```toml +> [[package]] +> name = "std" +> version = "0.0.0" +> source = "builtin" +> ``` +> +> The package version of `std`, `alloc` and `core` will be fixed at `0.0.0`. The +> optional lockfile fields `dependencies` and `checksum` will not be present for +> `builtin` dependencies. + +*See the following sections for rationale/alternatives:* + +- [*Why explicitly declare dependencies on the standard library in `Cargo.toml`?*][rationale-why-explicit-deps] +- [*Why disallow builtin dependencies to be combined with other sources?*][rationale-builtin-other-sources] +- [*Why disallow builtin dependencies on other crates?*][rationale-no-builtin-other-crates] +- [*Why unstably allow all names for `builtin` crates?*][rationale-unstable-builtin-crates] +- [*Why not use `noprelude` for explicit `builtin` dependencies?*][rationale-explicit-noprelude] +- [*Why not require builtin dependencies instead of supporting implicit ones?*][rationale-no-migration] +- [*Why disallow renaming standard library dependencies?*][rationale-package-key] +- [*Why disallow source replacement on `builtin` packages?*][rationale-source-replacement] +- [*Why add standard library dependencies to Cargo.lock?*][rationale-cargo-lock] + +*See the following sections for relevant unresolved questions:* + +- [*What syntax is used to identify dependencies on the standard library in `Cargo.toml`?*][unresolved-dep-syntax] +- [*What is the format for builtin dependencies in `Cargo.lock`?*][unresolved-lockfile] + +*See the following sections for future possibilities:* + +- [*Allow unstable crate names to be referenced behind cfgs without requiring nightly*][future-cfg-unstable-crate-name] +- [*Allow `builtin` source replacement*][future-source-replacement] +- [*Remove `rustc_dep_of_std`*][future-rustc_dep_of_std] + +## Non-`builtin` standard library dependencies +[non-builtin-standard-library-dependencies]: #non-builtin-standard-library-dependencies + +Cargo already supports `path` and `git` dependencies for crates named `core`, +`alloc` and `std` which continue to be supported and work: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { path = "../my_std" } # already supported by Cargo +``` + +A `core`/`alloc`/`std` dependency with a `path`/`git` source can be combined +with `builtin` dependencies: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { path = "../my_std" } +core = { builtin = true } +``` + +Crates with these dependency sources will remain unable to be published to +crates.io. + +## Patches +[patches]: #patches + +Under a perma-unstable feature it is permitted to patch standard library +dependencies with `path` and `git` sources (or any other source) +([?][rationale-patching]): + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true } + +[patch.builtin] # permitted on nightly +std = { .. } + +[patch.builtin] # permitted on nightly +std = { path = "../libstd" } +``` + +As with dependencies, crates with `path`/`git` patches for `core`, `alloc` or +`std` are not accepted by crates.io. + +*See the following sections for rationale/alternatives:* + +- [*Why unstably permit patching of standard library dependencies?*][rationale-patching] + +*See the following sections for relevant unresolved questions:* + +- [*What syntax is used to patch dependencies on the standard library in `Cargo.toml`?*][unresolved-patch-syntax] + +## Features +[features]: #features + +On a stable toolchain, it is not permitted to enable or disable features of +explicit standard library dependencies ([?][rationale-features]), as in the +below example: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true, features = [ "foo" ] } # not permitted +# ..or.. +std = { builtin = true, default-features = false } # not permitted +``` + +*See the following sections for rationale/alternatives:* + +- [*Why limit enabling standard library features to an unstable feature?*][rationale-features] + +*See the following sections for future possibilities:* + +- [*Allow enabling/disabling features with build-std*][future-features] + +## Public and private dependencies +[public-and-private-dependencies]: #public-and-private-dependencies + +Implicit and explicit dependencies on the standard library default to being +public dependencies ([?][rationale-default-public]). + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +``` + +..is equivalent to the following explicit dependency on `std`: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true, public = true } +``` + +*See the following sections for relevant unresolved questions:* + +- [*Should standard library dependencies default to public?*][unresolved-std-default-public] + +*See the following sections for rationale/alternatives:* + +- [*Why default to public for standard library dependencies?*][rationale-default-public] + +## `dev-dependencies` and `build-dependencies` +[dev-dependencies-and-build-dependencies]: #dev-dependencies-and-build-dependencies + +Explicit dependencies on the standard library can be specified in +`dev-dependencies` in the same way as regular `dependencies`. Any explicit +`builtin` dependency present in `dev-dependencies` table will disable the +implicit dependencies. It is possible for `dev-dependencies` to have additional +`builtin` dependencies that the `dependencies` section does not have (e.g. +requiring `std` when the regular dependencies only require `core`). + +Build scripts and proc macros continue to use the pre-built standard library as +in [`build-std=always`][always], and so explicit dependencies on the standard +library are not supported in `build-dependencies`. + +*See the following sections for relevant unresolved questions:* + +- [*Should we support `build-dependencies`?*][unresolved-build-deps] + +## Registries +[registries]: #registries + +Standard library dependencies will be present in the registry index +([?][rationale-cargo-index]). A `builtin_deps` key is added to the +[index's JSON schema][cargo-json-schema] ([?][rationale-cargo-builtindeps]). +`builtin_deps` is similar to the existing `deps` key and contains a list of JSON +objects, each representing a dependency that is "builtin" to the Rust toolchain +and cannot otherwise be found in the registry. The +["publish" endpoint][cargo-registry-web-publish] of the Registry Web API will +similarly be updated to support `builtin_deps`. + +> [!NOTE] +> +> It is expected that the keys of these objects will be: +> +> - `name` +> - String containing name of the `builtin` package. Can shadow the names of +> other packages in the registry (except those packages in the `deps` key +> of the current package) ([?][rationale-cargo-index-shadowing]) +> +> - `features`: +> - An array of strings containing enabled features in order to support +> changing the standard library features on nightly. Optional, empty by +> default. +> +> - `optional`, `default_features`, `target`, `kind`: +> - These keys have the same definition as in the `deps` key +> +> The keys `req`, `registry` and `package` from `deps` are not required per the +> limitations on builtin dependencies. +> +> The `builtin_deps` key is optional and if not present its default value will +> be the implicit builtin dependencies: +> +> ```json +> "builtin_deps" : [ +> { +> "name": "std", +> "features": [], +> "optional": false, +> "default_features": true, +> "target": null, +> "kind": "normal", +> }, +> { +> "name": "alloc", +> ... # as above +> }, +> { +> "name": "core", +> ... # as above +> } +> ] +> ``` +> +> When producing a registry index entry for a package Cargo will not serialise +> any `builtin` dependencies it inferred. This allows the set of inferred +> packages to change in the future if needed. Similarly, the published +> `Cargo.toml` will not explicitly declare any inferred dependencies. + +*See the following sections for rationale/alternatives:* + +- [*Why add standard library crates to Cargo's index?*][rationale-cargo-index] +- [*Why add a new key to Cargo's registry index JSON schema?*][rationale-cargo-builtindeps] +- [*Why can `builtin_deps` shadow other packages in the registry?*][rationale-cargo-index-shadowing] + +## Cargo subcommands +[cargo-subcommands]: #cargo-subcommands + +Any Cargo command which accepts a package spec with `-p` will now additionally +recognise `core`, `alloc` and `std` and none of their dependencies. Many of +Cargo's subcommands will need modification to support build-std: + +[`cargo add`][cargo-add]'s heuristics will include adding `std`, `alloc` or +`core` as builtin dependencies if these crate names are provided. `cargo add` +will additionally have a `--builtin` flag to allow for adding crates with a +`builtin` source explicitly: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true } # <-- this would be added +``` + +If attempting to add a crate name outside of `core`, `alloc` or `std` this will +fail unless the required `cargo-feature` is added to allow other `builtin` crate +names as described in [the rationale][rationale-unstable-builtin-crates]. + +If attempting to add a `builtin` crate with features then this will fail unless +the required `cargo-feature` is enabled as described in [*Features*][features]. + +[`cargo info`][cargo-info] will learn how to print information for the built-in +`std`, `alloc` and `core` dependencies: + +```shell-session +$ cargo info std +std +rust standard library +license: Apache 2.0 + MIT +rust-version: 1.86.0 +documentation: https://doc.rust-lang.org/1.86.0/std/index.html +``` + +```shell-session +$ cargo info alloc +alloc +rust standard library +license: Apache 2.0 + MIT +rust-version: 1.86.0 +documentation: https://doc.rust-lang.org/1.86.0/alloc/index.html +``` + +```shell-session +$ cargo info core +core +rust standard library +license: Apache 2.0 + MIT +rust-version: 1.86.0 +documentation: https://doc.rust-lang.org/1.86.0/core/index.html +``` + +[`cargo metadata`][cargo-metadata] will emit `std`, `alloc` and `core` +dependencies to the metadata emitted by `cargo metadata` (when those crates are +explicit dependencies). None of the standard library's dependencies will be +included. `source` would be set to `builtin` and the remaining fields would be +set like any other dependency. + +> [!NOTE] +> +> `cargo metadata` output could look as follows: +> +> ```json +> { +> "packages": [ +> { +> /* ... */ +> "dependencies": [ +> { +> "name": "std", +> "source": "builtin", +> "req": "*", +> "kind": null, +> "rename": null, +> "optional": false, +> "uses_default_features": true, +> "features": ["compiler-builtins-mem"], +> "target": null, +> "public": true +> } +> ], +> /* ... */ +> } +> ] +> } +> ``` + +[`cargo pkgid`][cargo-pkgid] when passed `-p core` would print +`builtin://.#core` as the source, likewise with `alloc` and `std`. This format +complies with [Cargo's spec for Package IDs][cargo-pkgid-spec]. + +[`cargo remove`][cargo-remove] will remove `core`, `alloc` or `std` explicitly +from the manifest if invoked with those crate names (using the same heuristics +as those described above for `cargo add`): + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true } # <-- this would be removed +``` + +[`cargo tree`][cargo-tree] will show `std`, `alloc` and `core` at appropriate +places in the tree of dependencies. As opaque dependencies, none of the other +dependencies of `std`, `alloc` or `core` will be shown. Neither `std`, `alloc` +or `core` will have a version number. + +> [!NOTE] +> +> `cargo tree` output could look as follows: +> +> ```shell-session +> $ cargo tree +> myproject v0.1.0 (/myproject) +> ├── rand v0.7.3 +> │ ├── getrandom v0.1.14 +> │ │ ├── cfg-if v0.1.10 +> │ │ │ └── core v0.0.0 +> │ │ ├── libc v0.2.68 +> │ │ │ └── core v0.0.0 +> │ │ └── core v0.0.0 +> │ ├── libc v0.2.68 (*) +> │ │ └── core v0.0.0 +> │ ├── rand_chacha v0.2.2 +> │ │ ├── ppv-lite86 v0.2.6 +> │ │ │ └── core v0.0.0 +> │ │ ├── rand_core v0.5.1 +> │ │ │ ├── getrandom v0.1.14 (*) +> │ │ │ └── core v0.0.0 +> │ │ └── std v0.0.0 +> │ │ └── alloc v0.0.0 +> │ │ └── core v0.0.0 +> │ ├── rand_core v0.5.1 (*) +> │ └── std v0.0.0 (*) +> └── std v0.0.0 (*) +> ``` + +This part of the RFC has no implications for the following Cargo subcommands: + +- [`cargo bench`][cargo-bench] +- [`cargo build`][cargo-build] +- [`cargo check`][cargo-check] +- [`cargo clean`][cargo-clean] +- [`cargo clippy`][cargo-clippy] +- [`cargo doc`][cargo-doc] +- [`cargo fetch`][cargo-fetch] +- [`cargo fix`][cargo-fix] +- [`cargo fmt`][cargo-fmt] +- [`cargo generate-lockfile`][cargo-generate-lockfile] +- [`cargo help`][cargo-help] +- [`cargo init`][cargo-init] +- [`cargo install`][cargo-install] +- [`cargo locate-project`][cargo-locate-project] +- [`cargo login`][cargo-login] +- [`cargo logout`][cargo-logout] +- [`cargo miri`][cargo-miri] +- [`cargo new`][cargo-new] +- [`cargo owner`][cargo-owner] +- [`cargo package`][cargo-package] +- [`cargo publish`][cargo-publish] +- [`cargo report`][cargo-report] +- [`cargo run`][cargo-run] +- [`cargo rustc`][cargo-rustc] +- [`cargo rustdoc`][cargo-rustdoc] +- [`cargo search`][cargo-search] +- [`cargo test`][cargo-test] +- [`cargo uninstall`][cargo-uninstall] +- [`cargo update`][cargo-update] +- [`cargo vendor`][cargo-vendor] +- [`cargo version`][cargo-version] +- [`cargo yank`][cargo-yank] + +# Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +This section aims to justify all of the decisions made in the proposed design +from [*Proposal*][proposal] and discuss why alternatives were not chosen. + +## Why explicitly declare dependencies on the standard library in `Cargo.toml`? +[rationale-why-explicit-deps]: #why-explicitly-declare-dependencies-on-the-standard-library-in-cargotoml + +If there are no explicit dependencies on standard library crates, Cargo would +need to be able to determine which standard library crates to build when this is +required: + +- Cargo could unconditionally build `std`, `alloc` and `core`. Not only would + this be unnecessary and wasteful for `no_std` crates in the embedded + ecosystem, but sometimes a target may not support building `std` at all and + this would cause the build to fail. + +- rustc could support a `--print` value that would print whether the crate + declares itself as `#![no_std]` crate, and based on this, Cargo could build + `std` or only `core`. This would require asking rustc to parse crates' + sources while resolving dependencies, slowing build times. Alternatively, + Cargo can already read Rust source to detect frontmatter (for `cargo script`) + so it could additionally look for `#![no_std]` itself. Regardless of how it + determines a crate is no-std, Cargo would also need to know whether to build + `alloc` too, which checking for `#![no_std]` does not help with. Cargo could + go further and ask rustc whether a crate (or its dependencies) used `alloc`, + but this seems needlessly complicated. + +- Cargo could allow the user to specify which crates are required to be built, + such as with the existing options to the `-Zbuild-std=` flag. + [`build-std=always`][always] proposes a `build-std-crates` flag to enable + explicit dependencies to be a separate part of this RFC. + +Furthermore, supporting explicit dependencies on standard library crates enables +use of other Cargo features that apply to dependencies in a natural and +intuitive way. If there were not explicit standard library dependencies and +enabling features on the `std` crate was desirable, then a mechanism other than +the standard syntax for this would be necessary, such as a flag (e.g. +`-Zbuild-std-features`) or option in Cargo's configuration. This also applies to +optional dependencies, public/private features, etc. + +Users already use Cargo features to toggle `#![no_std]` in crates which support +building without the standard library. When dependencies on the standard library +are exposed in `Cargo.toml` then they can be made optional and enabled by the +existing Cargo features that crates already have. + +↩ [*Proposal*][proposal] + +## Why disallow builtin dependencies to be combined with other sources? +[rationale-builtin-other-sources]: #why-disallow-builtin-dependencies-to-be-combined-with-other-sources + +If using `path`/`git` sources with `builtin` dependencies worked in the same way +as using `path`/`git` sources with `version` sources, then: crates with +`path`/`git` standard library dependencies could be pushed to crates.io. + +This is not desirable as it is unclear that supporting `path`/`git` sources +which shadow standard library crates was a deliberate choice and so enabling +that pattern to be used more widely when not necessary is needlessly permissive. + +In addition, when combined with a `git`/`path` source, the `version` constraint +also applies to package from the `git`/`path` source. If `version` were used +alongside `builtin`, then this behaviour would be a poor fit as.. + +- ..the `std`, `alloc` and `core` crates all currently have a version of `0.0.0` + +- ..choosing different version requirements for different `builtin` crates is + confusing when a single version of these crates is provided by the toolchain + +Hypothetically, choosing a different version for `builtin` crates could be a way +of supporting per-target/per-profile MSRVs, but this has limited utility. + +↩ [*Proposal*][proposal] + +## Why disallow builtin dependencies on other crates? +[rationale-no-builtin-other-crates]: #why-disallow-builtin-dependencies-on-other-crates + +`builtin` dependencies could be accepted on two other crates - dependencies of +the standard library, like `compiler_builtins`, or other crates in the sysroot +added manually by users, however: + +- The standard library's dependencies are not part of the stable interface of + the standard library and it is not desirable that users can observe their + existence or depend on them directly + +- Other crates in the sysroot added by users are not something that can + reasonably be supported by build-std and these crates should become regular + dependencies + +↩ [*Proposal*][proposal] + +## Why unstably allow all names for `builtin` crates? +[rationale-unstable-builtin-crates]: #why-unstably-allow-all-names-for-builtin-crates + +For any crate shipped with the standard library in the sysroot, the user can +already write an `extern crate` declaration to use it. Most are marked unstable +either explicitly or implicitly with the use of `-Zforce-unstable-if-unmarked` +so this does not allow items from these crates to be used on stable. + +For example, some users write benchmarks using `libtest` and have written +`extern crate test` without the `#[cfg(test)]` attribute to load the crate. +There may be other niche uses of unstable sysroot crates that this enables to +continue on nightly toolchains. + +An allowlist of `builtin` crate names isn't used here to avoid Cargo needing to +hardcode the names of many crates in the sysroot which are inherently unstable. + +↩ [*Proposal*][proposal] + +## Why not use `noprelude` for explicit `builtin` dependencies? +[rationale-explicit-noprelude]: #why-not-use-noprelude-for-explicit-builtin-dependencies + +Explicit builtin dependencies without the `noprelude` modifier behave more +consistently with other dependencies specified in the Cargo manifest. + +This is a trade-off, trading consistency of user experience with special-casing +in Cargo. Cargo would have to handle implicit vs explicit dependencies +differently. An explicit dependency on the standard library will behave +similarly to other dependencies in their manifest, but the behaviour will be +subtly different than with implicit builtin dependencies (where `extern crate` +is required). + +↩ [*Proposal*][proposal] + +## Why not require builtin dependencies instead of supporting implicit ones? +[rationale-no-migration]: #why-not-require-builtin-dependencies-instead-of-supporting-implicit-ones + +Requiring explicit `builtin` dependencies over an edition would increase the +boilerplate required for users of Cargo and make the minimal `Cargo.toml` file +larger. + +Supporting implicit dependencies allows the majority of the Rust ecosystem from +having to make any changes - `no_std` crates (or crates with a `std` feature) +will still benefit from adding explicit dependencies as allow them to be easily +used with `no_std` targets but users can still work around any legacy crates in +the graph with [`build-std-crates`][always]. + +↩ [*Proposal*][proposal] + +## Why disallow renaming standard library dependencies? +[rationale-package-key]: #why-disallow-renaming-standard-library-dependencies + +Cargo allows [renaming dependencies][cargo-docs-renaming] with the `package` +key, which allows user code to refer to dependencies by names which do not +match their `package` name in their respective `Cargo.toml` files. + +However, rustc expects the standard library crates to be present with their +existing names - for example, `core` is always added to the +[extern prelude][rust-extern-prelude]. + +Alternatively, a mechanism could be added to rustc so that it could be informed +of the user's names for `builtin` crates. + +↩ [*Proposal*][proposal] + +## Why disallow source replacement on `builtin` packages? +[rationale-source-replacement]: #why-disallow-source-replacement-on-builtin-packages + +Modifying the source code of the standard library in the `rust-src` component is +not supported. Source replacement of the `builtin` source could be a way to +support this in future but this is out-of-scope for this proposal. + +See [*Allow `builtin` source replacement*][future-source-replacement]. + +↩ [*Proposal*][proposal] + +## Why not permit overriding dependencies with `replace` or `paths`? +[rationale-overriding-builtins]: #why-not-permit-overriding-dependencies-with-replace-or-paths + +Similarly to [source replacement][rationale-source-replacement], easing +modification of the standard library sources is out-of-scope for this proposal. + +↩ [*Proposal*][proposal] + +## Why add standard library dependencies to `Cargo.lock`? +[rationale-cargo-lock]: #why-add-standard-library-dependencies-to-cargolock + +`Cargo.lock` is a direct serialisation of a resolve and that must be a two-way +non-lossy process in order to make the `Cargo.lock` useful without doing further +resolution to fill in missing `builtin` packages. + +↩ [*Proposal*][proposal] + +## Why unstably permit patching of the standard library dependencies? +[rationale-patching]: #why-unstably-permit-patching-of-the-standard-library-dependencies + +Being able to patch `builtin = true` dependencies and replace their source with +a `path` dependency is required to be able to replace `rustc_dep_of_std`. As +crates which use these sources cannot be published to crates.io, this would not +enable a usable general-purpose mechanism for crates to modify the standard +library sources. This capability is restricted to nightly toolchains as that is +all that is required for it to be used in replacing `rustc_dep_of_std`. + +↩ [*Patches*][patches] + +## Why limit enabling standard library features to an unstable feature? +[rationale-features]: #why-limit-enabling-standard-library-features-to-an-unstable-feature + +If it were possible to enable features of the standard library crates on stable +then all of the standard library's current features would immediately be held to +the same stability guarantees as the rest of the standard library, which is not +desirable. See +[*Allow enabling/disabling features with build-std*][future-features] + +↩ [*Features*][features] + +## Why default to public for standard library dependencies? +[rationale-default-public]: #why-default-to-public-for-standard-library-dependencies + +There are crates building on stable which re-export from the standard library. +If the standard library dependencies were not public then these crates would +start to trigger the `exported_private_dependencies` lint when upgrading to a +version of Cargo with a standard library dependency. + +↩ [*Public and private dependencies*][public-and-private-dependencies] + +## Why follow the default privacy of explicit standard library dependencies? +[rationale-explicit-private]: #why-follow-the-default-privacy-of-explicit-standard-library-dependencies + +This may be unintuitive when a user first writes an explicit standard library +dependency, triggering the `exported_private_dependency` lint, but this would be +caught immediately by the user. However, it is also unintuitive that the default +for privacy of a explicitly written dependency would depend on which crate the +dependency was (i.e. the standard library has a different default than +everything else). + +↩ [*Public and private dependencies*][public-and-private-dependencies] + +## Why add standard library crates to Cargo's index? +[rationale-cargo-index]: #why-add-standard-library-crates-to-cargos-index + +When Cargo builds the dependency graph, it is driven by the index (not +`Cargo.toml`), so builtin dependencies need to be included in the index. + +↩ [*Registries*][registries] + +## Why add a new key to Cargo's registry index JSON schema? +[rationale-cargo-builtindeps]: #why-add-a-new-key-to-cargos-registry-index-json-schema + +Cargo's [registry index schema][cargo-json-schema] is versioned and making a +behaviour-of-Cargo-modifying change to the existing `deps` keys would be a +breaking change. Each package is published under one particular version of the +schema, meaning that older versions of Cargo cannot use newer versions of +packages which are defined using a schema it does not have knowledge of. + +Cargo ignores packages published under an unsupported schema version, so older +versions of Cargo cannot use newer versions of packages relying on these +features (though this would be true because of an incompatible Cargo manifest +anyway). New schema versions are disruptive to users on older toolchains, as the +resolver will act as if a package does not exist. Recent Cargo versions have +improved error reporting for this circumstance. + +Some new fields, including `rust-version`, were added to all versions of the +schema. Cargo ignores fields it does not have knowledge of, so older versions of +Cargo will simply not use `rust-version` and its presence does not change their +behaviour. + +Existing versions of Cargo already function correctly without knowledge of +crate's standard library dependencies. A new top-level key will be ignored by +older versions of Cargo, while newer versions will understand it. This is a +different approach to that taken when artifact dependencies were added to the +schema, as those do not have a suitable representation in older versions of +Cargo. + +The obvious alternative to a `builtin_deps` key is to modify `deps` entries with +a new `builtin: bool` field and to increment the version of the schema. However, +these entries would not be understood by older versions of Cargo which would +look in the registry to find these packages and fail to do so. + +That approach could be made to work if dummy packages for `core`/`alloc`/`std` +were added to registries. Older versions of Cargo would pass these to rustc +via `--extern` and shadow the real standard library dependencies in the sysroot, +so these packages would need to contain `extern crate std; pub use std::*;` (and +similar for `alloc`/`core`) to try and load the pre-built libraries from the +sysroot (this is the same approach as packages like [embed-rs][embed-rs-source] +take today, using `path` dependencies for the standard library to shadow it). + +↩ [*Registries*][registries] + +## Why can `builtin_deps` shadow other packages in the registry? +[rationale-cargo-index-shadowing]: #why-can-builtin_deps-shadow-other-packages-in-the-registry + +While `crates.io` forbids certain crate names including `std`, `alloc` and +`core`, third party registries may allow them without a warning. The schema +needs a way to refer to packages with the same name either in the registry or +builtin, which `builtin_deps` allows. + +`builtin_deps` names are not allowed to shadow names of packages in `deps` as +these would conflict when passed to rustc via `--extern`. + +↩ [*Registries*][registries] + +# Unresolved questions +[unresolved-questions]: #unresolved-questions + +The following small details are likely to be bikeshed prior to this part of the +RFC's acceptance or stabilisation and aren't pertinent to the overall design: + +## What syntax is used to identify dependencies on the standard library in `Cargo.toml`? +[unresolved-dep-syntax]: #what-syntax-is-used-to-identify-dependencies-on-the-standard-library-in-cargotoml + +What syntax should be used for the explicit standard library dependencies? +`builtin = true`? `sysroot = true`? + +↩ [*Proposal*][proposal] + +## What is the format for builtin dependencies in `Cargo.lock`? +[unresolved-lockfile]: #what-is-the-format-for-builtin-dependencies-in-cargolock + +How should `builtin` deps be represented in lockfiles? Is `builtin = true` +appropriate? Could the `source` field be reused with the string "builtin" or +should it stay only as a URL+scheme? + +↩ [*Proposal*][proposal] + +## What syntax is used to patch dependencies on the standard library in `Cargo.toml`? +[unresolved-patch-syntax]: #what-syntax-is-used-to-patch-dependencies-on-the-standard-library-in-cargotoml + +`[patch.builtin]` is the natural syntax given `builtin` is a new source, but may +be needlessly different to existing packages. + +↩ [*Patches*][patches] + +## Should standard library dependencies default to public? +[unresolved-std-default-public]: #should-standard-library-dependencies-default-to-public + +Standard library dependencies defaulting to public is a trade-off between +special-casing in Cargo and requiring that any user with a dependency on the +standard library who re-exports from the standard library manually declare their +dependency as public. + +It is also inconsistent with +[*Why not use `noprelude` for explicit `builtin` dependencies?*][rationale-explicit-noprelude] +which aims to make builtin dependencies consistent with other dependencies in +the manifest. + +↩ [*Public and private dependencies*][public-and-private-dependencies] + +## Should we support `build-dependencies`? +[unresolved-build-deps]: #should-we-support-build-dependencies + +Allowing `builtin` dependencies to be used in `dependencies` and +`dev-dependencies` but not in `build-dependencies` is an inconsistency. + +However, supporting `builtin` dependencies in `build-dependencies` would permit +no-std build scripts. It is unclear whether supporting no-std build scripts +would be desirable. + +↩ [*`dev-dependencies` and `build-dependencies`*][dev-dependencies-and-build-dependencies] + +# Prior art +[prior-art]: #prior-art + +See the [*Background*][background] and [*History*][history] of the build-std +context RFC. + +# Future possibilities +[future-possibilities]: #future-possibilities + +There are many possible follow-ups to this part of the RFC: + +## Allow unstable crate names to be referenced behind cfgs without requiring nightly +[future-cfg-unstable-crate-name]: #allow-unstable-crate-names-to-be-referenced-behind-cfgs-without-requiring-nightly + +It is possible to allow builtin dependencies on unstable crate names to exist +behind cfgs and for the crate to be compiled on a stable toolchain as long as +the cfgs are not active. This is a trade-off - it adds a large constraint on +when Cargo can validate the set of crate names, but would enable users to avoid +using nightly or doing MSRV bumps. + +↩ [*Proposal*][proposal] + +## Allow `builtin` source replacement +[future-source-replacement]: #allow-builtin-source-replacement + +This involves allowing the user to blanket-override the standard library sources +with a `[source.builtin]` section of the Cargo configuration. + +As [rationale-source-replacement] details it is unclear if users need to do this +or if it's even something the Rust project wishes to support. + +↩ [*Proposal*][proposal] + +## Remove `rustc_dep_of_std` +[future-rustc_dep_of_std]: #remove-rustc_dep_of_std + +With first-class explicit dependencies on the standard library, +`rustc_dep_of_std` is rendered unnecessary and explicit dependencies on the +standard library can always be present in the `Cargo.toml` of the standard +library's dependencies. + +The `core`, `alloc` and `std` dependencies can be patched in the standard +library's workspace to point to the local copy of the crates. This avoids +`crates.io` dependencies needing to add support for `rustc_dep_of_std` before +the standard library can depend on them. + +↩ [*Proposal*][proposal] + +## Allow enabling/disabling features with build-std +[future-features]: #allow-enablingdisabling-features-with-build-std + +This would require the library team be comfortable with the features declared on +the standard library being part of the stable interface of the standard library. + +The behaviour of disabling default features has been highlighted as a potential +cause of breaking changes. + +Alternatively, this could be enabled alongside another proposal which would +allow the standard library to define some features as stable and others as +unstable. + +As there are some features that Cargo will set itself when appropriate (e.g. to +enable or disable [panic runtimes][panic-strategies] or +[`compiler-builtins/mem`][compiler-builtins-mem]), Cargo may need to always +prevent some otherwise stable features from being toggled as it controls those. + +↩ [*Features*][features] + +## Allow local builds of `compiler-rt` intrinsics +[future-compiler-builtins-c]: #allow-local-builds-of-compiler-rt-intrinsics + +The [`c` feature][background-dependencies] of `compiler_builtins` (which is also +exposed by `core`, `alloc` and `std` through `compiler-builtins-c`) causes its +`build.rs` file to build and link in more optimised C versions of intrinsics. + +It will not be enabled by default because it is possible that the target +platform does not have a suitable C compiler available. The user being able to +enable this manually will be enabled through work on features (see +[*Allow enabling/disabling features with build-std*][future-features]). Once the +user can enable `compiler-builtins/c`, they will need to manually configure +`CFLAGS` to ensure that the C components will link with Rust code. + +[build-std project goal]: https://rust-lang.github.io/rust-project-goals/2025h2/build-std.html + +[rfcs#3873]: https://github.com/rust-lang/rfcs/pull/3873 +[rfcs#3874]: https://github.com/rust-lang/rfcs/pull/3874 +[rfcs#3874-proposal]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#proposal +[rfcs#3874-rationale-and-alternatives]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#rationale-and-alternatives +[rfcs#3874-unresolved-questions]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#unresolved-questions +[rfcs#3874-future-possibilities]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#future-possibilities + +[build-std-context]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md +[background]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#background +[history]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#history +[motivations]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#motivation +[background-dependencies]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#dependencies +[always]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#proposal +[standard-library-crate-stability]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#standard-library-crate-stability +[panic-strategies]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#panic-strategies +[compiler-builtins-mem]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#compiler-builtinsmem +[always-noprelude]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#why-use-noprelude-with---extern + +[cargo-docs-renaming]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml +[cargo-json-schema]: https://doc.rust-lang.org/cargo/reference/registry-index.html#json-schema +[cargo-registry-web-publish]: https://doc.rust-lang.org/cargo/reference/registry-web-api.html#publish +[cargo-pkgid-spec]: https://doc.rust-lang.org/cargo/reference/pkgid-spec.html +[embed-rs-source]: https://github.com/embed-rs/stm32f7-discovery/blob/e2bf713263791c028c2a897f2eb1830d7f09eceb/core/src/lib.rs#L7 +[rust-extern-prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude + +[cargo-add]: https://doc.rust-lang.org/cargo/commands/cargo-add.html +[cargo-bench]: https://doc.rust-lang.org/cargo/commands/cargo-bench.html +[cargo-build]: https://doc.rust-lang.org/cargo/commands/cargo-build.html +[cargo-check]: https://doc.rust-lang.org/cargo/commands/cargo-check.html +[cargo-clean]: https://doc.rust-lang.org/cargo/commands/cargo-clean.html +[cargo-clippy]: https://doc.rust-lang.org/cargo/commands/cargo-clippy.html +[cargo-doc]: https://doc.rust-lang.org/cargo/commands/cargo-doc.html +[cargo-fetch]: https://doc.rust-lang.org/cargo/commands/cargo-fetch.html +[cargo-fix]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html +[cargo-fmt]: https://doc.rust-lang.org/cargo/commands/cargo-fmt.html +[cargo-generate-lockfile]: https://doc.rust-lang.org/cargo/commands/cargo-generate-lockfile.html +[cargo-help]: https://doc.rust-lang.org/cargo/commands/cargo-help.html +[cargo-info]: https://doc.rust-lang.org/cargo/commands/cargo-info.html +[cargo-init]: https://doc.rust-lang.org/cargo/commands/cargo-init.html +[cargo-install]: https://doc.rust-lang.org/cargo/commands/cargo-install.html +[cargo-locate-project]: https://doc.rust-lang.org/cargo/commands/cargo-locate-project.html +[cargo-login]: https://doc.rust-lang.org/cargo/commands/cargo-login.html +[cargo-logout]: https://doc.rust-lang.org/cargo/commands/cargo-login.html +[cargo-metadata]: https://doc.rust-lang.org/cargo/commands/cargo-metadata.html +[cargo-miri]: https://doc.rust-lang.org/cargo/commands/cargo-miri.html +[cargo-new]: https://doc.rust-lang.org/cargo/commands/cargo-new.html +[cargo-owner]: https://doc.rust-lang.org/cargo/commands/cargo-owner.html +[cargo-package]: https://doc.rust-lang.org/cargo/commands/cargo-package.html +[cargo-pkgid]: https://doc.rust-lang.org/cargo/commands/cargo-pkgid.html +[cargo-publish]: https://doc.rust-lang.org/cargo/commands/cargo-publish.html +[cargo-remove]: https://doc.rust-lang.org/cargo/commands/cargo-remove.html +[cargo-report]: https://doc.rust-lang.org/cargo/commands/cargo-report.html +[cargo-run]: https://doc.rust-lang.org/cargo/commands/cargo-run.html +[cargo-rustc]: https://doc.rust-lang.org/cargo/commands/cargo-rustc.html +[cargo-rustdoc]: https://doc.rust-lang.org/cargo/commands/cargo-rustdoc.html +[cargo-search]: https://doc.rust-lang.org/cargo/commands/cargo-search.html +[cargo-test]: https://doc.rust-lang.org/cargo/commands/cargo-test.html +[cargo-tree]: https://doc.rust-lang.org/cargo/commands/cargo-tree.html +[cargo-uninstall]: https://doc.rust-lang.org/cargo/commands/cargo-uninstall.html +[cargo-update]: https://doc.rust-lang.org/cargo/commands/cargo-update.html +[cargo-vendor]: https://doc.rust-lang.org/cargo/commands/cargo-vendor.html +[cargo-version]: https://doc.rust-lang.org/cargo/commands/cargo-version.html +[cargo-yank]: https://doc.rust-lang.org/cargo/commands/cargo-yank.html \ No newline at end of file From 3dba0edfa301ecdc11c7a8a523ab397449a0d304 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 31 Oct 2025 11:59:26 +0000 Subject: [PATCH 02/43] rename to rfc 3875 --- ...-dependencies.md => 3875-build-std-explicit-dependencies.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename text/{0000-build-std-explicit-dependencies.md => 3875-build-std-explicit-dependencies.md} (99%) diff --git a/text/0000-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md similarity index 99% rename from text/0000-build-std-explicit-dependencies.md rename to text/3875-build-std-explicit-dependencies.md index 0aef6c68141..9f2494e3ffe 100644 --- a/text/0000-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1,6 +1,6 @@ - Feature Name: `build-std-explicit-dependencies` - Start Date: 2025-06-05 -- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- RFC PR: [rust-lang/rfcs#3875](https://github.com/rust-lang/rfcs/pull/3875) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) # Summary From cfc101a8b3d0dac7845052bb22ae272fbee05c0e Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 12:55:11 +0000 Subject: [PATCH 03/43] move links to relevant sections --- text/3875-build-std-explicit-dependencies.md | 179 ++++++++++--------- 1 file changed, 92 insertions(+), 87 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 9f2494e3ffe..86beccd112b 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -15,9 +15,9 @@ different crates to require different standard library crates. RFCs:** 1. build-std context ([rfcs#3873]) - - [Background][background] - - [History][history] - - [Motivation][motivation] + - [Background][rfcs#3873-background] + - [History][rfcs#3873-history] + - [Motivation][rfcs#3873-motivation] 2. `build-std="always"` ([rfcs#3874]) - [Proposal][rfcs#3874-proposal] - [Rationale and alternatives][rfcs#3874-rationale-and-alternatives] @@ -31,13 +31,27 @@ RFCs:** 4. `build-std="compatible"` (RFC not opened yet) 5. `build-std="match-profile"` (RFC not opened yet) +[build-std project goal]: https://rust-lang.github.io/rust-project-goals/2025h2/build-std.html + +[rfcs#3873]: https://github.com/rust-lang/rfcs/pull/3873 +[rfcs#3873-proposal]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#proposal +[rfcs#3873-background]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#background +[rfcs#3873-history]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#history +[rfcs#3873-motivation]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#motivation +[rfcs#3873-dependencies]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#dependencies + +[rfcs#3874]: https://github.com/rust-lang/rfcs/pull/3874 +[rfcs#3874-proposal]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#proposal +[rfcs#3874-rationale-and-alternatives]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#rationale-and-alternatives +[rfcs#3874-unresolved-questions]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#unresolved-questions +[rfcs#3874-future-possibilities]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#future-possibilities + # Motivation [motivation]: #motivation This RFC builds on a large collection of prior art collated in the -[`build-std-context`][build-std-context] RFC. It does not directly address the -main [motivations] it identifies but supports -later proposals. +[`build-std-context`][rfcs#3873-proposal] RFC. It does not directly address the +main [rfcs#3873-motivation] it identifies but supports later proposals. The main motivation for this proposal is to support future extensions to build-std which allow public/private standard library dependencies or enabling @@ -85,14 +99,16 @@ Cargo feature. Crates without an explicit dependency on the standard library now have a implicit dependency ([?][rationale-no-migration]) on that target's default set -of standard library crates (see [build-std-always][standard-library-crate-stability]). -Any explicit `builtin` dependency present in any dependency table will disable -the implicit dependencies. +of standard library crates (see +[build-std-always][rfcs#3874-standard-library-crate-stability]). Any explicit +`builtin` dependency present in any dependency table will disable the implicit +dependencies. > [!NOTE] > > Implicit dependencies are passed to rustc with the `noprelude` modifier to -> ensure backwards compatibility as in [`build-std=always`][always-noprelude]. +> ensure backwards compatibility as in +> [`build-std=always`][rfcs#3874-noprelude]. When a `std` dependency is present an additional implicit dependency on the `test` crate is added for crates that are being tested with the default test @@ -216,6 +232,9 @@ files ([?][rationale-cargo-lock]). - [*Allow `builtin` source replacement*][future-source-replacement] - [*Remove `rustc_dep_of_std`*][future-rustc_dep_of_std] +[rfcs#3874-standard-library-crate-stability]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#standard-library-crate-stability +[rfcs#3874-noprelude]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#why-use-noprelude-with---extern + ## Non-`builtin` standard library dependencies [non-builtin-standard-library-dependencies]: #non-builtin-standard-library-dependencies @@ -356,8 +375,8 @@ implicit dependencies. It is possible for `dev-dependencies` to have additional requiring `std` when the regular dependencies only require `core`). Build scripts and proc macros continue to use the pre-built standard library as -in [`build-std=always`][always], and so explicit dependencies on the standard -library are not supported in `build-dependencies`. +in [`build-std=always`][rfcs#3874-proposal], and so explicit dependencies on the +standard library are not supported in `build-dependencies`. *See the following sections for relevant unresolved questions:* @@ -430,6 +449,8 @@ similarly be updated to support `builtin_deps`. - [*Why add a new key to Cargo's registry index JSON schema?*][rationale-cargo-builtindeps] - [*Why can `builtin_deps` shadow other packages in the registry?*][rationale-cargo-index-shadowing] +[cargo-registry-web-publish]: https://doc.rust-lang.org/cargo/reference/registry-web-api.html#publish + ## Cargo subcommands [cargo-subcommands]: #cargo-subcommands @@ -612,6 +633,47 @@ This part of the RFC has no implications for the following Cargo subcommands: - [`cargo version`][cargo-version] - [`cargo yank`][cargo-yank] +[cargo-pkgid-spec]: https://doc.rust-lang.org/cargo/reference/pkgid-spec.html + +[cargo-add]: https://doc.rust-lang.org/cargo/commands/cargo-add.html +[cargo-bench]: https://doc.rust-lang.org/cargo/commands/cargo-bench.html +[cargo-build]: https://doc.rust-lang.org/cargo/commands/cargo-build.html +[cargo-check]: https://doc.rust-lang.org/cargo/commands/cargo-check.html +[cargo-clean]: https://doc.rust-lang.org/cargo/commands/cargo-clean.html +[cargo-clippy]: https://doc.rust-lang.org/cargo/commands/cargo-clippy.html +[cargo-doc]: https://doc.rust-lang.org/cargo/commands/cargo-doc.html +[cargo-fetch]: https://doc.rust-lang.org/cargo/commands/cargo-fetch.html +[cargo-fix]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html +[cargo-fmt]: https://doc.rust-lang.org/cargo/commands/cargo-fmt.html +[cargo-generate-lockfile]: https://doc.rust-lang.org/cargo/commands/cargo-generate-lockfile.html +[cargo-help]: https://doc.rust-lang.org/cargo/commands/cargo-help.html +[cargo-info]: https://doc.rust-lang.org/cargo/commands/cargo-info.html +[cargo-init]: https://doc.rust-lang.org/cargo/commands/cargo-init.html +[cargo-install]: https://doc.rust-lang.org/cargo/commands/cargo-install.html +[cargo-locate-project]: https://doc.rust-lang.org/cargo/commands/cargo-locate-project.html +[cargo-login]: https://doc.rust-lang.org/cargo/commands/cargo-login.html +[cargo-logout]: https://doc.rust-lang.org/cargo/commands/cargo-login.html +[cargo-metadata]: https://doc.rust-lang.org/cargo/commands/cargo-metadata.html +[cargo-miri]: https://doc.rust-lang.org/cargo/commands/cargo-miri.html +[cargo-new]: https://doc.rust-lang.org/cargo/commands/cargo-new.html +[cargo-owner]: https://doc.rust-lang.org/cargo/commands/cargo-owner.html +[cargo-package]: https://doc.rust-lang.org/cargo/commands/cargo-package.html +[cargo-pkgid]: https://doc.rust-lang.org/cargo/commands/cargo-pkgid.html +[cargo-publish]: https://doc.rust-lang.org/cargo/commands/cargo-publish.html +[cargo-remove]: https://doc.rust-lang.org/cargo/commands/cargo-remove.html +[cargo-report]: https://doc.rust-lang.org/cargo/commands/cargo-report.html +[cargo-run]: https://doc.rust-lang.org/cargo/commands/cargo-run.html +[cargo-rustc]: https://doc.rust-lang.org/cargo/commands/cargo-rustc.html +[cargo-rustdoc]: https://doc.rust-lang.org/cargo/commands/cargo-rustdoc.html +[cargo-search]: https://doc.rust-lang.org/cargo/commands/cargo-search.html +[cargo-test]: https://doc.rust-lang.org/cargo/commands/cargo-test.html +[cargo-tree]: https://doc.rust-lang.org/cargo/commands/cargo-tree.html +[cargo-uninstall]: https://doc.rust-lang.org/cargo/commands/cargo-uninstall.html +[cargo-update]: https://doc.rust-lang.org/cargo/commands/cargo-update.html +[cargo-vendor]: https://doc.rust-lang.org/cargo/commands/cargo-vendor.html +[cargo-version]: https://doc.rust-lang.org/cargo/commands/cargo-version.html +[cargo-yank]: https://doc.rust-lang.org/cargo/commands/cargo-yank.html + # Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives @@ -643,8 +705,8 @@ required: - Cargo could allow the user to specify which crates are required to be built, such as with the existing options to the `-Zbuild-std=` flag. - [`build-std=always`][always] proposes a `build-std-crates` flag to enable - explicit dependencies to be a separate part of this RFC. + [`build-std=always`][rfcs#3874-proposal] proposes a `build-std-crates` flag to + enable explicit dependencies to be a separate part of this RFC. Furthermore, supporting explicit dependencies on standard library crates enables use of other Cargo features that apply to dependencies in a natural and @@ -747,7 +809,7 @@ Supporting implicit dependencies allows the majority of the Rust ecosystem from having to make any changes - `no_std` crates (or crates with a `std` feature) will still benefit from adding explicit dependencies as allow them to be easily used with `no_std` targets but users can still work around any legacy crates in -the graph with [`build-std-crates`][always]. +the graph with [`build-std-crates`][rfcs#3874-proposal]. ↩ [*Proposal*][proposal] @@ -767,6 +829,9 @@ of the user's names for `builtin` crates. ↩ [*Proposal*][proposal] +[cargo-docs-renaming]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml +[rust-extern-prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude + ## Why disallow source replacement on `builtin` packages? [rationale-source-replacement]: #why-disallow-source-replacement-on-builtin-packages @@ -891,6 +956,9 @@ take today, using `path` dependencies for the standard library to shadow it). ↩ [*Registries*][registries] +[cargo-json-schema]: https://doc.rust-lang.org/cargo/reference/registry-index.html#json-schema +[embed-rs-source]: https://github.com/embed-rs/stm32f7-discovery/blob/e2bf713263791c028c2a897f2eb1830d7f09eceb/core/src/lib.rs#L7 + ## Why can `builtin_deps` shadow other packages in the registry? [rationale-cargo-index-shadowing]: #why-can-builtin_deps-shadow-other-packages-in-the-registry @@ -965,8 +1033,8 @@ would be desirable. # Prior art [prior-art]: #prior-art -See the [*Background*][background] and [*History*][history] of the build-std -context RFC. +See the [*Background*][rfcs#3873-background] and [*History*][rfcs#3873-history] +of the build-std context RFC. # Future possibilities [future-possibilities]: #future-possibilities @@ -1024,16 +1092,19 @@ allow the standard library to define some features as stable and others as unstable. As there are some features that Cargo will set itself when appropriate (e.g. to -enable or disable [panic runtimes][panic-strategies] or -[`compiler-builtins/mem`][compiler-builtins-mem]), Cargo may need to always +enable or disable [panic runtimes][rfcs#3874-panic-strategies] or +[`compiler-builtins/mem`][rfcs#3874-compiler-builtins-mem]), Cargo may need to always prevent some otherwise stable features from being toggled as it controls those. ↩ [*Features*][features] +[rfcs#3874-panic-strategies]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#panic-strategies +[rfcs#3874-compiler-builtins-mem]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#compiler-builtinsmem + ## Allow local builds of `compiler-rt` intrinsics [future-compiler-builtins-c]: #allow-local-builds-of-compiler-rt-intrinsics -The [`c` feature][background-dependencies] of `compiler_builtins` (which is also +The [`c` feature][rfcs#3873-dependencies] of `compiler_builtins` (which is also exposed by `core`, `alloc` and `std` through `compiler-builtins-c`) causes its `build.rs` file to build and link in more optimised C versions of intrinsics. @@ -1042,70 +1113,4 @@ platform does not have a suitable C compiler available. The user being able to enable this manually will be enabled through work on features (see [*Allow enabling/disabling features with build-std*][future-features]). Once the user can enable `compiler-builtins/c`, they will need to manually configure -`CFLAGS` to ensure that the C components will link with Rust code. - -[build-std project goal]: https://rust-lang.github.io/rust-project-goals/2025h2/build-std.html - -[rfcs#3873]: https://github.com/rust-lang/rfcs/pull/3873 -[rfcs#3874]: https://github.com/rust-lang/rfcs/pull/3874 -[rfcs#3874-proposal]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#proposal -[rfcs#3874-rationale-and-alternatives]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#rationale-and-alternatives -[rfcs#3874-unresolved-questions]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#unresolved-questions -[rfcs#3874-future-possibilities]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#future-possibilities - -[build-std-context]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md -[background]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#background -[history]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#history -[motivations]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#motivation -[background-dependencies]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#dependencies -[always]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#proposal -[standard-library-crate-stability]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#standard-library-crate-stability -[panic-strategies]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#panic-strategies -[compiler-builtins-mem]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#compiler-builtinsmem -[always-noprelude]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#why-use-noprelude-with---extern - -[cargo-docs-renaming]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml -[cargo-json-schema]: https://doc.rust-lang.org/cargo/reference/registry-index.html#json-schema -[cargo-registry-web-publish]: https://doc.rust-lang.org/cargo/reference/registry-web-api.html#publish -[cargo-pkgid-spec]: https://doc.rust-lang.org/cargo/reference/pkgid-spec.html -[embed-rs-source]: https://github.com/embed-rs/stm32f7-discovery/blob/e2bf713263791c028c2a897f2eb1830d7f09eceb/core/src/lib.rs#L7 -[rust-extern-prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude - -[cargo-add]: https://doc.rust-lang.org/cargo/commands/cargo-add.html -[cargo-bench]: https://doc.rust-lang.org/cargo/commands/cargo-bench.html -[cargo-build]: https://doc.rust-lang.org/cargo/commands/cargo-build.html -[cargo-check]: https://doc.rust-lang.org/cargo/commands/cargo-check.html -[cargo-clean]: https://doc.rust-lang.org/cargo/commands/cargo-clean.html -[cargo-clippy]: https://doc.rust-lang.org/cargo/commands/cargo-clippy.html -[cargo-doc]: https://doc.rust-lang.org/cargo/commands/cargo-doc.html -[cargo-fetch]: https://doc.rust-lang.org/cargo/commands/cargo-fetch.html -[cargo-fix]: https://doc.rust-lang.org/cargo/commands/cargo-fix.html -[cargo-fmt]: https://doc.rust-lang.org/cargo/commands/cargo-fmt.html -[cargo-generate-lockfile]: https://doc.rust-lang.org/cargo/commands/cargo-generate-lockfile.html -[cargo-help]: https://doc.rust-lang.org/cargo/commands/cargo-help.html -[cargo-info]: https://doc.rust-lang.org/cargo/commands/cargo-info.html -[cargo-init]: https://doc.rust-lang.org/cargo/commands/cargo-init.html -[cargo-install]: https://doc.rust-lang.org/cargo/commands/cargo-install.html -[cargo-locate-project]: https://doc.rust-lang.org/cargo/commands/cargo-locate-project.html -[cargo-login]: https://doc.rust-lang.org/cargo/commands/cargo-login.html -[cargo-logout]: https://doc.rust-lang.org/cargo/commands/cargo-login.html -[cargo-metadata]: https://doc.rust-lang.org/cargo/commands/cargo-metadata.html -[cargo-miri]: https://doc.rust-lang.org/cargo/commands/cargo-miri.html -[cargo-new]: https://doc.rust-lang.org/cargo/commands/cargo-new.html -[cargo-owner]: https://doc.rust-lang.org/cargo/commands/cargo-owner.html -[cargo-package]: https://doc.rust-lang.org/cargo/commands/cargo-package.html -[cargo-pkgid]: https://doc.rust-lang.org/cargo/commands/cargo-pkgid.html -[cargo-publish]: https://doc.rust-lang.org/cargo/commands/cargo-publish.html -[cargo-remove]: https://doc.rust-lang.org/cargo/commands/cargo-remove.html -[cargo-report]: https://doc.rust-lang.org/cargo/commands/cargo-report.html -[cargo-run]: https://doc.rust-lang.org/cargo/commands/cargo-run.html -[cargo-rustc]: https://doc.rust-lang.org/cargo/commands/cargo-rustc.html -[cargo-rustdoc]: https://doc.rust-lang.org/cargo/commands/cargo-rustdoc.html -[cargo-search]: https://doc.rust-lang.org/cargo/commands/cargo-search.html -[cargo-test]: https://doc.rust-lang.org/cargo/commands/cargo-test.html -[cargo-tree]: https://doc.rust-lang.org/cargo/commands/cargo-tree.html -[cargo-uninstall]: https://doc.rust-lang.org/cargo/commands/cargo-uninstall.html -[cargo-update]: https://doc.rust-lang.org/cargo/commands/cargo-update.html -[cargo-vendor]: https://doc.rust-lang.org/cargo/commands/cargo-vendor.html -[cargo-version]: https://doc.rust-lang.org/cargo/commands/cargo-version.html -[cargo-yank]: https://doc.rust-lang.org/cargo/commands/cargo-yank.html \ No newline at end of file +`CFLAGS` to ensure that the C components will link with Rust code. \ No newline at end of file From 5b41f450bb775458d99e16b3b3a3baab376912ae Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 13:53:22 +0000 Subject: [PATCH 04/43] move no-std possibility from previous rfc --- text/3875-build-std-explicit-dependencies.md | 28 ++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 86beccd112b..578f6dccdb7 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -228,6 +228,7 @@ files ([?][rationale-cargo-lock]). *See the following sections for future possibilities:* +- [*Replace `#![no_std]` as the source-of-truth for whether a crate depends on `std`*][future-replace-no_std] - [*Allow unstable crate names to be referenced behind cfgs without requiring nightly*][future-cfg-unstable-crate-name] - [*Allow `builtin` source replacement*][future-source-replacement] - [*Remove `rustc_dep_of_std`*][future-rustc_dep_of_std] @@ -1041,6 +1042,33 @@ of the build-std context RFC. There are many possible follow-ups to this part of the RFC: +## Replace `#![no_std]` as the source-of-truth for whether a crate depends on `std` +[future-replace-no_std]: #replace-no_std-as-the-source-of-truth-for-whether-a-crate-depends-on-std + +Crates can currently use the crate attribute `#![no_std]` to indicate a lack of +dependency on `std`. Introducing `build-std-crates` from [RFC #3874][rfcs#3874] +or explicit dependencies would add a second way for the user to indicate a lack +of dependency on the standard library. It could therefore be desirable to +deprecate `#![no_std]` so that there remains only a single way to express a +dependency on the standard library. + +`#![no_std]` serves two purposes - it stops the compiler from adding `std` to +the extern prelude and it prevents the user from depending on anything from +`std` accidentally. rustc's default behaviour of loading `std` when not +explicitly provided the crate via an `--extern` flag should be preserved for +backwards-compatibility with existing direct invocations of rustc. + +`#![no_std]` could instead become a compiler flag which would indicate to the +compiler that `std` should not be loaded by default and that `core`'s prelude +should be used instead. Cargo would use this flag when driving rustc, providing +explicit paths to the newly-built or pre-built standard library crates, just as +with any other dependency. + +In addition, `#![no_std]` could be migrated to denying a lint which would +prevent use of items from `std`. + +↩ [*Proposal*][proposal] + ## Allow unstable crate names to be referenced behind cfgs without requiring nightly [future-cfg-unstable-crate-name]: #allow-unstable-crate-names-to-be-referenced-behind-cfgs-without-requiring-nightly From 48899c1ae2ba9fe8aa69309d35a35191adc5aa81 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 14:09:40 +0000 Subject: [PATCH 05/43] reference object form of build-std from prev rfc --- text/3875-build-std-explicit-dependencies.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 578f6dccdb7..8b7df74a260 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -8,7 +8,7 @@ Allow users to add explicit dependencies on standard library crates in the `Cargo.toml`. This enables Cargo to determine which standard library crates are -required by the crate graph without `build-std-crates` being set and for +required by the crate graph without `build-std.crates` being set and for different crates to require different standard library crates. **This RFC is is part of the [build-std project goal] and a series of build-std @@ -706,7 +706,7 @@ required: - Cargo could allow the user to specify which crates are required to be built, such as with the existing options to the `-Zbuild-std=` flag. - [`build-std=always`][rfcs#3874-proposal] proposes a `build-std-crates` flag to + [`build-std=always`][rfcs#3874-proposal] proposes a `build-std.crates` flag to enable explicit dependencies to be a separate part of this RFC. Furthermore, supporting explicit dependencies on standard library crates enables @@ -810,7 +810,7 @@ Supporting implicit dependencies allows the majority of the Rust ecosystem from having to make any changes - `no_std` crates (or crates with a `std` feature) will still benefit from adding explicit dependencies as allow them to be easily used with `no_std` targets but users can still work around any legacy crates in -the graph with [`build-std-crates`][rfcs#3874-proposal]. +the graph with [`build-std.crates`][rfcs#3874-proposal]. ↩ [*Proposal*][proposal] @@ -1046,7 +1046,7 @@ There are many possible follow-ups to this part of the RFC: [future-replace-no_std]: #replace-no_std-as-the-source-of-truth-for-whether-a-crate-depends-on-std Crates can currently use the crate attribute `#![no_std]` to indicate a lack of -dependency on `std`. Introducing `build-std-crates` from [RFC #3874][rfcs#3874] +dependency on `std`. Introducing `build-std.crates` from [RFC #3874][rfcs#3874] or explicit dependencies would add a second way for the user to indicate a lack of dependency on the standard library. It could therefore be desirable to deprecate `#![no_std]` so that there remains only a single way to express a From 87c3a957158e3d31ab299999948cc25911b70d1d Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 14:09:40 +0000 Subject: [PATCH 06/43] mention MSRV-implications of implicit builtins in registry index entries --- text/3875-build-std-explicit-dependencies.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 8b7df74a260..3619d16651e 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -441,8 +441,9 @@ similarly be updated to support `builtin_deps`. > > When producing a registry index entry for a package Cargo will not serialise > any `builtin` dependencies it inferred. This allows the set of inferred -> packages to change in the future if needed. Similarly, the published -> `Cargo.toml` will not explicitly declare any inferred dependencies. +> packages to change in the future if needed and prevents publishing a package +> with a new Cargo from raising your MSRV. Similarly, the published `Cargo.toml` +> will not explicitly declare any inferred dependencies. *See the following sections for rationale/alternatives:* @@ -1052,6 +1053,7 @@ of dependency on the standard library. It could therefore be desirable to deprecate `#![no_std]` so that there remains only a single way to express a dependency on the standard library. + `#![no_std]` serves two purposes - it stops the compiler from adding `std` to the extern prelude and it prevents the user from depending on anything from `std` accidentally. rustc's default behaviour of loading `std` when not From c214948a9728627caf23fb8f5475ccac34c618b2 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 14:47:17 +0000 Subject: [PATCH 07/43] add public with cargo add after stabilisation --- text/3875-build-std-explicit-dependencies.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 3619d16651e..80630afc073 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -482,6 +482,19 @@ names as described in [the rationale][rationale-unstable-builtin-crates]. If attempting to add a `builtin` crate with features then this will fail unless the required `cargo-feature` is enabled as described in [*Features*][features]. +Once public and private dependencies are stabilised ([rust#44663]), `cargo add` +will add `public = true` by default for the standard library dependencies added: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true, public = true } # <-- this would be added +``` + [`cargo info`][cargo-info] will learn how to print information for the built-in `std`, `alloc` and `core` dependencies: @@ -635,6 +648,7 @@ This part of the RFC has no implications for the following Cargo subcommands: - [`cargo version`][cargo-version] - [`cargo yank`][cargo-yank] +[rust#44663]: https://github.com/rust-lang/rust/issues/44663 [cargo-pkgid-spec]: https://doc.rust-lang.org/cargo/reference/pkgid-spec.html [cargo-add]: https://doc.rust-lang.org/cargo/commands/cargo-add.html From 6dccec5c2e031ae028314998fd9f7a215ca050a3 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 14:49:12 +0000 Subject: [PATCH 08/43] clarify implicit implicit not explicit --- text/3875-build-std-explicit-dependencies.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 80630afc073..dd3eda99fd1 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -903,9 +903,9 @@ desirable. See [rationale-default-public]: #why-default-to-public-for-standard-library-dependencies There are crates building on stable which re-export from the standard library. -If the standard library dependencies were not public then these crates would +If implicit standard library dependencies were not public then these crates would start to trigger the `exported_private_dependencies` lint when upgrading to a -version of Cargo with a standard library dependency. +version of Cargo with a implicit standard library dependency. ↩ [*Public and private dependencies*][public-and-private-dependencies] From 5d3a05898c8cbc2266fd1214dc37a1d5464c25d5 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 14:53:19 +0000 Subject: [PATCH 09/43] remove orphaned question --- text/3875-build-std-explicit-dependencies.md | 12 ------------ 1 file changed, 12 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index dd3eda99fd1..4cd5235f3f5 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -909,18 +909,6 @@ version of Cargo with a implicit standard library dependency. ↩ [*Public and private dependencies*][public-and-private-dependencies] -## Why follow the default privacy of explicit standard library dependencies? -[rationale-explicit-private]: #why-follow-the-default-privacy-of-explicit-standard-library-dependencies - -This may be unintuitive when a user first writes an explicit standard library -dependency, triggering the `exported_private_dependency` lint, but this would be -caught immediately by the user. However, it is also unintuitive that the default -for privacy of a explicitly written dependency would depend on which crate the -dependency was (i.e. the standard library has a different default than -everything else). - -↩ [*Public and private dependencies*][public-and-private-dependencies] - ## Why add standard library crates to Cargo's index? [rationale-cargo-index]: #why-add-standard-library-crates-to-cargos-index From f02b84908cf33e36e55e8e15e87d8efa3c5d366c Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 14:54:33 +0000 Subject: [PATCH 10/43] mention sysroot isn't great --- text/3875-build-std-explicit-dependencies.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 4cd5235f3f5..4daab162c57 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -986,7 +986,8 @@ RFC's acceptance or stabilisation and aren't pertinent to the overall design: [unresolved-dep-syntax]: #what-syntax-is-used-to-identify-dependencies-on-the-standard-library-in-cargotoml What syntax should be used for the explicit standard library dependencies? -`builtin = true`? `sysroot = true`? +`builtin = true`? `sysroot = true` (not ideal, as "sysroot" isn't a concept that +we typically introduce to end-users)? ↩ [*Proposal*][proposal] From 8996003fd30dd66a267c1ccda11ab03185691cfa Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 14:59:11 +0000 Subject: [PATCH 11/43] unblocks cargo#8798 --- text/3875-build-std-explicit-dependencies.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 4daab162c57..339ca857cb2 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1044,7 +1044,12 @@ of the build-std context RFC. # Future possibilities [future-possibilities]: #future-possibilities -There are many possible follow-ups to this part of the RFC: +This RFC unblocks fixing [rust-lang/cargo#8798], enabling no-std crates from +being prevented from having std dependencies. + +There are also many possible follow-ups to this part of the RFC: + +[rust-lang/cargo#8798]: https://github.com/rust-lang/cargo/issues/8798 ## Replace `#![no_std]` as the source-of-truth for whether a crate depends on `std` [future-replace-no_std]: #replace-no_std-as-the-source-of-truth-for-whether-a-crate-depends-on-std From 4b870f6764b6cfc16cb1bc691292122b480b3b2a Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 3 Nov 2025 15:09:30 +0000 Subject: [PATCH 12/43] include std deps in cargo metadata --- text/3875-build-std-explicit-dependencies.md | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 339ca857cb2..959dffd1001 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -527,9 +527,8 @@ documentation: https://doc.rust-lang.org/1.86.0/core/index.html [`cargo metadata`][cargo-metadata] will emit `std`, `alloc` and `core` dependencies to the metadata emitted by `cargo metadata` (when those crates are -explicit dependencies). None of the standard library's dependencies will be -included. `source` would be set to `builtin` and the remaining fields would be -set like any other dependency. +explicit dependencies). `source` would be set to `builtin` and the remaining +fields would be set like any other dependency. > [!NOTE] > From fb12d505be816d9820152f603592dcca684db42a Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 12 Nov 2025 13:35:39 +0000 Subject: [PATCH 13/43] add std deps in cargo metadata to unresolved qs --- text/3875-build-std-explicit-dependencies.md | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 959dffd1001..9084c5de649 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -528,7 +528,8 @@ documentation: https://doc.rust-lang.org/1.86.0/core/index.html [`cargo metadata`][cargo-metadata] will emit `std`, `alloc` and `core` dependencies to the metadata emitted by `cargo metadata` (when those crates are explicit dependencies). `source` would be set to `builtin` and the remaining -fields would be set like any other dependency. +fields would be set like any other dependency. See also unresolved question +[*Should `cargo metadata` include the standard library's dependencies?*][unresolved-cargo-metadata]. > [!NOTE] > @@ -1034,6 +1035,16 @@ would be desirable. ↩ [*`dev-dependencies` and `build-dependencies`*][dev-dependencies-and-build-dependencies] +## Should `cargo metadata` include the standard library's dependencies? +[unresolved-cargo-metadata]: #should-cargo-metadata-include-the-standard-librarys-dependencies + +`cargo metadata` is used by tools like rust-analyzer to determine the entire +crate graph and would benefit from knowledge of the standard library's +dependencies, but this leaks internal details of the standard library and is +counter to the intent behind opaque dependencies. + +↩ [*Cargo subcommands*][cargo-subcommands] + # Prior art [prior-art]: #prior-art From 393586355e379a81cec6c05002ba49bcaa3962da Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 12 Nov 2025 13:57:15 +0000 Subject: [PATCH 14/43] `no_std` w/ std deps lint in future possiblities --- text/3875-build-std-explicit-dependencies.md | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 9084c5de649..7a9d000be57 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1071,21 +1071,24 @@ of dependency on the standard library. It could therefore be desirable to deprecate `#![no_std]` so that there remains only a single way to express a dependency on the standard library. - `#![no_std]` serves two purposes - it stops the compiler from adding `std` to the extern prelude and it prevents the user from depending on anything from `std` accidentally. rustc's default behaviour of loading `std` when not explicitly provided the crate via an `--extern` flag should be preserved for backwards-compatibility with existing direct invocations of rustc. -`#![no_std]` could instead become a compiler flag which would indicate to the -compiler that `std` should not be loaded by default and that `core`'s prelude -should be used instead. Cargo would use this flag when driving rustc, providing -explicit paths to the newly-built or pre-built standard library crates, just as -with any other dependency. +Initially, if a crate has the `#![no_std]` attribute and has implicit +dependencies on the standard library in its `Cargo.toml`, a lint could be +emitted to suggest that their Cargo dependencies are adjusted. + +Eventually, `#![no_std]` could instead become a compiler flag which would +indicate to the compiler that `std` should not be loaded by default and that +`core`'s prelude should be used instead. Cargo would use this flag when driving +rustc, providing explicit paths to the newly-built or pre-built standard library +crates, just as with any other dependency. -In addition, `#![no_std]` could be migrated to denying a lint which would -prevent use of items from `std`. +In addition, uses of the `#![no_std]` attribute could be migrated to denying a +lint which would prevent use of items from `std`. ↩ [*Proposal*][proposal] From 3f611c504a5614b7788a3548038f7252cfe6db24 Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Wed, 3 Dec 2025 21:08:41 -0800 Subject: [PATCH 15/43] Increase heading levels As part of https://github.com/rust-lang/rfcs/pull/3883, we have switched the template to stop using level-1 headings which isn't the way mdbook is intended to be used. --- text/3875-build-std-explicit-dependencies.md | 86 ++++++++++---------- 1 file changed, 43 insertions(+), 43 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 7a9d000be57..abc44e196c3 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -3,7 +3,7 @@ - RFC PR: [rust-lang/rfcs#3875](https://github.com/rust-lang/rfcs/pull/3875) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) -# Summary +## Summary [summary]: #summary Allow users to add explicit dependencies on standard library crates in the @@ -46,7 +46,7 @@ RFCs:** [rfcs#3874-unresolved-questions]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#unresolved-questions [rfcs#3874-future-possibilities]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#future-possibilities -# Motivation +## Motivation [motivation]: #motivation This RFC builds on a large collection of prior art collated in the @@ -59,7 +59,7 @@ features of the standard library. Allowing the standard library to behave similarly to other dependencies also reduces user friction and can improve build times. -# Proposal +## Proposal [proposal]: #proposal Users can now optionally declare explicit dependencies on the standard library @@ -236,7 +236,7 @@ files ([?][rationale-cargo-lock]). [rfcs#3874-standard-library-crate-stability]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#standard-library-crate-stability [rfcs#3874-noprelude]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#why-use-noprelude-with---extern -## Non-`builtin` standard library dependencies +### Non-`builtin` standard library dependencies [non-builtin-standard-library-dependencies]: #non-builtin-standard-library-dependencies Cargo already supports `path` and `git` dependencies for crates named `core`, @@ -269,7 +269,7 @@ core = { builtin = true } Crates with these dependency sources will remain unable to be published to crates.io. -## Patches +### Patches [patches]: #patches Under a perma-unstable feature it is permitted to patch standard library @@ -303,7 +303,7 @@ As with dependencies, crates with `path`/`git` patches for `core`, `alloc` or - [*What syntax is used to patch dependencies on the standard library in `Cargo.toml`?*][unresolved-patch-syntax] -## Features +### Features [features]: #features On a stable toolchain, it is not permitted to enable or disable features of @@ -330,7 +330,7 @@ std = { builtin = true, default-features = false } # not permitted - [*Allow enabling/disabling features with build-std*][future-features] -## Public and private dependencies +### Public and private dependencies [public-and-private-dependencies]: #public-and-private-dependencies Implicit and explicit dependencies on the standard library default to being @@ -365,7 +365,7 @@ std = { builtin = true, public = true } - [*Why default to public for standard library dependencies?*][rationale-default-public] -## `dev-dependencies` and `build-dependencies` +### `dev-dependencies` and `build-dependencies` [dev-dependencies-and-build-dependencies]: #dev-dependencies-and-build-dependencies Explicit dependencies on the standard library can be specified in @@ -383,7 +383,7 @@ standard library are not supported in `build-dependencies`. - [*Should we support `build-dependencies`?*][unresolved-build-deps] -## Registries +### Registries [registries]: #registries Standard library dependencies will be present in the registry index @@ -453,7 +453,7 @@ similarly be updated to support `builtin_deps`. [cargo-registry-web-publish]: https://doc.rust-lang.org/cargo/reference/registry-web-api.html#publish -## Cargo subcommands +### Cargo subcommands [cargo-subcommands]: #cargo-subcommands Any Cargo command which accepts a package spec with `-p` will now additionally @@ -690,13 +690,13 @@ This part of the RFC has no implications for the following Cargo subcommands: [cargo-version]: https://doc.rust-lang.org/cargo/commands/cargo-version.html [cargo-yank]: https://doc.rust-lang.org/cargo/commands/cargo-yank.html -# Rationale and alternatives +## Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives This section aims to justify all of the decisions made in the proposed design from [*Proposal*][proposal] and discuss why alternatives were not chosen. -## Why explicitly declare dependencies on the standard library in `Cargo.toml`? +### Why explicitly declare dependencies on the standard library in `Cargo.toml`? [rationale-why-explicit-deps]: #why-explicitly-declare-dependencies-on-the-standard-library-in-cargotoml If there are no explicit dependencies on standard library crates, Cargo would @@ -739,7 +739,7 @@ existing Cargo features that crates already have. ↩ [*Proposal*][proposal] -## Why disallow builtin dependencies to be combined with other sources? +### Why disallow builtin dependencies to be combined with other sources? [rationale-builtin-other-sources]: #why-disallow-builtin-dependencies-to-be-combined-with-other-sources If using `path`/`git` sources with `builtin` dependencies worked in the same way @@ -764,7 +764,7 @@ of supporting per-target/per-profile MSRVs, but this has limited utility. ↩ [*Proposal*][proposal] -## Why disallow builtin dependencies on other crates? +### Why disallow builtin dependencies on other crates? [rationale-no-builtin-other-crates]: #why-disallow-builtin-dependencies-on-other-crates `builtin` dependencies could be accepted on two other crates - dependencies of @@ -781,7 +781,7 @@ added manually by users, however: ↩ [*Proposal*][proposal] -## Why unstably allow all names for `builtin` crates? +### Why unstably allow all names for `builtin` crates? [rationale-unstable-builtin-crates]: #why-unstably-allow-all-names-for-builtin-crates For any crate shipped with the standard library in the sysroot, the user can @@ -799,7 +799,7 @@ hardcode the names of many crates in the sysroot which are inherently unstable. ↩ [*Proposal*][proposal] -## Why not use `noprelude` for explicit `builtin` dependencies? +### Why not use `noprelude` for explicit `builtin` dependencies? [rationale-explicit-noprelude]: #why-not-use-noprelude-for-explicit-builtin-dependencies Explicit builtin dependencies without the `noprelude` modifier behave more @@ -814,7 +814,7 @@ is required). ↩ [*Proposal*][proposal] -## Why not require builtin dependencies instead of supporting implicit ones? +### Why not require builtin dependencies instead of supporting implicit ones? [rationale-no-migration]: #why-not-require-builtin-dependencies-instead-of-supporting-implicit-ones Requiring explicit `builtin` dependencies over an edition would increase the @@ -829,7 +829,7 @@ the graph with [`build-std.crates`][rfcs#3874-proposal]. ↩ [*Proposal*][proposal] -## Why disallow renaming standard library dependencies? +### Why disallow renaming standard library dependencies? [rationale-package-key]: #why-disallow-renaming-standard-library-dependencies Cargo allows [renaming dependencies][cargo-docs-renaming] with the `package` @@ -848,7 +848,7 @@ of the user's names for `builtin` crates. [cargo-docs-renaming]: https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#renaming-dependencies-in-cargotoml [rust-extern-prelude]: https://doc.rust-lang.org/reference/names/preludes.html#extern-prelude -## Why disallow source replacement on `builtin` packages? +### Why disallow source replacement on `builtin` packages? [rationale-source-replacement]: #why-disallow-source-replacement-on-builtin-packages Modifying the source code of the standard library in the `rust-src` component is @@ -859,7 +859,7 @@ See [*Allow `builtin` source replacement*][future-source-replacement]. ↩ [*Proposal*][proposal] -## Why not permit overriding dependencies with `replace` or `paths`? +### Why not permit overriding dependencies with `replace` or `paths`? [rationale-overriding-builtins]: #why-not-permit-overriding-dependencies-with-replace-or-paths Similarly to [source replacement][rationale-source-replacement], easing @@ -867,7 +867,7 @@ modification of the standard library sources is out-of-scope for this proposal. ↩ [*Proposal*][proposal] -## Why add standard library dependencies to `Cargo.lock`? +### Why add standard library dependencies to `Cargo.lock`? [rationale-cargo-lock]: #why-add-standard-library-dependencies-to-cargolock `Cargo.lock` is a direct serialisation of a resolve and that must be a two-way @@ -876,7 +876,7 @@ resolution to fill in missing `builtin` packages. ↩ [*Proposal*][proposal] -## Why unstably permit patching of the standard library dependencies? +### Why unstably permit patching of the standard library dependencies? [rationale-patching]: #why-unstably-permit-patching-of-the-standard-library-dependencies Being able to patch `builtin = true` dependencies and replace their source with @@ -888,7 +888,7 @@ all that is required for it to be used in replacing `rustc_dep_of_std`. ↩ [*Patches*][patches] -## Why limit enabling standard library features to an unstable feature? +### Why limit enabling standard library features to an unstable feature? [rationale-features]: #why-limit-enabling-standard-library-features-to-an-unstable-feature If it were possible to enable features of the standard library crates on stable @@ -899,7 +899,7 @@ desirable. See ↩ [*Features*][features] -## Why default to public for standard library dependencies? +### Why default to public for standard library dependencies? [rationale-default-public]: #why-default-to-public-for-standard-library-dependencies There are crates building on stable which re-export from the standard library. @@ -909,7 +909,7 @@ version of Cargo with a implicit standard library dependency. ↩ [*Public and private dependencies*][public-and-private-dependencies] -## Why add standard library crates to Cargo's index? +### Why add standard library crates to Cargo's index? [rationale-cargo-index]: #why-add-standard-library-crates-to-cargos-index When Cargo builds the dependency graph, it is driven by the index (not @@ -917,7 +917,7 @@ When Cargo builds the dependency graph, it is driven by the index (not ↩ [*Registries*][registries] -## Why add a new key to Cargo's registry index JSON schema? +### Why add a new key to Cargo's registry index JSON schema? [rationale-cargo-builtindeps]: #why-add-a-new-key-to-cargos-registry-index-json-schema Cargo's [registry index schema][cargo-json-schema] is versioned and making a @@ -963,7 +963,7 @@ take today, using `path` dependencies for the standard library to shadow it). [cargo-json-schema]: https://doc.rust-lang.org/cargo/reference/registry-index.html#json-schema [embed-rs-source]: https://github.com/embed-rs/stm32f7-discovery/blob/e2bf713263791c028c2a897f2eb1830d7f09eceb/core/src/lib.rs#L7 -## Why can `builtin_deps` shadow other packages in the registry? +### Why can `builtin_deps` shadow other packages in the registry? [rationale-cargo-index-shadowing]: #why-can-builtin_deps-shadow-other-packages-in-the-registry While `crates.io` forbids certain crate names including `std`, `alloc` and @@ -976,13 +976,13 @@ these would conflict when passed to rustc via `--extern`. ↩ [*Registries*][registries] -# Unresolved questions +## Unresolved questions [unresolved-questions]: #unresolved-questions The following small details are likely to be bikeshed prior to this part of the RFC's acceptance or stabilisation and aren't pertinent to the overall design: -## What syntax is used to identify dependencies on the standard library in `Cargo.toml`? +### What syntax is used to identify dependencies on the standard library in `Cargo.toml`? [unresolved-dep-syntax]: #what-syntax-is-used-to-identify-dependencies-on-the-standard-library-in-cargotoml What syntax should be used for the explicit standard library dependencies? @@ -991,7 +991,7 @@ we typically introduce to end-users)? ↩ [*Proposal*][proposal] -## What is the format for builtin dependencies in `Cargo.lock`? +### What is the format for builtin dependencies in `Cargo.lock`? [unresolved-lockfile]: #what-is-the-format-for-builtin-dependencies-in-cargolock How should `builtin` deps be represented in lockfiles? Is `builtin = true` @@ -1000,7 +1000,7 @@ should it stay only as a URL+scheme? ↩ [*Proposal*][proposal] -## What syntax is used to patch dependencies on the standard library in `Cargo.toml`? +### What syntax is used to patch dependencies on the standard library in `Cargo.toml`? [unresolved-patch-syntax]: #what-syntax-is-used-to-patch-dependencies-on-the-standard-library-in-cargotoml `[patch.builtin]` is the natural syntax given `builtin` is a new source, but may @@ -1008,7 +1008,7 @@ be needlessly different to existing packages. ↩ [*Patches*][patches] -## Should standard library dependencies default to public? +### Should standard library dependencies default to public? [unresolved-std-default-public]: #should-standard-library-dependencies-default-to-public Standard library dependencies defaulting to public is a trade-off between @@ -1023,7 +1023,7 @@ the manifest. ↩ [*Public and private dependencies*][public-and-private-dependencies] -## Should we support `build-dependencies`? +### Should we support `build-dependencies`? [unresolved-build-deps]: #should-we-support-build-dependencies Allowing `builtin` dependencies to be used in `dependencies` and @@ -1035,7 +1035,7 @@ would be desirable. ↩ [*`dev-dependencies` and `build-dependencies`*][dev-dependencies-and-build-dependencies] -## Should `cargo metadata` include the standard library's dependencies? +### Should `cargo metadata` include the standard library's dependencies? [unresolved-cargo-metadata]: #should-cargo-metadata-include-the-standard-librarys-dependencies `cargo metadata` is used by tools like rust-analyzer to determine the entire @@ -1045,13 +1045,13 @@ counter to the intent behind opaque dependencies. ↩ [*Cargo subcommands*][cargo-subcommands] -# Prior art +## Prior art [prior-art]: #prior-art See the [*Background*][rfcs#3873-background] and [*History*][rfcs#3873-history] of the build-std context RFC. -# Future possibilities +## Future possibilities [future-possibilities]: #future-possibilities This RFC unblocks fixing [rust-lang/cargo#8798], enabling no-std crates from @@ -1061,7 +1061,7 @@ There are also many possible follow-ups to this part of the RFC: [rust-lang/cargo#8798]: https://github.com/rust-lang/cargo/issues/8798 -## Replace `#![no_std]` as the source-of-truth for whether a crate depends on `std` +### Replace `#![no_std]` as the source-of-truth for whether a crate depends on `std` [future-replace-no_std]: #replace-no_std-as-the-source-of-truth-for-whether-a-crate-depends-on-std Crates can currently use the crate attribute `#![no_std]` to indicate a lack of @@ -1092,7 +1092,7 @@ lint which would prevent use of items from `std`. ↩ [*Proposal*][proposal] -## Allow unstable crate names to be referenced behind cfgs without requiring nightly +### Allow unstable crate names to be referenced behind cfgs without requiring nightly [future-cfg-unstable-crate-name]: #allow-unstable-crate-names-to-be-referenced-behind-cfgs-without-requiring-nightly It is possible to allow builtin dependencies on unstable crate names to exist @@ -1103,7 +1103,7 @@ using nightly or doing MSRV bumps. ↩ [*Proposal*][proposal] -## Allow `builtin` source replacement +### Allow `builtin` source replacement [future-source-replacement]: #allow-builtin-source-replacement This involves allowing the user to blanket-override the standard library sources @@ -1114,7 +1114,7 @@ or if it's even something the Rust project wishes to support. ↩ [*Proposal*][proposal] -## Remove `rustc_dep_of_std` +### Remove `rustc_dep_of_std` [future-rustc_dep_of_std]: #remove-rustc_dep_of_std With first-class explicit dependencies on the standard library, @@ -1129,7 +1129,7 @@ the standard library can depend on them. ↩ [*Proposal*][proposal] -## Allow enabling/disabling features with build-std +### Allow enabling/disabling features with build-std [future-features]: #allow-enablingdisabling-features-with-build-std This would require the library team be comfortable with the features declared on @@ -1152,7 +1152,7 @@ prevent some otherwise stable features from being toggled as it controls those. [rfcs#3874-panic-strategies]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#panic-strategies [rfcs#3874-compiler-builtins-mem]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#compiler-builtinsmem -## Allow local builds of `compiler-rt` intrinsics +### Allow local builds of `compiler-rt` intrinsics [future-compiler-builtins-c]: #allow-local-builds-of-compiler-rt-intrinsics The [`c` feature][rfcs#3873-dependencies] of `compiler_builtins` (which is also @@ -1164,4 +1164,4 @@ platform does not have a suitable C compiler available. The user being able to enable this manually will be enabled through work on features (see [*Allow enabling/disabling features with build-std*][future-features]). Once the user can enable `compiler-builtins/c`, they will need to manually configure -`CFLAGS` to ensure that the C components will link with Rust code. \ No newline at end of file +`CFLAGS` to ensure that the C components will link with Rust code. From 2d3416fb18c08dbd32e397a27d91d7dfb0b525f8 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 6 Jan 2026 11:20:05 +0000 Subject: [PATCH 16/43] update links to prev rfcs --- text/3875-build-std-explicit-dependencies.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index abc44e196c3..02275ec1086 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -33,12 +33,12 @@ RFCs:** [build-std project goal]: https://rust-lang.github.io/rust-project-goals/2025h2/build-std.html -[rfcs#3873]: https://github.com/rust-lang/rfcs/pull/3873 -[rfcs#3873-proposal]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#proposal -[rfcs#3873-background]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#background -[rfcs#3873-history]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#history -[rfcs#3873-motivation]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#motivation -[rfcs#3873-dependencies]: https://github.com/davidtwco/rfcs/blob/build-std-part-one-context/text/3873-build-std-context.md#dependencies +[rfcs#3873]: https://rust-lang.github.io/rfcs/3873-build-std-context.html +[rfcs#3873-proposal]: https://rust-lang.github.io/rfcs/3873-build-std-context.html#proposal +[rfcs#3873-background]: https://rust-lang.github.io/rfcs/3873-build-std-context.html#background +[rfcs#3873-history]: https://rust-lang.github.io/rfcs/3873-build-std-context.html#history +[rfcs#3873-motivation]: https://rust-lang.github.io/rfcs/3873-build-std-context.html#motivation +[rfcs#3873-dependencies]: https://rust-lang.github.io/rfcs/3873-build-std-context.html#dependencies [rfcs#3874]: https://github.com/rust-lang/rfcs/pull/3874 [rfcs#3874-proposal]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#proposal From fc16fa8fb25476664a3e4129524a820e77353be4 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 6 Jan 2026 11:25:01 +0000 Subject: [PATCH 17/43] built-in instead of version number in cargo tree --- text/3875-build-std-explicit-dependencies.md | 22 ++++++++++---------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 02275ec1086..3fd9519b3bf 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -593,24 +593,24 @@ or `core` will have a version number. > ├── rand v0.7.3 > │ ├── getrandom v0.1.14 > │ │ ├── cfg-if v0.1.10 -> │ │ │ └── core v0.0.0 +> │ │ │ └── core (built-in) > │ │ ├── libc v0.2.68 -> │ │ │ └── core v0.0.0 -> │ │ └── core v0.0.0 +> │ │ │ └── core (built-in) +> │ │ └── core (built-in) > │ ├── libc v0.2.68 (*) -> │ │ └── core v0.0.0 +> │ │ └── core (built-in) > │ ├── rand_chacha v0.2.2 > │ │ ├── ppv-lite86 v0.2.6 -> │ │ │ └── core v0.0.0 +> │ │ │ └── core (built-in) > │ │ ├── rand_core v0.5.1 > │ │ │ ├── getrandom v0.1.14 (*) -> │ │ │ └── core v0.0.0 -> │ │ └── std v0.0.0 -> │ │ └── alloc v0.0.0 -> │ │ └── core v0.0.0 +> │ │ │ └── core (built-in) +> │ │ └── std (built-in) +> │ │ └── alloc (built-in) +> │ │ └── core (built-in) > │ ├── rand_core v0.5.1 (*) -> │ └── std v0.0.0 (*) -> └── std v0.0.0 (*) +> │ └── std (built-in) (*) +> └── std (built-in) (*) > ``` This part of the RFC has no implications for the following Cargo subcommands: From 2b189a4cb8484ab71380c095652fefb97a4b9987 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 6 Jan 2026 11:27:34 +0000 Subject: [PATCH 18/43] adding non-optional core alongside optional std --- text/3875-build-std-explicit-dependencies.md | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 3fd9519b3bf..938440962eb 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -495,6 +495,20 @@ edition = "2024" std = { builtin = true, public = true } # <-- this would be added ``` +If adding `std` or `alloc` with `--optional`, then a non-optional `core` would +also be added: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true, optional = true } # <-- this would be added +core = { builtin = true } # <-- this would also be added +``` + [`cargo info`][cargo-info] will learn how to print information for the built-in `std`, `alloc` and `core` dependencies: From cd9b4dabd8ec53fbfee0ae32aa3dc6e1bf92117e Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 6 Jan 2026 11:36:10 +0000 Subject: [PATCH 19/43] clarify noprelude meaning --- text/3875-build-std-explicit-dependencies.md | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 938440962eb..7373c5521fe 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -93,9 +93,13 @@ Cargo feature. > [!NOTE] > > Explicit dependencies are passed to rustc without the `noprelude` modifier -> ([?][rationale-explicit-noprelude]). When adding an explicit dependency, users -> may need to adjust their code (removing extraneous `extern crate` statements -> or root-relative paths, like `::std`). +> ([?][rationale-explicit-noprelude]) (`noprelude` refers to the compiler's +> notion of the "extern prelude", not the prelude in the the user-facing +> sense of `std::prelude::*`). +> +> When adding an explicit dependency, users > may need to adjust their code +> (removing extraneous `extern crate` statements > or root-relative paths, +> like `::std` - this will likely only be the case on the 2015 edition). Crates without an explicit dependency on the standard library now have a implicit dependency ([?][rationale-no-migration]) on that target's default set From 97de9cd5c73a50c61aad7bcba601ca583b57fd8e Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 6 Jan 2026 11:41:57 +0000 Subject: [PATCH 20/43] clarify implicit deps --- text/3875-build-std-explicit-dependencies.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 7373c5521fe..4deef3ace09 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -105,8 +105,9 @@ Crates without an explicit dependency on the standard library now have a implicit dependency ([?][rationale-no-migration]) on that target's default set of standard library crates (see [build-std-always][rfcs#3874-standard-library-crate-stability]). Any explicit -`builtin` dependency present in any dependency table will disable the implicit -dependencies. +standard library dependency present in any dependency table will disable the +implicit dependencies (e.g. an explicit `builtin` or `path` dependency from +`std` will disable the implicit dependencies). > [!NOTE] > @@ -213,6 +214,9 @@ files ([?][rationale-cargo-lock]). > optional lockfile fields `dependencies` and `checksum` will not be present for > `builtin` dependencies. +A perma-unstable Cargo feature for disabling all standard library dependencies will +be added to allow the `core` crate to be defined. + *See the following sections for rationale/alternatives:* - [*Why explicitly declare dependencies on the standard library in `Cargo.toml`?*][rationale-why-explicit-deps] From bbb4c6a85e9e48087e929fa30583783fc23e1a41 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 13:41:53 +0000 Subject: [PATCH 21/43] fix mangled line wrapping --- text/3875-build-std-explicit-dependencies.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 4deef3ace09..7dd1ddb1ea5 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -97,9 +97,9 @@ Cargo feature. > notion of the "extern prelude", not the prelude in the the user-facing > sense of `std::prelude::*`). > -> When adding an explicit dependency, users > may need to adjust their code -> (removing extraneous `extern crate` statements > or root-relative paths, -> like `::std` - this will likely only be the case on the 2015 edition). +> When adding an explicit dependency, users may need to adjust their code +> (removing extraneous `extern crate` statements or root-relative paths, like +> `::std` - this will likely only be the case on the 2015 edition). Crates without an explicit dependency on the standard library now have a implicit dependency ([?][rationale-no-migration]) on that target's default set From ae2d36450d5dbdbe86840bb73faeab26c700c26e Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 13:43:22 +0000 Subject: [PATCH 22/43] clarify that patching is perma-unstable --- text/3875-build-std-explicit-dependencies.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 7dd1ddb1ea5..eeedc31bcee 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -185,7 +185,8 @@ Dependencies with `builtin = true` cannot be renamed with the `package` key on the `builtin` source using the `[source]` Cargo config table ([?][rationale-source-replacement]), and nor is it possible to override `builtin` dependencies with the `[replace]` sections or `paths` overrides -([?][rationale-overriding-builtins]), though [patching][patches] is permitted. +([?][rationale-overriding-builtins]), though [patching][patches] is permitted +under a perma-unstable feature flag. Dependencies with `builtin = true` can be specified as platform-specific dependencies: From be712e142918f76f0541012c2050f9ed942f4458 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 13:44:46 +0000 Subject: [PATCH 23/43] clarify public/private dependencies --- text/3875-build-std-explicit-dependencies.md | 54 ++++++++++++++------ 1 file changed, 38 insertions(+), 16 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index eeedc31bcee..5718d88628f 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -342,8 +342,8 @@ std = { builtin = true, default-features = false } # not permitted ### Public and private dependencies [public-and-private-dependencies]: #public-and-private-dependencies -Implicit and explicit dependencies on the standard library default to being -public dependencies ([?][rationale-default-public]). +Implicit dependencies on the standard library default to being public +dependencies ([?][rationale-default-implicit-public]). ```toml [package] @@ -366,13 +366,20 @@ edition = "2024" std = { builtin = true, public = true } ``` +Explicit dependencies on the standard library default to being private +dependencies ([?][rationale-default-implicit-public]). `cargo add` will add +`public = true` by default for builtin dependencies (see [*Cargo +subcommands*][cargo-subcommands]). + *See the following sections for relevant unresolved questions:* -- [*Should standard library dependencies default to public?*][unresolved-std-default-public] +- [*Should implicit standard library dependencies default to public?*][unresolved-std-default-implicit-public] +- [*Should explicit standard library dependencies default to private?*][unresolved-std-default-explicit-private] *See the following sections for rationale/alternatives:* -- [*Why default to public for standard library dependencies?*][rationale-default-public] +- [*Why default to public for implicit standard library dependencies?*][rationale-default-implicit-public] +- [*Why default to private for explicit standard library dependencies?*][rationale-default-explicit-private] ### `dev-dependencies` and `build-dependencies` [dev-dependencies-and-build-dependencies]: #dev-dependencies-and-build-dependencies @@ -922,8 +929,8 @@ desirable. See ↩ [*Features*][features] -### Why default to public for standard library dependencies? -[rationale-default-public]: #why-default-to-public-for-standard-library-dependencies +### Why default to public for implicit standard library dependencies? +[rationale-default-implicit-public]: #why-default-to-public-for-implicit-standard-library-dependencies There are crates building on stable which re-export from the standard library. If implicit standard library dependencies were not public then these crates would @@ -932,6 +939,17 @@ version of Cargo with a implicit standard library dependency. ↩ [*Public and private dependencies*][public-and-private-dependencies] +### Why default to private for explicit standard library dependencies? +[rationale-default-explicit-private]: #why-default-to-private-for-explicit-standard-library-dependencies + +All other explicitly written dependencies in the Cargo manifest are +private-by-default. This RFC tries to make builtin dependencies as consistent +with other dependencies in the manifest as possible (e.g. in [*Why not use +`noprelude` for explicit `builtin` +dependencies?*][rationale-explicit-noprelude]). + +↩ [*Public and private dependencies*][public-and-private-dependencies] + ### Why add standard library crates to Cargo's index? [rationale-cargo-index]: #why-add-standard-library-crates-to-cargos-index @@ -1031,18 +1049,22 @@ be needlessly different to existing packages. ↩ [*Patches*][patches] -### Should standard library dependencies default to public? -[unresolved-std-default-public]: #should-standard-library-dependencies-default-to-public +### Should implicit standard library dependencies default to public? +[unresolved-std-default-implicit-public]: #should-implicit-standard-library-dependencies-default-to-public + +Implicit standard library dependencies defaulting to public is a trade-off +between special-casing in Cargo and requiring that any user with a dependency on +the standard library who re-exports from the standard library manually declare +their dependency as public. + +↩ [*Public and private dependencies*][public-and-private-dependencies] -Standard library dependencies defaulting to public is a trade-off between -special-casing in Cargo and requiring that any user with a dependency on the -standard library who re-exports from the standard library manually declare their -dependency as public. +### Should explicit standard library dependencies default to private? +[unresolved-std-default-explicit-private]: #should-explicit-standard-library-dependencies-default-to-private -It is also inconsistent with -[*Why not use `noprelude` for explicit `builtin` dependencies?*][rationale-explicit-noprelude] -which aims to make builtin dependencies consistent with other dependencies in -the manifest. +Explicit standard library dependencies defaulting to private is a trade-off +between consistency with other dependencies in the manifest and implicit +standard library dependencies. ↩ [*Public and private dependencies*][public-and-private-dependencies] From 3cbfbb58116f9e733c7ad24c74985b8ec3b52886 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 15:45:51 +0000 Subject: [PATCH 24/43] cargo doesn't force new lockfile versions --- text/3875-build-std-explicit-dependencies.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 5718d88628f..6d4bc58bb74 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -904,6 +904,9 @@ modification of the standard library sources is out-of-scope for this proposal. non-lossy process in order to make the `Cargo.lock` useful without doing further resolution to fill in missing `builtin` packages. +Cargo will nevertheless need to support lockfiles without builtin dependencies +as Cargo does not force new lockfile versions. + ↩ [*Proposal*][proposal] ### Why unstably permit patching of the standard library dependencies? From 924f0da90854a8d67895967f197fa95c1f881c0a Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 15:46:47 +0000 Subject: [PATCH 25/43] add another reference to patching rationale --- text/3875-build-std-explicit-dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 6d4bc58bb74..15ed913f6ce 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -186,7 +186,7 @@ on the `builtin` source using the `[source]` Cargo config table ([?][rationale-source-replacement]), and nor is it possible to override `builtin` dependencies with the `[replace]` sections or `paths` overrides ([?][rationale-overriding-builtins]), though [patching][patches] is permitted -under a perma-unstable feature flag. +under a perma-unstable feature flag ([?][rationale-patching]). Dependencies with `builtin = true` can be specified as platform-specific dependencies: From 81298d9b486e81994fee9a1397d2f7dd9a21d8d9 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 15:48:34 +0000 Subject: [PATCH 26/43] clarify relevance to cargo index --- text/3875-build-std-explicit-dependencies.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 15ed913f6ce..3823da0b4f8 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -957,7 +957,9 @@ dependencies?*][rationale-explicit-noprelude]). [rationale-cargo-index]: #why-add-standard-library-crates-to-cargos-index When Cargo builds the dependency graph, it is driven by the index (not -`Cargo.toml`), so builtin dependencies need to be included in the index. +`Cargo.toml`), so builtin dependencies need to be included in the index format +(so that packages can have builtin dependencies - standard library crates will +not exist as top-level packages in the index). ↩ [*Registries*][registries] From 4bb6b8b46ee7f7dcf478d370fb61053e6cca7028 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 15:50:13 +0000 Subject: [PATCH 27/43] clarify patches are internal-use in unresolved q --- text/3875-build-std-explicit-dependencies.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 3823da0b4f8..c29bc02ee0b 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1050,7 +1050,8 @@ should it stay only as a URL+scheme? [unresolved-patch-syntax]: #what-syntax-is-used-to-patch-dependencies-on-the-standard-library-in-cargotoml `[patch.builtin]` is the natural syntax given `builtin` is a new source, but may -be needlessly different to existing packages. +be needlessly different to existing packages. This mechanism exists only for +internal purposes so the exact syntax isn't especially important. ↩ [*Patches*][patches] From ce9a5ea3157ed763d2fdf91164a3204c1062fe56 Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 15:52:58 +0000 Subject: [PATCH 28/43] clarify cargo metadata back compat --- text/3875-build-std-explicit-dependencies.md | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index c29bc02ee0b..c544e992723 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -558,8 +558,11 @@ documentation: https://doc.rust-lang.org/1.86.0/core/index.html [`cargo metadata`][cargo-metadata] will emit `std`, `alloc` and `core` dependencies to the metadata emitted by `cargo metadata` (when those crates are explicit dependencies). `source` would be set to `builtin` and the remaining -fields would be set like any other dependency. See also unresolved question -[*Should `cargo metadata` include the standard library's dependencies?*][unresolved-cargo-metadata]. +fields would be set like any other dependency. Per the `cargo metadata` +[*Compatibility*][cargo-metadata-compat] documentation, adding a new source kind +is not considered an incompatible change. See also unresolved question [*Should +`cargo metadata` include the standard library's +dependencies?*][unresolved-cargo-metadata]. > [!NOTE] > @@ -700,6 +703,7 @@ This part of the RFC has no implications for the following Cargo subcommands: [cargo-login]: https://doc.rust-lang.org/cargo/commands/cargo-login.html [cargo-logout]: https://doc.rust-lang.org/cargo/commands/cargo-login.html [cargo-metadata]: https://doc.rust-lang.org/cargo/commands/cargo-metadata.html +[cargo-metadata-compat]: https://doc.rust-lang.org/cargo/commands/cargo-metadata.html#compatibility [cargo-miri]: https://doc.rust-lang.org/cargo/commands/cargo-miri.html [cargo-new]: https://doc.rust-lang.org/cargo/commands/cargo-new.html [cargo-owner]: https://doc.rust-lang.org/cargo/commands/cargo-owner.html From 45f1a61f21cfab0fb8f8d934f71771962d4b7eff Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 20 Jan 2026 16:19:33 +0000 Subject: [PATCH 29/43] compare w/ implicit state vs tracking explicitness --- text/3875-build-std-explicit-dependencies.md | 24 +++++++++++--------- 1 file changed, 13 insertions(+), 11 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index c544e992723..9cb42024a84 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -455,11 +455,13 @@ similarly be updated to support `builtin_deps`. > ] > ``` > -> When producing a registry index entry for a package Cargo will not serialise -> any `builtin` dependencies it inferred. This allows the set of inferred -> packages to change in the future if needed and prevents publishing a package -> with a new Cargo from raising your MSRV. Similarly, the published `Cargo.toml` -> will not explicitly declare any inferred dependencies. +> When producing a registry index entry for a package Cargo will strip any +> `builtin` dependencies that match the implicit state. This allows the implicit +> state to change in the future if needed and prevents publishing a package with +> a new Cargo from raising your MSRV. Similarly, the published `Cargo.toml` will +> not explicitly declare any dependencies that match the implicit state. +> `builtin` dependencies that do match the implicit state could be made explicit +> in a future edition. *See the following sections for rationale/alternatives:* @@ -556,12 +558,12 @@ documentation: https://doc.rust-lang.org/1.86.0/core/index.html ``` [`cargo metadata`][cargo-metadata] will emit `std`, `alloc` and `core` -dependencies to the metadata emitted by `cargo metadata` (when those crates are -explicit dependencies). `source` would be set to `builtin` and the remaining -fields would be set like any other dependency. Per the `cargo metadata` -[*Compatibility*][cargo-metadata-compat] documentation, adding a new source kind -is not considered an incompatible change. See also unresolved question [*Should -`cargo metadata` include the standard library's +dependencies to the metadata emitted by `cargo metadata` (when those crates +differ from the implicit state). `source` would be set to `builtin` and the +remaining fields would be set like any other dependency. Per the `cargo +metadata` [*Compatibility*][cargo-metadata-compat] documentation, adding a new +source kind is not considered an incompatible change. See also unresolved +question [*Should `cargo metadata` include the standard library's dependencies?*][unresolved-cargo-metadata]. > [!NOTE] From 829a4043c00778a716ed4c57dd2c977f8b38dc69 Mon Sep 17 00:00:00 2001 From: David Wood Date: Fri, 6 Feb 2026 14:25:39 +0000 Subject: [PATCH 30/43] pass `-Zcrate-attr=no_std` --- text/3875-build-std-explicit-dependencies.md | 71 +++++++++++++------- 1 file changed, 46 insertions(+), 25 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 9cb42024a84..60cda423125 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -218,6 +218,10 @@ files ([?][rationale-cargo-lock]). A perma-unstable Cargo feature for disabling all standard library dependencies will be added to allow the `core` crate to be defined. +When a crate has no builtin dependency on `std` (or an optional builtin +dependency on `std`), then Cargo will pass `-Zcrate-attr=no_std` to rustc (or +some equivalent; [?][rationale-no_std]). + *See the following sections for rationale/alternatives:* - [*Why explicitly declare dependencies on the standard library in `Cargo.toml`?*][rationale-why-explicit-deps] @@ -229,6 +233,7 @@ be added to allow the `core` crate to be defined. - [*Why disallow renaming standard library dependencies?*][rationale-package-key] - [*Why disallow source replacement on `builtin` packages?*][rationale-source-replacement] - [*Why add standard library dependencies to Cargo.lock?*][rationale-cargo-lock] +- [*Why pass `-Zcrate-attr=no_std` to rustc?*][rationale-no_std] *See the following sections for relevant unresolved questions:* @@ -237,7 +242,6 @@ be added to allow the `core` crate to be defined. *See the following sections for future possibilities:* -- [*Replace `#![no_std]` as the source-of-truth for whether a crate depends on `std`*][future-replace-no_std] - [*Allow unstable crate names to be referenced behind cfgs without requiring nightly*][future-cfg-unstable-crate-name] - [*Allow `builtin` source replacement*][future-source-replacement] - [*Remove `rustc_dep_of_std`*][future-rustc_dep_of_std] @@ -915,6 +919,25 @@ as Cargo does not force new lockfile versions. ↩ [*Proposal*][proposal] +### Why pass `-Zcrate-attr=no_std` to rustc? +[rationale-no_std]: #why-pass--zcrate-attrno_std-to-rustc + +The introduction of explicit dependencies means that there are now two ways to +indicate whether a crate depends on the standard library - builtin dependencies +in the Cargo manifest and the `#![no_std]` attribute. This isn't ideal. + +By passing `-Zcrate-attr=no_std` to rustc (or some equivalent), users no longer +need to specify the attribute explicitly in their source code. The attribute can +still be explicitly specified this way, which is useful when rustc is used +without a build system like Cargo. Other build systems can similarly pass +`-Zcrate-attr=no_std` if emulating how build-std works in Cargo. + +Removing or replacing `#![no_std]` as a mechanism is left as a follow-up to avoid +introducing a language change in this RFC - see [*Replace `#![no_std]` as the +source-of-truth for whether a crate depends on `std`*][future-replace-no_std]. + +↩ [*Proposal*][proposal] + ### Why unstably permit patching of the standard library dependencies? [rationale-patching]: #why-unstably-permit-patching-of-the-standard-library-dependencies @@ -1122,30 +1145,28 @@ There are also many possible follow-ups to this part of the RFC: [future-replace-no_std]: #replace-no_std-as-the-source-of-truth-for-whether-a-crate-depends-on-std Crates can currently use the crate attribute `#![no_std]` to indicate a lack of -dependency on `std`. Introducing `build-std.crates` from [RFC #3874][rfcs#3874] -or explicit dependencies would add a second way for the user to indicate a lack -of dependency on the standard library. It could therefore be desirable to -deprecate `#![no_std]` so that there remains only a single way to express a -dependency on the standard library. - -`#![no_std]` serves two purposes - it stops the compiler from adding `std` to -the extern prelude and it prevents the user from depending on anything from -`std` accidentally. rustc's default behaviour of loading `std` when not -explicitly provided the crate via an `--extern` flag should be preserved for -backwards-compatibility with existing direct invocations of rustc. - -Initially, if a crate has the `#![no_std]` attribute and has implicit -dependencies on the standard library in its `Cargo.toml`, a lint could be -emitted to suggest that their Cargo dependencies are adjusted. - -Eventually, `#![no_std]` could instead become a compiler flag which would -indicate to the compiler that `std` should not be loaded by default and that -`core`'s prelude should be used instead. Cargo would use this flag when driving -rustc, providing explicit paths to the newly-built or pre-built standard library -crates, just as with any other dependency. - -In addition, uses of the `#![no_std]` attribute could be migrated to denying a -lint which would prevent use of items from `std`. +dependency on `std`. `#![no_std]` serves two purposes - it stops the compiler +from adding `std` to the extern prelude and it prevents the user from depending +on anything from `std` accidentally. + +rustc's default behaviour of loading `std` when not explicitly provided the +crate via an `--extern` flag must be preserved for backwards-compatibility +with existing direct invocations of rustc. + +Ideally, `#![no_std]` would be removed entirely and the compiler would only load +`std` if it were used, but this isn't possible with the current compiler +implementation. + +Therefore, an explicit flag or attribute is necessary to tell rustc whether to +load `std`. `-Zcrate-attr=no_std` could be replaced with a explicit compiler +flag `--no-std` (naming subject to bikeshed) that Cargo and other drivers of +rustc could use. `#![no_std]` could be removed over an edition alongside +addition of builtin dependencies to the Cargo manifest. + +As removing `#![no_std]` could easily be left to a follow-up, and is a change to +a stable attribute in the surface language (which would require language team +approval), it isn't included in this proposal to keep scope and the number of +required approvals small. ↩ [*Proposal*][proposal] From 65431fc7dcfb71025e9ca92d9d1d340e30c7a76a Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 12 Mar 2026 16:47:23 +0000 Subject: [PATCH 31/43] build-dependencies is a two-way door --- text/3875-build-std-explicit-dependencies.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 60cda423125..4a3909b9013 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1111,7 +1111,9 @@ Allowing `builtin` dependencies to be used in `dependencies` and However, supporting `builtin` dependencies in `build-dependencies` would permit no-std build scripts. It is unclear whether supporting no-std build scripts -would be desirable. +would be desirable. Not supporting `build-dependencies` initially is a safe +default that can be changed later if this is deemed necessary, without breaking +any existing users. ↩ [*`dev-dependencies` and `build-dependencies`*][dev-dependencies-and-build-dependencies] From b30e3f4dc0e9827a3f5196b245265fd49cbc16ad Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 12 Mar 2026 16:52:29 +0000 Subject: [PATCH 32/43] elaborate on compatibility concern --- text/3875-build-std-explicit-dependencies.md | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 4a3909b9013..3a5f51b72c6 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1125,6 +1125,21 @@ crate graph and would benefit from knowledge of the standard library's dependencies, but this leaks internal details of the standard library and is counter to the intent behind opaque dependencies. +This is primarily a compatibility concern, though were `builtin` dependencies to +be included in the metadata, it is expected that it would not be too disruptive, +as: + +- `cargo pkgid` and `cargo build --message-format` will unconditionally use the + new `pkgid` spec anyway; +- `cargo_metadata` does not currently parse the pkgid spec so this won't break + all users; +- and this will also show up in the source which is still opaque and + `cargo_metadata` does not parse + +Therefore this would only be a problem for users who are parsing the pkgid specs +using `cargo-util-schemas` or their own parser, which is unlikely to be +disruptive. + ↩ [*Cargo subcommands*][cargo-subcommands] ## Prior art From 9ec73aa586cca98a0c8be1b46114299f02f9d79e Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 12 Mar 2026 18:51:26 +0000 Subject: [PATCH 33/43] elaborate on cargo index need --- text/3875-build-std-explicit-dependencies.md | 37 ++++++++++++-------- 1 file changed, 23 insertions(+), 14 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 3a5f51b72c6..b6c4faba343 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -406,14 +406,16 @@ standard library are not supported in `build-dependencies`. ### Registries [registries]: #registries -Standard library dependencies will be present in the registry index -([?][rationale-cargo-index]). A `builtin_deps` key is added to the -[index's JSON schema][cargo-json-schema] ([?][rationale-cargo-builtindeps]). -`builtin_deps` is similar to the existing `deps` key and contains a list of JSON -objects, each representing a dependency that is "builtin" to the Rust toolchain -and cannot otherwise be found in the registry. The -["publish" endpoint][cargo-registry-web-publish] of the Registry Web API will -similarly be updated to support `builtin_deps`. +Standard library dependencies will be present in the registry index such that +standard library dependencies can be dependencies of other crates, but not as +top-level crates in the registry ([?][rationale-cargo-index]). + +A `builtin_deps` key is added to the [index's JSON schema][cargo-json-schema] +([?][rationale-cargo-builtindeps]). `builtin_deps` is similar to the existing +`deps` key and contains a list of JSON objects, each representing a dependency +that is "builtin" to the Rust toolchain and cannot otherwise be found in the +registry. The ["publish" endpoint][cargo-registry-web-publish] of the Registry +Web API will similarly be updated to support `builtin_deps`. > [!NOTE] > @@ -982,13 +984,20 @@ dependencies?*][rationale-explicit-noprelude]). ↩ [*Public and private dependencies*][public-and-private-dependencies] -### Why add standard library crates to Cargo's index? -[rationale-cargo-index]: #why-add-standard-library-crates-to-cargos-index +### Why include standard library crates in Cargo's index format? +[rationale-cargo-index]: #why-include-standard-library-crates-in-cargos-index-format + +When Cargo builds the unit graph - roughly speaking, think of this as the +compiler invocations it will eventually make - it queries the dependency +resolver as to which dependencies a given crate has. The dependency resolver +only looks at the source of a dependency, in many cases a registry source (i.e. +a dependency from crates.io). In practice, this is the entry in the Cargo index +for that dependency. As this is the only information available, that a crate +depends on the standard library must be reflected in the index entry. -When Cargo builds the dependency graph, it is driven by the index (not -`Cargo.toml`), so builtin dependencies need to be included in the index format -(so that packages can have builtin dependencies - standard library crates will -not exist as top-level packages in the index). +Alternatively, the Cargo manifests of dependencies would need to be parsed in +order to determine whether they have standard library dependencies as the index +entry would be insufficient. ↩ [*Registries*][registries] From 33b405123447b30ec9089c593de3b530684932ab Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 16 Apr 2026 10:12:18 +0100 Subject: [PATCH 34/43] update rfcs#3874 links --- text/3875-build-std-explicit-dependencies.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index b6c4faba343..0cee955d776 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -40,11 +40,11 @@ RFCs:** [rfcs#3873-motivation]: https://rust-lang.github.io/rfcs/3873-build-std-context.html#motivation [rfcs#3873-dependencies]: https://rust-lang.github.io/rfcs/3873-build-std-context.html#dependencies -[rfcs#3874]: https://github.com/rust-lang/rfcs/pull/3874 -[rfcs#3874-proposal]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#proposal -[rfcs#3874-rationale-and-alternatives]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#rationale-and-alternatives -[rfcs#3874-unresolved-questions]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#unresolved-questions -[rfcs#3874-future-possibilities]: https://github.com/davidtwco/rfcs/blob/build-std-part-two-always/text/3874-build-std-always.md#future-possibilities +[rfcs#3874]: https://rust-lang.github.io/rfcs/3874-build-std-always.html +[rfcs#3874-proposal]: https://rust-lang.github.io/rfcs/3874-build-std-always.html#proposal +[rfcs#3874-rationale-and-alternatives]: https://rust-lang.github.io/rfcs/3874-build-std-always.html#rationale-and-alternatives +[rfcs#3874-unresolved-questions]: https://rust-lang.github.io/rfcs/3874-build-std-always.html#unresolved-questions +[rfcs#3874-future-possibilities]: https://rust-lang.github.io/rfcs/3874-build-std-always.html#future-possibilities ## Motivation [motivation]: #motivation From c0120b3612567855f171e9fd79690e42b354757a Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 16 Apr 2026 10:16:01 +0100 Subject: [PATCH 35/43] add unresolved question for cargo index changes --- text/3875-build-std-explicit-dependencies.md | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 0cee955d776..d1e72b9a570 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -475,6 +475,10 @@ Web API will similarly be updated to support `builtin_deps`. - [*Why add a new key to Cargo's registry index JSON schema?*][rationale-cargo-builtindeps] - [*Why can `builtin_deps` shadow other packages in the registry?*][rationale-cargo-index-shadowing] +*See the following sections for relevant unresolved questions:* + +- [*Should parsed manifests be used instead of the registry index?*][unresolved-registry-changes] + [cargo-registry-web-publish]: https://doc.rust-lang.org/cargo/reference/registry-web-api.html#publish ### Cargo subcommands @@ -992,8 +996,8 @@ compiler invocations it will eventually make - it queries the dependency resolver as to which dependencies a given crate has. The dependency resolver only looks at the source of a dependency, in many cases a registry source (i.e. a dependency from crates.io). In practice, this is the entry in the Cargo index -for that dependency. As this is the only information available, that a crate -depends on the standard library must be reflected in the index entry. +for that dependency. As this is the information that is directly available, that +a crate depends on the standard library should be reflected in the index entry. Alternatively, the Cargo manifests of dependencies would need to be parsed in order to determine whether they have standard library dependencies as the index @@ -1126,6 +1130,15 @@ any existing users. ↩ [*`dev-dependencies` and `build-dependencies`*][dev-dependencies-and-build-dependencies] +### Should parsed manifests be used instead of the registry index? +[unresolved-registry-changes]: #should-parsed-manifests-be-used-instead-of-the-registry-index + +An alternative to changing the registry index would be checking the parsed +manifests of dependencies - which are downloaded and available when the unit +graph is being built (and used for other Cargo features). + +↩ [*Registries*][registries] + ### Should `cargo metadata` include the standard library's dependencies? [unresolved-cargo-metadata]: #should-cargo-metadata-include-the-standard-librarys-dependencies From 3eb3aa61b6c31d42427cd81a73d4bff78314c330 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 22 Apr 2026 13:09:27 +0100 Subject: [PATCH 36/43] link to rustc extern opts docs --- text/3875-build-std-explicit-dependencies.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index d1e72b9a570..4e1e8465d50 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -858,8 +858,12 @@ similarly to other dependencies in their manifest, but the behaviour will be subtly different than with implicit builtin dependencies (where `extern crate` is required). +See [the rustc documentation for more details on `noprelude`][doc_extern_opts]. + ↩ [*Proposal*][proposal] +[doc_extern_opts]: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/extern-options.html#--extern-options + ### Why not require builtin dependencies instead of supporting implicit ones? [rationale-no-migration]: #why-not-require-builtin-dependencies-instead-of-supporting-implicit-ones From 2d2c6dbd71915eaddc761c91b1e279780cf31da1 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 22 Apr 2026 13:17:39 +0100 Subject: [PATCH 37/43] elaborate on combined sources --- text/3875-build-std-explicit-dependencies.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 4e1e8465d50..f6656579e97 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -282,6 +282,23 @@ core = { builtin = true } Crates with these dependency sources will remain unable to be published to crates.io. +Building on both of the above, a `core`/`alloc`/`std` dependency can have +`path`/`git` source at the same time as a `builtin` source. This allows the +crate to remain publishable while the `path`/`git` source is only used locally: + +```toml +[package] +name = "hello_world" +version = "0.1.0" +edition = "2024" + +[dependencies] +std = { builtin = true, path = "../my_std" } # published as `builtin` dep, `path` used locally +``` + +This mirrors the existing behaviour for `path`/`git` sources when combined with +registry sources. + ### Patches [patches]: #patches From 3db442639974fc7636e7beb0c06fc885805b1957 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 22 Apr 2026 13:31:36 +0100 Subject: [PATCH 38/43] add `cargo_metadata` crate link --- text/3875-build-std-explicit-dependencies.md | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index f6656579e97..55a03ef9a9d 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1174,8 +1174,8 @@ as: - `cargo pkgid` and `cargo build --message-format` will unconditionally use the new `pkgid` spec anyway; -- `cargo_metadata` does not currently parse the pkgid spec so this won't break - all users; +- [`cargo_metadata`][crate_metadata] does not currently parse the pkgid spec so + this won't break all users; - and this will also show up in the source which is still opaque and `cargo_metadata` does not parse @@ -1185,6 +1185,8 @@ disruptive. ↩ [*Cargo subcommands*][cargo-subcommands] +[crate_metadata]: https://crates.io/crates/cargo_metadata + ## Prior art [prior-art]: #prior-art From 456c2a9ad5204520cb6e08de83907f26d6e3f616 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 22 Apr 2026 13:35:57 +0100 Subject: [PATCH 39/43] clarify applicability of dependency tables --- text/3875-build-std-explicit-dependencies.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 55a03ef9a9d..cdc2ca3e271 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -105,9 +105,10 @@ Crates without an explicit dependency on the standard library now have a implicit dependency ([?][rationale-no-migration]) on that target's default set of standard library crates (see [build-std-always][rfcs#3874-standard-library-crate-stability]). Any explicit -standard library dependency present in any dependency table will disable the -implicit dependencies (e.g. an explicit `builtin` or `path` dependency from -`std` will disable the implicit dependencies). +standard library dependency present in any dependency table applicable to the +current target will disable the implicit dependencies (e.g. an explicit +`builtin` or `path` dependency from `std` will disable the implicit +dependencies). > [!NOTE] > From ee09558a41922bbb4edd4e15e83e144a3b37872e Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 22 Apr 2026 13:36:52 +0100 Subject: [PATCH 40/43] remove duplicate defn in example --- text/3875-build-std-explicit-dependencies.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index cdc2ca3e271..d22d492ed8d 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -316,9 +316,6 @@ edition = "2024" [dependencies] std = { builtin = true } -[patch.builtin] # permitted on nightly -std = { .. } - [patch.builtin] # permitted on nightly std = { path = "../libstd" } ``` From 90197173fe1132f6883713787034bb3833370311 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 22 Apr 2026 13:47:18 +0100 Subject: [PATCH 41/43] mention `workspace.dependencies` --- text/3875-build-std-explicit-dependencies.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index d22d492ed8d..5bd8190a054 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -223,6 +223,10 @@ When a crate has no builtin dependency on `std` (or an optional builtin dependency on `std`), then Cargo will pass `-Zcrate-attr=no_std` to rustc (or some equivalent; [?][rationale-no_std]). +Builtin dependencies defined in `workspace.dependencies` are inherited by +members of the workspace in the same way as any other dependency and then the +same behaviour and constraints apply. + *See the following sections for rationale/alternatives:* - [*Why explicitly declare dependencies on the standard library in `Cargo.toml`?*][rationale-why-explicit-deps] From 927af0e57a44b2728a3facfe300cfd864ae0171d Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 22 Apr 2026 13:50:38 +0100 Subject: [PATCH 42/43] add unresolved q for pkgid format --- text/3875-build-std-explicit-dependencies.md | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 5bd8190a054..875e54f9029 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -626,7 +626,9 @@ dependencies?*][unresolved-cargo-metadata]. [`cargo pkgid`][cargo-pkgid] when passed `-p core` would print `builtin://.#core` as the source, likewise with `alloc` and `std`. This format -complies with [Cargo's spec for Package IDs][cargo-pkgid-spec]. +complies with [Cargo's spec for Package IDs][cargo-pkgid-spec]. See also +unresolved question [*What should the exact format of the `pkgid` spec for +builtin dependencies be?*][unresolved-cargo-pkgid]. [`cargo remove`][cargo-remove] will remove `core`, `alloc` or `std` explicitly from the manifest if invoked with those crate names (using the same heuristics @@ -1189,6 +1191,14 @@ disruptive. [crate_metadata]: https://crates.io/crates/cargo_metadata +### What should the exact format of the `pkgid` spec for builtin dependencies be? +[unresolved-cargo-pkgid]: #what-should-the-exact-format-of-the-pkgid-spec-for-builtin-dependencies-be + +The format for builtin dependencies of `cargo pkgid` can be changed prior to +stabilisation and does not need to match what is proposed in this RFC exactly. + +↩ [*Cargo subcommands*][cargo-subcommands] + ## Prior art [prior-art]: #prior-art From 9ead9428bb18eea2f1d194354b64e043c9d55abe Mon Sep 17 00:00:00 2001 From: Eric Huss Date: Mon, 4 May 2026 08:02:11 -0700 Subject: [PATCH 43/43] Set the tracking issue --- text/3875-build-std-explicit-dependencies.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3875-build-std-explicit-dependencies.md b/text/3875-build-std-explicit-dependencies.md index 875e54f9029..c45a990a890 100644 --- a/text/3875-build-std-explicit-dependencies.md +++ b/text/3875-build-std-explicit-dependencies.md @@ -1,7 +1,7 @@ - Feature Name: `build-std-explicit-dependencies` - Start Date: 2025-06-05 - RFC PR: [rust-lang/rfcs#3875](https://github.com/rust-lang/rfcs/pull/3875) -- Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) +- Tracking Issue: [rust-lang/cargo#16960](https://github.com/rust-lang/cargo/issues/16960) ## Summary [summary]: #summary