-
Notifications
You must be signed in to change notification settings - Fork 13.7k
-Znext-solver
: support non-defining uses in closures
#145925
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
@bors try @rust-timer queue |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
support non-defining uses in closures
This comment has been minimized.
This comment has been minimized.
f736683
to
e9dcabd
Compare
eaa44ba
to
4d7c068
Compare
This comment has been minimized.
This comment has been minimized.
4d7c068
to
22d33e3
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
22d33e3
to
378c073
Compare
378c073
to
4406446
Compare
-Znext-solver
support non-defining uses in closures
-Znext-solver
support non-defining uses in closures-Znext-solver
: support non-defining uses in closures
Finished benchmarking commit (f55097d): comparison URL. Overall result: ❌✅ regressions and improvements - please read the text belowBenchmarking 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 @bors rollup=never Instruction countOur most reliable metric. Used to determine the overall result above. However, even this metric can be noisy.
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.
CyclesResults (secondary 0.8%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis benchmark run did not return any relevant results for this metric. Bootstrap: 467.222s -> 467.244s (0.00%) |
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
intoborrowck_collect_region_constraints
andborrowck_check_region_constraints
, whereborrowck_collect_region_constraints
returns an enormousCollectRegionConstraintsResult
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 callsBorrowCheckRootCtxt::do_mir_borrowck
which starts by iterating over all nested bodies of the current function - visiting nested bodies before their parents - and computing theirCollectRegionConstraintsResult
.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 withborrowck_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 finalClosureRegionRequirements
of the nested body during MIR type check. We instead track that we need to apply these requirements indeferred_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 fromapply_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 callborrowck_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
FIXME(closure-req-clone)
withFIXME(#new-issue)
once this is ready to landr? @BoxyUwU