-
Notifications
You must be signed in to change notification settings - Fork 13.6k
[WIP] Resolver: introduce SmartResolver
for speculative and finalize resolutions.
#144912
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?
[WIP] Resolver: introduce SmartResolver
for speculative and finalize resolutions.
#144912
Conversation
4d8cc9f
to
3ab8e2f
Compare
None, | ||
None, | ||
) else { | ||
let Ok((Some(ext), _)) = SmartResolver::Finalize(this) |
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.
There are a lot of constructions like this, should we introduce some helpers in Resolver?:
fn early(&self) -> SmartResolver;
fn late(&mut self) -> SmartResolver;
impl<'r, 'ra, 'tcx> SmartResolver<'r, 'ra, 'tcx> { | ||
pub(crate) fn lint_if_path_starts_with_module( | ||
mut self, | ||
finalize: Option<Finalize>, | ||
path: &[Segment], | ||
second_binding: Option<NameBinding<'_>>, | ||
) { | ||
let Some(Finalize { node_id, root_span, .. }) = finalize else { | ||
return; | ||
}; |
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.
Should this take an Option<Finalize>
? Maybe we should handle this at the call site so this function can stay inside of the Resolver
.
pub(crate) trait ScopeVisitor<'ra, 'tcx> | ||
where | ||
Self: AsRef<Resolver<'ra, 'tcx>> + Sized, | ||
{ | ||
/// A generic scope visitor. | ||
/// Visits scopes in order to resolve some identifier in them or perform other actions. | ||
/// If the callback returns `Some` result, we stop visiting scopes and return it. | ||
pub(crate) fn visit_scopes<T>( | ||
&mut self, | ||
fn visit_scopes<T>( | ||
mut self, |
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.
In the first commit I have this function duplicated for SmartResolver
. In the second commit I have combined them in a trait, is this allowed?
fn record_segment_res<'r, 'ra, 'tcx>( | ||
mut this: SmartResolver<'r, 'ra, 'tcx>, | ||
finalize: Option<Finalize>, | ||
res: Res, | ||
id: Option<NodeId>, | ||
) { | ||
if finalize.is_some() | ||
&& let Some(id) = id | ||
&& !this.partial_res_map.contains_key(&id) | ||
{ | ||
assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id"); | ||
this.res_mut().record_partial_res(id, PartialRes::new(res)); | ||
} | ||
} | ||
|
||
for (segment_idx, &Segment { ident, id, .. }) in path.iter().enumerate() { | ||
debug!("resolve_path ident {} {:?} {:?}", segment_idx, ident, id); | ||
let record_segment_res = |this: &mut Self, res| { | ||
if finalize.is_some() | ||
&& let Some(id) = id | ||
&& !this.partial_res_map.contains_key(&id) | ||
{ | ||
assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id"); | ||
this.record_partial_res(id, PartialRes::new(res)); | ||
} | ||
}; |
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 was the only way i could circumvent borrow check errors. If this change is unwanted I can find out if the closure is still possible.
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.
Every use of the SmartResolver
in this file is SmartResolver::Finalize
, is this correct?
enum SmartResolver<'r, 'ra, 'tcx> { | ||
Speculative(&'r Resolver<'ra, 'tcx>), | ||
Finalize(&'r mut Resolver<'ra, '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.
Names are still debatable.
if trace { | ||
let kind = kind.expect("macro kind must be specified if tracing is enabled"); | ||
self.res_mut().multi_segment_macro_resolutions.push(( |
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.
Relevant part of the trace
and force
question in #gsoc > Project: Parallel Macro Expansion @ 💬.
Edit: CI also fails here
if trace { | ||
let kind = kind.expect("macro kind must be specified if tracing is enabled"); | ||
self.res_mut().single_segment_macro_resolutions.push(( |
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.
Relevant part of the trace
and force
question in #gsoc > Project: Parallel Macro Expansion @ 💬.
Edit: CI also fails here
The job Click to see the possible cause of the failure (guessed by this bot)
|
Introduce a
SmartResolver
, which knows when it's in speculative or finalize mode and if it's in finalize, it can give out a mutable reference to the actual Resolver:I have moved functions of the resolver to the smarter one, where I thought this was necessary, so if something looks out of place, it probably is.
I'll update this description when the pr is almost done, for now I'll post comments on parts of code I think deserve more attention, it's a pretty big diff...
r? petrochenkov