Skip to content

Commit 7b0735a

Browse files
committed
Auto merge of #54145 - nrc:save-path-segments, r=petrochenkov
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 4bd4e41 + 6dd5bb1 commit 7b0735a

40 files changed

+725
-833
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
}
@@ -471,8 +474,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
471474
}
472475
}
473476
ItemKind::Use(ref path, _) => {
474-
visitor.visit_id(item.id);
475-
visitor.visit_path(path, item.hir_id);
477+
visitor.visit_use(path, item.id, item.hir_id);
476478
}
477479
ItemKind::Static(ref typ, _, body) |
478480
ItemKind::Const(ref typ, body) => {
@@ -554,6 +556,14 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
554556
walk_list!(visitor, visit_attribute, &item.attrs);
555557
}
556558

559+
pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V,
560+
path: &'v Path,
561+
item_id: NodeId,
562+
hir_id: HirId) {
563+
visitor.visit_id(item_id);
564+
visitor.visit_path(path, hir_id);
565+
}
566+
557567
pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V,
558568
enum_definition: &'v EnumDef,
559569
generics: &'v Generics,
@@ -652,6 +662,9 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
652662
path_span: Span,
653663
segment: &'v PathSegment) {
654664
visitor.visit_ident(segment.ident);
665+
if let Some(id) = segment.id {
666+
visitor.visit_id(id);
667+
}
655668
if let Some(ref args) = segment.args {
656669
visitor.visit_generic_args(path_span, args);
657670
}

src/librustc/hir/lowering.rs

+89-33
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,12 @@ pub struct LoweringContext<'a> {
143143
}
144144

145145
pub trait Resolver {
146-
/// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc.
147-
fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool);
146+
/// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc.
147+
fn resolve_hir_path(
148+
&mut self,
149+
path: &ast::Path,
150+
is_value: bool,
151+
) -> hir::Path;
148152

149153
/// Obtain the resolution for a node id
150154
fn get_resolution(&mut self, id: NodeId) -> Option<PathResolution>;
@@ -163,7 +167,6 @@ pub trait Resolver {
163167
span: Span,
164168
crate_root: Option<&str>,
165169
components: &[&str],
166-
params: Option<P<hir::GenericArgs>>,
167170
is_value: bool,
168171
) -> hir::Path;
169172
}
@@ -1064,6 +1067,9 @@ impl<'a> LoweringContext<'a> {
10641067
}
10651068

10661069
fn lower_attr(&mut self, attr: &Attribute) -> Attribute {
1070+
// Note that we explicitly do not walk the path. Since we don't really
1071+
// lower attributes (we use the AST version) there is nowhere to keep
1072+
// the HirIds. We don't actually need HIR version of attributes anyway.
10671073
Attribute {
10681074
id: attr.id,
10691075
style: attr.style,
@@ -1677,6 +1683,7 @@ impl<'a> LoweringContext<'a> {
16771683
num_lifetimes,
16781684
parenthesized_generic_args,
16791685
itctx.reborrow(),
1686+
None,
16801687
)
16811688
})
16821689
.collect(),
@@ -1720,6 +1727,7 @@ impl<'a> LoweringContext<'a> {
17201727
0,
17211728
ParenthesizedGenericArgs::Warn,
17221729
itctx.reborrow(),
1730+
None,
17231731
));
17241732
let qpath = hir::QPath::TypeRelative(ty, segment);
17251733

