Skip to content

stabilize optimize attribute#157273

Open
veluca93 wants to merge 1 commit into
rust-lang:mainfrom
veluca93:optimize-attribte
Open

stabilize optimize attribute#157273
veluca93 wants to merge 1 commit into
rust-lang:mainfrom
veluca93:optimize-attribte

Conversation

@veluca93

@veluca93 veluca93 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

View all comments

This commit stabilizes the #[optimize] attribute, which allows for more fine-grained control of optimization levels.

Stabilization report

Summary

Tracking issue: #54882
Reference PRs: rust-lang/reference#2278

cc @rust-lang/lang @rust-lang/lang-advisors @rust-lang/t-compiler

What is stabilized

// Instructs the optimization pipeline to prioritize smaller code size over speed.
#[optimize(size)]
pub fn binary_size_sensitive() {
    // ...
}

// Instructs the optimization pipeline to prioritize execution speed over code size.
#[optimize(speed)]
pub fn performance_critical() {
    // ...
}

// Disables optimizations entirely for this item.
#[optimize(none)]
pub fn debug_only() {
    // ...
}

What isn't stabilized

We might want to allow specifying a per-function optimization level (i.e. #[optimize(level = 3)]). To my understanding, backend support for this is not quite there yet (and this - or other - extensions have consequently not been implemented yet).

Applying the attribute on a module level is also not implemented yet.

Design

Reference

RFC history

Answers to unresolved question

  • Should we also implement optimize(always)? optimize(level=x)?

Not yet.

  • Should there be any way to specify what global optimization for speed level is used in conjunction with the optimization for speed option (e.g. -Copt-level=s3 could be equivalent to -Copt-level=3 and #[optimize(size)] on the crate item).

Not yet.

Post-RFC changes

The optimize(none) variant was added. The variants above were discussed here: #54882 (comment)

Key points

Nightly uses

The standard library itself uses this attribute in a few places

Implementation

Major part

Coverage

Tool changes

Trivial changes to rust-analyzer to support the new attribute as an inert attribute: rust-lang/rust-analyzer#22511

Type system, opsem

Breaks the AM?

As far as the AM is concerned, this attribute doesn't exist.

Acknowledgments

Most of the work was not done by me, I'm just writing the stabilization report :-)

@nagisa did the initial implementation, @clubby789 implemented optimize(none) and fixed the attribute being allowed in too many places.

@rustbot

rustbot commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

rust-analyzer is developed in its own repository. If possible, consider making this change to rust-lang/rust-analyzer instead.

cc @rust-lang/rust-analyzer

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. labels Jun 1, 2026
@rustbot

rustbot commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

r? @JohnTitor

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

Use r? to explicitly pick a reviewer

Why was this reviewer chosen?

The reviewer was selected based on:

  • Owners of files modified in this PR: compiler
  • compiler expanded to 73 candidates
  • Random selection from 17 candidates

@rustbot

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@veluca93 veluca93 force-pushed the optimize-attribte branch from deb33c2 to 1de7123 Compare June 1, 2026 20:28
@rustbot

This comment has been minimized.

@veluca93 veluca93 force-pushed the optimize-attribte branch from 1de7123 to 56db805 Compare June 1, 2026 20:30
@veluca93 veluca93 changed the title stabilize optimize attribute (size, speed, and none) stabilize optimize attribute Jun 1, 2026
@tgross35

tgross35 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor

Given the interactions here, I expect this will need a lang+compiler FCP

@rustbot label +I-lang-nominated +I-compiler-nominated

See some recent discussion about this feature on Zulip #t-lang > status of #[optimize] attribute

@rustbot rustbot added I-compiler-nominated Nominated for discussion during a compiler team meeting. I-lang-nominated Nominated for discussion during a lang team meeting. labels Jun 1, 2026
@tgross35 tgross35 added needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. T-lang Relevant to the language team and removed T-rust-analyzer Relevant to the rust-analyzer team, which will review and decide on the PR/issue. T-libs Relevant to the library team, which will review and decide on the PR/issue. labels Jun 1, 2026
@rust-log-analyzer

This comment has been minimized.

@JohnTitor JohnTitor added S-blocked Status: Blocked on something else such as an RFC or other implementation work. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Jun 1, 2026
@JohnTitor

Copy link
Copy Markdown
Member

Marking as S-blocked given the current status.

@veluca93 veluca93 force-pushed the optimize-attribte branch from 56db805 to 680ec3c Compare June 1, 2026 22:03
@rustbot

rustbot commented Jun 1, 2026

Copy link
Copy Markdown
Collaborator

These commits modify tests/rustdoc-json.
rustdoc-json is a public (but unstable) interface.

Please ensure that if you've changed the output:

  • It's intentional.
  • The FORMAT_VERSION in src/librustdoc-json-types is bumped if necessary.

cc @aDotInTheVoid, @obi1kenobi

@rustbot rustbot added the A-rustdoc-json Area: Rustdoc JSON backend label Jun 1, 2026
@obi1kenobi

Copy link
Copy Markdown
Member

With my cargo-semver-checks hat on: do we expect this attribute to have SemVer implications?

For example, can applying or removing this attribute on an item influence the contexts in which that item may be used without compile errors or other changes that would be considered public-API-breaking?

@veluca93

veluca93 commented Jun 1, 2026

Copy link
Copy Markdown
Contributor Author

With my cargo-semver-checks hat on: do we expect this attribute to have SemVer implications?

For example, can applying or removing this attribute on an item influence the contexts in which that item may be used without compile errors or other changes that would be considered public-API-breaking?

I don't believe this is possible - the attribute should only influence how the compiler optimizes functions, and compiler optimizations should not have any visible effects.

Comment thread tests/ui/feature-gates/feature-gate-optimize_attribute.stderr Outdated

@jieyouxu jieyouxu Jun 2, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discussion: hm, I wonder if this attribute deserves an entry in the rustc book (a bit like lint levels), because while sure there's the Reference PR, but this is more like a compiler knob?

View changes since the review

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 5, 2026
Add a smoke test for the optimize attribute.

Tracking issue: rust-lang#54882
Stabilization PR: rust-lang#157273
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 5, 2026
…nline, r=JonathanBrouwer

Forbid optimize(none) with inline(always) or inline.

Tracking issue: rust-lang#54882
Stabilization PR: rust-lang#157273
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 5, 2026
Add a smoke test for the optimize attribute.

Tracking issue: rust-lang#54882
Stabilization PR: rust-lang#157273
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 5, 2026
…nline, r=JonathanBrouwer

Forbid optimize(none) with inline(always) or inline.

Tracking issue: rust-lang#54882
Stabilization PR: rust-lang#157273
jhpratt added a commit to jhpratt/rust that referenced this pull request Jun 5, 2026
Add a smoke test for the optimize attribute.

Tracking issue: rust-lang#54882
Stabilization PR: rust-lang#157273
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jun 5, 2026
…nline, r=JonathanBrouwer

Forbid optimize(none) with inline(always) or inline.

Tracking issue: rust-lang#54882
Stabilization PR: rust-lang#157273
GuillaumeGomez added a commit to GuillaumeGomez/rust that referenced this pull request Jun 5, 2026
Add a smoke test for the optimize attribute.

Tracking issue: rust-lang#54882
Stabilization PR: rust-lang#157273
rust-timer added a commit that referenced this pull request Jun 5, 2026
Rollup merge of #157475 - veluca93:optimize-smoke, r=jieyouxu

Add a smoke test for the optimize attribute.

Tracking issue: #54882
Stabilization PR: #157273
rust-timer added a commit that referenced this pull request Jun 5, 2026
Rollup merge of #157474 - veluca93:optimize-error-optimize-inline, r=JonathanBrouwer

Forbid optimize(none) with inline(always) or inline.

Tracking issue: #54882
Stabilization PR: #157273
@rust-bors

This comment has been minimized.

@traviscross

traviscross commented Jun 6, 2026

Copy link
Copy Markdown
Contributor

This is for lang to consider -- what is the intended behavior of #[optimize(..)] to a nested function? Does the attribute's effect "recursively apply"?

In my view, it should work in the same way as #[inline(…)].

This commit stabilizes the `#[optimize]` attribute, which allows for more fine-grained control
of optimization levels.
@veluca93 veluca93 force-pushed the optimize-attribte branch from c87a3e7 to 3aa06ad Compare June 6, 2026 08:02
@rustbot

rustbot commented Jun 6, 2026

Copy link
Copy Markdown
Collaborator

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

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

@veluca93

veluca93 commented Jun 6, 2026

Copy link
Copy Markdown
Contributor Author

On the capabilities and scope of the attribute (@nagisa): as you said, I don't believe we can ever give realistic guarantees on what effects those attributes will have - beyond the fact that they do not change the semantics of the program, and that they might affect compiler optimizations -- similarly to the inline attribute, and to most of the contents of the std::hint module. That said, IMO the final decision on this rests on t-lang.

On the meaning of optimize(size) (@nikic): I believe using LLVM's minsize is more likely to match the intent, but IMO having size = minsize makes it more awkward to have also something that maps to optsize (I'd find it more natural to have size, minsize than to have optsize, size). I am personally fine with having size = minsize, but again probably better left to t-lang :-)

