-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Keep resolved defs in path prefixes and emit them in save-analysis #54145
Changes from all commits
fc67d8f
b49da27
c2bb7ca
609d0bd
c480386
cdcbdfd
8ac3272
59cb170
63ac2aa
6dd5bb1
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -143,8 +143,12 @@ pub struct LoweringContext<'a> { | |
} | ||
|
||
pub trait Resolver { | ||
/// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc. | ||
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool); | ||
/// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc. | ||
fn resolve_hir_path( | ||
&mut self, | ||
path: &ast::Path, | ||
is_value: bool, | ||
) -> hir::Path; | ||
|
||
/// Obtain the resolution for a node id | ||
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>; | ||
|
@@ -163,7 +167,6 @@ pub trait Resolver { | |
span: Span, | ||
crate_root: Option<&str>, | ||
components: &[&str], | ||
params: Option<P<hir::GenericArgs>>, | ||
is_value: bool, | ||
) -> hir::Path; | ||
} | ||
|
@@ -1064,6 +1067,9 @@ impl<'a> LoweringContext<'a> { | |
} | ||
|
||
fn lower_attr(&mut self, attr: &Attribute) -> Attribute { | ||
// Note that we explicitly do not walk the path. Since we don't really | ||
// lower attributes (we use the AST version) there is nowhere to keep | ||
// the HirIds. We don't actually need HIR version of attributes anyway. | ||
Attribute { | ||
id: attr.id, | ||
style: attr.style, | ||
|
@@ -1677,6 +1683,7 @@ impl<'a> LoweringContext<'a> { | |
num_lifetimes, | ||
parenthesized_generic_args, | ||
itctx.reborrow(), | ||
None, | ||
) | ||
}) | ||
.collect(), | ||
|
@@ -1720,6 +1727,7 @@ impl<'a> LoweringContext<'a> { | |
0, | ||
ParenthesizedGenericArgs::Warn, | ||
itctx.reborrow(), | ||
None, | ||
)); | ||
let qpath = hir::QPath::TypeRelative(ty, segment); | ||
|
||
|
@@ -1748,6 +1756,7 @@ impl<'a> LoweringContext<'a> { | |
p: &Path, | ||
ident: Option<Ident>, | ||
param_mode: ParamMode, | ||
explicit_owner: Option<NodeId>, | ||
) -> hir::Path { | ||
hir::Path { | ||
def, | ||
|
@@ -1761,6 +1770,7 @@ impl<'a> LoweringContext<'a> { | |
0, | ||
ParenthesizedGenericArgs::Err, | ||
ImplTraitContext::disallowed(), | ||
explicit_owner, | ||
) | ||
}) | ||
.chain(ident.map(|ident| hir::PathSegment::from_ident(ident))) | ||
|
@@ -1771,7 +1781,7 @@ impl<'a> LoweringContext<'a> { | |
|
||
fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path { | ||
let def = self.expect_full_def(id); | ||
self.lower_path_extra(def, p, None, param_mode) | ||
self.lower_path_extra(def, p, None, param_mode, None) | ||
} | ||
|
||
fn lower_path_segment( | ||
|
@@ -1782,6 +1792,7 @@ impl<'a> LoweringContext<'a> { | |
expected_lifetimes: usize, | ||
parenthesized_generic_args: ParenthesizedGenericArgs, | ||
itctx: ImplTraitContext<'_>, | ||
explicit_owner: Option<NodeId>, | ||
) -> hir::PathSegment { | ||
let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args { | ||
let msg = "parenthesized parameters may only be used with a trait"; | ||
|
@@ -1852,8 +1863,17 @@ impl<'a> LoweringContext<'a> { | |
} | ||
} | ||
|
||
let def = self.expect_full_def(segment.id); | ||
let id = if let Some(owner) = explicit_owner { | ||
self.lower_node_id_with_owner(segment.id, owner) | ||
} else { | ||
self.lower_node_id(segment.id) | ||
}; | ||
|
||
hir::PathSegment::new( | ||
segment.ident, | ||
Some(id.node_id), | ||
Some(def), | ||
generic_args, | ||
infer_types, | ||
) | ||
|
@@ -2936,19 +2956,20 @@ impl<'a> LoweringContext<'a> { | |
attrs: &hir::HirVec<Attribute>, | ||
) -> hir::ItemKind { | ||
let path = &tree.prefix; | ||
let segments = prefix | ||
.segments | ||
.iter() | ||
.chain(path.segments.iter()) | ||
.cloned() | ||
.collect(); | ||
|
||
match tree.kind { | ||
UseTreeKind::Simple(rename, id1, id2) => { | ||
*name = tree.ident().name; | ||
|
||
// First apply the prefix to the path | ||
let mut path = Path { | ||
segments: prefix | ||
.segments | ||
.iter() | ||
.chain(path.segments.iter()) | ||
.cloned() | ||
.collect(), | ||
segments, | ||
span: path.span, | ||
}; | ||
|
||
|
@@ -2968,9 +2989,18 @@ impl<'a> LoweringContext<'a> { | |
// for later | ||
let ret_def = defs.next().unwrap_or(Def::Err); | ||
|
||
// Here, we are looping over namespaces, if they exist for the definition | ||
// being imported. We only handle type and value namespaces because we | ||
// won't be dealing with macros in the rest of the compiler. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That's strange, macro imports still need to be checked for stability/deprecation later on. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. But perhaps the comment is incorrect? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
They should but we don't support this yet.
When I was debugging, one of the ids was always equal to the primary id (I think that we don't look at the primary id here at all, just these two). I don't understand the stability/deprecation issue, I just added a comment because this seemed pretty non-obvious and took me a while to work out. |
||
// Essentially a single `use` which imports two names is desugared into | ||
// two imports. | ||
for (def, &new_node_id) in defs.zip([id1, id2].iter()) { | ||
let vis = vis.clone(); | ||
let name = name.clone(); | ||
let mut path = path.clone(); | ||
for seg in &mut path.segments { | ||
seg.id = self.sess.next_node_id(); | ||
} | ||
let span = path.span; | ||
self.resolver.definitions().create_def_with_parent( | ||
parent_def_index, | ||
|
@@ -2983,7 +3013,8 @@ impl<'a> LoweringContext<'a> { | |
|
||
self.with_hir_id_owner(new_node_id, |this| { | ||
let new_id = this.lower_node_id(new_node_id); | ||
let path = this.lower_path_extra(def, &path, None, ParamMode::Explicit); | ||
let path = | ||
this.lower_path_extra(def, &path, None, ParamMode::Explicit, None); | ||
let item = hir::ItemKind::Use(P(path), hir::UseKind::Single); | ||
let vis_kind = match vis.node { | ||
hir::VisibilityKind::Public => hir::VisibilityKind::Public, | ||
|
@@ -2993,7 +3024,6 @@ impl<'a> LoweringContext<'a> { | |
let id = this.next_id(); | ||
hir::VisibilityKind::Restricted { | ||
path: path.clone(), | ||
// We are allocating a new NodeId here | ||
id: id.node_id, | ||
hir_id: id.hir_id, | ||
} | ||
|
@@ -3016,50 +3046,60 @@ impl<'a> LoweringContext<'a> { | |
}); | ||
} | ||
|
||
let path = P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit)); | ||
let path = | ||
P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit, None)); | ||
hir::ItemKind::Use(path, hir::UseKind::Single) | ||
} | ||
UseTreeKind::Glob => { | ||
let path = P(self.lower_path( | ||
id, | ||
&Path { | ||
segments: prefix | ||
.segments | ||
.iter() | ||
.chain(path.segments.iter()) | ||
.cloned() | ||
.collect(), | ||
segments, | ||
span: path.span, | ||
}, | ||
ParamMode::Explicit, | ||
)); | ||
hir::ItemKind::Use(path, hir::UseKind::Glob) | ||
} | ||
UseTreeKind::Nested(ref trees) => { | ||
// Nested imports are desugared into simple imports. | ||
|
||
let prefix = Path { | ||
segments: prefix | ||
.segments | ||
.iter() | ||
.chain(path.segments.iter()) | ||
.cloned() | ||
.collect(), | ||
segments, | ||
span: prefix.span.to(path.span), | ||
}; | ||
|
||
// Add all the nested PathListItems in the HIR | ||
// Add all the nested PathListItems to the HIR. | ||
for &(ref use_tree, id) in trees { | ||
self.allocate_hir_id_counter(id, &use_tree); | ||
|
||
let LoweredNodeId { | ||
node_id: new_id, | ||
hir_id: new_hir_id, | ||
} = self.lower_node_id(id); | ||
|
||
let mut vis = vis.clone(); | ||
let mut name = name.clone(); | ||
let item = | ||
self.lower_use_tree(use_tree, &prefix, new_id, &mut vis, &mut name, &attrs); | ||
let mut prefix = prefix.clone(); | ||
|
||
// Give the segments new ids since they are being cloned. | ||
for seg in &mut prefix.segments { | ||
seg.id = self.sess.next_node_id(); | ||
} | ||
|
||
// Each `use` import is an item and thus are owners of the | ||
// names in the path. Up to this point the nested import is | ||
// the current owner, since we want each desugared import to | ||
// own its own names, we have to adjust the owner before | ||
// lowering the rest of the import. | ||
self.with_hir_id_owner(new_id, |this| { | ||
let item = this.lower_use_tree(use_tree, | ||
&prefix, | ||
new_id, | ||
&mut vis, | ||
&mut name, | ||
attrs); | ||
|
||
let vis_kind = match vis.node { | ||
hir::VisibilityKind::Public => hir::VisibilityKind::Public, | ||
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), | ||
|
@@ -3068,7 +3108,6 @@ impl<'a> LoweringContext<'a> { | |
let id = this.next_id(); | ||
hir::VisibilityKind::Restricted { | ||
path: path.clone(), | ||
// We are allocating a new NodeId here | ||
id: id.node_id, | ||
hir_id: id.hir_id, | ||
} | ||
|
@@ -3081,7 +3120,7 @@ impl<'a> LoweringContext<'a> { | |
hir::Item { | ||
id: new_id, | ||
hir_id: new_hir_id, | ||
name: name, | ||
name, | ||
attrs: attrs.clone(), | ||
node: item, | ||
vis, | ||
|
@@ -3645,6 +3684,7 @@ impl<'a> LoweringContext<'a> { | |
0, | ||
ParenthesizedGenericArgs::Err, | ||
ImplTraitContext::disallowed(), | ||
None, | ||
); | ||
let args = args.iter().map(|x| self.lower_expr(x)).collect(); | ||
hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args) | ||
|
@@ -4498,8 +4538,15 @@ impl<'a> LoweringContext<'a> { | |
} else { | ||
self.lower_node_id(id) | ||
}; | ||
let def = self.expect_full_def(id); | ||
hir::VisibilityKind::Restricted { | ||
path: P(self.lower_path(id, path, ParamMode::Explicit)), | ||
path: P(self.lower_path_extra( | ||
def, | ||
path, | ||
None, | ||
ParamMode::Explicit, | ||
explicit_owner, | ||
)), | ||
id: lowered_id.node_id, | ||
hir_id: lowered_id.hir_id, | ||
} | ||
|
@@ -4806,8 +4853,17 @@ impl<'a> LoweringContext<'a> { | |
params: Option<P<hir::GenericArgs>>, | ||
is_value: bool | ||
) -> hir::Path { | ||
self.resolver | ||
.resolve_str_path(span, self.crate_root, components, params, is_value) | ||
let mut path = self.resolver | ||
.resolve_str_path(span, self.crate_root, components, is_value); | ||
path.segments.last_mut().unwrap().args = params; | ||
|
||
|
||
for seg in path.segments.iter_mut() { | ||
if let Some(id) = seg.id { | ||
seg.id = Some(self.lower_node_id(id).node_id); | ||
} | ||
} | ||
path | ||
} | ||
|
||
fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> hir::Ty { | ||
|
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 and
walk_use
are unused.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.
They are used because it means the visitor walks down into the paths and path segments in a
use
statement.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.
visit_use
is used inwalk_item