-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
Region inference: split results from RegionInferenceContext #151688
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: main
Are you sure you want to change the base?
Region inference: split results from RegionInferenceContext #151688
Conversation
This comment has been minimized.
This comment has been minimized.
6befd69 to
13a57f6
Compare
This comment has been minimized.
This comment has been minimized.
13a57f6 to
00e8121
Compare
00e8121 to
454f98a
Compare
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This ensures all of region inference is immutable, and makes every operation that requires region inference to have been executed to run explicitly require the results.
Since this collapses `RegionInferenceContext`, `::solve()` now consumes the inference context.
on `InferredRegions`.
4c01f95 to
174023c
Compare
|
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. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
| skip( | ||
| infcx, | ||
| body, | ||
| polonius_output, | ||
| location_map, | ||
| placeholder_indices, | ||
| constraint_sccs, | ||
| liveness_constraints | ||
| ), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
skip_all + fields?
| let num_external_vids = | ||
| universal_region_relations.universal_regions.num_global_and_external_regions(); | ||
|
|
||
| let regioncx = { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why a block in the let?
| start_point: Location, | ||
| ) -> Option<Cause> { | ||
| let mut uf = UseFinder { body, regioncx, tcx, region_vid, start_point }; | ||
| let mut uf = UseFinder { body, tcx, region_vid, start_point, scc_values: &scc_values }; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why the explicit & here
| borrow_region: ty::RegionVid, | ||
| universal_regions: &'a UniversalRegions<'tcx>, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
swap these two fields
| ); | ||
|
|
||
| assert!(self.regioncx.universal_regions().is_universal_region(fr)); | ||
| //FIXME! assert!(self.regioncx.universal_regions().is_universal_region(fr)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
?
| let (_, span) = self.regioncx.get_argument_name_and_span_for_region( | ||
| let arg_ty = | ||
| self.universal_regions().unnormalized_input_tys[implicit_inputs + argument_index]; | ||
| let (_, span) = self.universal_regions().get_argument_name_and_span_for_region( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
move self.universal_regions() to a let stmt?
| let (upvar_name, upvar_span) = self.regioncx.get_upvar_name_and_span_for_region( | ||
| let upvar_index = | ||
| self.universal_regions().get_upvar_index_for_region(self.infcx.tcx, fr)?; | ||
| let (upvar_name, upvar_span) = self.universal_regions().get_upvar_name_and_span_for_region( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
here as well
| liveness: &LivenessValues, | ||
| pass_where: PassWhere, | ||
| out: &mut dyn io::Write, | ||
| ) -> io::Result<()> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
pls use a consistent function param ordering between the functions here :<
| let (definitions, _has_placeholders) = region_definitions( | ||
| infcx, | ||
| universal_regions, | ||
| &mut constraints.liveness_constraints.clone(), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is... very odd. You give a mutable reference to a clone?
please move the cloned thing into a let binding first
| outlives_constraints: &'a OutlivesConstraintSet<'tcx>, | ||
| mut w: &mut dyn Write, | ||
| ) -> io::Result<()> { | ||
| dot::render(&RawConstraints { tcx, region_definitions, outlives_constraints }, &mut w) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why reference RawConstraints. That type should be Copy
| dot::render(&SccConstraints { tcx, region_definitions, constraint_sccs, nodes_per_scc }, &mut w) | ||
| } | ||
|
|
||
| struct RawConstraints<'a, 'tcx> { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
make this copy and take it by value
| nodes_per_scc: IndexVec<ConstraintSccIndex, Vec<RegionVid>>, | ||
| region_definitions: &'a IndexVec<RegionVid, RegionDefinition<'tcx>>, | ||
| constraint_sccs: &'a ConstraintSccs, | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
same here
| outlives_requirements.as_mut(), | ||
| &mut errors_buffer, | ||
| type_tests, | ||
| ); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm, I would prefer check_type_tests to stay on the region inference context 🤔
they are a part of region inference to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
or like, the RegionInferenceCtxt should either not exist at all anymore, or still be used for the region computations 🤔 maybe chat about it in sync
| if let NllRegionVariableOrigin::FreeRegion = origin { | ||
| // Add all nodes in the CFG to liveness constraints for free regions | ||
| liveness_constraints.add_all_points(rvid); | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this is a functional change? 🤔
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
scc_values: InferredRegions feels wrong. Maybe just computed_regions: ComputedRegions, regions: InferredRegions
region_definitions why mutable liveness constraints
MirDumper::dump_mir why is scc_values an fn param instead of a field?
| // These clones can more or less be avoided, | ||
| // since they are probably idempotent. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what exactly does this comment mean? It's confusing to me
|
Can you rebase, I will then do a perf run and locally look at the docs after this PR as that should make it clearer how the API has changed |
| placeholder_indices: PlaceholderIndices<'tcx>, | ||
| ) -> (Option<ClosureRegionRequirements<'tcx>>, RegionErrors<'tcx>, InferredRegions<'tcx>) { | ||
| let num_external_vids = | ||
| universal_region_relations.universal_regions.num_global_and_external_regions(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why did u move this one up?
What?
This PR turns
RegionInferenceContextinto a builder that produces the inferred region values,InferredRegions. The resulting struct implements the public API ofRegionInferenceContextand replaces it inconsumers.rs.RegionInferenceContext::solve()now consumes (moves) the inference context. It is completely private to region inference.Why?
RegionInferenceContexthas become a huge dump for various values people want to access.region_inferitself is a very large file that's difficult to find your way around.RegionInferenceContextnow takes almost all of its fields by referenceKnock-on effects
RegionInferenceContextRegionInferenceContextnow almost exclusively contains references to values, as opposed to owning them. This addresses most offn compute_closure_requirements_modulo_opaquesshouldn't clone all its inputs #146079region_infergains two child modules and becomes a lot less of a behemoth.Detailed overview of changes
region_infer::constraint_searchandregion_infer::universal_regions.handle_placeholdersnow consumes less input and does constraint rewriting via mutable referencesconsumers.rsnow has aInferenceResultsinstead of aRegionInferenceContexteval_{equal, outlives}are moved toInferredRegionsConsumerOptionsis now calledInferredRegionscalculate_borrows_out_of_scope_at_locationof course now takesInferredRegionsLivenessValuesfor free regions is now initialised as live at all points along with the constraint rewriting during placeholder handling, as opposed to during construction ofRegionInferenceContextr? @lcnr
Closes #146079.