]> git.lizzy.rs Git - rust.git/commitdiff
save_analysis: support `QPath::LangItem`
authorDavid Wood <david@davidtw.co>
Tue, 4 Aug 2020 13:36:09 +0000 (14:36 +0100)
committerDavid Wood <david@davidtw.co>
Sun, 16 Aug 2020 14:42:26 +0000 (15:42 +0100)
This commit implements support for `QPath::LangItem` and
`GenericBound::LangItemTrait` in save analysis.

Signed-off-by: David Wood <david@davidtw.co>
src/librustc_save_analysis/dump_visitor.rs
src/librustc_save_analysis/lib.rs
src/librustc_save_analysis/sig.rs

index c1c165a9901f820fc857988a5383dd23969d851c..6e56e3b9ebb70df1ac4ee287cb2015e8983a2814 100644 (file)
@@ -702,15 +702,18 @@ fn process_trait(
 
         // super-traits
         for super_bound in trait_refs.iter() {
-            let trait_ref = match *super_bound {
-                hir::GenericBound::Trait(ref trait_ref, _) => trait_ref,
+            let (def_id, sub_span) = match *super_bound {
+                hir::GenericBound::Trait(ref trait_ref, _) => (
+                    self.lookup_def_id(trait_ref.trait_ref.hir_ref_id),
+                    trait_ref.trait_ref.path.segments.last().unwrap().ident.span,
+                ),
+                hir::GenericBound::LangItemTrait(lang_item, span, _, _) => {
+                    (Some(self.tcx.require_lang_item(lang_item, Some(span))), span)
+                }
                 hir::GenericBound::Outlives(..) => continue,
-                hir::GenericBound::LangItemTrait(..) => unimplemented!(),
             };
 
-            let trait_ref = &trait_ref.trait_ref;
-            if let Some(id) = self.lookup_def_id(trait_ref.hir_ref_id) {
-                let sub_span = trait_ref.path.segments.last().unwrap().ident.span;
+            if let Some(id) = def_id {
                 if !self.span.filter_generated(sub_span) {
                     let span = self.span_from_span(sub_span);
                     self.dumper.dump_ref(Ref {
@@ -763,12 +766,7 @@ fn dump_path_segment_ref(&mut self, id: hir::HirId, segment: &hir::PathSegment<'
     }
 
     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,
-            hir::QPath::LangItem(..) => unimplemented!(),
-        };
-        if self.span.filter_generated(span) {
+        if self.span.filter_generated(path.span()) {
             return;
         }
         self.dump_path_ref(id, path);
@@ -785,7 +783,7 @@ fn process_path(&mut self, id: hir::HirId, path: &hir::QPath<'tcx>) {
                 self.visit_ty(ty);
                 std::slice::from_ref(*segment)
             }
-            hir::QPath::LangItem(..) => unimplemented!(),
+            hir::QPath::LangItem(..) => return,
         };
         for seg in segments {
             if let Some(ref generic_args) = seg.args {
@@ -1358,11 +1356,7 @@ fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) {
                 }
 
                 if let Some(id) = self.lookup_def_id(t.hir_id) {
-                    let sub_span = match path {
-                        hir::QPath::Resolved(_, path) => path.segments.last().unwrap().ident.span,
-                        hir::QPath::TypeRelative(_, segment) => segment.ident.span,
-                        hir::QPath::LangItem(..) => unimplemented!(),
-                    };
+                    let sub_span = path.last_segment_span();
                     let span = self.span_from_span(sub_span);
                     self.dumper.dump_ref(Ref {
                         kind: RefKind::Type,
index a7eb344ff09f78818fa0453caf010a0087f58f19..fc8a5384739deea43e7c5b8607ef3c87287f5f41 100644 (file)
@@ -551,29 +551,22 @@ pub fn get_expr_data(&self, expr: &hir::Expr<'_>) -> Option<Data> {
                     }
                 }
             }
-            hir::ExprKind::Struct(qpath, ..) => {
-                let segment = match qpath {
-                    hir::QPath::Resolved(_, path) => path.segments.last().unwrap(),
-                    hir::QPath::TypeRelative(_, segment) => segment,
-                    hir::QPath::LangItem(..) => unimplemented!(),
-                };
-                match ty.kind {
-                    ty::Adt(def, _) => {
-                        let sub_span = segment.ident.span;
-                        filter!(self.span_utils, sub_span);
-                        let span = self.span_from_span(sub_span);
-                        Some(Data::RefData(Ref {
-                            kind: RefKind::Type,
-                            span,
-                            ref_id: id_from_def_id(def.did),
-                        }))
-                    }
-                    _ => {
-                        debug!("expected adt, found {:?}", ty);
-                        None
-                    }
+            hir::ExprKind::Struct(qpath, ..) => match ty.kind {
+                ty::Adt(def, _) => {
+                    let sub_span = qpath.last_segment_span();
+                    filter!(self.span_utils, sub_span);
+                    let span = self.span_from_span(sub_span);
+                    Some(Data::RefData(Ref {
+                        kind: RefKind::Type,
+                        span,
+                        ref_id: id_from_def_id(def.did),
+                    }))
                 }
-            }
+                _ => {
+                    debug!("expected adt, found {:?}", ty);
+                    None
+                }
+            },
             hir::ExprKind::MethodCall(ref seg, ..) => {
                 let method_id = match self.typeck_results().type_dependent_def_id(expr.hir_id) {
                     Some(id) => id,
@@ -637,10 +630,9 @@ pub fn get_path_res(&self, hir_id: hir::HirId) -> Res {
             })
             | Node::Ty(&hir::Ty { kind: hir::TyKind::Path(ref qpath), .. }) => match qpath {
                 hir::QPath::Resolved(_, path) => path.res,
-                hir::QPath::TypeRelative(..) => self
+                hir::QPath::TypeRelative(..) | hir::QPath::LangItem(..) => self
                     .maybe_typeck_results
                     .map_or(Res::Err, |typeck_results| typeck_results.qpath_res(qpath, hir_id)),
-                hir::QPath::LangItem(..) => unimplemented!(),
             },
 
             Node::Binding(&hir::Pat {
@@ -655,7 +647,7 @@ 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),
-            hir::QPath::LangItem(..) => unimplemented!(),
+            hir::QPath::LangItem(..) => None,
         };
         segment.and_then(|seg| {
             self.get_path_segment_data(seg).or_else(|| self.get_path_segment_data_with_id(seg, id))
index 6a9ad3c38f496d3b0ed304aee5d2fd0ebdee3e35..f6869cbbfd2aa4545a2e0587db384b5aeac49435 100644 (file)
@@ -286,7 +286,9 @@ fn make(&self, offset: usize, _parent_id: Option<hir::HirId>, scx: &SaveContext<
                     refs: vec![SigElement { id, start, end }],
                 })
             }
-            hir::TyKind::Path(hir::QPath::LangItem(..)) => unimplemented!(),
+            hir::TyKind::Path(hir::QPath::LangItem(lang_item, _)) => {
+                Ok(text_sig(format!("#[lang = \"{}\"]", lang_item.name())))
+            }
             hir::TyKind::TraitObject(bounds, ..) => {
                 // FIXME recurse into bounds
                 let bounds: Vec<hir::GenericBound<'_>> = bounds