@@ -1748,6 +1756,7 @@ impl<'a> LoweringContext<'a> {
17481756
p: &Path,
17491757
ident: Option<Ident>,
17501758
param_mode: ParamMode,
1759+
explicit_owner: Option<NodeId>,
17511760
) -> hir::Path {
17521761
hir::Path {
17531762
def,
@@ -1761,6 +1770,7 @@ impl<'a> LoweringContext<'a> {
17611770
0,
17621771
ParenthesizedGenericArgs::Err,
17631772
ImplTraitContext::disallowed(),
1773+
explicit_owner,
17641774
)
17651775
})
17661776
.chain(ident.map(|ident| hir::PathSegment::from_ident(ident)))
@@ -1771,7 +1781,7 @@ impl<'a> LoweringContext<'a> {
17711781

17721782
fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path {
17731783
let def = self.expect_full_def(id);
1774-
self.lower_path_extra(def, p, None, param_mode)
1784+
self.lower_path_extra(def, p, None, param_mode, None)
17751785
}
17761786

17771787
fn lower_path_segment(
@@ -1782,6 +1792,7 @@ impl<'a> LoweringContext<'a> {
17821792
expected_lifetimes: usize,
17831793
parenthesized_generic_args: ParenthesizedGenericArgs,
17841794
itctx: ImplTraitContext<'_>,
1795+
explicit_owner: Option<NodeId>,
17851796
) -> hir::PathSegment {
17861797
let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args {
17871798
let msg = "parenthesized parameters may only be used with a trait";
@@ -1852,8 +1863,17 @@ impl<'a> LoweringContext<'a> {
18521863
}
18531864
}
18541865

1866+
let def = self.expect_full_def(segment.id);
1867+
let id = if let Some(owner) = explicit_owner {
1868+
self.lower_node_id_with_owner(segment.id, owner)
1869+
} else {
1870+
self.lower_node_id(segment.id)
1871+
};
1872+
18551873
hir::PathSegment::new(
18561874
segment.ident,
1875+
Some(id.node_id),
1876+
Some(def),
18571877
generic_args,
18581878
infer_types,
18591879
)
@@ -2936,19 +2956,20 @@ impl<'a> LoweringContext<'a> {
29362956
attrs: &hir::HirVec<Attribute>,
29372957
) -> hir::ItemKind {
29382958
let path = &tree.prefix;
2959+
let segments = prefix
2960+
.segments
2961+
.iter()
2962+
.chain(path.segments.iter())
2963+
.cloned()
2964+
.collect();
29392965

29402966
match tree.kind {
29412967
UseTreeKind::Simple(rename, id1, id2) => {
29422968
*name = tree.ident().name;
29432969

29442970
// First apply the prefix to the path
29452971
let mut path = Path {
2946-
segments: prefix
2947-
.segments
2948-
.iter()
2949-
.chain(path.segments.iter())
2950-
.cloned()
2951-
.collect(),
2972+
segments,
29522973
span: path.span,
29532974
};
29542975

@@ -2968,9 +2989,18 @@ impl<'a> LoweringContext<'a> {
29682989
// for later
29692990
let ret_def = defs.next().unwrap_or(Def::Err);
29702991

2992+
// Here, we are looping over namespaces, if they exist for the definition
2993+
// being imported. We only handle type and value namespaces because we
2994+
// won't be dealing with macros in the rest of the compiler.
2995+
// Essentially a single `use` which imports two names is desugared into
2996+
// two imports.
29712997
for (def, &new_node_id) in defs.zip([id1, id2].iter()) {
29722998
let vis = vis.clone();
29732999
let name = name.clone();
3000+
let mut path = path.clone();
3001+
for seg in &mut path.segments {
3002+
seg.id = self.sess.next_node_id();
3003+
}
29743004
let span = path.span;
29753005
self.resolver.definitions().create_def_with_parent(
29763006
parent_def_index,
@@ -2983,7 +3013,8 @@ impl<'a> LoweringContext<'a> {
29833013

29843014
self.with_hir_id_owner(new_node_id, |this| {
29853015
let new_id = this.lower_node_id(new_node_id);
2986-
let path = this.lower_path_extra(def, &path, None, ParamMode::Explicit);
3016+
let path =
3017+
this.lower_path_extra(def, &path, None, ParamMode::Explicit, None);
29873018
let item = hir::ItemKind::Use(P(path), hir::UseKind::Single);
29883019
let vis_kind = match vis.node {
29893020
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
@@ -2993,7 +3024,6 @@ impl<'a> LoweringContext<'a> {
29933024
let id = this.next_id();
29943025
hir::VisibilityKind::Restricted {
29953026
path: path.clone(),
2996-
// We are allocating a new NodeId here
29973027
id: id.node_id,
29983028
hir_id: id.hir_id,
29993029
}
@@ -3016,50 +3046,60 @@ impl<'a> LoweringContext<'a> {
30163046
});
30173047
}
30183048

3019-
let path = P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit));
3049+
let path =
3050+
P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit, None));
30203051
hir::ItemKind::Use(path, hir::UseKind::Single)
30213052
}
30223053
UseTreeKind::Glob => {
30233054
let path = P(self.lower_path(
30243055
id,
30253056
&Path {
3026-
segments: prefix
3027-
.segments
3028-
.iter()
3029-
.chain(path.segments.iter())
3030-
.cloned()
3031-
.collect(),
3057+
segments,
30323058
span: path.span,
30333059
},
30343060
ParamMode::Explicit,
30353061
));
30363062
hir::ItemKind::Use(path, hir::UseKind::Glob)
30373063
}
30383064
UseTreeKind::Nested(ref trees) => {
3065+
// Nested imports are desugared into simple imports.
3066+
30393067
let prefix = Path {
3040-
segments: prefix
3041-
.segments
3042-
.iter()
3043-
.chain(path.segments.iter())
3044-
.cloned()
3045-
.collect(),
3068+
segments,
30463069
span: prefix.span.to(path.span),
30473070
};
30483071

3049-
// Add all the nested PathListItems in the HIR
3072+
// Add all the nested PathListItems to the HIR.
30503073
for &(ref use_tree, id) in trees {
30513074
self.allocate_hir_id_counter(id, &use_tree);
3075+
30523076
let LoweredNodeId {
30533077
node_id: new_id,
30543078
hir_id: new_hir_id,
30553079
} = self.lower_node_id(id);
30563080

30573081
let mut vis = vis.clone();
30583082
let mut name = name.clone();
3059-
let item =
3060-
self.lower_use_tree(use_tree, &prefix, new_id, &mut vis, &mut name, &attrs);
3083+
let mut prefix = prefix.clone();
30613084

3085+
// Give the segments new ids since they are being cloned.
3086+
for seg in &mut prefix.segments {
3087+
seg.id = self.sess.next_node_id();
3088+
}
3089+
3090+
// Each `use` import is an item and thus are owners of the
3091+
// names in the path. Up to this point the nested import is
3092+
// the current owner, since we want each desugared import to
3093+
// own its own names, we have to adjust the owner before
3094+
// lowering the rest of the import.
30623095
self.with_hir_id_owner(new_id, |this| {
3096+
let item = this.lower_use_tree(use_tree,
3097+
&prefix,
3098+
new_id,
3099+
&mut vis,
3100+
&mut name,
3101+
attrs);
3102+
30633103
let vis_kind = match vis.node {
30643104
hir::VisibilityKind::Public => hir::VisibilityKind::Public,
30653105
hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar),
@@ -3068,7 +3108,6 @@ impl<'a> LoweringContext<'a> {
30683108
let id = this.next_id();
30693109
hir::VisibilityKind::Restricted {
30703110
path: path.clone(),
3071-
// We are allocating a new NodeId here
30723111
id: id.node_id,
30733112
hir_id: id.hir_id,
30743113
}
@@ -3081,7 +3120,7 @@ impl<'a> LoweringContext<'a> {
30813120
hir::Item {
30823121
id: new_id,
30833122
hir_id: new_hir_id,
3084-
name: name,
3123+
name,
30853124
attrs: attrs.clone(),
30863125
node: item,
30873126
vis,
@@ -3645,6 +3684,7 @@ impl<'a> LoweringContext<'a> {
36453684
0,
36463685
ParenthesizedGenericArgs::Err,
36473686
ImplTraitContext::disallowed(),
3687+
None,
36483688
);
36493689
let args = args.iter().map(|x| self.lower_expr(x)).collect();
36503690
hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args)
@@ -4498,8 +4538,15 @@ impl<'a> LoweringContext<'a> {
44984538
} else {
44994539
self.lower_node_id(id)
45004540
};
4541+
let def = self.expect_full_def(id);
45014542
hir::VisibilityKind::Restricted {
4502-
path: P(self.lower_path(id, path, ParamMode::Explicit)),
4543+
path: P(self.lower_path_extra(
4544+
def,
4545+
path,
4546+
None,
4547+
ParamMode::Explicit,
4548+
explicit_owner,
4549+
)),
45034550
id: lowered_id.node_id,
45044551
hir_id: lowered_id.hir_id,
45054552
}
@@ -4806,8 +4853,17 @@ impl<'a> LoweringContext<'a> {
48064853
params: Option<P<hir::GenericArgs>>,
48074854
is_value: bool
48084855
) -> hir::Path {
4809-
self.resolver
4810-
.resolve_str_path(span, self.crate_root, components, params, is_value)
4856+
let mut path = self.resolver
4857+
.resolve_str_path(span, self.crate_root, components, is_value);
4858+
path.segments.last_mut().unwrap().args = params;
4859+
4860+
4861+
for seg in path.segments.iter_mut() {
4862+
if let Some(id) = seg.id {
4863+
seg.id = Some(self.lower_node_id(id).node_id);
4864+
}
4865+
}
4866+
path
48114867
}
48124868

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

src/librustc/hir/map/collector.rs

+17-5
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,22 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
210210
None => format!("{:?}", node)
211211
};
212212

213-
if hir_id == ::hir::DUMMY_HIR_ID {
214-
debug!("Maybe you forgot to lower the node id {:?}?", id);
215-
}
213+
let forgot_str = if hir_id == ::hir::DUMMY_HIR_ID {
214+
format!("\nMaybe you forgot to lower the node id {:?}?", id)
215+
} else {
216+
String::new()
217+
};
216218

217219
bug!("inconsistent DepNode for `{}`: \
218-
current_dep_node_owner={}, hir_id.owner={}",
220+
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}) {}",
219221
node_str,
220222
self.definitions
221223
.def_path(self.current_dep_node_owner)
222224
.to_string_no_crate(),
223-
self.definitions.def_path(hir_id.owner).to_string_no_crate())
225+
self.current_dep_node_owner,
226+
self.definitions.def_path(hir_id.owner).to_string_no_crate(),
227+
hir_id.owner,
228+
forgot_str)
224229
}
225230
}
226231

@@ -392,6 +397,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
392397
});
393398
}
394399

400+
fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment) {
401+
if let Some(id) = path_segment.id {
402+
self.insert(id, Node::PathSegment(path_segment));
403+
}
404+
intravisit::walk_path_segment(self, path_span, path_segment);
405+
}
406+
395407
fn visit_ty(&mut self, ty: &'hir Ty) {
396408
self.insert(ty.id, Node::Ty(ty));
397409

0 commit comments

Comments
 (0)