resolve: no allocation in resolve_ident_in(_local)_module_*#158604
resolve: no allocation in resolve_ident_in(_local)_module_*#158604LorrensP-2158466 wants to merge 1 commit into
resolve_ident_in(_local)_module_*#158604Conversation
|
@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.
resolve: no allocation in `resolve_ident_in(_local)_module_*`
This comment has been minimized.
This comment has been minimized.
|
Finished benchmarking commit (c6760d2): comparison URL. Overall result: ✅ improvements - no action neededBenchmarking means the PR may be perf-sensitive. It's automatically marked not fit for rolling up. Overriding is possible but disadvised: it risks changing compiler perf. @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 6.2%)A less reliable metric. May be of interest, but not used to determine the overall result above.
Binary sizeThis perf run didn't have relevant results for this metric. Bootstrap: 490.57s -> 486.678s (-0.79%) |
|
Nice perf, however both kinds of asserts fail: let Some(resolution) = self.resolution(module.to_module(), key) else {
assert!(finalize.is_some() == !module.has_unexpanded_invocations());
return Err(ControlFlow::Continue(Determinacy::determined(
!module.has_unexpanded_invocations(),
)));
};and kind 2: if let Some(finalize) = finalize {
assert!(!module.has_unexpanded_invocations());
return self.get_mut().finalize_module_binding(
ident,
orig_ident_span,
binding,
parent_scope,
finalize,
shadowing,
);
}Kind 1 is a bit fragile, if we are not in In the early return, I noticed that this assertion does not trigger, which seems a bit more logical: // finalize implies no unexpanded invocations
assert!(!finalize.is_some() || !module.has_unexpanded_invocations()); |
|
Then let's do #158604 (comment) to preserve the existing behavior.
That's indeed weird and needs to be investigated, but not necessarily as a part of this PR.
Yeah, "implies" is of course the right condition, not "equals". |
Did this plus the other comments. @rustbot ready
So it was pretty easy to track, when we collect invocations in the expansion algorithm, we enter // ...
let vis = self.resolve_visibility(&item.vis);
// ...Which uses match self.r.try_resolve_visibility(&self.parent_scope, vis, true) {pub(crate) fn try_resolve_visibility(
&mut self,
parent_scope: &ParentScope<'ra>,
vis: &ast::Visibility,
finalize: bool,
) -> Result<Visibility, VisResolutionError> {so it seems there are multiple levels of /// Invariant: if `Finalize` is used, expansion and import resolution must be complete.
#[derive(Copy, Clone, Debug)]
struct Finalize { ... }Should i open an issue? |
|
The current version doesn't mirror |
The visibility resolution is sort of hacky, it has to produce some definite result very early when nothing is ready, and cannot delay resolution. But due to restrictions on visibility paths it probably works correctly. |
a1f67c3 to
ccd5b9f
Compare
Indeed, i was a bit fast there, oops. @rustbot ready
Alright! |
|
✌️ @LorrensP-2158466, you can now approve this pull request! If @petrochenkov told you to " |
|
Reminder, once the PR becomes ready for a review, use |
…esolve_ident_in_*`
ccd5b9f to
d737d29
Compare
|
@bors r=petrochenkov |
View all comments
Somewhat of a follow up of #158207 and #158035. Remove the
or_defaultcall ofNameResolutionswhich does an arena allocation. Prep work for parallel import resolution.moduleandbindingkeyinstead of theNameResolution. This should have no impact asNameResolutionsare found by that pair.Option<NameResolution>the logic changed a bit to work withNone. Did this by following the logic of the functions to see what would happen with a completely empty resolution (or_default).r? @petrochenkov