Skip to content

Do not deduce parameter attributes during CTFE#151842

Open
eggyal wants to merge 1 commit intorust-lang:mainfrom
eggyal:skip-deducing-parameter-attrs-during-ctfe
Open

Do not deduce parameter attributes during CTFE#151842
eggyal wants to merge 1 commit intorust-lang:mainfrom
eggyal:skip-deducing-parameter-attrs-during-ctfe

Conversation

@eggyal
Copy link
Contributor

@eggyal eggyal commented Jan 29, 2026

Ever since #103172 (cc @pcwalton), fn_abi_of_instance might look at a function's body to deduce certain codegen optimization attributes for its indirectly-passed parameters beyond what can be determined purely from its signature (namely today ArgAttribute::ReadOnly and ArgAttribute::CapturesNone). However, this can lead to cycles when performed during CTFE, despite such attributes being irrelevant to the evaluation result.

This patch breaks a subquery out from fn_abi_of_instance, fn_abi_of_instance_no_deduced_attrs, which returns the ABI before such parameter attributes are deduced; and that new subquery is used in CTFE instead.

This is the correct fix that #151784 was (incorrectly) attempting to part-address.

Fixes #151748
r? jdonszelmann (as requested in the previous PR)

@rustbot
Copy link
Collaborator

rustbot commented Jan 29, 2026

Some changes occurred to the CTFE / Miri interpreter

cc @rust-lang/miri

Some changes occurred to the CTFE machinery

cc @RalfJung, @oli-obk, @lcnr

@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. labels Jan 29, 2026
@eggyal eggyal force-pushed the skip-deducing-parameter-attrs-during-ctfe branch from 5650820 to ea095f5 Compare January 29, 2026 22:26
@rust-log-analyzer

This comment has been minimized.

@eggyal
Copy link
Contributor Author

eggyal commented Jan 29, 2026

@rustbot author

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

rustbot commented Jan 29, 2026

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

@eggyal eggyal force-pushed the skip-deducing-parameter-attrs-during-ctfe branch from ea095f5 to de839fc Compare January 30, 2026 06:50
@RalfJung
Copy link
Member

Note that ABI "adjustments" typically do more than just deducing parameter attributes. So if "unadjusted" just refers to the attributes, that's confusing naming.

Also, having the full signature might be relevant for the UB checking that const-eval and Miri are doing. So it's at least slightly concerning that we shouldn't be able to access some of that info any more. What exactly is the difference between the signatures we obtain this way?

@eggyal
Copy link
Contributor Author

eggyal commented Jan 30, 2026

Agreed—I'll rename to fn_abi_of_instance_no_deduced_attrs.

The only differences are in the attributes of indirectly-passed parameters, which will include ArgAttribute::ReadOnly and/or ArgAttribute::CapturesNone in optimised builds when their applicability can be inferred from the function body.

@RalfJung
Copy link
Member

RalfJung commented Jan 30, 2026

Looking at #151748, it seems like the underlying issue is that fn_sig_of_instance looks at the body of the function. That is indeed somewhat sus -- at least all the UB-relevant information should be deducible without the body. Please extend the PR description to explain this; it currently takes a bit of digging to fiure out what problem you're actually solving.

If we end up resolving this by splitting the query, it is very important that the queries have good documentation explaining their relationship. We want to avoid someone changing this code in the future in a way that removes too much information from the "unadjusted" signature.

@eggyal
Copy link
Contributor Author

eggyal commented Jan 30, 2026

I've updated the PR description—hopefully it's now clearer?

Re documentation, the "unadjusted" query (to be renamed fn_abi_of_instance_no_deduced_attrs) is currently documented as follows:

Compute a FnAbi suitable for declaring/defining an fn instance, and for direct calls to an fn. This ABI does not have deduced parameter attributes set, and therefore may produce less optimal codegen than fn_abi_of_instance (which should be preferred instead). However, CTFE may wish to avoid such parameter attribute deduction, as it can otherwise result in loops during typeck.

Happy to clarify it further if required.

@eggyal
Copy link
Contributor Author

eggyal commented Jan 30, 2026

I've updated the documentation to:

