Skip to content

Commit 7b94fdb

Browse files
committed
save_analysis: better handle paths
1 parent bc10b68 commit 7b94fdb

File tree

3 files changed

+74
-27
lines changed

3 files changed

+74
-27
lines changed

src/librustc_save_analysis/dump_visitor.rs

Lines changed: 51 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -199,23 +199,23 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
199199
self.dumper.compilation_opts(data);
200200
}
201201

202-
fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx>) {
203-
for seg in path.segments {
202+
fn write_segments(&mut self, segments: impl IntoIterator<Item = &'tcx hir::PathSegment<'tcx>>) {
203+
for seg in segments {
204204
if let Some(data) = self.save_ctxt.get_path_segment_data(seg) {
205205
self.dumper.dump_ref(data);
206206
}
207207
}
208208
}
209209

210+
fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx>) {
211+
self.write_segments(path.segments)
212+
}
213+
210214
// As write_sub_paths, but does not process the last ident in the path (assuming it
211215
// will be processed elsewhere). See note on write_sub_paths about global.
212216
fn write_sub_paths_truncated(&mut self, path: &'tcx hir::Path<'tcx>) {
213217
if let [segments @ .., _] = path.segments {
214-
for seg in segments {
215-
if let Some(data) = self.save_ctxt.get_path_segment_data(seg) {
216-
self.dumper.dump_ref(data);
217-
}
218-
}
218+
self.write_segments(segments)
219219
}
220220
}
221221

@@ -643,7 +643,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
643643
self.nest_tables(map.local_def_id(item.hir_id), |v| {
644644
v.visit_ty(&typ);
645645
if let &Some(ref trait_ref) = trait_ref {
646-
v.process_path(trait_ref.hir_ref_id, &trait_ref.path);
646+
v.process_path(trait_ref.hir_ref_id, &hir::QPath::Resolved(None, &trait_ref.path));
647647
}
648648
v.process_generic_params(generics, "", item.hir_id);
649649
for impl_item in impl_items {
@@ -746,7 +746,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
746746
}
747747
}
748748

749-
fn dump_path_ref(&mut self, id: hir::HirId, path: &hir::Path<'tcx>) {
749+
fn dump_path_ref(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) {
750750
let path_data = self.save_ctxt.get_path_data(id, path);
751751
if let Some(path_data) = path_data {
752752
self.dumper.dump_ref(path_data);
@@ -760,14 +760,30 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
760760
}
761761
}
762762

763-
fn process_path(&mut self, id: hir::HirId, path: &'tcx hir::Path<'tcx>) {
764-
if self.span.filter_generated(path.span) {
763+
fn process_path(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) {
764+
let span = match path {
765+
hir::QPath::Resolved(_, path) => path.span,
766+
hir::QPath::TypeRelative(_, segment) => segment.ident.span,
767+
};
768+
if self.span.filter_generated(span) {
765769
return;
766770
}
767771
self.dump_path_ref(id, path);
768772

769773
// Type arguments
770-
for seg in path.segments {
774+
let segments = match path {
775+
hir::QPath::Resolved(ty, path) => {
776+
if let Some(ty) = ty {
777+
self.visit_ty(ty);
778+
}
779+
path.segments
780+
}
781+
hir::QPath::TypeRelative(ty, segment) => {
782+
self.visit_ty(ty);
783+
std::slice::from_ref(*segment)
784+
}
785+
};
786+
for seg in segments {
771787
if let Some(ref generic_args) = seg.args {
772788
for arg in generic_args.args {
773789
if let hir::GenericArg::Type(ref ty) = arg {
@@ -777,7 +793,9 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
777793
}
778794
}
779795

780-
self.write_sub_paths_truncated(path);
796+
if let hir::QPath::Resolved(_, path) = path {
797+
self.write_sub_paths_truncated(path);
798+
}
781799
}
782800

783801
fn process_struct_lit(
@@ -931,9 +949,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
931949
}
932950

933951
for (id, ref path) in collector.collected_paths {
934-
if let hir::QPath::Resolved(_, path) = path {
935-
self.process_path(id, path);
936-
}
952+
self.process_path(id, path);
937953
}
938954
}
939955

@@ -1135,7 +1151,10 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
11351151
fn process_bounds(&mut self, bounds: hir::GenericBounds<'tcx>) {
11361152
for bound in bounds {
11371153
if let hir::GenericBound::Trait(ref trait_ref, _) = *bound {
1138-
self.process_path(trait_ref.trait_ref.hir_ref_id, &trait_ref.trait_ref.path)
1154+
self.process_path(
1155+
trait_ref.trait_ref.hir_ref_id,
1156+
&hir::QPath::Resolved(None, &trait_ref.trait_ref.path),
1157+
)
11391158
}
11401159
}
11411160
}
@@ -1330,13 +1349,16 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
13301349
fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
13311350
self.process_macro_use(t.span);
13321351
match t.kind {
1333-
hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
1352+
hir::TyKind::Path(ref path) => {
13341353
if generated_code(t.span) {
13351354
return;
13361355
}
13371356

13381357
if let Some(id) = self.lookup_def_id(t.hir_id) {
1339-
let sub_span = path.segments.last().unwrap().ident.span;
1358+
let sub_span = match path {
1359+
hir::QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
1360+
hir::QPath::TypeRelative(_, segment) => segment.ident.span,
1361+
};
13401362
let span = self.span_from_span(sub_span);
13411363
self.dumper.dump_ref(Ref {
13421364
kind: RefKind::Type,
@@ -1345,8 +1367,10 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
13451367
});
13461368
}
13471369

1348-
self.write_sub_paths_truncated(path);
1349-
intravisit::walk_path(self, path);
1370+
if let hir::QPath::Resolved(_, path) = path {
1371+
self.write_sub_paths_truncated(path);
1372+
}
1373+
intravisit::walk_qpath(self, path, t.hir_id, t.span);
13501374
}
13511375
hir::TyKind::Array(ref ty, ref anon_const) => {
13521376
self.visit_ty(ty);
@@ -1355,6 +1379,10 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
13551379
v.visit_expr(&map.body(anon_const.body).value)
13561380
});
13571381
}
1382+
hir::TyKind::Def(item_id, _) => {
1383+
let item = self.tcx.hir().item(item_id.id);
1384+
self.nest_tables(self.tcx.hir().local_def_id(item_id.id), |v| v.visit_item(item));
1385+
}
13581386
_ => intravisit::walk_ty(self, t),
13591387
}
13601388
}
@@ -1432,8 +1460,8 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
14321460
self.visit_expr(&arm.body);
14331461
}
14341462

1435-
fn visit_path(&mut self, p: &'tcx hir::Path<'tcx>, id: hir::HirId) {
1436-
self.process_path(id, p);
1463+
fn visit_qpath(&mut self, path: &'tcx hir::QPath<'tcx>, id: hir::HirId, _: Span) {
1464+
self.process_path(id, path);
14371465
}
14381466

14391467
fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {

src/librustc_save_analysis/lib.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -579,7 +579,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
579579
ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(null_id),
580580
}))
581581
}
582-
hir::ExprKind::Path(hir::QPath::Resolved(_, path)) => {
582+
hir::ExprKind::Path(ref path) => {
583583
self.get_path_data(expr.hir_id, path).map(Data::RefData)
584584
}
585585
_ => {
@@ -631,8 +631,12 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
631631
}
632632
}
633633

634-
pub fn get_path_data(&self, id: hir::HirId, path: &hir::Path<'_>) -> Option<Ref> {
635-
path.segments.last().and_then(|seg| {
634+
pub fn get_path_data(&self, id: hir::HirId, path: &hir::QPath<'_>) -> Option<Ref> {
635+
let segment = match path {
636+
hir::QPath::Resolved(_, path) => path.segments.last(),
637+
hir::QPath::TypeRelative(_, segment) => Some(*segment),
638+
};
639+
segment.and_then(|seg| {
636640
self.get_path_segment_data(seg).or_else(|| self.get_path_segment_data_with_id(seg, id))
637641
})
638642
}

src/librustc_save_analysis/sig.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,6 +281,22 @@ impl<'hir> Sig for hir::Ty<'hir> {
281281
})
282282
}
283283
}
284+
hir::TyKind::Path(hir::QPath::TypeRelative(ty, segment)) => {
285+
let nested_ty = ty.make(offset + 1, id, scx)?;
286+
let prefix = format!("<{}>::", nested_ty.text,);
287+
288+
let name = path_segment_to_string(segment);
289+
let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
290+
let id = id_from_def_id(res.def_id());
291+
292+
let start = offset + prefix.len();
293+
let end = start + name.len();
294+
Ok(Signature {
295+
text: prefix + &name,
296+
defs: vec![],
297+
refs: vec![SigElement { id, start, end }],
298+
})
299+
}
284300
hir::TyKind::TraitObject(bounds, ..) => {
285301
// FIXME recurse into bounds
286302
let bounds: Vec<hir::GenericBound<'_>> = bounds
@@ -311,7 +327,6 @@ impl<'hir> Sig for hir::Ty<'hir> {
311327
hir::TyKind::Typeof(_)
312328
| hir::TyKind::Infer
313329
| hir::TyKind::Def(..)
314-
| hir::TyKind::Path(..)
315330
| hir::TyKind::Err => Err("Ty"),
316331
}
317332
}

0 commit comments

Comments
 (0)