From 44fc14e857b338942c04a2150b05327b08860151 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 23 Feb 2026 02:08:47 -0800 Subject: [PATCH 01/11] Cargo: `hints.min-opt-level` This RFC adds a mechanism for crates to *hint* that builds should use optimization by default, while still allowing the top-level crate to easily override this. --- text/0000-cargo-hints-min-opt-level.md | 158 +++++++++++++++++++++++++ 1 file changed, 158 insertions(+) create mode 100644 text/0000-cargo-hints-min-opt-level.md diff --git a/text/0000-cargo-hints-min-opt-level.md b/text/0000-cargo-hints-min-opt-level.md new file mode 100644 index 00000000000..74176b0dccb --- /dev/null +++ b/text/0000-cargo-hints-min-opt-level.md @@ -0,0 +1,158 @@ +- Feature Name: `cargo-hints-min-opt-level` +- Start Date: 2026-02-22 +- 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 Rust library to provide a simple hint about the minimum opt-level to +build them with. + +## Motivation +[motivation]: #motivation + +When people build Rust projects, they have a choice of tradeoffs between the +speed of the build and the performance of the code at runtime. Builds using the +dev profile aim for minimal build time at the expense of unoptimized code at +runtime; builds using the release profile spend more time building in order to +improve runtime performance. + +However, there are some library crates for which almost every use case wants +optimization, because an unoptimized build provides so little performance as to +be unusable. Such libraries typically include a note in their `README.md` +warning users to turn on optimization even in the dev profile: + +```toml +[profile.dev.package."example-high-performance-package"] +opt-level = 3 +``` + +This RFC adds a mechanism for crates to *hint* that builds should use +optimization by default, while still allowing the top-level crate to easily +override this. + +## Guide-level explanation +[guide-level-explanation]: #guide-level-explanation + +Some libraries benefit strongly from optimization, or are hurt especially by +builds without optimization, to the point that they expect almost no users to +ever want to run them unoptimized. Such libraries can use the Cargo `hints` +system to provide a minimum optimization level: + +```toml +[hints] +min-opt-level = 2 +``` + +When building with a profile with a default optimization level lower than the +`hints.min-opt-level` value, the crate will be built with the specified minimum +optimization level instead. When building with a profile with a higher +default optimization level, that higher optimization level will take precedence. + +This applies whether the optimization level is the default for the profile, or +is set by the user explicitly for the profile: + +```toml +[profile.dev] +opt-level = 1 +# Does not override a higher hints.min-opt-level specified in a dependency. +``` + +To override the hinted minimum optimization level, the top-level crate can use +profile overrides to set the opt-level. Any opt-level specified via profile +overrides will take precedence over any hint, whether the profile override +applies to a specific crate or to all dependencies: + +```toml +[profile.dev.package."*"] +opt-level = 1 +# Overrides hints.min-opt-level specified in a dependency. + +[profile.dev.package."random-package"] +opt-level = 0 +# Overrides hints.min-opt-level specified in a dependency. +``` + +## Reference-level explanation +[reference-level-explanation]: #reference-level-explanation + +The `hints.min-opt-level` key requires an integer, and only supports numeric +hint levels (0, 1, 2, 3). Non-numeric hint levels like `s` and `z` are not +supported, because they don't fit into a strictly ordered progression. + +`hints.min-opt-level`, like any hint, does not affect a crate's MSRV; older +versions of Cargo will ignore it. + +Any profile override will take precedence over `hint.min-opt-level`, including +an override for all dependencies, an override for all build dependencies, or an +override for a specific dependency. + +A profile specifying an `opt-level` will not override a higher +`hints.min-opt-level` specified in a dependency. + +## Drawbacks +[drawbacks]: #drawbacks + +Crates could overuse this mechanism, requiring optimization even when they +don't actually need it. We should provide clear documentation recommending when +to use it and when not to use it. + +## Rationale and alternatives +[rationale-and-alternatives]: #rationale-and-alternatives + +This mechanism intentionally does not offer a "maximum optimization level", nor +does it support optimizing for size. + +This mechanism intentionally does not provide access to any specific target +feature flags, as this is typically something the top-level crate needs to +retain full control over based on its minimum system requirements. + +We could support multiple min-opt-level hints, one for dev-like profiles and +one for release-like profiles, for crates that want a lower min-opt-level in +the dev profile. However, `profile.release` already defaults to `opt-level = +3`, so `min-opt-level` will generally never affect the release profile, only +the dev profile. Thus, a single setting seems sufficient. + +We could have a simple boolean, e.g. `optimize-in-dev = true`, and leave it to +Cargo whether that means opt-level 1, 2, or 3. This would be simpler, but would +prevent crates from determining whether they benefit from opt-level 3 (e.g. +aggressive vectorization and loop unrolling) or not. + +## Prior art +[prior-art]: #prior-art + +Cargo already provides the profile overrides mechanism, for the top-level crate +to specify the opt-level of individual crates. + +This RFC builds on the `hints` mechanism, currently used for +`hints.mostly-unused`. The +[post announcing `hints.mostly-unused`](https://blog.rust-lang.org/inside-rust/2025/07/15/call-for-testing-hint-mostly-unused/) +included +[a section on future hints such as `min-opt-level`](https://blog.rust-lang.org/inside-rust/2025/07/15/call-for-testing-hint-mostly-unused/#future-hints). +Cargo has +[an issue discussing `min-opt-level`](https://github.com/rust-lang/cargo/issues/8501). + +C and C++ compilers provide directives such as `#pragma optimize` or +`__attribute__((optimize))`, which let individual files or functions define an +optimization level. + +## Future possibilities +[future-possibilities]: #future-possibilities + +`hints.min-opt-level` is a simple mechanism providing a single hint. There are +many other possible optimization hints a library *might* wish to provide, and +we could consider adding further hints for those in the future. Any such hint +would need to balance the tradeoffs between value, additional complexity, and +whether crates in the ecosystem know the right optimization level for their +crate better than their users do. + +We could in particular have a `max-opt-level`, for crates that don't benefit +from `opt-level = 3` to lower the optimiation level to 2. + +We may in the future want to change the default optimization level for the dev +profile to 1, rather than 0. opt-level 1 includes optimizations that can make +compilation *faster*, such as by sending less code to the codegen backend (e.g. +LLVM). This might reduce the number of crates motivated to use this mechanism, +but the mechanism would remain important, as there are library crates which +strongly benefit from opt-level 2 or 3. From c55f8305fcdb99c55ef49b5767e6a6d85d0bc48a Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 23 Feb 2026 02:11:12 -0800 Subject: [PATCH 02/11] RFC 3924 --- ...hints-min-opt-level.md => 3924-cargo-hints-min-opt-level.md} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename text/{0000-cargo-hints-min-opt-level.md => 3924-cargo-hints-min-opt-level.md} (98%) diff --git a/text/0000-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md similarity index 98% rename from text/0000-cargo-hints-min-opt-level.md rename to text/3924-cargo-hints-min-opt-level.md index 74176b0dccb..9128820f20f 100644 --- a/text/0000-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -1,6 +1,6 @@ - Feature Name: `cargo-hints-min-opt-level` - Start Date: 2026-02-22 -- RFC PR: [rust-lang/rfcs#0000](https://github.com/rust-lang/rfcs/pull/0000) +- RFC PR: [rust-lang/rfcs#3924](https://github.com/rust-lang/rfcs/pull/3924) - Rust Issue: [rust-lang/rust#0000](https://github.com/rust-lang/rust/issues/0000) ## Summary From 1a0f38bd13a0d9cb6339e1d7ad5309378b126fae Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 23 Feb 2026 02:58:56 -0800 Subject: [PATCH 03/11] min-opt-level does not apply to the library's dependencies --- text/3924-cargo-hints-min-opt-level.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index 9128820f20f..6af80419ec0 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -91,6 +91,10 @@ override for a specific dependency. A profile specifying an `opt-level` will not override a higher `hints.min-opt-level` specified in a dependency. +Note that a hint provided by a given library crate only applies to that +specific crate, not that package's dependencies. If the code that needs +optimizing is in a dependency, that dependency would need to add the hint. + ## Drawbacks [drawbacks]: #drawbacks @@ -119,6 +123,10 @@ Cargo whether that means opt-level 1, 2, or 3. This would be simpler, but would prevent crates from determining whether they benefit from opt-level 3 (e.g. aggressive vectorization and loop unrolling) or not. +We could have a hint apply recursively to dependencies. This seems like more +control than a library crate could have, as a dependency may be used in +multiple places in the crate graph. + ## Prior art [prior-art]: #prior-art From b80600274a3c78eef72f071aa3a58463a48fa2f4 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 16:54:07 -0800 Subject: [PATCH 04/11] Expand motivation --- text/3924-cargo-hints-min-opt-level.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index 6af80419ec0..f61861ff8cf 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -30,7 +30,8 @@ opt-level = 3 This RFC adds a mechanism for crates to *hint* that builds should use optimization by default, while still allowing the top-level crate to easily -override this. +override this. Handling this in dependencies makes it automatic for users, and +also makes it easier to keep up with an evolving dependency tree. ## Guide-level explanation [guide-level-explanation]: #guide-level-explanation From fb7b4c3bb40ea7b898be1e1e6301e717192bf7ca Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 16:59:06 -0800 Subject: [PATCH 05/11] Discuss limitations on third-party dependencies or inlined/monomorphized code --- text/3924-cargo-hints-min-opt-level.md | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index f61861ff8cf..540d11343f7 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -103,6 +103,16 @@ Crates could overuse this mechanism, requiring optimization even when they don't actually need it. We should provide clear documentation recommending when to use it and when not to use it. +### Limitations + +Library crates cannot set this for dependencies they do not maintain; a crate +can only set the min-opt-level for itself. This may cause issues for crates +whose performance depends heavily on its dependencies; such crates may still +have to rely on user documentation. + +Library optimizations may not apply to code inlined or monomorphized by a +user's crate. + ## Rationale and alternatives [rationale-and-alternatives]: #rationale-and-alternatives @@ -165,3 +175,10 @@ compilation *faster*, such as by sending less code to the codegen backend (e.g. LLVM). This might reduce the number of crates motivated to use this mechanism, but the mechanism would remain important, as there are library crates which strongly benefit from opt-level 2 or 3. + +We may want to provide a further mechanism for libraries whose performance +depends heavily on their dependencies to optimize those dependencies. + +We may want to provide a mechanism for libraries to optimize code inlined or +monomorphized by a user's crate. That would likely require compiler +enhancements. From 2997fa165dc2ab0fb81f17e2182157a9800533f9 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 17:01:32 -0800 Subject: [PATCH 06/11] Remove stray whitespace Co-authored-by: nora <48135649+Noratrieb@users.noreply.github.com> --- text/3924-cargo-hints-min-opt-level.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index 540d11343f7..edb1dacabf1 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -46,7 +46,7 @@ system to provide a minimum optimization level: min-opt-level = 2 ``` -When building with a profile with a default optimization level lower than the +When building with a profile with a default optimization level lower than the `hints.min-opt-level` value, the crate will be built with the specified minimum optimization level instead. When building with a profile with a higher default optimization level, that higher optimization level will take precedence. From 40e53d40f4f2850493193132c5085f504c16b7c0 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 17:04:10 -0800 Subject: [PATCH 07/11] Discuss crates potentially wanting to override in their own workspace --- text/3924-cargo-hints-min-opt-level.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index edb1dacabf1..c2cdba04849 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -103,6 +103,9 @@ Crates could overuse this mechanism, requiring optimization even when they don't actually need it. We should provide clear documentation recommending when to use it and when not to use it. +If a crate using this mechanism wishes to nonetheless build with different +optimizations within its own workspace, it would have to add an override. + ### Limitations Library crates cannot set this for dependencies they do not maintain; a crate From 3f53e4befbfd465ea00630321ce5d6f0c0a93d64 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 17:07:37 -0800 Subject: [PATCH 08/11] Mention the possibility of overrides that set a minimum but not a maximum Particularly relevant for `"*"` overrides. --- text/3924-cargo-hints-min-opt-level.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index c2cdba04849..4f337991037 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -172,6 +172,11 @@ crate better than their users do. We could in particular have a `max-opt-level`, for crates that don't benefit from `opt-level = 3` to lower the optimiation level to 2. +The mechanism to override a dependency's opt-level using `profile.dev.package` +forces a given opt-level whether the dependency asks for higher or lower. Users +of overrides, particularly those for `"*"`, might want a mechanism for setting +a minimum without overriding a higher optimization level. + We may in the future want to change the default optimization level for the dev profile to 1, rather than 0. opt-level 1 includes optimizations that can make compilation *faster*, such as by sending less code to the codegen backend (e.g. From 383f3600abbfedbe9c02008335d2226c40691166 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 17:12:57 -0800 Subject: [PATCH 09/11] Add alternative about supporting `"s"` or `"z"` --- text/3924-cargo-hints-min-opt-level.md | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index 4f337991037..75ddc77457b 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -137,6 +137,16 @@ Cargo whether that means opt-level 1, 2, or 3. This would be simpler, but would prevent crates from determining whether they benefit from opt-level 3 (e.g. aggressive vectorization and loop unrolling) or not. +We could support `"z"` or `"s"` somehow. This would be more complex and require +more design, since those aren't on a linear scale like the numeric optimization +levels. Furthermore, these seem less likely to be usefully determined by +dependencies: whether a dependency will have massive performance issues if +built without optimization is something the dependency may know, while the need +for size optimization seems likely to be use-case-dependent and better set by +the top-level crate. (The use of crates *designed* for embedded, for instance, +does not necessarily indicate that the user is size-constrained and would +*prefer* size optimizations.) + We could have a hint apply recursively to dependencies. This seems like more control than a library crate could have, as a dependency may be used in multiple places in the crate graph. From 7772471a15f8f98722563f40d9e4bf5a02fabb0f Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 17:17:44 -0800 Subject: [PATCH 10/11] Top-level `"s"` and `"z"` override dependency `min-opt-level` Crates optimizing for size are likely to want size-over-speed optimizations in their dependencies as well. --- text/3924-cargo-hints-min-opt-level.md | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index 75ddc77457b..a863935e04d 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -75,12 +75,19 @@ opt-level = 0 # Overrides hints.min-opt-level specified in a dependency. ``` +Note that setting `opt-level = "s"` or `opt-level = "z"` in the top-level +crate's profile *will* override `min-opt-level` in a dependency, on the theory +that crates optimizing for size are likely to want size-over-speed +optimizations in their dependencies as well. + ## Reference-level explanation [reference-level-explanation]: #reference-level-explanation The `hints.min-opt-level` key requires an integer, and only supports numeric -hint levels (0, 1, 2, 3). Non-numeric hint levels like `s` and `z` are not -supported, because they don't fit into a strictly ordered progression. +hint levels (0, 1, 2, 3). Non-numeric hint levels like `"s"` and `"z"` are not +supported, because they don't fit into a strictly ordered progression, and +because they're more likely to be use-case-dependent and better determined by +the top-level crate. `hints.min-opt-level`, like any hint, does not affect a crate's MSRV; older versions of Cargo will ignore it. @@ -169,6 +176,14 @@ C and C++ compilers provide directives such as `#pragma optimize` or `__attribute__((optimize))`, which let individual files or functions define an optimization level. +## Unresolved questions +[unresolved-questions]: #unresolved-questions + +Should a profile with `opt-level = "s"` or `opt-level = "z"` +override a dependency's `min-opt-level`? This RFC says it should, +but sometimes users might not want that. We could also give more +control over that. + ## Future possibilities [future-possibilities]: #future-possibilities From 78b164fb4ef92acb9112ff6f4b2bf6c3e1e5e438 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Thu, 5 Mar 2026 17:22:36 -0800 Subject: [PATCH 11/11] Document in drawbacks that different users will have different tradeoffs Aiming for an improvement on balance, but it won't be an improvement for *every* user. --- text/3924-cargo-hints-min-opt-level.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/text/3924-cargo-hints-min-opt-level.md b/text/3924-cargo-hints-min-opt-level.md index a863935e04d..03a291e10ac 100644 --- a/text/3924-cargo-hints-min-opt-level.md +++ b/text/3924-cargo-hints-min-opt-level.md @@ -110,6 +110,14 @@ Crates could overuse this mechanism, requiring optimization even when they don't actually need it. We should provide clear documentation recommending when to use it and when not to use it. +Even when used for the intended purpose, different users may have different +tradeoffs. The override mechanism allows users to retain control, but the +defaults will not be ideal for *all* users. The mechanism proposed by this RFC +is making a deliberate tradeoff, and proposes that the defaults will work +better for more users than the *current* default of not providing these hints, +but this RFC does not claim the new default will be an improvement for every +user. + If a crate using this mechanism wishes to nonetheless build with different optimizations within its own workspace, it would have to add an override.