Compute a FnAbi suitable for declaring/defining an fn instance, and for direct calls to an fn. Indirectly-passed parameters in the returned ABI might not include all possible codegen optimization attributes (such as ReadOnly or CapturesNone), as deducing these requires inspection of function bodies that can lead to cycles when perfomed during typeck. Post typeck, you should prefer the optimized ABI returned by fn_abi_of_instance.

NB: the ABI returned by this query must not differ from that returned by fn_abi_of_instance in any other way.

@rustbot ready

@eggyal eggyal force-pushed the skip-deducing-parameter-attrs-during-ctfe branch from de839fc to 6a5ec89 Compare January 30, 2026 08:19
@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. and removed S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. labels Jan 30, 2026
@rust-log-analyzer

This comment has been minimized.

`fn_abi_of_instance` can look at function bodies to deduce codegen
optimization attributes (namely `ArgAttribute::ReadOnly` and
`ArgAttribute::CapturesNone`) of indirectly-passed parameters.  This can
lead to cycles when performed during typeck, when such attributes are
irrelevant.

This patch breaks a subquery out from `fn_abi_of_instance`,
`fn_abi_of_instance_no_deduced_attrs`, which returns the ABI before such
parameter attributes are deduced; and that new subquery is used in CTFE
instead.
@eggyal eggyal force-pushed the skip-deducing-parameter-attrs-during-ctfe branch from 6a5ec89 to 132a633 Compare January 30, 2026 08:27
@RalfJung
Copy link
Member

That name and PR description are much better, thank you!

@RalfJung
Copy link
Member

@bors try
@rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors bot pushed a commit that referenced this pull request Jan 30, 2026
…tfe, r=<try>

Do not deduce parameter attributes during CTFE
@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Jan 30, 2026
Comment on lines +1815 to +1818
/// to an `fn`. Indirectly-passed parameters in the returned ABI might not include all possible
/// codegen optimization attributes (such as `ReadOnly` or `CapturesNone`), as deducing these
/// requires inspection of function bodies that can lead to cycles when performed during typeck.
/// Post typeck, you should prefer the optimized ABI returned by `fn_abi_of_instance`.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// to an `fn`. Indirectly-passed parameters in the returned ABI might not include all possible
/// codegen optimization attributes (such as `ReadOnly` or `CapturesNone`), as deducing these
/// requires inspection of function bodies that can lead to cycles when performed during typeck.
/// Post typeck, you should prefer the optimized ABI returned by `fn_abi_of_instance`.
/// to an `fn`. This query does *not* look at the function body to deduce further
/// attributes for function arguments as doing so can lead to cycles during typeck.
/// Post typeck, you should prefer the optimized ABI returned by `fn_abi_of_instance`.

Let's not list what exactly gets put into "deduced attrs" as that will inevitably expand in the future.

Comment on lines +1831 to +1836
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for direct calls*
/// to an `fn`. Indirectly-passed parameters in the returned ABI will include applicable
/// codegen optimization attributes, including `ReadOnly` and `CapturesNone` -- deduction of
/// which requires inspection of function bodies that can lead to cycles when performed during
/// typeck. During typeck, you should therefore use instead the unoptimized ABI returned by
/// `fn_abi_of_instance_no_deduced_attrs`.
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for direct calls*
/// to an `fn`. Indirectly-passed parameters in the returned ABI will include applicable
/// codegen optimization attributes, including `ReadOnly` and `CapturesNone` -- deduction of
/// which requires inspection of function bodies that can lead to cycles when performed during
/// typeck. During typeck, you should therefore use instead the unoptimized ABI returned by
/// `fn_abi_of_instance_no_deduced_attrs`.
/// Compute a `FnAbi` suitable for declaring/defining an `fn` instance, and for direct calls*
/// to an `fn`. This query looks at the function body to deduce further attributes, which
/// can lead to cycles when performed during typeck. During typeck, you should therefore
/// instead use `fn_abi_of_instance_no_deduced_attrs`.

@RalfJung
Copy link
Member

I gave some feedback on the comments. I have not looked at the actual code changes at all.

@rust-bors
Copy link
Contributor

rust-bors bot commented Jan 30, 2026

☀️ Try build successful (CI)
Build commit: cbab83a (cbab83a2924e26be5f80b36c1432a52a618b6c07, parent: e823167aa6f7f03aea8e91208ce9bace8ad9ebf2)