On behaviour of nested functions: I agree with @traviscross that it probably should be the same as inline, and as far as I can tell this is indeed the current behaviour.

github-actions Bot pushed a commit to rust-lang/stdarch that referenced this pull request Jun 8, 2026
…JonathanBrouwer

Forbid optimize(none) with inline(always) or inline.

Tracking issue: rust-lang/rust#54882
Stabilization PR: rust-lang/rust#157273
github-actions Bot pushed a commit to rust-lang/stdarch that referenced this pull request Jun 8, 2026
Add a smoke test for the optimize attribute.

Tracking issue: rust-lang/rust#54882
Stabilization PR: rust-lang/rust#157273
@traviscross traviscross added the I-lang-radar Items that are on lang's radar and will need eventual work or consideration. label Jun 10, 2026
@joshtriplett

joshtriplett commented Jun 10, 2026

Copy link
Copy Markdown
Member

Leaving aside whether we apply the optimize attribute recursively to nested items, it'd be helpful to know whether it applies recursively to closures. If those are treated the same way, that seems likely to be surprising; I think people would expect the attribute to apply recursively to closures. If the easiest way to do that is to also apply recursively to items, then I think that's what we should do, as closures seem likely to be the common case where it's desired and where it'd be otherwise inconvenient to do.

(Also, can we confirm whether we can write the attribute in a fashion that applies to closures?)

