diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 23004d8035c64..1ac0d3946386a 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1861,6 +1861,7 @@ impl<'a> LoweringContext<'a> { let def = self.expect_full_def(segment.id); hir::PathSegment::new( segment.ident, + Some(segment.id), Some(def), generic_args, infer_types, diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index bd12a5e0cb4d8..7e5dd3f3756f7 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -392,6 +392,13 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> { }); } + fn visit_path_segment(&mut self, path_span: Span, path_segment: &'hir PathSegment) { + if let Some(id) = path_segment.id { + self.insert(id, Node::PathSegment(path_segment)); + } + intravisit::walk_path_segment(self, path_span, path_segment); + } + fn visit_ty(&mut self, ty: &'hir Ty) { self.insert(ty.id, Node::Ty(ty)); diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index f5f9bcd3b5ea5..d89bb5db12f26 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -204,7 +204,7 @@ impl<'hir> Map<'hir> { if let Some(entry) = self.map[id.as_usize()] { self.dep_graph.read_index(entry.dep_node); } else { - bug!("called `HirMap::read()` with invalid `NodeId`") + bug!("called `HirMap::read()` with invalid `NodeId`: {:?}", id) } } @@ -344,6 +344,7 @@ impl<'hir> Map<'hir> { Node::AnonConst(_) | Node::Expr(_) | Node::Stmt(_) | + Node::PathSegment(_) | Node::Ty(_) | Node::TraitRef(_) | Node::Pat(_) | @@ -884,6 +885,7 @@ impl<'hir> Map<'hir> { Some(Node::AnonConst(constant)) => self.body(constant.body).value.span, Some(Node::Expr(expr)) => expr.span, Some(Node::Stmt(stmt)) => stmt.span, + Some(Node::PathSegment(seg)) => seg.ident.span, Some(Node::Ty(ty)) => ty.span, Some(Node::TraitRef(tr)) => tr.path.span, Some(Node::Binding(pat)) => pat.span, @@ -1098,6 +1100,7 @@ impl<'a> print::State<'a> { Node::AnonConst(a) => self.print_anon_const(&a), Node::Expr(a) => self.print_expr(&a), Node::Stmt(a) => self.print_stmt(&a), + Node::PathSegment(_) => bug!("cannot print PathSegment"), Node::Ty(a) => self.print_type(&a), Node::TraitRef(a) => self.print_trait_ref(&a), Node::Binding(a) | @@ -1215,6 +1218,9 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String { Some(Node::Stmt(_)) => { format!("stmt {}{}", map.node_to_pretty_string(id), id_str) } + Some(Node::PathSegment(_)) => { + format!("path segment {}{}", map.node_to_pretty_string(id), id_str) + } Some(Node::Ty(_)) => { format!("type {}{}", map.node_to_pretty_string(id), id_str) } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index e3c8f1eadf198..c72a4a6dfc2b2 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -347,6 +347,7 @@ impl fmt::Display for Path { pub struct PathSegment { /// The identifier portion of this path segment. pub ident: Ident, + pub id: Option, pub def: Option, /// Type/lifetime parameters attached to this path. They come in @@ -368,15 +369,23 @@ impl PathSegment { pub fn from_ident(ident: Ident) -> PathSegment { PathSegment { ident, + id: None, def: None, infer_types: true, args: None, } } - pub fn new(ident: Ident, def: Option, args: GenericArgs, infer_types: bool) -> Self { + pub fn new( + ident: Ident, + id: Option, + def: Option, + args: GenericArgs, + infer_types: bool, + ) -> Self { PathSegment { ident, + id, def, infer_types, args: if args.is_empty() { @@ -2514,6 +2523,7 @@ pub enum Node<'hir> { AnonConst(&'hir AnonConst), Expr(&'hir Expr), Stmt(&'hir Stmt), + PathSegment(&'hir PathSegment), Ty(&'hir Ty), TraitRef(&'hir TraitRef), Binding(&'hir Pat), diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index f30cb365eb7f4..b220634d0d903 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -174,6 +174,7 @@ impl_stable_hash_for!(struct hir::Path { impl_stable_hash_for!(struct hir::PathSegment { ident -> (ident.name), + id, def, infer_types, args diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3164f3a83f04f..cdb6e9a23182c 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -392,18 +392,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> { e.emit(); } - for &(ref tree, id) in items { - let prefix = ast::Path { - segments: module_path.iter() - .map(|ident| { - let mut seg = ast::PathSegment::from_ident(ident.0); - seg.id = self.session.next_node_id(); - seg - }) - .collect(), - span: path.span, - }; + let prefix = ast::Path { + segments: module_path.into_iter() + .map(|(ident, id)| { + let mut seg = ast::PathSegment::from_ident(ident); + seg.id = id.expect("Missing node id"); + seg + }) + .collect(), + span: path.span, + }; + for &(ref tree, id) in items { self.build_reduced_graph_for_use_tree( root_use_tree, root_id, diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 96ebd82df3a32..4eb40320c4abb 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -3614,6 +3614,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { for (i, &(ident, id)) in path.iter().enumerate() { debug!("resolve_path ident {} {:?}", i, ident); + let is_last = i == path.len() - 1; let ns = if is_last { opt_ns.unwrap_or(TypeNS) } else { TypeNS }; let name = ident.name; @@ -3713,10 +3714,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let maybe_assoc = opt_ns != Some(MacroNS) && PathSource::Type.is_expected(def); if let Some(next_module) = binding.module() { module = Some(ModuleOrUniformRoot::Module(next_module)); - if !is_last && record_used { + if record_used { if let Some(id) = id { - assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id"); - self.record_def(id, PathResolution::new(def)); + if !self.def_map.contains_key(&id) { + assert!(id != ast::DUMMY_NODE_ID, "Trying to resolve dummy id"); + self.record_def(id, PathResolution::new(def)); + } } } } else if def == Def::ToolMod && i + 1 != path.len() { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 49b871e767783..7ba1783400664 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -812,9 +812,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { variant: &'l ty::VariantDef, base: &'l Option>, ) { - self.write_sub_paths_truncated(path); - if let Some(struct_lit_data) = self.save_ctxt.get_expr_data(ex) { + 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); @@ -1232,8 +1231,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { value: String::new(), parent, }); + self.write_sub_paths_truncated(&path); } - self.write_sub_paths_truncated(&path); } ast::UseTreeKind::Glob => { let path = ast::Path { @@ -1268,8 +1267,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { value: names.join(", "), parent, }); + self.write_sub_paths(&path); } - self.write_sub_paths(&path); } ast::UseTreeKind::Nested(ref nested_items) => { let prefix = ast::Path { diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c4777393a9897..23eab3e15f643 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -632,6 +632,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Node::Visibility(&Spanned { node: hir::VisibilityKind::Restricted { ref path, .. }, .. }) => path.def, + Node::PathSegment(seg) => match seg.def { + Some(def) => def, + None => HirDef::Err, + }, Node::Expr(&hir::Expr { node: hir::ExprKind::Struct(ref qpath, ..), ..