@rust-timer

This comment has been minimized.

@rust-timer
Copy link
Collaborator

Finished benchmarking commit (cbab83a): comparison URL.

Overall result: ❌ regressions - please read the text below

Benchmarking this pull request means it may be perf-sensitive – we'll automatically label it not fit for rolling up. You can override this, but we strongly advise not to, due to possible changes in compiler perf.

Next Steps: If you can justify the regressions found in this try perf run, please do so in sufficient writing along with @rustbot label: +perf-regression-triaged. If not, please fix the regressions and do another perf run. If its results are neutral or positive, the label will be automatically removed.

@bors rollup=never
@rustbot label: -S-waiting-on-perf +perf-regression

Instruction count

Our most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.

mean range count
Regressions ❌
(primary)
0.4% [0.2%, 1.0%] 36
Regressions ❌
(secondary)
0.7% [0.4%, 1.3%] 8
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.4% [0.2%, 1.0%] 36

Max RSS (memory usage)

Results (primary 1.1%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
1.1% [0.7%, 1.5%] 4
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 1.1% [0.7%, 1.5%] 4

Cycles

Results (secondary 2.5%)

A less reliable metric. May be of interest, but not used to determine the overall result above.

mean range count
Regressions ❌
(primary)
- - 0
Regressions ❌
(secondary)
2.5% [2.2%, 2.9%] 7
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

This benchmark run did not return any relevant results for this metric.

Bootstrap: 474.712s -> 472.121s (-0.55%)
Artifact size: 397.79 MiB -> 397.81 MiB (0.00%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Jan 30, 2026
@jdonszelmann
Copy link
Contributor

@rustbot reroll, not quite comfy with reviewing this one. @RalfJung maybe you're the right reviewer?

@rustbot
Copy link
Collaborator

rustbot commented Feb 2, 2026

Error: Parsing assign command in comment failed: ...' reroll' | error: expected end of command at >| ', not quit'...

Please file an issue on GitHub at triagebot if there's a problem with this bot, or reach out on #triagebot on Zulip.

@eggyal
Copy link
Contributor Author

eggyal commented Feb 4, 2026

Re the performance regression, it's worth noting that these cycles currently lead to us rejecting valid programs such as can be seen in the linked issue, the simplest minimisation of which is included as a new UI test with this PR:

fn main() {
let _ = async || {
let COMPLEX_CONSTANT = ();
};
}
const fn do_nothing() {}
const COMPLEX_CONSTANT: () = do_nothing();

Accordingly I think a 0.4% mean instruction count regression in the primary suite might be acceptable in order not to continue rejecting such programs? But of course if there's a more performant solution, that would be preferable.

@rustbot label: +perf-regression-triaged

@rustbot rustbot added the perf-regression-triaged The performance regression has been triaged. label Feb 4, 2026
@theemathas
Copy link
Contributor

Since the previous command failed:

@rustbot reroll

@rustbot rustbot assigned BoxyUwU and unassigned jdonszelmann Feb 4, 2026
@RalfJung
Copy link
Member

RalfJung commented Feb 4, 2026

This is a pretty broad regression, ISTM we should explore other ways of fixing this / ways to improve the performance of this before deciding to go with this approach.

Cc @rust-lang/wg-compiler-performance

@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 4, 2026

r? RalfJung

@rustbot rustbot assigned RalfJung and unassigned BoxyUwU Feb 4, 2026
@rustbot
Copy link
Collaborator

rustbot commented Feb 4, 2026

RalfJung is not on the review rotation at the moment.
They may take a while to respond.

@rust-bors
Copy link
Contributor

rust-bors bot commented Feb 4, 2026

☔ The latest upstream changes (presumably #152089) made this pull request unmergeable. Please resolve the merge conflicts.

@eggyal
Copy link
Contributor Author

eggyal commented Feb 4, 2026

@rustbot author

@rustbot rustbot added S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. and removed S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. labels Feb 4, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

perf-regression Performance regression. perf-regression-triaged The performance regression has been triaged. S-waiting-on-author Status: This is awaiting some action (such as code changes or more information) from the author. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1.93 regression satisfying send obligation

8 participants