@joshtriplett

Copy link
Copy Markdown
Member

Random bikeshed-color suggestion (for future extension, not derailing what's currently proposed for stabilization):

  • optimize(size) = opt-level="z"
  • optimize(size,speed) = opt-level="s"

@veluca93

Copy link
Copy Markdown
Contributor Author

Leaving aside whether we apply the optimize attribute recursively to nested items, it'd be helpful to know whether it applies recursively to closures. If those are treated the same way, that seems likely to be surprising; I think people would expect the attribute to apply recursively to closures. If the easiest way to do that is to also apply recursively to items, then I think that's what we should do, as closures seem likely to be the common case where it's desired and where it'd be otherwise inconvenient to do.

(Also, can we confirm whether we can write the attribute in a fashion that applies to closures?)

As far as I can tell, it is not (and neither is inline, fwiw).
The attribute can be written as {#[optimize(size)] |x| x} or similar, but that seems to have no effect as far as I can tell. So that probably requires some fixing.

@scottmcm

Copy link
Copy Markdown
Member

This choice should be optimized. We could also map to optsize instead, or we could expect both options. I don't have any specific preference here, I just want to make sure we're making a deliberate decision.

At least from a lang perspective I'd be happy adding things like optimize(min_size) in the future if compiler said they were useful, so if size was s for now and we could add more things for z in future if that would be useful that'd be good for me.

@veluca93

Copy link
Copy Markdown
Contributor Author

This choice should be optimized. We could also map to optsize instead, or we could expect both options. I don't have any specific preference here, I just want to make sure we're making a deliberate decision.

At least from a lang perspective I'd be happy adding things like optimize(min_size) in the future if compiler said they were useful, so if size was s for now and we could add more things for z in future if that would be useful that'd be good for me.

my 2c: I prefer #[optimize(size, speed)] over having min_size and size, but I like both.

@traviscross

Copy link
Copy Markdown
Contributor

For my own part, on the meaning question, I'm happy for optimize(size) to mean "optimize for size at all costs". If, in the future, we want a way to express "optimize for a balance between both size and speed", I'd be happy with optimize(size, speed) for that.

Regarding the degree to which this is a lang question, I think what we intend for an attribute to mean (e.g., "optimize for size at all costs"), and consequently, what we'd write in the Reference about it, is a lang question. How to best implement that, in terms of which flags to apply, is a compiler one. E.g., our docs say that z "often results in larger binaries than s". Compiler would be within its rights if it were to conclude that, on balance, s better achieves the "optimize for size at all costs" intended meaning.

On the other two questions:

One, I still expect this attribute to affect only the item to which it is applied, in the same way as inline and our other codegen attributes. We treat closures as a kind of pseudo-item for this purpose.

If we were to later want to apply this to modules and to functions in a way that it would affect inner items, I'd expect this to be syntactically distinct and to work in the same way with inline. E.g., maybe we'd add an apply(…) (TODO: naming bikeshed) attribute and then write #[apply(inline(always))] fn f() { … } and #[apply(optimize(speed))] fn f() { … }.

Two, on the question of whether we're happy with the capability and scope of this attribute, e.g., that no guarantees can be made about optimize(none), I'm happy with that. As with our other codegen attributes, nobody should rely on these, e.g., to ensure constant-time operation.

@traviscross

Copy link
Copy Markdown
Contributor

In the lang meeting today, we discussed the three questions raised as concerns:

On the capabilities and scope question, we were all agreed that we're happy to accept the limitations.

On the question of meaning, we were happy with optimize(size) focusing on size optimization and leaving to compiler to determine what that means in terms of the appropriate flags to apply. We discussed how we could later accept optimize(size, speed), if needed, and people seemed generally happy with that.

On the question of whether this applies recursively to inner items, my sense of the meeting was that we were happy for this to land in its current form where it does not apply recursively, but I note @joshtriplett's earlier comment in #157273 (comment), so I'll let him speak to whether he considers application to inner closures something we should discuss and resolve before proceeding.

@jieyouxu: Does that help with the concerns you raised? Once you've resolved those, I'm planning to propose dual FCP merge between lang and compiler.

@veluca93

Copy link
Copy Markdown
Contributor Author

FWIW, specifically for closures, I think we should at least make an optimize attribute applied to a closure do something if the closure is not inlined, regardless of whether closures inherit the optimize attribute of the function they live in.

Since often closures are MIR-inlined (I believe!), perhaps having the closure inherit the attribute is the least surprising behaviour - otherwise whether the closure inherits the attribute or not depends on hard-to-control optimizations (of course whether the attribute does something at all also depends on optimizations, but we should at least try to not make the problem worse)

@jieyouxu

Copy link
Copy Markdown
Member

Does that help with the concerns you raised? Once you've resolved those, I'm planning to propose dual FCP merge between lang and compiler.

Yes, unless we still have that closure semantics question to make a deliberate decision on. I was mostly just forwarding important comments as concerns so they're not lost.

@rustbot resolve are-we-happy-wiht-capability-and-scope-of-this-attribute
@rustbot resolve meaning-of-optimize-size
@rustbot resolve explicitly-decide-on-effect-on-nested-functions

@rustbot rustbot removed the S-waiting-on-concerns Status: Awaiting concerns to be addressed by the author label Jun 11, 2026
@traviscross

Copy link
Copy Markdown
Contributor

The attribute can be written as {#[optimize(size)] |x| x} or similar, but that seems to have no effect as far as I can tell. So that probably requires some fixing.

FWIW, specifically for closures, I think we should at least make an optimize attribute applied to a closure do something if the closure is not inlined...

As best I can tell, optimize on closures does have effect and seems to work in the way I'd expect (i.e., in the same way as inline). E.g., Godbolt link.

@veluca93: Are we looking at the same thing?

@veluca93

Copy link
Copy Markdown
Contributor Author

The attribute can be written as {#[optimize(size)] |x| x} or similar, but that seems to have no effect as far as I can tell. So that probably requires some fixing.

FWIW, specifically for closures, I think we should at least make an optimize attribute applied to a closure do something if the closure is not inlined...

As best I can tell, optimize on closures does have effect and seems to work in the way I'd expect (i.e., in the same way as inline). E.g., Godbolt link.

@veluca93: Are we looking at the same thing?

I think we are looking at similar things, at least - I tried (size) instead of (none) and its behaviour seems a bit less predictable, see https://rust.godbolt.org/z/jGjc51PKn :-)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-attributes Area: Attributes (`#[…]`, `#![…]`) A-rustdoc-json Area: Rustdoc JSON backend I-lang-nominated Nominated for discussion during a lang team meeting. I-lang-radar Items that are on lang's radar and will need eventual work or consideration. needs-fcp This change is insta-stable, or significant enough to need a team FCP to proceed. P-lang-drag-1 Lang team prioritization drag level 1. https://rust-lang.zulipchat.com/#narrow/channel/410516-t-lang S-blocked Status: Blocked on something else such as an RFC or other implementation work. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team

Projects

None yet

Development

Successfully merging this pull request may close these issues.