diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index 68ce93d3db90f..ccea041699ee1 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -346,12 +346,15 @@ pub fn run_compiler( queries.global_ctxt()?; + // Drop AST after creating GlobalCtxt to free memory + let _timer = sess.prof.generic_activity("drop_ast"); + mem::drop(queries.expansion()?.take()); + if sess.opts.debugging_opts.no_analysis || sess.opts.debugging_opts.ast_json { return early_exit(); } if sess.opts.debugging_opts.save_analysis { - let expanded_crate = &queries.expansion()?.peek().0; let crate_name = queries.crate_name()?.peek().clone(); queries.global_ctxt()?.peek_mut().enter(|tcx| { let result = tcx.analysis(LOCAL_CRATE); @@ -359,7 +362,6 @@ pub fn run_compiler( sess.time("save_analysis", || { save::process_crate( tcx, - &expanded_crate, &crate_name, &compiler.input(), None, @@ -371,13 +373,7 @@ pub fn run_compiler( }); result - // AST will be dropped *after* the `after_analysis` callback - // (needed by the RLS) })?; - } else { - // Drop AST after creating GlobalCtxt to free memory - let _timer = sess.prof.generic_activity("drop_ast"); - mem::drop(queries.expansion()?.take()); } queries.global_ctxt()?.peek_mut().enter(|tcx| tcx.analysis(LOCAL_CRATE))?; @@ -386,10 +382,6 @@ pub fn run_compiler( return early_exit(); } - if sess.opts.debugging_opts.save_analysis { - mem::drop(queries.expansion()?.take()); - } - queries.ongoing_codegen()?; if sess.opts.debugging_opts.print_type_sizes { diff --git a/src/librustc_hir_pretty/lib.rs b/src/librustc_hir_pretty/lib.rs index 8eb19cbb65a0a..e642915b86a5e 100644 --- a/src/librustc_hir_pretty/lib.rs +++ b/src/librustc_hir_pretty/lib.rs @@ -203,6 +203,30 @@ pub fn visibility_qualified>>(vis: &hir::Visibility<'_ }) } +pub fn generic_params_to_string(generic_params: &[GenericParam<'_>]) -> String { + to_string(NO_ANN, |s| s.print_generic_params(generic_params)) +} + +pub fn bounds_to_string<'b>(bounds: impl IntoIterator>) -> String { + to_string(NO_ANN, |s| s.print_bounds("", bounds)) +} + +pub fn param_to_string(arg: &hir::Param<'_>) -> String { + to_string(NO_ANN, |s| s.print_param(arg)) +} + +pub fn ty_to_string(ty: &hir::Ty<'_>) -> String { + to_string(NO_ANN, |s| s.print_type(ty)) +} + +pub fn path_segment_to_string(segment: &hir::PathSegment<'_>) -> String { + to_string(NO_ANN, |s| s.print_path_segment(segment)) +} + +pub fn path_to_string(segment: &hir::Path<'_>) -> String { + to_string(NO_ANN, |s| s.print_path(segment, false)) +} + impl<'a> State<'a> { pub fn cbox(&mut self, u: usize) { self.s.cbox(u); diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 3dd715f9e3df6..a5e61ab9ab033 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -13,19 +13,19 @@ //! DumpVisitor walks the AST and processes it, and Dumper is used for //! recording the output. -use rustc_ast::ast::{self, Attribute, NodeId, PatKind}; -use rustc_ast::ptr::P; -use rustc_ast::token; -use rustc_ast::visit::{self, Visitor}; -use rustc_ast::walk_list; -use rustc_ast_pretty::pprust::{bounds_to_string, generic_params_to_string, ty_to_string}; +use rustc_ast::ast::{self}; +use rustc_ast::{token, walk_list}; use rustc_data_structures::fx::FxHashSet; +use rustc_hir as hir; use rustc_hir::def::{DefKind as HirDefKind, Res}; use rustc_hir::def_id::{DefId, LocalDefId}; +use rustc_hir::intravisit::{self, Visitor}; +use rustc_hir_pretty::{bounds_to_string, generic_params_to_string, ty_to_string}; +use rustc_middle::hir::map::Map; use rustc_middle::span_bug; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; use rustc_session::config::Input; -use rustc_span::source_map::{respan, DUMMY_SP}; +use rustc_span::source_map::respan; use rustc_span::symbol::Ident; use rustc_span::*; @@ -36,7 +36,7 @@ use crate::dumper::{Access, Dumper}; use crate::sig; use crate::span_utils::SpanUtils; use crate::{ - escape, generated_code, id_from_def_id, id_from_node_id, lower_attributes, PathCollector, + escape, generated_code, id_from_def_id, id_from_hir_id, lower_attributes, PathCollector, SaveContext, }; @@ -124,11 +124,11 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.save_ctxt.span_from_span(span) } - fn lookup_def_id(&self, ref_id: NodeId) -> Option { + fn lookup_def_id(&self, ref_id: hir::HirId) -> Option { self.save_ctxt.lookup_def_id(ref_id) } - pub fn dump_crate_info(&mut self, name: &str, krate: &ast::Crate) { + pub fn dump_crate_info(&mut self, name: &str, krate: &hir::Crate<'_>) { let source_file = self.tcx.sess.local_crate_source_file.as_ref(); let crate_root = source_file.map(|source_file| { let source_file = Path::new(source_file); @@ -151,7 +151,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { }, crate_root: crate_root.unwrap_or_else(|| "".to_owned()), external_crates: self.save_ctxt.get_external_crates(), - span: self.span_from_span(krate.span), + span: self.span_from_span(krate.item.span), }; self.dumper.crate_prelude(data); @@ -199,8 +199,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.dumper.compilation_opts(data); } - fn write_sub_paths(&mut self, path: &ast::Path) { - for seg in &path.segments { + fn write_sub_paths(&mut self, path: &'tcx hir::Path<'tcx>) { + for seg in path.segments { if let Some(data) = self.save_ctxt.get_path_segment_data(seg) { self.dumper.dump_ref(data); } @@ -209,7 +209,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { // 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: &ast::Path) { + fn write_sub_paths_truncated(&mut self, path: &'tcx hir::Path<'tcx>) { for seg in &path.segments[..path.segments.len() - 1] { if let Some(data) = self.save_ctxt.get_path_segment_data(seg) { self.dumper.dump_ref(data); @@ -217,23 +217,19 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } } - fn process_formals(&mut self, formals: &'l [ast::Param], qualname: &str) { + fn process_formals(&mut self, formals: &'tcx [hir::Param<'tcx>], qualname: &str) { for arg in formals { self.visit_pat(&arg.pat); - let mut collector = PathCollector::new(); + let mut collector = PathCollector::new(self.tcx); collector.visit_pat(&arg.pat); - for (id, ident, ..) in collector.collected_idents { - // FIXME(#71104) Should really be using just `node_id_to_hir_id` but - // some `NodeId` do not seem to have a corresponding HirId. - let hir_id = self.tcx.hir().opt_node_id_to_hir_id(id); - let typ = - match hir_id.and_then(|hir_id| self.save_ctxt.tables.node_type_opt(hir_id)) { - Some(s) => s.to_string(), - None => continue, - }; + for (hir_id, ident, ..) in collector.collected_idents { + let typ = match self.save_ctxt.tables.node_type_opt(hir_id) { + Some(s) => s.to_string(), + None => continue, + }; if !self.span.filter_generated(ident.span) { - let id = id_from_node_id(id, &self.save_ctxt); + let id = id_from_hir_id(hir_id, &self.save_ctxt); let span = self.span_from_span(ident.span); self.dumper.dump_def( @@ -260,75 +256,74 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { fn process_method( &mut self, - sig: &'l ast::FnSig, - body: Option<&'l ast::Block>, - id: ast::NodeId, + sig: &'tcx hir::FnSig<'tcx>, + body: Option, + hir_id: hir::HirId, ident: Ident, - generics: &'l ast::Generics, - vis: ast::Visibility, + generics: &'tcx hir::Generics<'tcx>, + vis: &hir::Visibility<'tcx>, span: Span, ) { - debug!("process_method: {}:{}", id, ident); + debug!("process_method: {}:{}", hir_id, ident); let map = &self.tcx.hir(); - let hir_id = map.node_id_to_hir_id(id); self.nest_tables(map.local_def_id(hir_id), |v| { - if let Some(mut method_data) = v.save_ctxt.get_method_data(id, ident, span) { - v.process_formals(&sig.decl.inputs, &method_data.qualname); - v.process_generic_params(&generics, &method_data.qualname, id); + if let Some(mut method_data) = v.save_ctxt.get_method_data(hir_id, ident, span) { + if let Some(body) = body { + v.process_formals(map.body(body).params, &method_data.qualname); + } + v.process_generic_params(&generics, &method_data.qualname, hir_id); method_data.value = crate::make_signature(&sig.decl, &generics); - method_data.sig = sig::method_signature(id, ident, generics, sig, &v.save_ctxt); + method_data.sig = sig::method_signature(hir_id, ident, generics, sig, &v.save_ctxt); v.dumper.dump_def(&access_from_vis!(v.save_ctxt, vis, hir_id), method_data); } // walk arg and return types - for arg in &sig.decl.inputs { - v.visit_ty(&arg.ty); + for arg in sig.decl.inputs { + v.visit_ty(arg); } - if let ast::FnRetTy::Ty(ref ret_ty) = sig.decl.output { - // In async functions, return types are desugared and redefined - // as an `impl Trait` existential type. Because of this, to match - // the definition paths when resolving nested types we need to - // start walking from the newly-created definition. - match sig.header.asyncness { - ast::Async::Yes { return_impl_trait_id, .. } => { - let hir_id = map.node_id_to_hir_id(return_impl_trait_id); - v.nest_tables(map.local_def_id(hir_id), |v| v.visit_ty(ret_ty)) - } - _ => v.visit_ty(ret_ty), - } + if let hir::FnRetTy::Return(ref ret_ty) = sig.decl.output { + v.visit_ty(ret_ty) } // walk the fn body if let Some(body) = body { - v.visit_block(body); + v.visit_expr(&map.body(body).value); } }); } - fn process_struct_field_def(&mut self, field: &ast::StructField, parent_id: NodeId) { + fn process_struct_field_def( + &mut self, + field: &'tcx hir::StructField<'tcx>, + parent_id: hir::HirId, + ) { let field_data = self.save_ctxt.get_field_data(field, parent_id); if let Some(field_data) = field_data { - let hir_id = self.tcx.hir().node_id_to_hir_id(field.id); - self.dumper.dump_def(&access_from!(self.save_ctxt, field, hir_id), field_data); + self.dumper.dump_def(&access_from!(self.save_ctxt, field, field.hir_id), field_data); } } // Dump generic params bindings, then visit_generics - fn process_generic_params(&mut self, generics: &'l ast::Generics, prefix: &str, id: NodeId) { - for param in &generics.params { + fn process_generic_params( + &mut self, + generics: &'tcx hir::Generics<'tcx>, + prefix: &str, + id: hir::HirId, + ) { + for param in generics.params { match param.kind { - ast::GenericParamKind::Lifetime { .. } => {} - ast::GenericParamKind::Type { .. } => { - let param_ss = param.ident.span; + hir::GenericParamKind::Lifetime { .. } => {} + hir::GenericParamKind::Type { .. } => { + let param_ss = param.name.ident().span; let name = escape(self.span.snippet(param_ss)); // Append $id to name to make sure each one is unique. let qualname = format!("{}::{}${}", prefix, name, id); if !self.span.filter_generated(param_ss) { - let id = id_from_node_id(param.id, &self.save_ctxt); + let id = id_from_hir_id(param.hir_id, &self.save_ctxt); let span = self.span_from_span(param_ss); self.dumper.dump_def( @@ -350,7 +345,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { ); } } - ast::GenericParamKind::Const { .. } => {} + hir::GenericParamKind::Const { .. } => {} } } self.visit_generics(generics); @@ -358,90 +353,73 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { fn process_fn( &mut self, - item: &'l ast::Item, - decl: &'l ast::FnDecl, - header: &'l ast::FnHeader, - ty_params: &'l ast::Generics, - body: Option<&'l ast::Block>, + item: &'tcx hir::Item<'tcx>, + decl: &'tcx hir::FnDecl<'tcx>, + _header: &'tcx hir::FnHeader, + ty_params: &'tcx hir::Generics<'tcx>, + body: hir::BodyId, ) { let map = &self.tcx.hir(); - let hir_id = map.node_id_to_hir_id(item.id); - self.nest_tables(map.local_def_id(hir_id), |v| { + self.nest_tables(map.local_def_id(item.hir_id), |v| { + let body = map.body(body); if let Some(fn_data) = v.save_ctxt.get_item_data(item) { down_cast_data!(fn_data, DefData, item.span); - v.process_formals(&decl.inputs, &fn_data.qualname); - v.process_generic_params(ty_params, &fn_data.qualname, item.id); + v.process_formals(body.params, &fn_data.qualname); + v.process_generic_params(ty_params, &fn_data.qualname, item.hir_id); - v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), fn_data); + v.dumper.dump_def(&access_from!(v.save_ctxt, item, item.hir_id), fn_data); } - for arg in &decl.inputs { - v.visit_ty(&arg.ty) + for arg in decl.inputs { + v.visit_ty(arg) } - if let ast::FnRetTy::Ty(ref ret_ty) = decl.output { - if let ast::TyKind::ImplTrait(..) = ret_ty.kind { - // FIXME: Opaque type desugaring prevents us from easily - // processing trait bounds. See `visit_ty` for more details. - } else { - // In async functions, return types are desugared and redefined - // as an `impl Trait` existential type. Because of this, to match - // the definition paths when resolving nested types we need to - // start walking from the newly-created definition. - match header.asyncness { - ast::Async::Yes { return_impl_trait_id, .. } => { - let hir_id = map.node_id_to_hir_id(return_impl_trait_id); - v.nest_tables(map.local_def_id(hir_id), |v| v.visit_ty(ret_ty)) - } - _ => v.visit_ty(ret_ty), - } - } + if let hir::FnRetTy::Return(ref ret_ty) = decl.output { + v.visit_ty(ret_ty) } - walk_list!(v, visit_block, body); + v.visit_expr(&body.value); }); } fn process_static_or_const_item( &mut self, - item: &'l ast::Item, - typ: &'l ast::Ty, - expr: Option<&'l ast::Expr>, + item: &'tcx hir::Item<'tcx>, + typ: &'tcx hir::Ty<'tcx>, + expr: &'tcx hir::Expr<'tcx>, ) { - let hir_id = self.tcx.hir().node_id_to_hir_id(item.id); - self.nest_tables(self.tcx.hir().local_def_id(hir_id), |v| { + self.nest_tables(self.tcx.hir().local_def_id(item.hir_id), |v| { if let Some(var_data) = v.save_ctxt.get_item_data(item) { down_cast_data!(var_data, DefData, item.span); - v.dumper.dump_def(&access_from!(v.save_ctxt, item, hir_id), var_data); + v.dumper.dump_def(&access_from!(v.save_ctxt, item, item.hir_id), var_data); } v.visit_ty(&typ); - walk_list!(v, visit_expr, expr); + v.visit_expr(expr); }); } fn process_assoc_const( &mut self, - id: ast::NodeId, + hir_id: hir::HirId, ident: Ident, - typ: &'l ast::Ty, - expr: Option<&'l ast::Expr>, + typ: &'tcx hir::Ty<'tcx>, + expr: Option<&'tcx hir::Expr<'tcx>>, parent_id: DefId, - vis: ast::Visibility, - attrs: &'l [Attribute], + vis: &hir::Visibility<'tcx>, + attrs: &'tcx [ast::Attribute], ) { - let hir_id = self.tcx.hir().node_id_to_hir_id(id); let qualname = format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id(hir_id).to_def_id())); if !self.span.filter_generated(ident.span) { - let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt); + let sig = sig::assoc_const_signature(hir_id, ident.name, typ, expr, &self.save_ctxt); let span = self.span_from_span(ident.span); self.dumper.dump_def( &access_from_vis!(self.save_ctxt, vis, hir_id), Def { kind: DefKind::Const, - id: id_from_node_id(id, &self.save_ctxt), + id: id_from_hir_id(hir_id, &self.save_ctxt), span, name: ident.name.to_string(), qualname, @@ -468,32 +446,32 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { // FIXME tuple structs should generate tuple-specific data. fn process_struct( &mut self, - item: &'l ast::Item, - def: &'l ast::VariantData, - ty_params: &'l ast::Generics, + item: &'tcx hir::Item<'tcx>, + def: &'tcx hir::VariantData<'tcx>, + ty_params: &'tcx hir::Generics<'tcx>, ) { debug!("process_struct {:?} {:?}", item, item.span); let name = item.ident.to_string(); - let hir_id = self.tcx.hir().node_id_to_hir_id(item.id); - let qualname = - format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id(hir_id).to_def_id())); + let qualname = format!( + "::{}", + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.hir_id).to_def_id()) + ); let kind = match item.kind { - ast::ItemKind::Struct(_, _) => DefKind::Struct, - ast::ItemKind::Union(_, _) => DefKind::Union, + hir::ItemKind::Struct(_, _) => DefKind::Struct, + hir::ItemKind::Union(_, _) => DefKind::Union, _ => unreachable!(), }; let (value, fields) = match item.kind { - ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, ..), ..) - | ast::ItemKind::Union(ast::VariantData::Struct(ref fields, ..), ..) => { + hir::ItemKind::Struct(hir::VariantData::Struct(ref fields, ..), ..) + | hir::ItemKind::Union(hir::VariantData::Struct(ref fields, ..), ..) => { let include_priv_fields = !self.save_ctxt.config.pub_only; let fields_str = fields .iter() - .enumerate() - .filter_map(|(i, f)| { + .filter_map(|f| { if include_priv_fields || f.vis.node.is_pub() { - f.ident.map(|i| i.to_string()).or_else(|| Some(i.to_string())) + Some(f.ident.to_string()) } else { None } @@ -501,7 +479,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { .collect::>() .join(", "); let value = format!("{} {{ {} }}", name, fields_str); - (value, fields.iter().map(|f| id_from_node_id(f.id, &self.save_ctxt)).collect()) + (value, fields.iter().map(|f| id_from_hir_id(f.hir_id, &self.save_ctxt)).collect()) } _ => (String::new(), vec![]), }; @@ -509,10 +487,10 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); self.dumper.dump_def( - &access_from!(self.save_ctxt, item, hir_id), + &access_from!(self.save_ctxt, item, item.hir_id), Def { kind, - id: id_from_node_id(item.id, &self.save_ctxt), + id: id_from_hir_id(item.hir_id, &self.save_ctxt), span, name, qualname: qualname.clone(), @@ -522,26 +500,26 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { decl_id: None, docs: self.save_ctxt.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, &self.save_ctxt), - attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt), + attributes: lower_attributes(item.attrs.to_vec(), &self.save_ctxt), }, ); } - self.nest_tables(self.tcx.hir().local_def_id(hir_id), |v| { + self.nest_tables(self.tcx.hir().local_def_id(item.hir_id), |v| { for field in def.fields() { - v.process_struct_field_def(field, item.id); + v.process_struct_field_def(field, item.hir_id); v.visit_ty(&field.ty); } - v.process_generic_params(ty_params, &qualname, item.id); + v.process_generic_params(ty_params, &qualname, item.hir_id); }); } fn process_enum( &mut self, - item: &'l ast::Item, - enum_definition: &'l ast::EnumDef, - ty_params: &'l ast::Generics, + item: &'tcx hir::Item<'tcx>, + enum_definition: &'tcx hir::EnumDef<'tcx>, + ty_params: &'tcx hir::Generics<'tcx>, ) { let enum_data = self.save_ctxt.get_item_data(item); let enum_data = match enum_data { @@ -550,29 +528,22 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { }; down_cast_data!(enum_data, DefData, item.span); - let hir_id = self.tcx.hir().node_id_to_hir_id(item.id); - let access = access_from!(self.save_ctxt, item, hir_id); + let access = access_from!(self.save_ctxt, item, item.hir_id); - for variant in &enum_definition.variants { + for variant in enum_definition.variants { let name = variant.ident.name.to_string(); let qualname = format!("{}::{}", enum_data.qualname, name); let name_span = variant.ident.span; match variant.data { - ast::VariantData::Struct(ref fields, ..) => { - let fields_str = fields - .iter() - .enumerate() - .map(|(i, f)| { - f.ident.map(|i| i.to_string()).unwrap_or_else(|| i.to_string()) - }) - .collect::>() - .join(", "); + hir::VariantData::Struct(ref fields, ..) => { + let fields_str = + fields.iter().map(|f| f.ident.to_string()).collect::>().join(", "); let value = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str); if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); - let id = id_from_node_id(variant.id, &self.save_ctxt); - let parent = Some(id_from_node_id(item.id, &self.save_ctxt)); + let id = id_from_hir_id(variant.id, &self.save_ctxt); + let parent = Some(id_from_hir_id(item.hir_id, &self.save_ctxt)); self.dumper.dump_def( &access, @@ -589,7 +560,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { docs: self.save_ctxt.docs_for_attrs(&variant.attrs), sig: sig::variant_signature(variant, &self.save_ctxt), attributes: lower_attributes( - variant.attrs.clone(), + variant.attrs.to_vec(), &self.save_ctxt, ), }, @@ -598,7 +569,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } ref v => { let mut value = format!("{}::{}", enum_data.name, name); - if let &ast::VariantData::Tuple(ref fields, _) = v { + if let &hir::VariantData::Tuple(ref fields, _) = v { value.push('('); value.push_str( &fields @@ -611,8 +582,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); - let id = id_from_node_id(variant.id, &self.save_ctxt); - let parent = Some(id_from_node_id(item.id, &self.save_ctxt)); + let id = id_from_hir_id(variant.id, &self.save_ctxt); + let parent = Some(id_from_hir_id(item.hir_id, &self.save_ctxt)); self.dumper.dump_def( &access, @@ -629,7 +600,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { docs: self.save_ctxt.docs_for_attrs(&variant.attrs), sig: sig::variant_signature(variant, &self.save_ctxt), attributes: lower_attributes( - variant.attrs.clone(), + variant.attrs.to_vec(), &self.save_ctxt, ), }, @@ -640,20 +611,20 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { for field in variant.data.fields() { self.process_struct_field_def(field, variant.id); - self.visit_ty(&field.ty); + self.visit_ty(field.ty); } } - self.process_generic_params(ty_params, &enum_data.qualname, item.id); + self.process_generic_params(ty_params, &enum_data.qualname, item.hir_id); self.dumper.dump_def(&access, enum_data); } fn process_impl( &mut self, - item: &'l ast::Item, - generics: &'l ast::Generics, - trait_ref: &'l Option, - typ: &'l ast::Ty, - impl_items: &'l [P], + item: &'tcx hir::Item<'tcx>, + generics: &'tcx hir::Generics<'tcx>, + trait_ref: &'tcx Option>, + typ: &'tcx hir::Ty<'tcx>, + impl_items: &'tcx [hir::ImplItemRef<'tcx>], ) { if let Some(impl_data) = self.save_ctxt.get_item_data(item) { if !self.span.filter_generated(item.span) { @@ -667,46 +638,48 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } let map = &self.tcx.hir(); - let hir_id = map.node_id_to_hir_id(item.id); - self.nest_tables(map.local_def_id(hir_id), |v| { + 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.ref_id, &trait_ref.path); + v.process_path(trait_ref.hir_ref_id, &trait_ref.path); } - v.process_generic_params(generics, "", item.id); + v.process_generic_params(generics, "", item.hir_id); for impl_item in impl_items { - v.process_impl_item(impl_item, map.local_def_id(hir_id).to_def_id()); + v.process_impl_item( + map.impl_item(impl_item.id), + map.local_def_id(item.hir_id).to_def_id(), + ); } }); } fn process_trait( &mut self, - item: &'l ast::Item, - generics: &'l ast::Generics, - trait_refs: &'l ast::GenericBounds, - methods: &'l [P], + item: &'tcx hir::Item<'tcx>, + generics: &'tcx hir::Generics<'tcx>, + trait_refs: hir::GenericBounds<'tcx>, + methods: &'tcx [hir::TraitItemRef], ) { let name = item.ident.to_string(); let qualname = format!( "::{}", - self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()) + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.hir_id).to_def_id()) ); let mut val = name.clone(); if !generics.params.is_empty() { - val.push_str(&generic_params_to_string(&generics.params)); + val.push_str(&generic_params_to_string(generics.params)); } if !trait_refs.is_empty() { val.push_str(": "); val.push_str(&bounds_to_string(trait_refs)); } if !self.span.filter_generated(item.ident.span) { - let id = id_from_node_id(item.id, &self.save_ctxt); + let id = id_from_hir_id(item.hir_id, &self.save_ctxt); let span = self.span_from_span(item.ident.span); - let children = methods.iter().map(|i| id_from_node_id(i.id, &self.save_ctxt)).collect(); - let hir_id = self.tcx.hir().node_id_to_hir_id(item.id); + let children = + methods.iter().map(|i| id_from_hir_id(i.id.hir_id, &self.save_ctxt)).collect(); self.dumper.dump_def( - &access_from!(self.save_ctxt, item, hir_id), + &access_from!(self.save_ctxt, item, item.hir_id), Def { kind: DefKind::Trait, id, @@ -719,7 +692,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { decl_id: None, docs: self.save_ctxt.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, &self.save_ctxt), - attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt), + attributes: lower_attributes(item.attrs.to_vec(), &self.save_ctxt), }, ); } @@ -727,12 +700,12 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { // super-traits for super_bound in trait_refs.iter() { let trait_ref = match *super_bound { - ast::GenericBound::Trait(ref trait_ref, _) => trait_ref, - ast::GenericBound::Outlives(..) => continue, + hir::GenericBound::Trait(ref trait_ref, _) => trait_ref, + hir::GenericBound::Outlives(..) => continue, }; let trait_ref = &trait_ref.trait_ref; - if let Some(id) = self.lookup_def_id(trait_ref.ref_id) { + 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 !self.span.filter_generated(sub_span) { let span = self.span_from_span(sub_span); @@ -746,60 +719,57 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { kind: RelationKind::SuperTrait, span, from: id_from_def_id(id), - to: id_from_node_id(item.id, &self.save_ctxt), + to: id_from_hir_id(item.hir_id, &self.save_ctxt), }); } } } // walk generics and methods - self.process_generic_params(generics, &qualname, item.id); + self.process_generic_params(generics, &qualname, item.hir_id); for method in methods { let map = &self.tcx.hir(); - self.process_trait_item(method, map.local_def_id_from_node_id(item.id).to_def_id()) + self.process_trait_item( + map.trait_item(method.id), + map.local_def_id(item.hir_id).to_def_id(), + ) } } - // `item` is the module in question, represented as an item. - fn process_mod(&mut self, item: &ast::Item) { + // `item` is the module in question, represented as an( item. + fn process_mod(&mut self, item: &'tcx hir::Item<'tcx>) { if let Some(mod_data) = self.save_ctxt.get_item_data(item) { down_cast_data!(mod_data, DefData, item.span); - let hir_id = self.tcx.hir().node_id_to_hir_id(item.id); - self.dumper.dump_def(&access_from!(self.save_ctxt, item, hir_id), mod_data); + self.dumper.dump_def(&access_from!(self.save_ctxt, item, item.hir_id), mod_data); } } - fn dump_path_ref(&mut self, id: NodeId, path: &ast::Path) { + fn dump_path_ref(&mut self, id: hir::HirId, path: &hir::Path<'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); } } - fn process_path(&mut self, id: NodeId, path: &'l ast::Path) { + fn dump_path_segment_ref(&mut self, id: hir::HirId, segment: &hir::PathSegment<'tcx>) { + let segment_data = self.save_ctxt.get_path_segment_data_with_id(segment, id); + if let Some(segment_data) = segment_data { + self.dumper.dump_ref(segment_data); + } + } + + fn process_path(&mut self, id: hir::HirId, path: &'tcx hir::Path<'tcx>) { if self.span.filter_generated(path.span) { return; } self.dump_path_ref(id, path); // Type arguments - for seg in &path.segments { + for seg in path.segments { if let Some(ref generic_args) = seg.args { - match **generic_args { - ast::GenericArgs::AngleBracketed(ref data) => { - for arg in &data.args { - if let ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) = arg { - self.visit_ty(ty); - } - } - } - ast::GenericArgs::Parenthesized(ref data) => { - for t in &data.inputs { - self.visit_ty(t); - } - if let ast::FnRetTy::Ty(ty) = &data.output { - self.visit_ty(ty); - } + for arg in generic_args.args { + if let hir::GenericArg::Type(ref ty) = arg { + self.visit_ty(ty); } } } @@ -810,14 +780,16 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { fn process_struct_lit( &mut self, - ex: &'l ast::Expr, - path: &'l ast::Path, - fields: &'l [ast::Field], - variant: &'l ty::VariantDef, - base: &'l Option>, + ex: &'tcx hir::Expr<'tcx>, + path: &'tcx hir::QPath<'tcx>, + fields: &'tcx [hir::Field<'tcx>], + variant: &'tcx ty::VariantDef, + base: Option<&'tcx hir::Expr<'tcx>>, ) { if let Some(struct_lit_data) = self.save_ctxt.get_expr_data(ex) { - self.write_sub_paths_truncated(path); + if let hir::QPath::Resolved(_, path) = path { + self.write_sub_paths_truncated(path); + } down_cast_data!(struct_lit_data, RefData, ex.span); if !generated_code(ex.span) { self.dumper.dump_ref(struct_lit_data); @@ -837,9 +809,9 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { fn process_method_call( &mut self, - ex: &'l ast::Expr, - seg: &'l ast::PathSegment, - args: &'l [P], + ex: &'tcx hir::Expr<'tcx>, + seg: &'tcx hir::PathSegment<'tcx>, + args: &'tcx [hir::Expr<'tcx>], ) { debug!("process_method_call {:?} {:?}", ex, ex.span); if let Some(mcd) = self.save_ctxt.get_expr_data(ex) { @@ -850,13 +822,11 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } // Explicit types in the turbo-fish. - if let Some(ref generic_args) = seg.args { - if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args { - for arg in &data.args { - if let ast::AngleBracketedArg::Arg(ast::GenericArg::Type(ty)) = arg { - self.visit_ty(ty) - }; - } + if let Some(generic_args) = seg.args { + for arg in generic_args.args { + if let hir::GenericArg::Type(ty) = arg { + self.visit_ty(&ty) + }; } } @@ -864,19 +834,18 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { walk_list!(self, visit_expr, args); } - fn process_pat(&mut self, p: &'l ast::Pat) { + fn process_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { match p.kind { - PatKind::Struct(ref _path, ref fields, _) => { + hir::PatKind::Struct(ref _path, fields, _) => { // FIXME do something with _path? - let hir_id = self.tcx.hir().node_id_to_hir_id(p.id); - let adt = match self.save_ctxt.tables.node_type_opt(hir_id) { + let adt = match self.save_ctxt.tables.node_type_opt(p.hir_id) { Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(), _ => { - visit::walk_pat(self, p); + intravisit::walk_pat(self, p); return; } }; - let variant = adt.variant_of_res(self.save_ctxt.get_path_res(p.id)); + let variant = adt.variant_of_res(self.save_ctxt.get_path_res(p.hir_id)); for field in fields { if let Some(index) = self.tcx.find_field_index(field.ident, variant) { @@ -892,22 +861,22 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.visit_pat(&field.pat); } } - _ => visit::walk_pat(self, p), + _ => intravisit::walk_pat(self, p), } } - fn process_var_decl(&mut self, pat: &'l ast::Pat) { + fn process_var_decl(&mut self, pat: &'tcx hir::Pat<'tcx>) { // The pattern could declare multiple new vars, // we must walk the pattern and collect them all. - let mut collector = PathCollector::new(); + let mut collector = PathCollector::new(self.tcx); collector.visit_pat(&pat); self.visit_pat(&pat); // Process collected paths. for (id, ident, _) in collector.collected_idents { - match self.save_ctxt.get_path_res(id) { + let res = self.save_ctxt.get_path_res(id); + match res { Res::Local(hir_id) => { - let id = self.tcx.hir().hir_id_to_node_id(hir_id); let typ = self .save_ctxt .tables @@ -917,8 +886,8 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { // Rust uses the id of the pattern for var lookups, so we'll use it too. if !self.span.filter_generated(ident.span) { - let qualname = format!("{}${}", ident.to_string(), id); - let id = id_from_node_id(id, &self.save_ctxt); + let qualname = format!("{}${}", ident.to_string(), hir_id); + let id = id_from_hir_id(hir_id, &self.save_ctxt); let span = self.span_from_span(ident.span); self.dumper.dump_def( @@ -951,7 +920,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { _, ) | Res::SelfTy(..) => { - self.dump_path_ref(id, &ast::Path::from_ident(ident)); + self.dump_path_segment_ref(id, &hir::PathSegment::from_ident(ident)); } def => { error!("unexpected definition kind when processing collected idents: {:?}", def) @@ -960,7 +929,9 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } for (id, ref path) in collector.collected_paths { - self.process_path(id, path); + if let hir::QPath::Resolved(_, path) = path { + self.process_path(id, path); + } } } @@ -1007,45 +978,49 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { // } } - fn process_trait_item(&mut self, trait_item: &'l ast::AssocItem, trait_id: DefId) { + fn process_trait_item(&mut self, trait_item: &'tcx hir::TraitItem<'tcx>, trait_id: DefId) { self.process_macro_use(trait_item.span); let vis_span = trait_item.span.shrink_to_lo(); match trait_item.kind { - ast::AssocItemKind::Const(_, ref ty, ref expr) => { + hir::TraitItemKind::Const(ref ty, body) => { + let body = body.map(|b| &self.tcx.hir().body(b).value); + let respan = respan(vis_span, hir::VisibilityKind::Public); self.process_assoc_const( - trait_item.id, + trait_item.hir_id, trait_item.ident, &ty, - expr.as_ref().map(|e| &**e), + body, trait_id, - respan(vis_span, ast::VisibilityKind::Public), + &respan, &trait_item.attrs, ); } - ast::AssocItemKind::Fn(_, ref sig, ref generics, ref body) => { + hir::TraitItemKind::Fn(ref sig, ref trait_fn) => { + let body = + if let hir::TraitFn::Provided(body) = trait_fn { Some(*body) } else { None }; + let respan = respan(vis_span, hir::VisibilityKind::Public); self.process_method( sig, - body.as_ref().map(|x| &**x), - trait_item.id, + body, + trait_item.hir_id, trait_item.ident, - generics, - respan(vis_span, ast::VisibilityKind::Public), + &trait_item.generics, + &respan, trait_item.span, ); } - ast::AssocItemKind::TyAlias(_, _, ref bounds, ref default_ty) => { + hir::TraitItemKind::Type(ref bounds, ref default_ty) => { // FIXME do something with _bounds (for type refs) let name = trait_item.ident.name.to_string(); let qualname = format!( "::{}", - self.tcx.def_path_str( - self.tcx.hir().local_def_id_from_node_id(trait_item.id).to_def_id() - ) + self.tcx + .def_path_str(self.tcx.hir().local_def_id(trait_item.hir_id).to_def_id()) ); if !self.span.filter_generated(trait_item.ident.span) { let span = self.span_from_span(trait_item.ident.span); - let id = id_from_node_id(trait_item.id, &self.save_ctxt); + let id = id_from_hir_id(trait_item.hir_id, &self.save_ctxt); self.dumper.dump_def( &Access { public: true, reachable: true }, @@ -1061,13 +1036,16 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { decl_id: None, docs: self.save_ctxt.docs_for_attrs(&trait_item.attrs), sig: sig::assoc_type_signature( - trait_item.id, + trait_item.hir_id, trait_item.ident, Some(bounds), default_ty.as_ref().map(|ty| &**ty), &self.save_ctxt, ), - attributes: lower_attributes(trait_item.attrs.clone(), &self.save_ctxt), + attributes: lower_attributes( + trait_item.attrs.to_vec(), + &self.save_ctxt, + ), }, ); } @@ -1076,98 +1054,122 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.visit_ty(default_ty) } } - ast::AssocItemKind::MacCall(_) => {} } } - fn process_impl_item(&mut self, impl_item: &'l ast::AssocItem, impl_id: DefId) { + fn process_impl_item(&mut self, impl_item: &'tcx hir::ImplItem<'tcx>, impl_id: DefId) { self.process_macro_use(impl_item.span); match impl_item.kind { - ast::AssocItemKind::Const(_, ref ty, ref expr) => { + hir::ImplItemKind::Const(ref ty, body) => { + let body = self.tcx.hir().body(body); self.process_assoc_const( - impl_item.id, + impl_item.hir_id, impl_item.ident, &ty, - expr.as_deref(), + Some(&body.value), impl_id, - impl_item.vis.clone(), + &impl_item.vis, &impl_item.attrs, ); } - ast::AssocItemKind::Fn(_, ref sig, ref generics, ref body) => { + hir::ImplItemKind::Fn(ref sig, body) => { self.process_method( sig, - body.as_deref(), - impl_item.id, + Some(body), + impl_item.hir_id, impl_item.ident, - generics, - impl_item.vis.clone(), + &impl_item.generics, + &impl_item.vis, impl_item.span, ); } - ast::AssocItemKind::TyAlias(_, _, _, None) => {} - ast::AssocItemKind::TyAlias(_, _, _, Some(ref ty)) => { + hir::ImplItemKind::OpaqueTy(..) => {} + hir::ImplItemKind::TyAlias(ref ty) => { // FIXME: uses of the assoc type should ideally point to this // 'def' and the name here should be a ref to the def in the // trait. self.visit_ty(ty) } - ast::AssocItemKind::MacCall(_) => {} } } - /// Dumps imports in a use tree recursively. - /// - /// A use tree is an import that may contain nested braces (RFC 2128). The `use_tree` parameter - /// is the current use tree under scrutiny, while `id` and `prefix` are its corresponding node - /// ID and path. `root_item` is the topmost use tree in the hierarchy. - /// - /// If `use_tree` is a simple or glob import, it is dumped into the analysis data. Otherwise, - /// each child use tree is dumped recursively. - fn process_use_tree( - &mut self, - use_tree: &'l ast::UseTree, - id: NodeId, - root_item: &'l ast::Item, - prefix: &ast::Path, - ) { - let path = &use_tree.prefix; - - // The access is calculated using the current tree ID, but with the root tree's visibility - // (since nested trees don't have their own visibility). - let hir_id = self.tcx.hir().node_id_to_hir_id(id); - let access = access_from!(self.save_ctxt, root_item, hir_id); - - // The parent `DefId` of a given use tree is always the enclosing item. - let parent = self - .save_ctxt - .tcx - .hir() - .opt_local_def_id_from_node_id(id) - .and_then(|id| self.save_ctxt.tcx.parent(id.to_def_id())) - .map(id_from_def_id); - - match use_tree.kind { - ast::UseTreeKind::Simple(alias, ..) => { - let ident = use_tree.ident(); - let path = ast::Path { - segments: prefix.segments.iter().chain(path.segments.iter()).cloned().collect(), - span: path.span, - }; + pub(crate) fn process_crate(&mut self, krate: &'tcx hir::Crate<'tcx>) { + let id = hir::CRATE_HIR_ID; + let qualname = + format!("::{}", self.tcx.def_path_str(self.tcx.hir().local_def_id(id).to_def_id())); + + let sm = self.tcx.sess.source_map(); + let filename = sm.span_to_filename(krate.item.span); + let data_id = id_from_hir_id(id, &self.save_ctxt); + let children = krate + .item + .module + .item_ids + .iter() + .map(|i| id_from_hir_id(i.id, &self.save_ctxt)) + .collect(); + let span = self.span_from_span(krate.item.span); + + self.dumper.dump_def( + &Access { public: true, reachable: true }, + Def { + kind: DefKind::Mod, + id: data_id, + name: String::new(), + qualname, + span, + value: filename.to_string(), + children, + parent: None, + decl_id: None, + docs: self.save_ctxt.docs_for_attrs(krate.item.attrs), + sig: None, + attributes: lower_attributes(krate.item.attrs.to_owned(), &self.save_ctxt), + }, + ); + intravisit::walk_crate(self, krate); + } + + 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) + } + } + } +} +impl<'l, 'tcx> Visitor<'tcx> for DumpVisitor<'l, 'tcx> { + type Map = Map<'tcx>; + + fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { + intravisit::NestedVisitorMap::All(self.tcx.hir()) + } + + fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { + self.process_macro_use(item.span); + match item.kind { + hir::ItemKind::Use(path, hir::UseKind::Single) => { let sub_span = path.segments.last().unwrap().ident.span; if !self.span.filter_generated(sub_span) { - let ref_id = self.lookup_def_id(id).map(id_from_def_id); - let alias_span = alias.map(|i| self.span_from_span(i.span)); + let access = access_from!(self.save_ctxt, item, item.hir_id); + let ref_id = self.lookup_def_id(item.hir_id).map(id_from_def_id); let span = self.span_from_span(sub_span); + let parent = self + .save_ctxt + .tcx + .hir() + .opt_local_def_id(item.hir_id) + .and_then(|id| self.save_ctxt.tcx.parent(id.to_def_id())) + .map(id_from_def_id); self.dumper.import( &access, Import { kind: ImportKind::Use, ref_id, span, - alias_span, - name: ident.to_string(), + alias_span: None, + name: item.ident.to_string(), value: String::new(), parent, }, @@ -1175,25 +1177,27 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { self.write_sub_paths_truncated(&path); } } - ast::UseTreeKind::Glob => { - let path = ast::Path { - segments: prefix.segments.iter().chain(path.segments.iter()).cloned().collect(), - span: path.span, - }; - + hir::ItemKind::Use(path, hir::UseKind::Glob) => { // Make a comma-separated list of names of imported modules. - let def_id = self.tcx.hir().local_def_id_from_node_id(id); + let def_id = self.tcx.hir().local_def_id(item.hir_id); let names = self.tcx.names_imported_by_glob_use(def_id); let names: Vec<_> = names.iter().map(|n| n.to_string()).collect(); // Otherwise it's a span with wrong macro expansion info, which // we don't want to track anyway, since it's probably macro-internal `use` if let Some(sub_span) = - self.span.sub_span_of_token(use_tree.span, token::BinOp(token::Star)) + self.span.sub_span_of_token(item.span, token::BinOp(token::Star)) { - if !self.span.filter_generated(use_tree.span) { + if !self.span.filter_generated(item.span) { + let access = access_from!(self.save_ctxt, item, item.hir_id); let span = self.span_from_span(sub_span); - + let parent = self + .save_ctxt + .tcx + .hir() + .opt_local_def_id(item.hir_id) + .and_then(|id| self.save_ctxt.tcx.parent(id.to_def_id())) + .map(id_from_def_id); self.dumper.import( &access, Import { @@ -1210,73 +1214,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> { } } } - ast::UseTreeKind::Nested(ref nested_items) => { - let prefix = ast::Path { - segments: prefix.segments.iter().chain(path.segments.iter()).cloned().collect(), - span: path.span, - }; - for &(ref tree, id) in nested_items { - self.process_use_tree(tree, id, root_item, &prefix); - } - } - } - } - - fn process_bounds(&mut self, bounds: &'l ast::GenericBounds) { - for bound in bounds { - if let ast::GenericBound::Trait(ref trait_ref, _) = *bound { - self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path) - } - } - } -} - -impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { - fn visit_mod(&mut self, m: &'l ast::Mod, span: Span, attrs: &[ast::Attribute], id: NodeId) { - // Since we handle explicit modules ourselves in visit_item, this should - // only get called for the root module of a crate. - assert_eq!(id, ast::CRATE_NODE_ID); - - let qualname = format!( - "::{}", - self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(id).to_def_id()) - ); - - let sm = self.tcx.sess.source_map(); - let filename = sm.span_to_filename(span); - let data_id = id_from_node_id(id, &self.save_ctxt); - let children = m.items.iter().map(|i| id_from_node_id(i.id, &self.save_ctxt)).collect(); - let span = self.span_from_span(span); - - self.dumper.dump_def( - &Access { public: true, reachable: true }, - Def { - kind: DefKind::Mod, - id: data_id, - name: String::new(), - qualname, - span, - value: filename.to_string(), - children, - parent: None, - decl_id: None, - docs: self.save_ctxt.docs_for_attrs(attrs), - sig: None, - attributes: lower_attributes(attrs.to_owned(), &self.save_ctxt), - }, - ); - visit::walk_mod(self, m); - } - - fn visit_item(&mut self, item: &'l ast::Item) { - use rustc_ast::ast::ItemKind::*; - self.process_macro_use(item.span); - match item.kind { - Use(ref use_tree) => { - let prefix = ast::Path { segments: vec![], span: DUMMY_SP }; - self.process_use_tree(use_tree, item.id, item, &prefix); - } - ExternCrate(_) => { + hir::ItemKind::ExternCrate(_) => { let name_span = item.ident.span; if !self.span.filter_generated(name_span) { let span = self.span_from_span(name_span); @@ -1284,7 +1222,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { .save_ctxt .tcx .hir() - .opt_local_def_id_from_node_id(item.id) + .opt_local_def_id(item.hir_id) .and_then(|id| self.save_ctxt.tcx.parent(id.to_def_id())) .map(id_from_def_id); self.dumper.import( @@ -1301,43 +1239,44 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { ); } } - Fn(_, ref sig, ref ty_params, ref body) => { - self.process_fn(item, &sig.decl, &sig.header, ty_params, body.as_deref()) + hir::ItemKind::Fn(ref sig, ref ty_params, body) => { + self.process_fn(item, sig.decl, &sig.header, ty_params, body) + } + hir::ItemKind::Static(ref typ, _, body) => { + let body = self.tcx.hir().body(body); + self.process_static_or_const_item(item, typ, &body.value) + } + hir::ItemKind::Const(ref typ, body) => { + let body = self.tcx.hir().body(body); + self.process_static_or_const_item(item, typ, &body.value) } - Static(ref typ, _, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()), - Const(_, ref typ, ref e) => self.process_static_or_const_item(item, typ, e.as_deref()), - Struct(ref def, ref ty_params) | Union(ref def, ref ty_params) => { + hir::ItemKind::Struct(ref def, ref ty_params) + | hir::ItemKind::Union(ref def, ref ty_params) => { self.process_struct(item, def, ty_params) } - Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params), - Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => { + hir::ItemKind::Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params), + hir::ItemKind::Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => { self.process_impl(item, generics, of_trait, &self_ty, items) } - Trait(_, _, ref generics, ref trait_refs, ref methods) => { + hir::ItemKind::Trait(_, _, ref generics, ref trait_refs, methods) => { self.process_trait(item, generics, trait_refs, methods) } - Mod(ref m) => { + hir::ItemKind::Mod(ref m) => { self.process_mod(item); - visit::walk_mod(self, m); + intravisit::walk_mod(self, m, item.hir_id); } - TyAlias(_, ref ty_params, _, ref ty) => { + hir::ItemKind::TyAlias(ty, ref generics) => { let qualname = format!( "::{}", - self.tcx.def_path_str( - self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id() - ) + self.tcx.def_path_str(self.tcx.hir().local_def_id(item.hir_id).to_def_id()) ); - let value = match ty { - Some(ty) => ty_to_string(&ty), - None => "_".to_string(), - }; + let value = ty_to_string(&ty); if !self.span.filter_generated(item.ident.span) { let span = self.span_from_span(item.ident.span); - let id = id_from_node_id(item.id, &self.save_ctxt); - let hir_id = self.tcx.hir().node_id_to_hir_id(item.id); + let id = id_from_hir_id(item.hir_id, &self.save_ctxt); self.dumper.dump_def( - &access_from!(self.save_ctxt, item, hir_id), + &access_from!(self.save_ctxt, item, item.hir_id), Def { kind: DefKind::Type, id, @@ -1350,52 +1289,51 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { decl_id: None, docs: self.save_ctxt.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, &self.save_ctxt), - attributes: lower_attributes(item.attrs.clone(), &self.save_ctxt), + attributes: lower_attributes(item.attrs.to_vec(), &self.save_ctxt), }, ); } - walk_list!(self, visit_ty, ty); - self.process_generic_params(ty_params, &qualname, item.id); + self.visit_ty(ty); + self.process_generic_params(generics, &qualname, item.hir_id); } - MacCall(_) => (), - _ => visit::walk_item(self, item), + _ => intravisit::walk_item(self, item), } } - fn visit_generics(&mut self, generics: &'l ast::Generics) { - for param in &generics.params { + fn visit_generics(&mut self, generics: &'tcx hir::Generics<'tcx>) { + for param in generics.params { match param.kind { - ast::GenericParamKind::Lifetime { .. } => {} - ast::GenericParamKind::Type { ref default, .. } => { - self.process_bounds(¶m.bounds); + hir::GenericParamKind::Lifetime { .. } => {} + hir::GenericParamKind::Type { ref default, .. } => { + self.process_bounds(param.bounds); if let Some(ref ty) = default { - self.visit_ty(&ty); + self.visit_ty(ty); } } - ast::GenericParamKind::Const { ref ty } => { - self.process_bounds(¶m.bounds); - self.visit_ty(&ty); + hir::GenericParamKind::Const { ref ty } => { + self.process_bounds(param.bounds); + self.visit_ty(ty); } } } - for pred in &generics.where_clause.predicates { - if let ast::WherePredicate::BoundPredicate(ref wbp) = *pred { - self.process_bounds(&wbp.bounds); - self.visit_ty(&wbp.bounded_ty); + for pred in generics.where_clause.predicates { + if let hir::WherePredicate::BoundPredicate(ref wbp) = *pred { + self.process_bounds(wbp.bounds); + self.visit_ty(wbp.bounded_ty); } } } - fn visit_ty(&mut self, t: &'l ast::Ty) { + fn visit_ty(&mut self, t: &'tcx hir::Ty<'tcx>) { self.process_macro_use(t.span); match t.kind { - ast::TyKind::Path(_, ref path) => { + hir::TyKind::Path(hir::QPath::Resolved(_, path)) => { if generated_code(t.span) { return; } - if let Some(id) = self.lookup_def_id(t.id) { + if let Some(id) = self.lookup_def_id(t.hir_id) { let sub_span = path.segments.last().unwrap().ident.span; let span = self.span_from_span(sub_span); self.dumper.dump_ref(Ref { @@ -1406,57 +1344,37 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { } self.write_sub_paths_truncated(path); - visit::walk_path(self, path); + intravisit::walk_path(self, path); } - ast::TyKind::Array(ref element, ref length) => { - self.visit_ty(element); - let hir_id = self.tcx.hir().node_id_to_hir_id(length.id); - self.nest_tables(self.tcx.hir().local_def_id(hir_id), |v| { - v.visit_expr(&length.value) + hir::TyKind::Array(ref ty, ref anon_const) => { + self.visit_ty(ty); + let map = self.tcx.hir(); + self.nest_tables(self.tcx.hir().local_def_id(anon_const.hir_id), |v| { + v.visit_expr(&map.body(anon_const.body).value) }); } - ast::TyKind::ImplTrait(id, ref bounds) => { - // FIXME: As of writing, the opaque type lowering introduces - // another DefPath scope/segment (used to declare the resulting - // opaque type item). - // However, the synthetic scope does *not* have associated - // typeck tables, which means we can't nest it and we fire an - // assertion when resolving the qualified type paths in trait - // bounds... - // This will panic if called on return type `impl Trait`, which - // we guard against in `process_fn`. - // FIXME(#71104) Should really be using just `node_id_to_hir_id` but - // some `NodeId` do not seem to have a corresponding HirId. - if let Some(hir_id) = self.tcx.hir().opt_node_id_to_hir_id(id) { - self.nest_tables(self.tcx.hir().local_def_id(hir_id), |v| { - v.process_bounds(bounds) - }); - } - } - _ => visit::walk_ty(self, t), + _ => intravisit::walk_ty(self, t), } } - fn visit_expr(&mut self, ex: &'l ast::Expr) { + fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) { debug!("visit_expr {:?}", ex.kind); self.process_macro_use(ex.span); match ex.kind { - ast::ExprKind::Struct(ref path, ref fields, ref base) => { - let expr_hir_id = self.save_ctxt.tcx.hir().node_id_to_hir_id(ex.id); - let hir_expr = self.save_ctxt.tcx.hir().expect_expr(expr_hir_id); + hir::ExprKind::Struct(ref path, ref fields, ref base) => { + let hir_expr = self.save_ctxt.tcx.hir().expect_expr(ex.hir_id); let adt = match self.save_ctxt.tables.expr_ty_opt(&hir_expr) { Some(ty) if ty.ty_adt_def().is_some() => ty.ty_adt_def().unwrap(), _ => { - visit::walk_expr(self, ex); + intravisit::walk_expr(self, ex); return; } }; - let node_id = self.save_ctxt.tcx.hir().hir_id_to_node_id(hir_expr.hir_id); - let res = self.save_ctxt.get_path_res(node_id); - self.process_struct_lit(ex, path, fields, adt.variant_of_res(res), base) + let res = self.save_ctxt.get_path_res(hir_expr.hir_id); + self.process_struct_lit(ex, path, fields, adt.variant_of_res(res), *base) } - ast::ExprKind::MethodCall(ref seg, ref args) => self.process_method_call(ex, seg, args), - ast::ExprKind::Field(ref sub_ex, _) => { + hir::ExprKind::MethodCall(ref seg, _, args) => self.process_method_call(ex, seg, args), + hir::ExprKind::Field(ref sub_ex, _) => { self.visit_expr(&sub_ex); if let Some(field_data) = self.save_ctxt.get_expr_data(ex) { @@ -1466,71 +1384,62 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { } } } - ast::ExprKind::Closure(_, _, _, ref decl, ref body, _fn_decl_span) => { - let id = format!("${}", ex.id); + hir::ExprKind::Closure(_, ref decl, body, _fn_decl_span, _) => { + let id = format!("${}", ex.hir_id); // walk arg and return types - for arg in &decl.inputs { - self.visit_ty(&arg.ty); + for ty in decl.inputs { + self.visit_ty(ty); } - if let ast::FnRetTy::Ty(ref ret_ty) = decl.output { - self.visit_ty(&ret_ty); + if let hir::FnRetTy::Return(ref ret_ty) = decl.output { + self.visit_ty(ret_ty); } // walk the body - let hir_id = self.tcx.hir().node_id_to_hir_id(ex.id); - self.nest_tables(self.tcx.hir().local_def_id(hir_id), |v| { - v.process_formals(&decl.inputs, &id); - v.visit_expr(body) + let map = self.tcx.hir(); + self.nest_tables(self.tcx.hir().local_def_id(ex.hir_id), |v| { + let body = map.body(body); + v.process_formals(body.params, &id); + v.visit_expr(&body.value) }); } - ast::ExprKind::ForLoop(ref pattern, ref subexpression, ref block, _) => { - self.process_var_decl(pattern); - debug!("for loop, walk sub-expr: {:?}", subexpression.kind); - self.visit_expr(subexpression); - visit::walk_block(self, block); - } - ast::ExprKind::Let(ref pat, ref scrutinee) => { - self.process_var_decl(pat); - self.visit_expr(scrutinee); - } - ast::ExprKind::Repeat(ref element, ref count) => { - self.visit_expr(element); - let hir_id = self.tcx.hir().node_id_to_hir_id(count.id); - self.nest_tables(self.tcx.hir().local_def_id(hir_id), |v| { - v.visit_expr(&count.value) + hir::ExprKind::Repeat(ref expr, ref anon_const) => { + self.visit_expr(expr); + let map = self.tcx.hir(); + self.nest_tables(self.tcx.hir().local_def_id(anon_const.hir_id), |v| { + v.visit_expr(&map.body(anon_const.body).value) }); } // In particular, we take this branch for call and path expressions, // where we'll index the idents involved just by continuing to walk. - _ => visit::walk_expr(self, ex), + _ => intravisit::walk_expr(self, ex), } } - fn visit_pat(&mut self, p: &'l ast::Pat) { + fn visit_pat(&mut self, p: &'tcx hir::Pat<'tcx>) { self.process_macro_use(p.span); self.process_pat(p); } - fn visit_arm(&mut self, arm: &'l ast::Arm) { + fn visit_arm(&mut self, arm: &'tcx hir::Arm<'tcx>) { self.process_var_decl(&arm.pat); - if let Some(expr) = &arm.guard { + if let Some(hir::Guard::If(expr)) = &arm.guard { self.visit_expr(expr); } self.visit_expr(&arm.body); } - fn visit_path(&mut self, p: &'l ast::Path, id: NodeId) { + fn visit_path(&mut self, p: &'tcx hir::Path<'tcx>, id: hir::HirId) { self.process_path(id, p); } - fn visit_stmt(&mut self, s: &'l ast::Stmt) { + fn visit_stmt(&mut self, s: &'tcx hir::Stmt<'tcx>) { self.process_macro_use(s.span); - visit::walk_stmt(self, s) + intravisit::walk_stmt(self, s) } - fn visit_local(&mut self, l: &'l ast::Local) { + fn visit_local(&mut self, l: &'tcx hir::Local<'tcx>) { self.process_macro_use(l.span); self.process_var_decl(&l.pat); @@ -1539,29 +1448,27 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { walk_list!(self, visit_expr, &l.init); } - fn visit_foreign_item(&mut self, item: &'l ast::ForeignItem) { - let hir_id = self.tcx.hir().node_id_to_hir_id(item.id); - let access = access_from!(self.save_ctxt, item, hir_id); + fn visit_foreign_item(&mut self, item: &'tcx hir::ForeignItem<'tcx>) { + let access = access_from!(self.save_ctxt, item, item.hir_id); match item.kind { - ast::ForeignItemKind::Fn(_, ref sig, ref generics, _) => { - let decl = &sig.decl; + hir::ForeignItemKind::Fn(decl, _, ref generics) => { if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(fn_data, DefData, item.span); - self.process_generic_params(generics, &fn_data.qualname, item.id); + self.process_generic_params(generics, &fn_data.qualname, item.hir_id); self.dumper.dump_def(&access, fn_data); } - for arg in &decl.inputs { - self.visit_ty(&arg.ty); + for ty in decl.inputs { + self.visit_ty(ty); } - if let ast::FnRetTy::Ty(ref ret_ty) = decl.output { - self.visit_ty(&ret_ty); + if let hir::FnRetTy::Return(ref ret_ty) = decl.output { + self.visit_ty(ret_ty); } } - ast::ForeignItemKind::Static(ref ty, _, _) => { + hir::ForeignItemKind::Static(ref ty, _) => { if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(var_data, DefData, item.span); self.dumper.dump_def(&access, var_data); @@ -1569,13 +1476,12 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { self.visit_ty(ty); } - ast::ForeignItemKind::TyAlias(..) => { + hir::ForeignItemKind::Type => { if let Some(var_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(var_data, DefData, item.span); self.dumper.dump_def(&access, var_data); } } - ast::ForeignItemKind::MacCall(..) => {} } } } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 3bd68a9c656ce..8c7731c18e9c4 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -9,14 +9,16 @@ mod dumper; mod span_utils; mod sig; -use rustc_ast::ast::{self, Attribute, NodeId, PatKind, DUMMY_NODE_ID}; +use rustc_ast::ast::{self}; use rustc_ast::util::comments::strip_doc_comment_decoration; -use rustc_ast::visit::{self, Visitor}; -use rustc_ast_pretty::pprust::{self, param_to_string, ty_to_string}; +use rustc_ast_pretty::pprust::attribute_to_string; use rustc_hir as hir; use rustc_hir::def::{CtorOf, DefKind as HirDefKind, Res}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; +use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::Node; +use rustc_hir_pretty::ty_to_string; +use rustc_middle::hir::map::Map; use rustc_middle::middle::cstore::ExternCrate; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::{self, DefIdTree, TyCtxt}; @@ -129,34 +131,32 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { result } - pub fn get_extern_item_data(&self, item: &ast::ForeignItem) -> Option { - let qualname = format!( - "::{}", - self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id()) - ); + pub fn get_extern_item_data(&self, item: &hir::ForeignItem<'_>) -> Option { + let def_id = self.tcx.hir().local_def_id(item.hir_id).to_def_id(); + let qualname = format!("::{}", self.tcx.def_path_str(def_id)); match item.kind { - ast::ForeignItemKind::Fn(_, ref sig, ref generics, _) => { + hir::ForeignItemKind::Fn(ref decl, _, ref generics) => { filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::ForeignFunction, - id: id_from_node_id(item.id, self), + id: id_from_def_id(def_id), span: self.span_from_span(item.ident.span), name: item.ident.to_string(), qualname, - value: make_signature(&sig.decl, generics), + value: make_signature(decl, generics), parent: None, children: vec![], decl_id: None, docs: self.docs_for_attrs(&item.attrs), sig: sig::foreign_item_signature(item, self), - attributes: lower_attributes(item.attrs.clone(), self), + attributes: lower_attributes(item.attrs.to_vec(), self), })) } - ast::ForeignItemKind::Static(ref ty, _, _) => { + hir::ForeignItemKind::Static(ref ty, _) => { filter!(self.span_utils, item.ident.span); - let id = id_from_node_id(item.id, self); + let id = id_from_def_id(def_id); let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { @@ -171,28 +171,23 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { decl_id: None, docs: self.docs_for_attrs(&item.attrs), sig: sig::foreign_item_signature(item, self), - attributes: lower_attributes(item.attrs.clone(), self), + attributes: lower_attributes(item.attrs.to_vec(), self), })) } // FIXME(plietar): needs a new DefKind in rls-data - ast::ForeignItemKind::TyAlias(..) => None, - ast::ForeignItemKind::MacCall(..) => None, + hir::ForeignItemKind::Type => None, } } - pub fn get_item_data(&self, item: &ast::Item) -> Option { + pub fn get_item_data(&self, item: &hir::Item<'_>) -> Option { + let def_id = self.tcx.hir().local_def_id(item.hir_id).to_def_id(); match item.kind { - ast::ItemKind::Fn(_, ref sig, .., ref generics, _) => { - let qualname = format!( - "::{}", - self.tcx.def_path_str( - self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id() - ) - ); + hir::ItemKind::Fn(ref sig, ref generics, _) => { + let qualname = format!("::{}", self.tcx.def_path_str(def_id)); filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::Function, - id: id_from_node_id(item.id, self), + id: id_from_def_id(def_id), span: self.span_from_span(item.ident.span), name: item.ident.to_string(), qualname, @@ -202,20 +197,15 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { decl_id: None, docs: self.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: lower_attributes(item.attrs.clone(), self), + attributes: lower_attributes(item.attrs.to_vec(), self), })) } - ast::ItemKind::Static(ref typ, ..) => { - let qualname = format!( - "::{}", - self.tcx.def_path_str( - self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id() - ) - ); + hir::ItemKind::Static(ref typ, ..) => { + let qualname = format!("::{}", self.tcx.def_path_str(def_id)); filter!(self.span_utils, item.ident.span); - let id = id_from_node_id(item.id, self); + let id = id_from_def_id(def_id); let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { @@ -230,19 +220,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { decl_id: None, docs: self.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: lower_attributes(item.attrs.clone(), self), + attributes: lower_attributes(item.attrs.to_vec(), self), })) } - ast::ItemKind::Const(_, ref typ, _) => { - let qualname = format!( - "::{}", - self.tcx.def_path_str( - self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id() - ) - ); + hir::ItemKind::Const(ref typ, _) => { + let qualname = format!("::{}", self.tcx.def_path_str(def_id)); filter!(self.span_utils, item.ident.span); - let id = id_from_node_id(item.id, self); + let id = id_from_def_id(def_id); let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { @@ -257,16 +242,11 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { decl_id: None, docs: self.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: lower_attributes(item.attrs.clone(), self), + attributes: lower_attributes(item.attrs.to_vec(), self), })) } - ast::ItemKind::Mod(ref m) => { - let qualname = format!( - "::{}", - self.tcx.def_path_str( - self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id() - ) - ); + hir::ItemKind::Mod(ref m) => { + let qualname = format!("::{}", self.tcx.def_path_str(def_id)); let sm = self.tcx.sess.source_map(); let filename = sm.span_to_filename(m.inner); @@ -275,48 +255,43 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { Some(Data::DefData(Def { kind: DefKind::Mod, - id: id_from_node_id(item.id, self), + id: id_from_def_id(def_id), name: item.ident.to_string(), qualname, span: self.span_from_span(item.ident.span), value: filename.to_string(), parent: None, - children: m.items.iter().map(|i| id_from_node_id(i.id, self)).collect(), + children: m.item_ids.iter().map(|i| id_from_hir_id(i.id, self)).collect(), decl_id: None, docs: self.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: lower_attributes(item.attrs.clone(), self), + attributes: lower_attributes(item.attrs.to_vec(), self), })) } - ast::ItemKind::Enum(ref def, _) => { + hir::ItemKind::Enum(ref def, _) => { let name = item.ident.to_string(); - let qualname = format!( - "::{}", - self.tcx.def_path_str( - self.tcx.hir().local_def_id_from_node_id(item.id).to_def_id() - ) - ); + let qualname = format!("::{}", self.tcx.def_path_str(def_id)); filter!(self.span_utils, item.ident.span); let variants_str = def.variants.iter().map(|v| v.ident.to_string()).collect::>().join(", "); let value = format!("{}::{{{}}}", name, variants_str); Some(Data::DefData(Def { kind: DefKind::Enum, - id: id_from_node_id(item.id, self), + id: id_from_def_id(def_id), span: self.span_from_span(item.ident.span), name, qualname, value, parent: None, - children: def.variants.iter().map(|v| id_from_node_id(v.id, self)).collect(), + children: def.variants.iter().map(|v| id_from_hir_id(v.id, self)).collect(), decl_id: None, docs: self.docs_for_attrs(&item.attrs), sig: sig::item_signature(item, self), - attributes: lower_attributes(item.attrs.clone(), self), + attributes: lower_attributes(item.attrs.to_vec(), self), })) } - ast::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => { - if let ast::TyKind::Path(None, ref path) = self_ty.kind { + hir::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => { + if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = self_ty.kind { // Common case impl for a struct or something basic. if generated_code(path.span) { return None; @@ -327,7 +302,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let impl_id = self.next_impl_id(); let span = self.span_from_span(sub_span); - let type_data = self.lookup_def_id(self_ty.id); + let type_data = self.lookup_def_id(self_ty.hir_id); type_data.map(|type_data| { Data::RelationData( Relation { @@ -336,7 +311,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { from: id_from_def_id(type_data), to: of_trait .as_ref() - .and_then(|t| self.lookup_def_id(t.ref_id)) + .and_then(|t| self.lookup_def_id(t.hir_ref_id)) .map(id_from_def_id) .unwrap_or_else(null_id), }, @@ -351,7 +326,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { parent: None, children: items .iter() - .map(|i| id_from_node_id(i.id, self)) + .map(|i| id_from_hir_id(i.id.hir_id, self)) .collect(), docs: String::new(), sig: None, @@ -370,126 +345,120 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } } - pub fn get_field_data(&self, field: &ast::StructField, scope: NodeId) -> Option { - if let Some(ident) = field.ident { - let name = ident.to_string(); - let qualname = format!( - "::{}::{}", - self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(scope).to_def_id()), - ident - ); - filter!(self.span_utils, ident.span); - let def_id = self.tcx.hir().local_def_id_from_node_id(field.id).to_def_id(); - let typ = self.tcx.type_of(def_id).to_string(); - - let id = id_from_node_id(field.id, self); - let span = self.span_from_span(ident.span); - - Some(Def { - kind: DefKind::Field, - id, - span, - name, - qualname, - value: typ, - parent: Some(id_from_node_id(scope, self)), - children: vec![], - decl_id: None, - docs: self.docs_for_attrs(&field.attrs), - sig: sig::field_signature(field, self), - attributes: lower_attributes(field.attrs.clone(), self), - }) - } else { - None - } + pub fn get_field_data(&self, field: &hir::StructField<'_>, scope: hir::HirId) -> Option { + let name = field.ident.to_string(); + let scope_def_id = self.tcx.hir().local_def_id(scope).to_def_id(); + let qualname = format!("::{}::{}", self.tcx.def_path_str(scope_def_id), field.ident); + filter!(self.span_utils, field.ident.span); + let field_def_id = self.tcx.hir().local_def_id(field.hir_id).to_def_id(); + let typ = self.tcx.type_of(field_def_id).to_string(); + + let id = id_from_def_id(field_def_id); + let span = self.span_from_span(field.ident.span); + + Some(Def { + kind: DefKind::Field, + id, + span, + name, + qualname, + value: typ, + parent: Some(id_from_def_id(scope_def_id)), + children: vec![], + decl_id: None, + docs: self.docs_for_attrs(&field.attrs), + sig: sig::field_signature(field, self), + attributes: lower_attributes(field.attrs.to_vec(), self), + }) } // FIXME would be nice to take a MethodItem here, but the ast provides both // trait and impl flavours, so the caller must do the disassembly. - pub fn get_method_data(&self, id: ast::NodeId, ident: Ident, span: Span) -> Option { + pub fn get_method_data(&self, hir_id: hir::HirId, ident: Ident, span: Span) -> Option { // The qualname for a method is the trait name or name of the struct in an impl in // which the method is declared in, followed by the method's name. - let (qualname, parent_scope, decl_id, docs, attributes) = match self - .tcx - .impl_of_method(self.tcx.hir().local_def_id_from_node_id(id).to_def_id()) - { - Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) { - Some(Node::Item(item)) => match item.kind { - hir::ItemKind::Impl { ref self_ty, .. } => { - let hir = self.tcx.hir(); - - let mut qualname = String::from("<"); - qualname.push_str(&rustc_hir_pretty::id_to_string(&hir, self_ty.hir_id)); - - let trait_id = self.tcx.trait_id_of_impl(impl_id); + let def_id = self.tcx.hir().local_def_id(hir_id).to_def_id(); + let (qualname, parent_scope, decl_id, docs, attributes) = + match self.tcx.impl_of_method(def_id) { + Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) { + Some(Node::Item(item)) => match item.kind { + hir::ItemKind::Impl { ref self_ty, .. } => { + let hir = self.tcx.hir(); + + let mut qualname = String::from("<"); + qualname + .push_str(&rustc_hir_pretty::id_to_string(&hir, self_ty.hir_id)); + + let trait_id = self.tcx.trait_id_of_impl(impl_id); + let mut docs = String::new(); + let mut attrs = vec![]; + if let Some(Node::ImplItem(item)) = hir.find(hir_id) { + docs = self.docs_for_attrs(&item.attrs); + attrs = item.attrs.to_vec(); + } + + let mut decl_id = None; + if let Some(def_id) = trait_id { + // A method in a trait impl. + qualname.push_str(" as "); + qualname.push_str(&self.tcx.def_path_str(def_id)); + + decl_id = self + .tcx + .associated_items(def_id) + .filter_by_name_unhygienic(ident.name) + .next() + .map(|item| item.def_id); + } + qualname.push_str(">"); + + (qualname, trait_id, decl_id, docs, attrs) + } + _ => { + span_bug!( + span, + "Container {:?} for method {} not an impl?", + impl_id, + hir_id + ); + } + }, + r => { + span_bug!( + span, + "Container {:?} for method {} is not a node item {:?}", + impl_id, + hir_id, + r + ); + } + }, + None => match self.tcx.trait_of_item(def_id) { + Some(def_id) => { let mut docs = String::new(); let mut attrs = vec![]; - if let Some(Node::ImplItem(item)) = hir.find(hir.node_id_to_hir_id(id)) { + + if let Some(Node::TraitItem(item)) = self.tcx.hir().find(hir_id) { docs = self.docs_for_attrs(&item.attrs); attrs = item.attrs.to_vec(); } - let mut decl_id = None; - if let Some(def_id) = trait_id { - // A method in a trait impl. - qualname.push_str(" as "); - qualname.push_str(&self.tcx.def_path_str(def_id)); - - decl_id = self - .tcx - .associated_items(def_id) - .filter_by_name_unhygienic(ident.name) - .next() - .map(|item| item.def_id); - } - qualname.push_str(">"); - - (qualname, trait_id, decl_id, docs, attrs) + ( + format!("::{}", self.tcx.def_path_str(def_id)), + Some(def_id), + None, + docs, + attrs, + ) } - _ => { - span_bug!(span, "Container {:?} for method {} not an impl?", impl_id, id); + None => { + debug!("could not find container for method {} at {:?}", hir_id, span); + // This is not necessarily a bug, if there was a compilation error, + // the tables we need might not exist. + return None; } }, - r => { - span_bug!( - span, - "Container {:?} for method {} is not a node item {:?}", - impl_id, - id, - r - ); - } - }, - None => match self - .tcx - .trait_of_item(self.tcx.hir().local_def_id_from_node_id(id).to_def_id()) - { - Some(def_id) => { - let mut docs = String::new(); - let mut attrs = vec![]; - let hir_id = self.tcx.hir().node_id_to_hir_id(id); - - if let Some(Node::TraitItem(item)) = self.tcx.hir().find(hir_id) { - docs = self.docs_for_attrs(&item.attrs); - attrs = item.attrs.to_vec(); - } - - ( - format!("::{}", self.tcx.def_path_str(def_id)), - Some(def_id), - None, - docs, - attrs, - ) - } - None => { - debug!("could not find container for method {} at {:?}", id, span); - // This is not necessarily a bug, if there was a compilation error, - // the tables we need might not exist. - return None; - } - }, - }; + }; let qualname = format!("{}::{}", qualname, ident.name); @@ -497,7 +466,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { Some(Def { kind: DefKind::Method, - id: id_from_node_id(id, self), + id: id_from_def_id(def_id), span: self.span_from_span(ident.span), name: ident.name.to_string(), qualname, @@ -512,8 +481,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { }) } - pub fn get_trait_ref_data(&self, trait_ref: &ast::TraitRef) -> Option { - self.lookup_def_id(trait_ref.ref_id).and_then(|def_id| { + pub fn get_trait_ref_data(&self, trait_ref: &hir::TraitRef<'_>) -> Option { + self.lookup_def_id(trait_ref.hir_ref_id).and_then(|def_id| { let span = trait_ref.path.span; if generated_code(span) { return None; @@ -525,22 +494,20 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { }) } - pub fn get_expr_data(&self, expr: &ast::Expr) -> Option { - let expr_hir_id = self.tcx.hir().node_id_to_hir_id(expr.id); - let hir_node = self.tcx.hir().expect_expr(expr_hir_id); + pub fn get_expr_data(&self, expr: &hir::Expr<'_>) -> Option { + let hir_node = self.tcx.hir().expect_expr(expr.hir_id); let ty = self.tables.expr_ty_adjusted_opt(&hir_node); if ty.is_none() || ty.unwrap().kind == ty::Error { return None; } match expr.kind { - ast::ExprKind::Field(ref sub_ex, ident) => { - let sub_ex_hir_id = self.tcx.hir().node_id_to_hir_id(sub_ex.id); - let hir_node = match self.tcx.hir().find(sub_ex_hir_id) { + hir::ExprKind::Field(ref sub_ex, ident) => { + let hir_node = match self.tcx.hir().find(sub_ex.hir_id) { Some(Node::Expr(expr)) => expr, _ => { debug!( "Missing or weird node for sub-expression {} in {:?}", - sub_ex.id, expr + sub_ex.hir_id, expr ); return None; } @@ -567,7 +534,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } } } - ast::ExprKind::Struct(ref path, ..) => { + hir::ExprKind::Struct(hir::QPath::Resolved(_, path), ..) => { match self.tables.expr_ty_adjusted(&hir_node).kind { ty::Adt(def, _) if !def.is_enum() => { let sub_span = path.segments.last().unwrap().ident.span; @@ -587,9 +554,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } } } - ast::ExprKind::MethodCall(ref seg, ..) => { - let expr_hir_id = self.tcx.hir().definitions().node_id_to_hir_id(expr.id); - let method_id = match self.tables.type_dependent_def_id(expr_hir_id) { + hir::ExprKind::MethodCall(ref seg, ..) => { + let method_id = match self.tables.type_dependent_def_id(expr.hir_id) { Some(id) => id, None => { debug!("could not resolve method id for {:?}", expr); @@ -609,8 +575,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { ref_id: def_id.or(decl_id).map(id_from_def_id).unwrap_or_else(null_id), })) } - ast::ExprKind::Path(_, ref path) => { - self.get_path_data(expr.id, path).map(Data::RefData) + hir::ExprKind::Path(hir::QPath::Resolved(_, path)) => { + self.get_path_data(expr.hir_id, path).map(Data::RefData) } _ => { // FIXME @@ -619,12 +585,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } } - pub fn get_path_res(&self, id: NodeId) -> Res { - // FIXME(#71104) - let hir_id = match self.tcx.hir().opt_node_id_to_hir_id(id) { - Some(id) => id, - None => return Res::Err, - }; + pub fn get_path_res(&self, hir_id: hir::HirId) -> Res { match self.tcx.hir().get(hir_id) { Node::TraitRef(tr) => tr.path.res, @@ -638,7 +599,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { Some(res) if res != Res::Err => res, _ => { let parent_node = self.tcx.hir().get_parent_node(hir_id); - self.get_path_res(self.tcx.hir().hir_id_to_node_id(parent_node)) + self.get_path_res(parent_node) } }, @@ -666,33 +627,24 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } } - pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option { + pub fn get_path_data(&self, id: hir::HirId, path: &hir::Path<'_>) -> Option { path.segments.last().and_then(|seg| { self.get_path_segment_data(seg).or_else(|| self.get_path_segment_data_with_id(seg, id)) }) } - pub fn get_path_segment_data(&self, path_seg: &ast::PathSegment) -> Option { - self.get_path_segment_data_with_id(path_seg, path_seg.id) + pub fn get_path_segment_data(&self, path_seg: &hir::PathSegment<'_>) -> Option { + self.get_path_segment_data_with_id(path_seg, path_seg.hir_id?) } - fn get_path_segment_data_with_id( + pub fn get_path_segment_data_with_id( &self, - path_seg: &ast::PathSegment, - id: NodeId, + path_seg: &hir::PathSegment<'_>, + id: hir::HirId, ) -> Option { // Returns true if the path is function type sugar, e.g., `Fn(A) -> B`. - fn fn_type(seg: &ast::PathSegment) -> bool { - if let Some(ref generic_args) = seg.args { - if let ast::GenericArgs::Parenthesized(_) = **generic_args { - return true; - } - } - false - } - - if id == DUMMY_NODE_ID { - return None; + fn fn_type(seg: &hir::PathSegment<'_>) -> bool { + seg.args.map(|args| args.parenthesized).unwrap_or(false) } let res = self.get_path_res(id); @@ -701,11 +653,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let span = self.span_from_span(span); match res { - Res::Local(id) => Some(Ref { - kind: RefKind::Variable, - span, - ref_id: id_from_node_id(self.tcx.hir().hir_id_to_node_id(id), self), - }), + Res::Local(id) => { + Some(Ref { kind: RefKind::Variable, span, ref_id: id_from_hir_id(id, self) }) + } Res::Def(HirDefKind::Trait, def_id) if fn_type(path_seg) => { Some(Ref { kind: RefKind::Type, span, ref_id: id_from_def_id(def_id) }) } @@ -791,7 +741,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { pub fn get_field_ref_data( &self, - field_ref: &ast::Field, + field_ref: &hir::Field<'_>, variant: &ty::VariantDef, ) -> Option { filter!(self.span_utils, field_ref.ident.span); @@ -839,14 +789,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { }) } - fn lookup_def_id(&self, ref_id: NodeId) -> Option { + fn lookup_def_id(&self, ref_id: hir::HirId) -> Option { match self.get_path_res(ref_id) { Res::PrimTy(_) | Res::SelfTy(..) | Res::Err => None, def => def.opt_def_id(), } } - fn docs_for_attrs(&self, attrs: &[Attribute]) -> String { + fn docs_for_attrs(&self, attrs: &[ast::Attribute]) -> String { let mut result = String::new(); for attr in attrs { @@ -890,7 +840,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { } } -fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String { +fn make_signature(decl: &hir::FnDecl<'_>, generics: &hir::Generics<'_>) -> String { let mut sig = "fn ".to_owned(); if !generics.params.is_empty() { sig.push('<'); @@ -898,18 +848,18 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String { &generics .params .iter() - .map(|param| param.ident.to_string()) + .map(|param| param.name.ident().to_string()) .collect::>() .join(", "), ); sig.push_str("> "); } sig.push('('); - sig.push_str(&decl.inputs.iter().map(param_to_string).collect::>().join(", ")); + sig.push_str(&decl.inputs.iter().map(ty_to_string).collect::>().join(", ")); sig.push(')'); match decl.output { - ast::FnRetTy::Default(_) => sig.push_str(" -> ()"), - ast::FnRetTy::Ty(ref t) => sig.push_str(&format!(" -> {}", ty_to_string(t))), + hir::FnRetTy::DefaultReturn(_) => sig.push_str(" -> ()"), + hir::FnRetTy::Return(ref t) => sig.push_str(&format!(" -> {}", ty_to_string(t))), } sig @@ -918,26 +868,33 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String { // An AST visitor for collecting paths (e.g., the names of structs) and formal // variables (idents) from patterns. struct PathCollector<'l> { - collected_paths: Vec<(NodeId, &'l ast::Path)>, - collected_idents: Vec<(NodeId, Ident, ast::Mutability)>, + tcx: TyCtxt<'l>, + collected_paths: Vec<(hir::HirId, &'l hir::QPath<'l>)>, + collected_idents: Vec<(hir::HirId, Ident, hir::Mutability)>, } impl<'l> PathCollector<'l> { - fn new() -> PathCollector<'l> { - PathCollector { collected_paths: vec![], collected_idents: vec![] } + fn new(tcx: TyCtxt<'l>) -> PathCollector<'l> { + PathCollector { tcx, collected_paths: vec![], collected_idents: vec![] } } } impl<'l> Visitor<'l> for PathCollector<'l> { - fn visit_pat(&mut self, p: &'l ast::Pat) { + type Map = Map<'l>; + + fn nested_visit_map(&mut self) -> intravisit::NestedVisitorMap { + intravisit::NestedVisitorMap::All(self.tcx.hir()) + } + + fn visit_pat(&mut self, p: &'l hir::Pat<'l>) { match p.kind { - PatKind::Struct(ref path, ..) => { - self.collected_paths.push((p.id, path)); + hir::PatKind::Struct(ref path, ..) => { + self.collected_paths.push((p.hir_id, path)); } - PatKind::TupleStruct(ref path, ..) | PatKind::Path(_, ref path) => { - self.collected_paths.push((p.id, path)); + hir::PatKind::TupleStruct(ref path, ..) | hir::PatKind::Path(ref path) => { + self.collected_paths.push((p.hir_id, path)); } - PatKind::Ident(bm, ident, _) => { + hir::PatKind::Binding(bm, _, ident, _) => { debug!( "PathCollector, visit ident in pat {}: {:?} {:?}", ident, p.span, ident.span @@ -946,14 +903,18 @@ impl<'l> Visitor<'l> for PathCollector<'l> { // Even if the ref is mut, you can't change the ref, only // the data pointed at, so showing the initialising expression // is still worthwhile. - ast::BindingMode::ByRef(_) => ast::Mutability::Not, - ast::BindingMode::ByValue(mt) => mt, + hir::BindingAnnotation::Unannotated | hir::BindingAnnotation::Ref => { + hir::Mutability::Not + } + hir::BindingAnnotation::Mutable | hir::BindingAnnotation::RefMut => { + hir::Mutability::Mut + } }; - self.collected_idents.push((p.id, ident, immut)); + self.collected_idents.push((p.hir_id, ident, immut)); } _ => {} } - visit::walk_pat(self, p); + intravisit::walk_pat(self, p); } } @@ -1035,7 +996,6 @@ impl SaveHandler for CallbackHandler<'_> { pub fn process_crate<'l, 'tcx, H: SaveHandler>( tcx: TyCtxt<'tcx>, - krate: &ast::Crate, cratename: &str, input: &'l Input, config: Option, @@ -1063,9 +1023,9 @@ pub fn process_crate<'l, 'tcx, H: SaveHandler>( let mut visitor = DumpVisitor::new(save_ctxt); - visitor.dump_crate_info(cratename, krate); + visitor.dump_crate_info(cratename, tcx.hir().krate()); visitor.dump_compilation_options(input, cratename); - visit::walk_crate(&mut visitor, krate); + visitor.process_crate(tcx.hir().krate()); handler.save(&visitor.save_ctxt, &visitor.analysis()) }) @@ -1109,13 +1069,17 @@ fn id_from_def_id(id: DefId) -> rls_data::Id { rls_data::Id { krate: id.krate.as_u32(), index: id.index.as_u32() } } -fn id_from_node_id(id: NodeId, scx: &SaveContext<'_, '_>) -> rls_data::Id { - let def_id = scx.tcx.hir().opt_local_def_id_from_node_id(id); +fn id_from_hir_id(id: hir::HirId, scx: &SaveContext<'_, '_>) -> rls_data::Id { + let def_id = scx.tcx.hir().opt_local_def_id(id); def_id.map(|id| id_from_def_id(id.to_def_id())).unwrap_or_else(|| { - // Create a *fake* `DefId` out of a `NodeId` by subtracting the `NodeId` - // out of the maximum u32 value. This will work unless you have *billions* - // of definitions in a single crate (very unlikely to actually happen). - rls_data::Id { krate: LOCAL_CRATE.as_u32(), index: !id.as_u32() } + // Create a *fake* `DefId` out of a `HirId` by combining the owner + // `local_def_index` and the `local_id`. + // This will work unless you have *billions* of definitions in a single + // crate (very unlikely to actually happen). + rls_data::Id { + krate: LOCAL_CRATE.as_u32(), + index: id.owner.local_def_index.as_u32() | id.local_id.as_u32().reverse_bits(), + } }) } @@ -1123,7 +1087,10 @@ fn null_id() -> rls_data::Id { rls_data::Id { krate: u32::max_value(), index: u32::max_value() } } -fn lower_attributes(attrs: Vec, scx: &SaveContext<'_, '_>) -> Vec { +fn lower_attributes( + attrs: Vec, + scx: &SaveContext<'_, '_>, +) -> Vec { attrs .into_iter() // Only retain real attributes. Doc comments are lowered separately. @@ -1133,7 +1100,7 @@ fn lower_attributes(attrs: Vec, scx: &SaveContext<'_, '_>) -> Vec) -> Option { +pub fn item_signature(item: &hir::Item<'_>, scx: &SaveContext<'_, '_>) -> Option { if !scx.config.signatures { return None; } @@ -42,7 +44,7 @@ pub fn item_signature(item: &ast::Item, scx: &SaveContext<'_, '_>) -> Option, scx: &SaveContext<'_, '_>, ) -> Option { if !scx.config.signatures { @@ -53,7 +55,10 @@ pub fn foreign_item_signature( /// Signature for a struct or tuple field declaration. /// Does not include a trailing comma. -pub fn field_signature(field: &ast::StructField, scx: &SaveContext<'_, '_>) -> Option { +pub fn field_signature( + field: &hir::StructField<'_>, + scx: &SaveContext<'_, '_>, +) -> Option { if !scx.config.signatures { return None; } @@ -61,7 +66,10 @@ pub fn field_signature(field: &ast::StructField, scx: &SaveContext<'_, '_>) -> O } /// Does not include a trailing comma. -pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext<'_, '_>) -> Option { +pub fn variant_signature( + variant: &hir::Variant<'_>, + scx: &SaveContext<'_, '_>, +) -> Option { if !scx.config.signatures { return None; } @@ -69,10 +77,10 @@ pub fn variant_signature(variant: &ast::Variant, scx: &SaveContext<'_, '_>) -> O } pub fn method_signature( - id: NodeId, + id: hir::HirId, ident: Ident, - generics: &ast::Generics, - m: &ast::FnSig, + generics: &hir::Generics<'_>, + m: &hir::FnSig<'_>, scx: &SaveContext<'_, '_>, ) -> Option { if !scx.config.signatures { @@ -82,10 +90,10 @@ pub fn method_signature( } pub fn assoc_const_signature( - id: NodeId, + id: hir::HirId, ident: Symbol, - ty: &ast::Ty, - default: Option<&ast::Expr>, + ty: &hir::Ty<'_>, + default: Option<&hir::Expr<'_>>, scx: &SaveContext<'_, '_>, ) -> Option { if !scx.config.signatures { @@ -95,10 +103,10 @@ pub fn assoc_const_signature( } pub fn assoc_type_signature( - id: NodeId, + id: hir::HirId, ident: Ident, - bounds: Option<&ast::GenericBounds>, - default: Option<&ast::Ty>, + bounds: Option>, + default: Option<&hir::Ty<'_>>, scx: &SaveContext<'_, '_>, ) -> Option { if !scx.config.signatures { @@ -110,7 +118,7 @@ pub fn assoc_type_signature( type Result = std::result::Result; trait Sig { - fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_, '_>) -> Result; + fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_, '_>) -> Result; } fn extend_sig( @@ -145,39 +153,34 @@ fn text_sig(text: String) -> Signature { Signature { text, defs: vec![], refs: vec![] } } -fn push_extern(text: &mut String, ext: Extern) { - match ext { - Extern::None => {} - Extern::Implicit => text.push_str("extern "), - Extern::Explicit(abi) => text.push_str(&format!("extern \"{}\" ", abi.symbol)), - } -} - -impl Sig for ast::Ty { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { - let id = Some(self.id); +impl<'hir> Sig for hir::Ty<'hir> { + fn make( + &self, + offset: usize, + _parent_id: Option, + scx: &SaveContext<'_, '_>, + ) -> Result { + let id = Some(self.hir_id); match self.kind { - ast::TyKind::Slice(ref ty) => { + hir::TyKind::Slice(ref ty) => { let nested = ty.make(offset + 1, id, scx)?; let text = format!("[{}]", nested.text); Ok(replace_text(nested, text)) } - ast::TyKind::Ptr(ref mt) => { + hir::TyKind::Ptr(ref mt) => { let prefix = match mt.mutbl { - ast::Mutability::Mut => "*mut ", - ast::Mutability::Not => "*const ", + hir::Mutability::Mut => "*mut ", + hir::Mutability::Not => "*const ", }; let nested = mt.ty.make(offset + prefix.len(), id, scx)?; let text = format!("{}{}", prefix, nested.text); Ok(replace_text(nested, text)) } - ast::TyKind::Rptr(ref lifetime, ref mt) => { + hir::TyKind::Rptr(ref lifetime, ref mt) => { let mut prefix = "&".to_owned(); - if let &Some(ref l) = lifetime { - prefix.push_str(&l.ident.to_string()); - prefix.push(' '); - } - if let ast::Mutability::Mut = mt.mutbl { + prefix.push_str(&lifetime.name.ident().to_string()); + prefix.push(' '); + if let hir::Mutability::Mut = mt.mutbl { prefix.push_str("mut "); }; @@ -185,9 +188,8 @@ impl Sig for ast::Ty { let text = format!("{}{}", prefix, nested.text); Ok(replace_text(nested, text)) } - ast::TyKind::Never => Ok(text_sig("!".to_owned())), - ast::TyKind::CVarArgs => Ok(text_sig("...".to_owned())), - ast::TyKind::Tup(ref ts) => { + hir::TyKind::Never => Ok(text_sig("!".to_owned())), + hir::TyKind::Tup(ts) => { let mut text = "(".to_owned(); let mut defs = vec![]; let mut refs = vec![]; @@ -201,12 +203,7 @@ impl Sig for ast::Ty { text.push(')'); Ok(Signature { text, defs, refs }) } - ast::TyKind::Paren(ref ty) => { - let nested = ty.make(offset + 1, id, scx)?; - let text = format!("({})", nested.text); - Ok(replace_text(nested, text)) - } - ast::TyKind::BareFn(ref f) => { + hir::TyKind::BareFn(ref f) => { let mut text = String::new(); if !f.generic_params.is_empty() { // FIXME defs, bounds on lifetimes @@ -215,8 +212,8 @@ impl Sig for ast::Ty { &f.generic_params .iter() .filter_map(|param| match param.kind { - ast::GenericParamKind::Lifetime { .. } => { - Some(param.ident.to_string()) + hir::GenericParamKind::Lifetime { .. } => { + Some(param.name.ident().to_string()) } _ => None, }) @@ -226,23 +223,22 @@ impl Sig for ast::Ty { text.push('>'); } - if let ast::Unsafe::Yes(_) = f.unsafety { + if let hir::Unsafety::Unsafe = f.unsafety { text.push_str("unsafe "); } - push_extern(&mut text, f.ext); text.push_str("fn("); let mut defs = vec![]; let mut refs = vec![]; - for i in &f.decl.inputs { - let nested = i.ty.make(offset + text.len(), Some(i.id), scx)?; + for i in f.decl.inputs { + let nested = i.make(offset + text.len(), Some(i.hir_id), scx)?; text.push_str(&nested.text); text.push(','); defs.extend(nested.defs.into_iter()); refs.extend(nested.refs.into_iter()); } text.push(')'); - if let ast::FnRetTy::Ty(ref t) = f.decl.output { + if let hir::FnRetTy::Return(ref t) = f.decl.output { text.push_str(" -> "); let nested = t.make(offset + text.len(), None, scx)?; text.push_str(&nested.text); @@ -253,23 +249,19 @@ impl Sig for ast::Ty { Ok(Signature { text, defs, refs }) } - ast::TyKind::Path(None, ref path) => path.make(offset, id, scx), - ast::TyKind::Path(Some(ref qself), ref path) => { - let nested_ty = qself.ty.make(offset + 1, id, scx)?; - let prefix = if qself.position == 0 { - format!("<{}>::", nested_ty.text) - } else if qself.position == 1 { - let first = pprust::path_segment_to_string(&path.segments[0]); - format!("<{} as {}>::", nested_ty.text, first) - } else { - // FIXME handle path instead of elipses. - format!("<{} as ...>::", nested_ty.text) - }; + hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) => path.make(offset, id, scx), + hir::TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref path)) => { + let nested_ty = qself.make(offset + 1, id, scx)?; + let prefix = format!( + "<{} as {}>::", + nested_ty.text, + path_segment_to_string(&path.segments[0]) + ); - let name = pprust::path_segment_to_string(path.segments.last().ok_or("Bad path")?); + let name = path_segment_to_string(path.segments.last().ok_or("Bad path")?); let res = scx.get_path_res(id.ok_or("Missing id for Path")?); let id = id_from_def_id(res.def_id()); - if path.segments.len() - qself.position == 1 { + if path.segments.len() == 2 { let start = offset + prefix.len(); let end = start + name.len(); @@ -289,44 +281,60 @@ impl Sig for ast::Ty { }) } } - ast::TyKind::TraitObject(ref bounds, ..) => { + hir::TyKind::TraitObject(bounds, ..) => { // FIXME recurse into bounds - let nested = pprust::bounds_to_string(bounds); + let bounds: Vec> = bounds + .iter() + .map(|hir::PolyTraitRef { bound_generic_params, trait_ref, span }| { + hir::GenericBound::Trait( + hir::PolyTraitRef { + bound_generic_params, + trait_ref: hir::TraitRef { + path: trait_ref.path, + hir_ref_id: trait_ref.hir_ref_id, + }, + span: *span, + }, + hir::TraitBoundModifier::None, + ) + }) + .collect(); + let nested = bounds_to_string(&bounds); Ok(text_sig(nested)) } - ast::TyKind::ImplTrait(_, ref bounds) => { - // FIXME recurse into bounds - let nested = pprust::bounds_to_string(bounds); - Ok(text_sig(format!("impl {}", nested))) - } - ast::TyKind::Array(ref ty, ref v) => { + hir::TyKind::Array(ref ty, ref anon_const) => { let nested_ty = ty.make(offset + 1, id, scx)?; - let expr = pprust::expr_to_string(&v.value).replace('\n', " "); + let expr = id_to_string(&scx.tcx.hir(), anon_const.body.hir_id).replace('\n', " "); let text = format!("[{}; {}]", nested_ty.text, expr); Ok(replace_text(nested_ty, text)) } - ast::TyKind::Typeof(_) - | ast::TyKind::Infer - | ast::TyKind::Err - | ast::TyKind::ImplicitSelf - | ast::TyKind::MacCall(_) => Err("Ty"), + hir::TyKind::Typeof(_) + | hir::TyKind::Infer + | hir::TyKind::Def(..) + | hir::TyKind::Path(..) + | hir::TyKind::Err => Err("Ty"), } } } -impl Sig for ast::Item { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { - let id = Some(self.id); +impl<'hir> Sig for hir::Item<'hir> { + fn make( + &self, + offset: usize, + _parent_id: Option, + scx: &SaveContext<'_, '_>, + ) -> Result { + let id = Some(self.hir_id); match self.kind { - ast::ItemKind::Static(ref ty, m, ref expr) => { + hir::ItemKind::Static(ref ty, m, ref body) => { let mut text = "static ".to_owned(); - if m == ast::Mutability::Mut { + if m == hir::Mutability::Mut { text.push_str("mut "); } let name = self.ident.to_string(); let defs = vec![SigElement { - id: id_from_node_id(self.id, scx), + id: id_from_hir_id(self.hir_id, scx), start: offset + text.len(), end: offset + text.len() + name.len(), }]; @@ -336,21 +344,19 @@ impl Sig for ast::Item { let ty = ty.make(offset + text.len(), id, scx)?; text.push_str(&ty.text); - if let Some(expr) = expr { - text.push_str(" = "); - let expr = pprust::expr_to_string(expr).replace('\n', " "); - text.push_str(&expr); - } + text.push_str(" = "); + let expr = id_to_string(&scx.tcx.hir(), body.hir_id).replace('\n', " "); + text.push_str(&expr); text.push(';'); Ok(extend_sig(ty, text, defs, vec![])) } - ast::ItemKind::Const(_, ref ty, ref expr) => { + hir::ItemKind::Const(ref ty, ref body) => { let mut text = "const ".to_owned(); let name = self.ident.to_string(); let defs = vec![SigElement { - id: id_from_node_id(self.id, scx), + id: id_from_hir_id(self.hir_id, scx), start: offset + text.len(), end: offset + text.len() + name.len(), }]; @@ -360,38 +366,35 @@ impl Sig for ast::Item { let ty = ty.make(offset + text.len(), id, scx)?; text.push_str(&ty.text); - if let Some(expr) = expr { - text.push_str(" = "); - let expr = pprust::expr_to_string(expr).replace('\n', " "); - text.push_str(&expr); - } + text.push_str(" = "); + let expr = id_to_string(&scx.tcx.hir(), body.hir_id).replace('\n', " "); + text.push_str(&expr); text.push(';'); Ok(extend_sig(ty, text, defs, vec![])) } - ast::ItemKind::Fn(_, ast::FnSig { ref decl, header }, ref generics, _) => { + hir::ItemKind::Fn(hir::FnSig { ref decl, header }, ref generics, _) => { let mut text = String::new(); - if let ast::Const::Yes(_) = header.constness { + if let hir::Constness::Const = header.constness { text.push_str("const "); } - if header.asyncness.is_async() { + if hir::IsAsync::Async == header.asyncness { text.push_str("async "); } - if let ast::Unsafe::Yes(_) = header.unsafety { + if let hir::Unsafety::Unsafe = header.unsafety { text.push_str("unsafe "); } - push_extern(&mut text, header.ext); text.push_str("fn "); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; sig.text.push('('); - for i in &decl.inputs { + for i in decl.inputs { // FIXME should descend into patterns to add defs. - sig.text.push_str(&pprust::pat_to_string(&i.pat)); sig.text.push_str(": "); - let nested = i.ty.make(offset + sig.text.len(), Some(i.id), scx)?; + let nested = i.make(offset + sig.text.len(), Some(i.hir_id), scx)?; sig.text.push_str(&nested.text); sig.text.push(','); sig.defs.extend(nested.defs.into_iter()); @@ -399,7 +402,7 @@ impl Sig for ast::Item { } sig.text.push(')'); - if let ast::FnRetTy::Ty(ref t) = decl.output { + if let hir::FnRetTy::Return(ref t) = decl.output { sig.text.push_str(" -> "); let nested = t.make(offset + sig.text.len(), None, scx)?; sig.text.push_str(&nested.text); @@ -410,11 +413,11 @@ impl Sig for ast::Item { Ok(sig) } - ast::ItemKind::Mod(ref _mod) => { + hir::ItemKind::Mod(ref _mod) => { let mut text = "mod ".to_owned(); let name = self.ident.to_string(); let defs = vec![SigElement { - id: id_from_node_id(self.id, scx), + id: id_from_hir_id(self.hir_id, scx), start: offset + text.len(), end: offset + text.len() + name.len(), }]; @@ -424,78 +427,82 @@ impl Sig for ast::Item { Ok(Signature { text, defs, refs: vec![] }) } - ast::ItemKind::TyAlias(_, ref generics, _, ref ty) => { + hir::ItemKind::TyAlias(ref ty, ref generics) => { let text = "type ".to_owned(); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; sig.text.push_str(" = "); - let ty = match ty { - Some(ty) => ty.make(offset + sig.text.len(), id, scx)?, - None => return Err("Ty"), - }; + let ty = ty.make(offset + sig.text.len(), id, scx)?; sig.text.push_str(&ty.text); sig.text.push(';'); Ok(merge_sigs(sig.text.clone(), vec![sig, ty])) } - ast::ItemKind::Enum(_, ref generics) => { + hir::ItemKind::Enum(_, ref generics) => { let text = "enum ".to_owned(); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; sig.text.push_str(" {}"); Ok(sig) } - ast::ItemKind::Struct(_, ref generics) => { + hir::ItemKind::Struct(_, ref generics) => { let text = "struct ".to_owned(); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; sig.text.push_str(" {}"); Ok(sig) } - ast::ItemKind::Union(_, ref generics) => { + hir::ItemKind::Union(_, ref generics) => { let text = "union ".to_owned(); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; sig.text.push_str(" {}"); Ok(sig) } - ast::ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, _) => { + hir::ItemKind::Trait(is_auto, unsafety, ref generics, bounds, _) => { let mut text = String::new(); - if is_auto == ast::IsAuto::Yes { + if is_auto == hir::IsAuto::Yes { text.push_str("auto "); } - if let ast::Unsafe::Yes(_) = unsafety { + if let hir::Unsafety::Unsafe = unsafety { text.push_str("unsafe "); } text.push_str("trait "); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; if !bounds.is_empty() { sig.text.push_str(": "); - sig.text.push_str(&pprust::bounds_to_string(bounds)); + sig.text.push_str(&bounds_to_string(bounds)); } // FIXME where clause sig.text.push_str(" {}"); Ok(sig) } - ast::ItemKind::TraitAlias(ref generics, ref bounds) => { + hir::ItemKind::TraitAlias(ref generics, bounds) => { let mut text = String::new(); text.push_str("trait "); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; if !bounds.is_empty() { sig.text.push_str(" = "); - sig.text.push_str(&pprust::bounds_to_string(bounds)); + sig.text.push_str(&bounds_to_string(bounds)); } // FIXME where clause sig.text.push_str(";"); Ok(sig) } - ast::ItemKind::Impl { + hir::ItemKind::Impl { unsafety, polarity, defaultness, + defaultness_span: _, constness, ref generics, ref of_trait, @@ -503,14 +510,14 @@ impl Sig for ast::Item { items: _, } => { let mut text = String::new(); - if let ast::Defaultness::Default(_) = defaultness { + if let hir::Defaultness::Default { .. } = defaultness { text.push_str("default "); } - if let ast::Unsafe::Yes(_) = unsafety { + if let hir::Unsafety::Unsafe = unsafety { text.push_str("unsafe "); } text.push_str("impl"); - if let ast::Const::Yes(_) = constness { + if let hir::Constness::Const = constness { text.push_str(" const"); } @@ -520,7 +527,7 @@ impl Sig for ast::Item { text.push(' '); let trait_sig = if let Some(ref t) = *of_trait { - if let ast::ImplPolarity::Negative(_) = polarity { + if let hir::ImplPolarity::Negative(_) = polarity { text.push('!'); } let trait_sig = t.path.make(offset + text.len(), id, scx)?; @@ -540,27 +547,23 @@ impl Sig for ast::Item { // FIXME where clause } - ast::ItemKind::ForeignMod(_) => Err("extern mod"), - ast::ItemKind::GlobalAsm(_) => Err("glboal asm"), - ast::ItemKind::ExternCrate(_) => Err("extern crate"), + hir::ItemKind::ForeignMod(_) => Err("extern mod"), + hir::ItemKind::GlobalAsm(_) => Err("glboal asm"), + hir::ItemKind::ExternCrate(_) => Err("extern crate"), + hir::ItemKind::OpaqueTy(..) => Err("opaque type"), // FIXME should implement this (e.g., pub use). - ast::ItemKind::Use(_) => Err("import"), - ast::ItemKind::MacCall(..) | ast::ItemKind::MacroDef(_) => Err("Macro"), + hir::ItemKind::Use(..) => Err("import"), } } } -impl Sig for ast::Path { - fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_, '_>) -> Result { +impl<'hir> Sig for hir::Path<'hir> { + fn make(&self, offset: usize, id: Option, scx: &SaveContext<'_, '_>) -> Result { let res = scx.get_path_res(id.ok_or("Missing id for Path")?); let (name, start, end) = match res { Res::PrimTy(..) | Res::SelfTy(..) | Res::Err => { - return Ok(Signature { - text: pprust::path_to_string(self), - defs: vec![], - refs: vec![], - }); + return Ok(Signature { text: path_to_string(self), defs: vec![], refs: vec![] }); } Res::Def(DefKind::AssocConst | DefKind::Variant | DefKind::Ctor(..), _) => { let len = self.segments.len(); @@ -570,13 +573,13 @@ impl Sig for ast::Path { // FIXME: really we should descend into the generics here and add SigElements for // them. // FIXME: would be nice to have a def for the first path segment. - let seg1 = pprust::path_segment_to_string(&self.segments[len - 2]); - let seg2 = pprust::path_segment_to_string(&self.segments[len - 1]); + let seg1 = path_segment_to_string(&self.segments[len - 2]); + let seg2 = path_segment_to_string(&self.segments[len - 1]); let start = offset + seg1.len() + 2; (format!("{}::{}", seg1, seg2), start, start + seg2.len()) } _ => { - let name = pprust::path_segment_to_string(self.segments.last().ok_or("Bad path")?); + let name = path_segment_to_string(self.segments.last().ok_or("Bad path")?); let end = offset + name.len(); (name, offset, end) } @@ -588,8 +591,13 @@ impl Sig for ast::Path { } // This does not cover the where clause, which must be processed separately. -impl Sig for ast::Generics { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { +impl<'hir> Sig for hir::Generics<'hir> { + fn make( + &self, + offset: usize, + _parent_id: Option, + scx: &SaveContext<'_, '_>, + ) -> Result { if self.params.is_empty() { return Ok(text_sig(String::new())); } @@ -597,30 +605,30 @@ impl Sig for ast::Generics { let mut text = "<".to_owned(); let mut defs = Vec::with_capacity(self.params.len()); - for param in &self.params { + for param in self.params { let mut param_text = String::new(); - if let ast::GenericParamKind::Const { .. } = param.kind { + if let hir::GenericParamKind::Const { .. } = param.kind { param_text.push_str("const "); } - param_text.push_str(¶m.ident.as_str()); + param_text.push_str(¶m.name.ident().as_str()); defs.push(SigElement { - id: id_from_node_id(param.id, scx), + id: id_from_hir_id(param.hir_id, scx), start: offset + text.len(), end: offset + text.len() + param_text.as_str().len(), }); - if let ast::GenericParamKind::Const { ref ty } = param.kind { + if let hir::GenericParamKind::Const { ref ty } = param.kind { param_text.push_str(": "); - param_text.push_str(&pprust::ty_to_string(&ty)); + param_text.push_str(&ty_to_string(&ty)); } if !param.bounds.is_empty() { param_text.push_str(": "); match param.kind { - ast::GenericParamKind::Lifetime { .. } => { + hir::GenericParamKind::Lifetime { .. } => { let bounds = param .bounds .iter() .map(|bound| match bound { - ast::GenericBound::Outlives(lt) => lt.ident.to_string(), + hir::GenericBound::Outlives(lt) => lt.name.ident().to_string(), _ => panic!(), }) .collect::>() @@ -628,11 +636,11 @@ impl Sig for ast::Generics { param_text.push_str(&bounds); // FIXME add lifetime bounds refs. } - ast::GenericParamKind::Type { .. } => { - param_text.push_str(&pprust::bounds_to_string(¶m.bounds)); + hir::GenericParamKind::Type { .. } => { + param_text.push_str(&bounds_to_string(param.bounds)); // FIXME descend properly into bounds. } - ast::GenericParamKind::Const { .. } => { + hir::GenericParamKind::Const { .. } => { // Const generics cannot contain bounds. } } @@ -646,21 +654,24 @@ impl Sig for ast::Generics { } } -impl Sig for ast::StructField { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { +impl<'hir> Sig for hir::StructField<'hir> { + fn make( + &self, + offset: usize, + _parent_id: Option, + scx: &SaveContext<'_, '_>, + ) -> Result { let mut text = String::new(); - let mut defs = None; - if let Some(ident) = self.ident { - text.push_str(&ident.to_string()); - defs = Some(SigElement { - id: id_from_node_id(self.id, scx), - start: offset, - end: offset + text.len(), - }); - text.push_str(": "); - } - let mut ty_sig = self.ty.make(offset + text.len(), Some(self.id), scx)?; + text.push_str(&self.ident.to_string()); + let defs = Some(SigElement { + id: id_from_hir_id(self.hir_id, scx), + start: offset, + end: offset + text.len(), + }); + text.push_str(": "); + + let mut ty_sig = self.ty.make(offset + text.len(), Some(self.hir_id), scx)?; text.push_str(&ty_sig.text); ty_sig.text = text; ty_sig.defs.extend(defs.into_iter()); @@ -668,14 +679,19 @@ impl Sig for ast::StructField { } } -impl Sig for ast::Variant { - fn make(&self, offset: usize, parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { +impl<'hir> Sig for hir::Variant<'hir> { + fn make( + &self, + offset: usize, + parent_id: Option, + scx: &SaveContext<'_, '_>, + ) -> Result { let mut text = self.ident.to_string(); match self.data { - ast::VariantData::Struct(ref fields, r) => { + hir::VariantData::Struct(fields, r) => { let id = parent_id.unwrap(); let name_def = SigElement { - id: id_from_node_id(id, scx), + id: id_from_hir_id(id, scx), start: offset, end: offset + text.len(), }; @@ -696,9 +712,9 @@ impl Sig for ast::Variant { text.push('}'); Ok(Signature { text, defs, refs }) } - ast::VariantData::Tuple(ref fields, id) => { + hir::VariantData::Tuple(fields, id) => { let name_def = SigElement { - id: id_from_node_id(id, scx), + id: id_from_hir_id(id, scx), start: offset, end: offset + text.len(), }; @@ -715,9 +731,9 @@ impl Sig for ast::Variant { text.push(')'); Ok(Signature { text, defs, refs }) } - ast::VariantData::Unit(id) => { + hir::VariantData::Unit(id) => { let name_def = SigElement { - id: id_from_node_id(id, scx), + id: id_from_hir_id(id, scx), start: offset, end: offset + text.len(), }; @@ -727,23 +743,26 @@ impl Sig for ast::Variant { } } -impl Sig for ast::ForeignItem { - fn make(&self, offset: usize, _parent_id: Option, scx: &SaveContext<'_, '_>) -> Result { - let id = Some(self.id); +impl<'hir> Sig for hir::ForeignItem<'hir> { + fn make( + &self, + offset: usize, + _parent_id: Option, + scx: &SaveContext<'_, '_>, + ) -> Result { + let id = Some(self.hir_id); match self.kind { - ast::ForeignItemKind::Fn(_, ref sig, ref generics, _) => { - let decl = &sig.decl; + hir::ForeignItemKind::Fn(decl, _, ref generics) => { let mut text = String::new(); text.push_str("fn "); - let mut sig = name_and_generics(text, offset, generics, self.id, self.ident, scx)?; + let mut sig = + name_and_generics(text, offset, generics, self.hir_id, self.ident, scx)?; sig.text.push('('); - for i in &decl.inputs { - // FIXME should descend into patterns to add defs. - sig.text.push_str(&pprust::pat_to_string(&i.pat)); + for i in decl.inputs { sig.text.push_str(": "); - let nested = i.ty.make(offset + sig.text.len(), Some(i.id), scx)?; + let nested = i.make(offset + sig.text.len(), Some(i.hir_id), scx)?; sig.text.push_str(&nested.text); sig.text.push(','); sig.defs.extend(nested.defs.into_iter()); @@ -751,7 +770,7 @@ impl Sig for ast::ForeignItem { } sig.text.push(')'); - if let ast::FnRetTy::Ty(ref t) = decl.output { + if let hir::FnRetTy::Return(ref t) = decl.output { sig.text.push_str(" -> "); let nested = t.make(offset + sig.text.len(), None, scx)?; sig.text.push_str(&nested.text); @@ -762,14 +781,14 @@ impl Sig for ast::ForeignItem { Ok(sig) } - ast::ForeignItemKind::Static(ref ty, m, _) => { + hir::ForeignItemKind::Static(ref ty, m) => { let mut text = "static ".to_owned(); - if m == ast::Mutability::Mut { + if m == Mutability::Mut { text.push_str("mut "); } let name = self.ident.to_string(); let defs = vec![SigElement { - id: id_from_node_id(self.id, scx), + id: id_from_hir_id(self.hir_id, scx), start: offset + text.len(), end: offset + text.len() + name.len(), }]; @@ -781,11 +800,11 @@ impl Sig for ast::ForeignItem { Ok(extend_sig(ty_sig, text, defs, vec![])) } - ast::ForeignItemKind::TyAlias(..) => { + hir::ForeignItemKind::Type => { let mut text = "type ".to_owned(); let name = self.ident.to_string(); let defs = vec![SigElement { - id: id_from_node_id(self.id, scx), + id: id_from_hir_id(self.hir_id, scx), start: offset + text.len(), end: offset + text.len() + name.len(), }]; @@ -794,7 +813,6 @@ impl Sig for ast::ForeignItem { Ok(Signature { text, defs, refs: vec![] }) } - ast::ForeignItemKind::MacCall(..) => Err("macro"), } } } @@ -802,14 +820,14 @@ impl Sig for ast::ForeignItem { fn name_and_generics( mut text: String, offset: usize, - generics: &ast::Generics, - id: NodeId, + generics: &hir::Generics<'_>, + id: hir::HirId, name: Ident, scx: &SaveContext<'_, '_>, ) -> Result { let name = name.to_string(); let def = SigElement { - id: id_from_node_id(id, scx), + id: id_from_hir_id(id, scx), start: offset + text.len(), end: offset + text.len() + name.len(), }; @@ -821,16 +839,16 @@ fn name_and_generics( } fn make_assoc_type_signature( - id: NodeId, + id: hir::HirId, ident: Ident, - bounds: Option<&ast::GenericBounds>, - default: Option<&ast::Ty>, + bounds: Option>, + default: Option<&hir::Ty<'_>>, scx: &SaveContext<'_, '_>, ) -> Result { let mut text = "type ".to_owned(); let name = ident.to_string(); let mut defs = vec![SigElement { - id: id_from_node_id(id, scx), + id: id_from_hir_id(id, scx), start: text.len(), end: text.len() + name.len(), }]; @@ -839,7 +857,7 @@ fn make_assoc_type_signature( if let Some(bounds) = bounds { text.push_str(": "); // FIXME should descend into bounds - text.push_str(&pprust::bounds_to_string(bounds)); + text.push_str(&bounds_to_string(bounds)); } if let Some(default) = default { text.push_str(" = "); @@ -853,16 +871,16 @@ fn make_assoc_type_signature( } fn make_assoc_const_signature( - id: NodeId, + id: hir::HirId, ident: Symbol, - ty: &ast::Ty, - default: Option<&ast::Expr>, + ty: &hir::Ty<'_>, + default: Option<&hir::Expr<'_>>, scx: &SaveContext<'_, '_>, ) -> Result { let mut text = "const ".to_owned(); let name = ident.to_string(); let mut defs = vec![SigElement { - id: id_from_node_id(id, scx), + id: id_from_hir_id(id, scx), start: text.len(), end: text.len() + name.len(), }]; @@ -877,41 +895,38 @@ fn make_assoc_const_signature( if let Some(default) = default { text.push_str(" = "); - text.push_str(&pprust::expr_to_string(default)); + text.push_str(&id_to_string(&scx.tcx.hir(), default.hir_id)); } text.push(';'); Ok(Signature { text, defs, refs }) } fn make_method_signature( - id: NodeId, + id: hir::HirId, ident: Ident, - generics: &ast::Generics, - m: &ast::FnSig, + generics: &hir::Generics<'_>, + m: &hir::FnSig<'_>, scx: &SaveContext<'_, '_>, ) -> Result { // FIXME code dup with function signature let mut text = String::new(); - if let ast::Const::Yes(_) = m.header.constness { + if let hir::Constness::Const = m.header.constness { text.push_str("const "); } - if m.header.asyncness.is_async() { + if hir::IsAsync::Async == m.header.asyncness { text.push_str("async "); } - if let ast::Unsafe::Yes(_) = m.header.unsafety { + if let hir::Unsafety::Unsafe = m.header.unsafety { text.push_str("unsafe "); } - push_extern(&mut text, m.header.ext); text.push_str("fn "); let mut sig = name_and_generics(text, 0, generics, id, ident, scx)?; sig.text.push('('); - for i in &m.decl.inputs { - // FIXME should descend into patterns to add defs. - sig.text.push_str(&pprust::pat_to_string(&i.pat)); + for i in m.decl.inputs { sig.text.push_str(": "); - let nested = i.ty.make(sig.text.len(), Some(i.id), scx)?; + let nested = i.make(sig.text.len(), Some(i.hir_id), scx)?; sig.text.push_str(&nested.text); sig.text.push(','); sig.defs.extend(nested.defs.into_iter()); @@ -919,7 +934,7 @@ fn make_method_signature( } sig.text.push(')'); - if let ast::FnRetTy::Ty(ref t) = m.decl.output { + if let hir::FnRetTy::Return(ref t) = m.decl.output { sig.text.push_str(" -> "); let nested = t.make(sig.text.len(), None, scx)?; sig.text.push_str(&nested.text); diff --git a/src/tools/rls b/src/tools/rls index 085f24b9ecbc0..8d7a7167c15b9 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 085f24b9ecbc0e90d204cab1c111c4abe4608ce0 +Subproject commit 8d7a7167c15b9154755588c39b22b2336c89ca68