about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authormarmeladema <xademax@gmail.com>2020-06-05 23:07:03 +0100
committermarmeladema <xademax@gmail.com>2020-06-09 00:11:32 +0100
commit7b94fdb95cc3dd2bfb2cd6f58fe6f8943cd971e6 (patch)
tree6716c3e210a32dbfebd9a417764dcefe50b16795 /src
parentbc10b68e798477066d4b1ec4886a3b1cdc4feb7e (diff)
downloadrust-7b94fdb95cc3dd2bfb2cd6f58fe6f8943cd971e6.tar.gz
rust-7b94fdb95cc3dd2bfb2cd6f58fe6f8943cd971e6.zip
save_analysis: better handle paths
Diffstat (limited to 'src')
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs74
-rw-r--r--src/librustc_save_analysis/lib.rs10
-rw-r--r--src/librustc_save_analysis/sig.rs17
3 files changed, 74 insertions, 27 deletions
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 489d38b00df..fdcf98b37af 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -199,23 +199,23 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         self.dumper.compilation_opts(data);
     }
 
-    fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx>) {
-        for seg in path.segments {
+    fn write_segments(&mut self, segments: impl IntoIterator<Item = &'tcx hir::PathSegment<'tcx>>) {
+        for seg in segments {
             if let Some(data) = self.save_ctxt.get_path_segment_data(seg) {
                 self.dumper.dump_ref(data);
             }
         }
     }
 
+    fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx>) {
+        self.write_segments(path.segments)
+    }
+
     // As write_sub_paths, but does not process the last ident in the path (assuming it
     // will be processed elsewhere). See note on write_sub_paths about global.
     fn write_sub_paths_truncated(&mut self, path: &'tcx hir::Path<'tcx>) {
         if let [segments @ .., _] = path.segments {
-            for seg in segments {
-                if let Some(data) = self.save_ctxt.get_path_segment_data(seg) {
-                    self.dumper.dump_ref(data);
-                }
-            }
+            self.write_segments(segments)
         }
     }
 
@@ -643,7 +643,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         self.nest_tables(map.local_def_id(item.hir_id), |v| {
             v.visit_ty(&typ);
             if let &Some(ref trait_ref) = trait_ref {
-                v.process_path(trait_ref.hir_ref_id, &trait_ref.path);
+                v.process_path(trait_ref.hir_ref_id, &hir::QPath::Resolved(None, &trait_ref.path));
             }
             v.process_generic_params(generics, "", item.hir_id);
             for impl_item in impl_items {
@@ -746,7 +746,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         }
     }
 
-    fn dump_path_ref(&mut self, id: hir::HirId, path: &hir::Path<'tcx>) {
+    fn dump_path_ref(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) {
         let path_data = self.save_ctxt.get_path_data(id, path);
         if let Some(path_data) = path_data {
             self.dumper.dump_ref(path_data);
@@ -760,14 +760,30 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         }
     }
 
-    fn process_path(&mut self, id: hir::HirId, path: &'tcx hir::Path<'tcx>) {
-        if self.span.filter_generated(path.span) {
+    fn process_path(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) {
+        let span = match path {
+            hir::QPath::Resolved(_, path) => path.span,
+            hir::QPath::TypeRelative(_, segment) => segment.ident.span,
+        };
+        if self.span.filter_generated(span) {
             return;
         }
         self.dump_path_ref(id, path);
 
         // Type arguments
-        for seg in path.segments {
+        let segments = match path {
+            hir::QPath::Resolved(ty, path) => {
+                if let Some(ty) = ty {
+                    self.visit_ty(ty);
+                }
+                path.segments
+            }
+            hir::QPath::TypeRelative(ty, segment) => {
+                self.visit_ty(ty);
+                std::slice::from_ref(*segment)
+            }
+        };
+        for seg in segments {
             if let Some(ref generic_args) = seg.args {
                 for arg in generic_args.args {
                     if let hir::GenericArg::Type(ref ty) = arg {
@@ -777,7 +793,9 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
             }
         }
 
-        self.write_sub_paths_truncated(path);
+        if let hir::QPath::Resolved(_, path) = path {
+            self.write_sub_paths_truncated(path);
+        }
     }
 
     fn process_struct_lit(
@@ -931,9 +949,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
         }
 
         for (id, ref path) in collector.collected_paths {
-            if let hir::QPath::Resolved(_, path) = path {
-                self.process_path(id, path);
-            }
+            self.process_path(id, path);
         }
     }
 
@@ -1135,7 +1151,10 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
     fn process_bounds(&mut self, bounds: hir::GenericBounds<'tcx>) {
         for bound in bounds {
             if let hir::GenericBound::Trait(ref trait_ref, _) = *bound {
-                self.process_path(trait_ref.trait_ref.hir_ref_id, &trait_ref.trait_ref.path)
+                self.process_path(
+                    trait_ref.trait_ref.hir_ref_id,
+                    &hir::QPath::Resolved(None, &trait_ref.trait_ref.path),
+                )
             }
         }
     }
@@ -1330,13 +1349,16 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
     fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
         self.process_macro_use(t.span);
         match t.kind {
-            hir::TyKind::Path(hir::QPath::Resolved(_, path)) => {
+            hir::TyKind::Path(ref path) => {
                 if generated_code(t.span) {
                     return;
                 }
 
                 if let Some(id) = self.lookup_def_id(t.hir_id) {
-                    let sub_span = path.segments.last().unwrap().ident.span;
+                    let sub_span = match path {
+                        hir::QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
+                        hir::QPath::TypeRelative(_, segment) => segment.ident.span,
+                    };
                     let span = self.span_from_span(sub_span);
                     self.dumper.dump_ref(Ref {
                         kind: RefKind::Type,
@@ -1345,8 +1367,10 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
                     });
                 }
 
-                self.write_sub_paths_truncated(path);
-                intravisit::walk_path(self, path);
+                if let hir::QPath::Resolved(_, path) = path {
+                    self.write_sub_paths_truncated(path);
+                }
+                intravisit::walk_qpath(self, path, t.hir_id, t.span);
             }
             hir::TyKind::Array(ref ty, ref anon_const) => {
                 self.visit_ty(ty);
@@ -1355,6 +1379,10 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
                     v.visit_expr(&map.body(anon_const.body).value)
                 });
             }
+            hir::TyKind::Def(item_id, _) => {
+                let item = self.tcx.hir().item(item_id.id);
+                self.nest_tables(self.tcx.hir().local_def_id(item_id.id), |v| v.visit_item(item));
+            }
             _ => intravisit::walk_ty(self, t),
         }
     }
@@ -1432,8 +1460,8 @@ impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> {
         self.visit_expr(&arm.body);
     }
 
-    fn visit_path(&mut self, p: &'tcx hir::Path<'tcx>, id: hir::HirId) {
-        self.process_path(id, p);
+    fn visit_qpath(&mut self, path: &'tcx hir::QPath<'tcx>, id: hir::HirId, _: Span) {
+        self.process_path(id, path);
     }
 
     fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) {
diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs
index 0341b542526..2f46301e76b 100644
--- a/src/librustc_save_analysis/lib.rs
+++ b/src/librustc_save_analysis/lib.rs
@@ -579,7 +579,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
                     ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(null_id),
                 }))
             }
-            hir::ExprKind::Path(hir::QPath::Resolved(_, path)) => {
+            hir::ExprKind::Path(ref path) => {
                 self.get_path_data(expr.hir_id, path).map(Data::RefData)
             }
             _ => {
@@ -631,8 +631,12 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
         }
     }
 
-    pub fn get_path_data(&self, id: hir::HirId, path: &hir::Path<'_>) -> Option<Ref> {
-        path.segments.last().and_then(|seg| {
+    pub fn get_path_data(&self, id: hir::HirId, path: &hir::QPath<'_>) -> Option<Ref> {
+        let segment = match path {
+            hir::QPath::Resolved(_, path) => path.segments.last(),
+            hir::QPath::TypeRelative(_, segment) => Some(*segment),
+        };
+        segment.and_then(|seg| {
             self.get_path_segment_data(seg).or_else(|| self.get_path_segment_data_with_id(seg, id))
         })
     }
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 6fec5cdba8b..52c1c3b99db 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -281,6 +281,22 @@ impl<'hir> Sig for hir::Ty<'hir> {
                     })
                 }
             }
+            hir::TyKind::Path(hir::QPath::TypeRelative(ty, segment)) => {
+                let nested_ty = ty.make(offset + 1, id, scx)?;
+                let prefix = format!("<{}>::", nested_ty.text,);
+
+                let name = path_segment_to_string(segment);
+                let res = scx.get_path_res(id.ok_or("Missing id for Path")?);
+                let id = id_from_def_id(res.def_id());
+
+                let start = offset + prefix.len();
+                let end = start + name.len();
+                Ok(Signature {
+                    text: prefix + &name,
+                    defs: vec![],
+                    refs: vec![SigElement { id, start, end }],
+                })
+            }
             hir::TyKind::TraitObject(bounds, ..) => {
                 // FIXME recurse into bounds
                 let bounds: Vec<hir::GenericBound<'_>> = bounds
@@ -311,7 +327,6 @@ impl<'hir> Sig for hir::Ty<'hir> {
             hir::TyKind::Typeof(_)
             | hir::TyKind::Infer
             | hir::TyKind::Def(..)
-            | hir::TyKind::Path(..)
             | hir::TyKind::Err => Err("Ty"),
         }
     }