From 1e2f350d921e73d7165fe9d7a5f0f6cfe613e3df Mon Sep 17 00:00:00 2001 From: David Wood Date: Tue, 4 Aug 2020 14:36:09 +0100 Subject: [PATCH] save_analysis: support `QPath::LangItem` This commit implements support for `QPath::LangItem` and `GenericBound::LangItemTrait` in save analysis. Signed-off-by: David Wood --- src/librustc_save_analysis/dump_visitor.rs | 30 +++++++--------- src/librustc_save_analysis/lib.rs | 42 +++++++++------------- src/librustc_save_analysis/sig.rs | 4 ++- 3 files changed, 32 insertions(+), 44 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index c1c165a9901f8..6e56e3b9ebb70 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -702,15 +702,18 @@ impl<'tcx> DumpVisitor<'tcx> { // 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 @@ impl<'tcx> DumpVisitor<'tcx> { } 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 @@ impl<'tcx> DumpVisitor<'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 @@ impl<'tcx> Visitor<'tcx> for DumpVisitor<'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, diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index a7eb344ff09f7..fc8a5384739de 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -551,29 +551,22 @@ impl<'tcx> SaveContext<'tcx> { } } } - 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 @@ impl<'tcx> SaveContext<'tcx> { }) | 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 @@ impl<'tcx> SaveContext<'tcx> { 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)) diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 6a9ad3c38f496..f6869cbbfd2aa 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -286,7 +286,9 @@ impl<'hir> Sig for hir::Ty<'hir> { 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> = bounds