Skip to content

Conversation

lcnr
Copy link
Contributor

@lcnr lcnr commented Aug 27, 2025

Cleaned up version of #139587, finishing the implementation of rust-lang/types-team#129. While theoretically impacting stable, this should not impact any code in practice. The reasoning for why this is the case is subtle however.

What does it do

We split do_mir_borrowck into borrowck_collect_region_constraints and borrowck_check_region_constraints, where borrowck_collect_region_constraints returns an enormous CollectRegionConstraintsResult struct which contains all the relevant data to actually handle opaque type uses and to check the region constraints later on.

query mir_borrowck now simply calls BorrowCheckRootCtxt::do_mir_borrowck which starts by iterating over all nested bodies of the current function - visiting nested bodies before their parents - and computing their CollectRegionConstraintsResult.

After we've collected all constraints it's time to actually compute the concrete types for the opaques defined by this function. With this PR we now compute the concrete types of opaques for each body before using them to check the non-defining uses of any of them.

After we've computed the concrete types by using all bodies, we use apply_computed_concrete_opaque_types for each body to constrain non-defining uses, before finally finishing with borrowck_check_region_constraints. We always visit nested bodies before their parents when doing this.

ClosureRegionRequirements

As we only call borrowck_collect_region_constraints for nested bodies before type checking the parent, we can't simply use the final ClosureRegionRequirements of the nested body during MIR type check. We instead track that we need to apply these requirements in deferred_closure_requirements.

We now manually apply the final closure requirements to each body after handling opaque types.

This works, except that we may need the region constraints of nested bodies to successfully define an opaque type in the parent. This is handled by using a new fn compute_closure_requirements_modulo_opaques which duplicates region checking - while ignoring any errors - before we've added the constraints from apply_computed_concrete_opaque_types. This is necessary for a lot of async tests, as pretty much the entire function is inside of an async block while the opaque type gets defined in the parent.

As an performance optimization we only use fn compute_closure_requirements_modulo_opaques in case the nested body actually depends on any opaque types. Otherwise we eagerly call borrowck_check_region_constraints and apply the final closure region requirements right away.

Impact on stable code

Handling the opaque type uses in the parent function now only uses the closure requirements modulo opaques, while it previously also considered member constraints from nested bodies. However, for nested bodies, External regions were not considered universal. The only member constraints propagated this way could therefore force some region to be 'static. While theoretically breaking, I don't expect that we'd ever encounter this in practice.

TODO

  • replace FIXME(closure-req-clone) with FIXME(#new-issue) once this is ready to land

r? @BoxyUwU

@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 Aug 27, 2025
@lcnr
Copy link
Contributor Author

lcnr commented Aug 27, 2025

@bors try @rust-timer queue

@rust-timer

This comment has been minimized.

@rust-bors

This comment has been minimized.

rust-bors bot added a commit that referenced this pull request Aug 27, 2025
support non-defining uses in closures
@rustbot rustbot added the S-waiting-on-perf Status: Waiting on a perf run to be completed. label Aug 27, 2025
@rust-log-analyzer

This comment has been minimized.

@lcnr lcnr force-pushed the revealing-use-closures-2 branch 2 times, most recently from f736683 to e9dcabd Compare August 27, 2025 12:01
@lcnr lcnr force-pushed the revealing-use-closures-2 branch 3 times, most recently from eaa44ba to 4d7c068 Compare August 27, 2025 12:16
@lcnr lcnr added WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) and removed T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. labels Aug 27, 2025
@rust-log-analyzer

This comment has been minimized.

@lcnr lcnr force-pushed the revealing-use-closures-2 branch from 4d7c068 to 22d33e3 Compare August 27, 2025 12:58
@rustbot rustbot added the T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. label Aug 27, 2025
@rust-log-analyzer

This comment has been minimized.

@rust-bors
Copy link

rust-bors bot commented Aug 27, 2025

☀️ Try build successful (CI)
Build commit: f55097d (f55097dba6b9481e3e3e65d3d7c2279c1a900519, parent: 4f808ba6bf9f1c8dde30d009e73386d984491587)

@rust-timer

This comment has been minimized.

@lcnr lcnr force-pushed the revealing-use-closures-2 branch from 22d33e3 to 378c073 Compare August 27, 2025 13:58
@lcnr lcnr force-pushed the revealing-use-closures-2 branch from 378c073 to 4406446 Compare August 27, 2025 14:06
@traviscross traviscross added the I-lang-radar Items that are on lang's radar and will need eventual work or consideration. label Aug 27, 2025
@lcnr lcnr changed the title support non-defining uses in closures -Znext-solver support non-defining uses in closures Aug 27, 2025
@lcnr lcnr changed the title -Znext-solver support non-defining uses in closures -Znext-solver: support non-defining uses in closures Aug 27, 2025
@rust-timer
Copy link
Collaborator

Finished benchmarking commit (f55097d): comparison URL.

Overall result: ❌✅ regressions and improvements - 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%, 0.6%] 13
Regressions ❌
(secondary)
0.4% [0.2%, 0.9%] 18
Improvements ✅
(primary)
-0.2% [-0.2%, -0.2%] 2
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) 0.3% [-0.2%, 0.6%] 15

Max RSS (memory usage)

Results (primary -1.0%, secondary -2.3%)

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

mean range count
Regressions ❌
(primary)
1.3% [1.3%, 1.3%] 1
Regressions ❌
(secondary)
- - 0
Improvements ✅
(primary)
-2.1% [-2.5%, -1.6%] 2
Improvements ✅
(secondary)
-2.3% [-2.3%, -2.3%] 1
All ❌✅ (primary) -1.0% [-2.5%, 1.3%] 3

Cycles

Results (secondary 0.8%)

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)
0.8% [0.8%, 0.8%] 1
Improvements ✅
(primary)
- - 0
Improvements ✅
(secondary)
- - 0
All ❌✅ (primary) - - 0

Binary size

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

Bootstrap: 467.222s -> 467.244s (0.00%)
Artifact size: 391.17 MiB -> 391.06 MiB (-0.03%)

@rustbot rustbot added perf-regression Performance regression. and removed S-waiting-on-perf Status: Waiting on a perf run to be completed. labels Aug 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-lang-radar Items that are on lang's radar and will need eventual work or consideration. perf-regression Performance regression. 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. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants