Skip to content

Commit a7610b0

Browse files
committed
Auto merge of #54145 - nrc:save-path-segments, r=<try>
Keep resolved defs in path prefixes and emit them in save-analysis Closes rust-dev-tools/rls-analysis#109 r? @eddyb or @petrochenkov
2 parents f7eb7fb + 81ee74b commit a7610b0

31 files changed

+619
-713
lines changed

src/librustc/hir/intravisit.rs

+15-2
Original file line numberDiff line numberDiff line change
@@ -298,6 +298,9 @@ pub trait Visitor<'v> : Sized {
298298
fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: BodyId, s: Span, id: NodeId) {
299299
walk_fn(self, fk, fd, b, s, id)
300300
}
301+
fn visit_use(&mut self, path: &'v Path, id: NodeId, hir_id: HirId) {
302+
walk_use(self, path, id, hir_id)
303+
}
301304
fn visit_trait_item(&mut self, ti: &'v TraitItem) {
302305
walk_trait_item(self, ti)
303306
}
@@ -469,8 +472,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
469472
}
470473
}
471474
ItemKind::Use(ref path, _) => {
472-
visitor.visit_id(item.id);
473-
visitor.visit_path(path, item.hir_id);
475+
visitor.visit_use(path, item.id, item.hir_id);
474476
}
475477
ItemKind::Static(ref typ, _, body) |
476478
ItemKind::Const(ref typ, body) => {
@@ -552,6 +554,14 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
552554
walk_list!(visitor, visit_attribute, &item.attrs);
553555
}
554556

557+
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V,
558+
path: &'v Path,
559+
item_id: NodeId,
560+
hir_id: HirId) {
561+
visitor.visit_id(item_id);
562+
visitor.visit_path(path, hir_id);
563+
}
564+
555565
pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
556566
enum_definition: &'v EnumDef,
557567
generics: &'v Generics,
@@ -650,6 +660,9 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
650660
path_span: Span,
651661
segment: &'v PathSegment) {
652662
visitor.visit_ident(segment.ident);
663+
if let Some(id) = segment.id {
664+
visitor.visit_id(id);
665+
}
653666
if let Some(ref args) = segment.args {
654667
visitor.visit_generic_args(path_span, args);
655668
}

src/librustc/hir/lowering.rs

+89-33
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,13 @@ pub struct LoweringContext<'a> {
144144
}
145145

146146
pub trait Resolver {
147-
/// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
148-
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);
147+
/// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
148+
fn resolve_hir_path(
149+
&mut self,
150+
path: &ast::Path,
151+
args: Option<P<hir::GenericArgs>>,
152+
is_value: bool,
153+
) -> hir::Path;
149154

150155
/// Obtain the resolution for a node id
151156
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
@@ -164,7 +169,7 @@ pub trait Resolver {
164169
span: Span,
165170
crate_root: Option<&str>,
166171
components: &[&str],
167-
params: Option<P<hir::GenericArgs>>,
172+
args: Option<P<hir::GenericArgs>>,
168173
is_value: bool,
169174
) -> hir::Path;
170175
}
@@ -1060,6 +1065,9 @@ impl<'a> LoweringContext<'a> {
10601065
}
10611066

10621067
fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
1068+
// Note that we explicitly do not walk the path. Since we don't really
1069+
// lower attributes (we use the AST version) there is nowhere to keep
1070+
// the HirIds. We don't actually need HIR version of attributes anyway.
10631071
Attribute {
10641072
id: attr.id,
10651073
style: attr.style,
@@ -1673,6 +1681,7 @@ impl<'a> LoweringContext<'a> {
16731681
num_lifetimes,
16741682
parenthesized_generic_args,
16751683
itctx.reborrow(),
1684+
None,
16761685
)
16771686
})
16781687
.collect(),
@@ -1716,6 +1725,7 @@ impl<'a> LoweringContext<'a> {
17161725
0,
17171726
ParenthesizedGenericArgs::Warn,
17181727
itctx.reborrow(),
1728+
None,
17191729
));
17201730
let qpath = hir::QPath::TypeRelative(ty, segment);
17211731

@@ -1744,6 +1754,7 @@ impl<'a> LoweringContext<'a> {
17441754
p: &Path,
17451755
ident: Option<Ident>,
17461756
param_mode: ParamMode,
1757+
explicit_owner: Option<NodeId>,
17471758
) -> hir::Path {
17481759
hir::Path {
17491760
def,
@@ -1757,6 +1768,7 @@ impl<'a> LoweringContext<'a> {
17571768
0,
17581769
ParenthesizedGenericArgs::Err,
17591770
ImplTraitContext::disallowed(),
1771+
explicit_owner,
17601772
)
17611773
})
17621774
.chain(ident.map(|ident| hir::PathSegment::from_ident(ident)))
@@ -1767,7 +1779,7 @@ impl<'a> LoweringContext<'a> {
17671779

17681780
fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
17691781
let def = self.expect_full_def(id);
1770-
self.lower_path_extra(def, p, None, param_mode)
1782+
self.lower_path_extra(def, p, None, param_mode, None)
17711783
}
17721784

17731785
fn lower_path_segment(
@@ -1778,6 +1790,7 @@ impl<'a> LoweringContext<'a> {
17781790
expected_lifetimes: usize,
17791791
parenthesized_generic_args: ParenthesizedGenericArgs,
17801792
itctx: ImplTraitContext<'_>,
1793+
explicit_owner: Option<NodeId>,
17811794
) -> hir::PathSegment {
17821795
let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args {
17831796
let msg = "parenthesized parameters may only be used with a trait";
@@ -1848,8 +1861,17 @@ impl<'a> LoweringContext<'a> {
18481861
}
18491862
}
18501863

1864+
let def = self.expect_full_def(segment.id);
1865+
let id = if let Some(owner) = explicit_owner {
1866+
self.lower_node_id_with_owner(segment.id, owner)
1867+
} else {
1868+
self.lower_node_id(segment.id)
1869+
};
1870+
18511871
hir::PathSegment::new(
18521872
segment.ident,
1873+
Some(id.node_id),
1874+
Some(def),
18531875
generic_args,
18541876
infer_types,
18551877
)
@@ -2913,19 +2935,20 @@ impl<'a> LoweringContext<'a> {
29132935
attrs: &hir::HirVec<Attribute>,
29142936
) -> hir::ItemKind {
29152937
let path = &tree.prefix;
2938+
let segments = prefix
2939+
.segments
2940+
.iter()
2941+
.chain(path.segments.iter())
2942+
.cloned()
2943+
.collect();
29162944

29172945
match tree.kind {
29182946
UseTreeKind::Simple(rename, id1, id2) => {
29192947
*name = tree.ident().name;
29202948

29212949
// First apply the prefix to the path
29222950
let mut path = Path {
2923-
segments: prefix
2924-
.segments
2925-
.iter()
2926-
.chain(path.segments.iter())
2927-
.cloned()
2928-
.collect(),
2951+
segments,
29292952
span: path.span,
29302953
};
29312954

@@ -2945,9 +2968,18 @@ impl<'a> LoweringContext<'a> {
29452968
// for later
29462969
let ret_def = defs.next().unwrap_or(Def::Err);
29472970

2971+
// Here, we are looping over namespaces, if they exist for the definition
2972+
// being imported. We only handle type and value namespaces because we
2973+
// won't be dealing with macros in the rest of the compiler.
2974+
// Essentially a single `use` which imports two names is desugared into
2975+
// two imports.
29482976
for (def, &new_node_id) in defs.zip([id1, id2].iter()) {
29492977
let vis = vis.clone();
29502978
let name = name.clone();
2979+
let mut path = path.clone();
2980+
for seg in &mut path.segments {
2981+
seg.id = self.sess.next_node_id();
2982+
}
29512983
let span = path.span;
29522984
self.resolver.definitions().create_def_with_parent(
29532985
parent_def_index,
@@ -2960,7 +2992,8 @@ impl<'a> LoweringContext<'a> {
29602992

29612993
self.with_hir_id_owner(new_node_id, |this| {
29622994
let new_id = this.lower_node_id(new_node_id);
2963-
let path = this.lower_path_extra(def, &path, None, ParamMode::Explicit);
2995+
let path =
2996+
this.lower_path_extra(def, &path, None, ParamMode::Explicit, None);
29642997
let item = hir::ItemKind::Use(P(path), hir::UseKind::Single);
29652998
let vis_kind = match vis.node {
29662999
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
@@ -2970,7 +3003,6 @@ impl<'a> LoweringContext<'a> {
29703003
let id = this.next_id();
29713004
hir::VisibilityKind::Restricted {
29723005
path: path.clone(),
2973-
// We are allocating a new NodeId here
29743006
id: id.node_id,
29753007
hir_id: id.hir_id,
29763008
}
@@ -2993,50 +3025,60 @@ impl<'a> LoweringContext<'a> {
29933025
});
29943026
}
29953027

2996-
let path = P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit));
3028+
let path =
3029+
P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit, None));
29973030
hir::ItemKind::Use(path, hir::UseKind::Single)
29983031
}
29993032
UseTreeKind::Glob => {
30003033
let path = P(self.lower_path(
30013034
id,
30023035
&Path {
3003-
segments: prefix
3004-
.segments
3005-
.iter()
3006-
.chain(path.segments.iter())
3007-
.cloned()
3008-
.collect(),
3036+
segments,
30093037
span: path.span,
30103038
},
30113039
ParamMode::Explicit,
30123040
));
30133041
hir::ItemKind::Use(path, hir::UseKind::Glob)
30143042
}
30153043
UseTreeKind::Nested(ref trees) => {
3044+
// Nested imports are desugared into simple imports.
3045+
30163046
let prefix = Path {
3017-
segments: prefix
3018-
.segments
3019-
.iter()
3020-
.chain(path.segments.iter())
3021-
.cloned()
3022-
.collect(),
3047+
segments,
30233048
span: prefix.span.to(path.span),
30243049
};
30253050

3026-
// Add all the nested PathListItems in the HIR
3051+
// Add all the nested PathListItems to the HIR.
30273052
for &(ref use_tree, id) in trees {
30283053
self.allocate_hir_id_counter(id, &use_tree);
3054+
30293055
let LoweredNodeId {
30303056
node_id: new_id,
30313057
hir_id: new_hir_id,
30323058
} = self.lower_node_id(id);
30333059

30343060
let mut vis = vis.clone();
30353061
let mut name = name.clone();
3036-
let item =
3037-
self.lower_use_tree(use_tree, &prefix, new_id, &mut vis, &mut name, &attrs);
3062+
let mut prefix = prefix.clone();
3063+
3064+
// Give the segments new ids since they are being cloned.
3065+
for seg in &mut prefix.segments {
3066+
seg.id = self.sess.next_node_id();
3067+
}
30383068

3069+
// Each `use` import is an item and thus are owners of the
3070+
// names in the path. Up to this point the nested import is
3071+
// the current owner, since we want each desugared import to
3072+
// own its own names, we have to adjust the owner before
3073+
// lowering the rest of the import.
30393074
self.with_hir_id_owner(new_id, |this| {
3075+
let item = this.lower_use_tree(use_tree,
3076+
&prefix,
3077+
new_id,
3078+
&mut vis,
3079+
&mut name,
3080+
attrs);
3081+
30403082
let vis_kind = match vis.node {
30413083
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
30423084
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
@@ -3045,7 +3087,6 @@ impl<'a> LoweringContext<'a> {
30453087
let id = this.next_id();
30463088
hir::VisibilityKind::Restricted {
30473089
path: path.clone(),
3048-
// We are allocating a new NodeId here
30493090
id: id.node_id,
30503091
hir_id: id.hir_id,
30513092
}
@@ -3058,7 +3099,7 @@ impl<'a> LoweringContext<'a> {
30583099
hir::Item {
30593100
id: new_id,
30603101
hir_id: new_hir_id,
3061-
name: name,
3102+
name,
30623103
attrs: attrs.clone(),
30633104
node: item,
30643105
vis,
@@ -3622,6 +3663,7 @@ impl<'a> LoweringContext<'a> {
36223663
0,
36233664
ParenthesizedGenericArgs::Err,
36243665
ImplTraitContext::disallowed(),
3666+
None,
36253667
);
36263668
let args = args.iter().map(|x| self.lower_expr(x)).collect();
36273669
hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args)
@@ -4475,8 +4517,15 @@ impl<'a> LoweringContext<'a> {
44754517
} else {
44764518
self.lower_node_id(id)
44774519
};
4520+
let def = self.expect_full_def(id);
44784521
hir::VisibilityKind::Restricted {
4479-
path: P(self.lower_path(id, path, ParamMode::Explicit)),
4522+
path: P(self.lower_path_extra(
4523+
def,
4524+
path,
4525+
None,
4526+
ParamMode::Explicit,
4527+
explicit_owner,
4528+
)),
44804529
id: lowered_id.node_id,
44814530
hir_id: lowered_id.hir_id,
44824531
}
@@ -4783,8 +4832,15 @@ impl<'a> LoweringContext<'a> {
47834832
params: Option<P<hir::GenericArgs>>,
47844833
is_value: bool
47854834
) -> hir::Path {
4786-
self.resolver
4787-
.resolve_str_path(span, self.crate_root, components, params, is_value)
4835+
let mut path = self.resolver
4836+
.resolve_str_path(span, self.crate_root, components, params, is_value);
4837+
4838+
for seg in path.segments.iter_mut() {
4839+
if let Some(id) = seg.id {
4840+
seg.id = Some(self.lower_node_id(id).node_id);
4841+
}
4842+
}
4843+
path
47884844
}
47894845

47904846
fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> hir::Ty {

0 commit comments

Comments
 (0)