From fc67d8fac48d48bcdeaab1c8e0a2770e0f246247 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Fri, 31 Aug 2018 12:01:26 +1200 Subject: [PATCH 01/10] Give each PathSegment a NodeId --- src/libsyntax/ast.rs | 10 ++++++++-- src/libsyntax/ext/build.rs | 8 ++++++-- src/libsyntax/fold.rs | 4 +++- src/libsyntax/parse/parser.rs | 4 ++-- 4 files changed, 19 insertions(+), 7 deletions(-) diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 9ed628e2ed337..7548c2988547b 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -129,6 +129,8 @@ pub struct PathSegment { /// The identifier portion of this path segment. pub ident: Ident, + pub id: NodeId, + /// Type/lifetime parameters attached to this path. They come in /// two flavors: `Path` and `Path(A,B) -> C`. /// `None` means that no parameter list is supplied (`Path`), @@ -140,10 +142,14 @@ pub struct PathSegment { impl PathSegment { pub fn from_ident(ident: Ident) -> Self { - PathSegment { ident, args: None } + PathSegment { ident, id: DUMMY_NODE_ID, args: None } } pub fn crate_root(span: Span) -> Self { - PathSegment::from_ident(Ident::new(keywords::CrateRoot.name(), span)) + PathSegment { + ident: Ident::new(keywords::CrateRoot.name(), span), + id: CRATE_NODE_ID, + args: None, + } } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 6210003a40da4..7928ec1606b1d 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -329,7 +329,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } else { None }; - segments.push(ast::PathSegment { ident: last_ident.with_span_pos(span), args }); + segments.push(ast::PathSegment { + ident: last_ident.with_span_pos(span), + id: ast::DUMMY_NODE_ID, + args, + }); let mut path = ast::Path { span, segments }; if global { if let Some(seg) = path.make_root() { @@ -366,7 +370,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } else { None }; - path.segments.push(ast::PathSegment { ident, args }); + path.segments.push(ast::PathSegment { ident, id: ast::DUMMY_NODE_ID, args }); (ast::QSelf { ty: self_type, diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index 18d5970462f63..bec193548e176 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -468,8 +468,9 @@ pub fn noop_fold_usize(i: usize, _: &mut T) -> usize { pub fn noop_fold_path(Path { segments, span }: Path, fld: &mut T) -> Path { Path { - segments: segments.move_map(|PathSegment { ident, args }| PathSegment { + segments: segments.move_map(|PathSegment { ident, id, args }| PathSegment { ident: fld.fold_ident(ident), + id: fld.new_id(id), args: args.map(|args| args.map(|args| fld.fold_generic_args(args))), }), span: fld.new_span(span) @@ -1234,6 +1235,7 @@ pub fn noop_fold_expr(Expr {id, node, span, attrs}: Expr, folder: &mu ExprKind::MethodCall( PathSegment { ident: folder.fold_ident(seg.ident), + id: folder.new_id(seg.id), args: seg.args.map(|args| { args.map(|args| folder.fold_generic_args(args)) }), diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 9c47589a0bd27..619a53e1c7c95 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2134,10 +2134,10 @@ impl<'a> Parser<'a> { ParenthesisedArgs { inputs, output, span }.into() }; - PathSegment { ident, args } + PathSegment { ident, args, id: ast::DUMMY_NODE_ID } } else { // Generic arguments are not found. - PathSegment::from_ident(ident) + PathSegment::from_ident(ident,) }) } From b49da276b307a58c7b3e5d5332fa32bccfb32f77 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 6 Sep 2018 19:24:33 +1200 Subject: [PATCH 02/10] Store a resolved def on hir::PathSegment --- src/librustc/hir/lowering.rs | 14 +- src/librustc/hir/mod.rs | 5 +- src/librustc/ich/impls_hir.rs | 1 + src/librustc_resolve/build_reduced_graph.rs | 51 +++--- src/librustc_resolve/lib.rs | 171 ++++++++++++-------- src/librustc_resolve/macros.rs | 24 ++- src/librustc_resolve/resolve_imports.rs | 25 +-- src/libsyntax/ast.rs | 2 +- 8 files changed, 182 insertions(+), 111 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index afb5f23db5b83..23004d8035c64 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -143,8 +143,13 @@ pub struct LoweringContext<'a> { } pub trait Resolver { - /// Resolve a hir path generated by the lowerer when expanding `for`, `if let`, etc. - fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool); + /// Resolve a path generated by the lowerer when expanding `for`, `if let`, etc. + fn resolve_hir_path( + &mut self, + path: &ast::Path, + args: Option>, + is_value: bool, + ) -> hir::Path; /// Obtain the resolution for a node id fn get_resolution(&mut self, id: NodeId) -> Option; @@ -163,7 +168,7 @@ pub trait Resolver { span: Span, crate_root: Option<&str>, components: &[&str], - params: Option>, + args: Option>, is_value: bool, ) -> hir::Path; } @@ -1380,6 +1385,7 @@ impl<'a> LoweringContext<'a> { // does not actually exist in the AST. lctx.items.insert(exist_ty_id.node_id, exist_ty_item); + let def = Def::Existential(DefId::local(exist_ty_def_index)); // `impl Trait` now just becomes `Foo<'a, 'b, ..>` hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes) }) @@ -1852,8 +1858,10 @@ impl<'a> LoweringContext<'a> { } } + let def = self.expect_full_def(segment.id); hir::PathSegment::new( segment.ident, + Some(def), generic_args, infer_types, ) diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index d5de6197a2e48..e3c8f1eadf198 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 def: Option, /// Type/lifetime parameters attached to this path. They come in /// two flavors: `Path` and `Path(A,B) -> C`. Note that @@ -367,14 +368,16 @@ impl PathSegment { pub fn from_ident(ident: Ident) -> PathSegment { PathSegment { ident, + def: None, infer_types: true, args: None, } } - pub fn new(ident: Ident, args: GenericArgs, infer_types: bool) -> Self { + pub fn new(ident: Ident, def: Option, args: GenericArgs, infer_types: bool) -> Self { PathSegment { ident, + def, infer_types, args: if args.is_empty() { None diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index a48bd4eeb09a3..f30cb365eb7f4 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), + def, infer_types, args }); diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index aa7bfeae5f48b..3164f3a83f04f 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -141,7 +141,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let prefix_iter = || parent_prefix.iter().cloned() .chain(use_tree.prefix.segments.iter().map(|seg| seg.ident)); let prefix_start = prefix_iter().next(); - let starts_with_non_keyword = prefix_start.map_or(false, |ident| { + let starts_with_non_keyword = prefix_start.map_or(false, |(ident, _)| { !ident.is_path_segment_keyword() }); @@ -202,13 +202,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let source = prefix_start.unwrap(); // Helper closure to emit a canary with the given base path. - let emit = |this: &mut Self, base: Option| { + let emit = |this: &mut Self, base: Option<(Ident, Option)>| { let subclass = SingleImport { target: Ident { name: keywords::Underscore.name().gensymed(), - span: source.span, + span: source.0.span, }, - source, + source: source.0, result: PerNS { type_ns: Cell::new(Err(Undetermined)), value_ns: Cell::new(Err(Undetermined)), @@ -219,7 +219,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { this.add_import_directive( base.into_iter().collect(), subclass.clone(), - source.span, + source.0.span, id, root_use_tree.span, root_id, @@ -230,15 +230,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }; // A single simple `self::x` canary. - emit(self, Some(Ident { + emit(self, Some((Ident { name: keywords::SelfValue.name(), - span: source.span, - })); + span: source.0.span, + }, source.1))); // One special unprefixed canary per block scope around // the import, to detect items unreachable by `self::x`. let orig_current_module = self.current_module; - let mut span = source.span.modern(); + let mut span = source.0.span.modern(); loop { match self.current_module.kind { ModuleKind::Block(..) => emit(self, None), @@ -265,10 +265,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if nested { // Correctly handle `self` - if source.name == keywords::SelfValue.name() { + if source.0.name == keywords::SelfValue.name() { type_ns_only = true; - let empty_prefix = module_path.last().map_or(true, |ident| { + let empty_prefix = module_path.last().map_or(true, |(ident, _)| { ident.name == keywords::CrateRoot.name() }); if empty_prefix { @@ -284,20 +284,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Replace `use foo::self;` with `use foo;` source = module_path.pop().unwrap(); if rename.is_none() { - ident = source; + ident = source.0; } } } else { // Disallow `self` - if source.name == keywords::SelfValue.name() { + if source.0.name == keywords::SelfValue.name() { resolve_error(self, use_tree.span, ResolutionError::SelfImportsOnlyAllowedWithin); } // Disallow `use $crate;` - if source.name == keywords::DollarCrate.name() && module_path.is_empty() { - let crate_root = self.resolve_crate_root(source); + if source.0.name == keywords::DollarCrate.name() && module_path.is_empty() { + let crate_root = self.resolve_crate_root(source.0); let crate_name = match crate_root.kind { ModuleKind::Def(_, name) => name, ModuleKind::Block(..) => unreachable!(), @@ -307,11 +307,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // while the current crate doesn't have a valid `crate_name`. if crate_name != keywords::Invalid.name() { // `crate_name` should not be interpreted as relative. - module_path.push(Ident { + module_path.push((Ident { name: keywords::CrateRoot.name(), - span: source.span, - }); - source.name = crate_name; + span: source.0.span, + }, Some(self.session.next_node_id()))); + source.0.name = crate_name; } if rename.is_none() { ident.name = crate_name; @@ -332,7 +332,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let subclass = SingleImport { target: ident, - source, + source: source.0, result: PerNS { type_ns: Cell::new(Err(Undetermined)), value_ns: Cell::new(Err(Undetermined)), @@ -393,6 +393,17 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } 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, + }; + 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 2c21067bd58c8..96ebd82df3a32 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1534,8 +1534,13 @@ impl<'a, 'b: 'a, 'cl: 'b> ty::DefIdTree for &'a Resolver<'b, 'cl> { /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that /// the resolver is no longer needed as all the relevant information is inline. impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> { - fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) { - self.resolve_hir_path_cb(path, is_value, + fn resolve_hir_path( + &mut self, + path: &ast::Path, + args: Option>, + is_value: bool, + ) -> hir::Path { + self.resolve_hir_path_cb(path, args, is_value, |resolver, span, error| resolve_error(resolver, span, error)) } @@ -1547,30 +1552,20 @@ impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> { args: Option>, is_value: bool ) -> hir::Path { - let mut segments = iter::once(keywords::CrateRoot.ident()) + let segments = iter::once(keywords::CrateRoot.ident()) .chain( crate_root.into_iter() .chain(components.iter().cloned()) .map(Ident::from_str) - ).map(hir::PathSegment::from_ident).collect::>(); + ).map(|i| self.new_ast_path_segment(i)).collect::>(); - if let Some(args) = args { - let ident = segments.last().unwrap().ident; - *segments.last_mut().unwrap() = hir::PathSegment { - ident, - args: Some(args), - infer_types: true, - }; - } - let mut path = hir::Path { + let path = ast::Path { span, - def: Def::Err, - segments: segments.into(), + segments, }; - self.resolve_hir_path(&mut path, is_value); - path + self.resolve_hir_path(&path, args, is_value) } fn get_resolution(&mut self, id: NodeId) -> Option { @@ -1596,23 +1591,27 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { use std::iter; let mut errored = false; - let mut path = if path_str.starts_with("::") { - hir::Path { + let path = if path_str.starts_with("::") { + ast::Path { span, - def: Def::Err, - segments: iter::once(keywords::CrateRoot.ident()).chain({ - path_str.split("::").skip(1).map(Ident::from_str) - }).map(hir::PathSegment::from_ident).collect(), + segments: iter::once(keywords::CrateRoot.ident()) + .chain({ + path_str.split("::").skip(1).map(Ident::from_str) + }) + .map(|i| self.new_ast_path_segment(i)) + .collect(), } } else { - hir::Path { + ast::Path { span, - def: Def::Err, - segments: path_str.split("::").map(Ident::from_str) - .map(hir::PathSegment::from_ident).collect(), + segments: path_str + .split("::") + .map(Ident::from_str) + .map(|i| self.new_ast_path_segment(i)) + .collect(), } }; - self.resolve_hir_path_cb(&mut path, is_value, |_, _, _| errored = true); + let path = self.resolve_hir_path_cb(&path, None, is_value, |_, _, _| errored = true); if errored || path.def == Def::Err { Err(()) } else { @@ -1621,16 +1620,23 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { } /// resolve_hir_path, but takes a callback in case there was an error - fn resolve_hir_path_cb(&mut self, path: &mut hir::Path, is_value: bool, error_callback: F) + fn resolve_hir_path_cb( + &mut self, + path: &ast::Path, + args: Option>, + is_value: bool, + error_callback: F, + ) -> hir::Path where F: for<'c, 'b> FnOnce(&'c mut Resolver, Span, ResolutionError<'b>) { let namespace = if is_value { ValueNS } else { TypeNS }; - let hir::Path { ref segments, span, ref mut def } = *path; - let path: Vec<_> = segments.iter().map(|seg| seg.ident).collect(); + let span = path.span; + let segments = &path.segments; + let path: Vec<_> = segments.iter().map(|seg| (seg.ident, Some(seg.id))).collect(); // FIXME (Manishearth): Intra doc links won't get warned of epoch changes - match self.resolve_path(None, &path, Some(namespace), true, span, CrateLint::No) { + let def = match self.resolve_path(None, &path, Some(namespace), true, span, CrateLint::No) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => - *def = module.def().unwrap(), + module.def().unwrap(), PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => *def = path_res.base_def(), PathResult::NonModule(..) => @@ -1648,9 +1654,28 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { PathResult::Indeterminate => unreachable!(), PathResult::Failed(span, msg, _) => { error_callback(self, span, ResolutionError::FailedToResolve(&msg)); + Def::Err } + }; + + let mut segments: Vec<_> = segments.iter().map(|seg| { + let mut hir_seg = hir::PathSegment::from_ident(seg.ident); + hir_seg.def = Some(self.def_map.get(&seg.id).map_or(Def::Err, |p| p.base_def())); + hir_seg + }).collect(); + segments.last_mut().unwrap().args = args; + hir::Path { + span, + def, + segments: segments.into(), } } + + fn new_ast_path_segment(&self, ident: Ident) -> ast::PathSegment { + let mut seg = ast::PathSegment::from_ident(ident); + seg.id = self.session.next_node_id(); + seg + } } impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { @@ -2458,7 +2483,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let mut new_id = None; if let Some(trait_ref) = opt_trait_ref { let path: Vec<_> = trait_ref.path.segments.iter() - .map(|seg| seg.ident) + .map(|seg| (seg.ident, Some(seg.id))) .collect(); let def = self.smart_resolve_path_fragment( trait_ref.ref_id, @@ -2956,7 +2981,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { crate_lint: CrateLint ) -> PathResolution { let segments = &path.segments.iter() - .map(|seg| seg.ident) + .map(|seg| (seg.ident, Some(seg.id))) .collect::>(); self.smart_resolve_path_fragment(id, qself, segments, path.span, source, crate_lint) } @@ -2964,12 +2989,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn smart_resolve_path_fragment(&mut self, id: NodeId, qself: Option<&QSelf>, - path: &[Ident], + path: &[(Ident, Option)], span: Span, source: PathSource, crate_lint: CrateLint) -> PathResolution { - let ident_span = path.last().map_or(span, |ident| ident.span); + let ident_span = path.last().map_or(span, |ident| ident.0.span); let ns = source.namespace(); let is_expected = &|def| source.is_expected(def); let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false }; @@ -2979,17 +3004,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // Make the base error. let expected = source.descr_expected(); let path_str = names_to_string(path); - let item_str = path.last().unwrap(); + let item_str = path.last().unwrap().0; let code = source.error_code(def.is_some()); let (base_msg, fallback_label, base_span) = if let Some(def) = def { (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), format!("not a {}", expected), span) } else { - let item_span = path.last().unwrap().span; + let item_span = path.last().unwrap().0.span; let (mod_prefix, mod_str) = if path.len() == 1 { (String::new(), "this scope".to_string()) - } else if path.len() == 2 && path[0].name == keywords::CrateRoot.name() { + } else if path.len() == 2 && path[0].0.name == keywords::CrateRoot.name() { (String::new(), "the crate root".to_string()) } else { let mod_path = &path[..path.len() - 1]; @@ -2999,7 +3024,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { module.def(), _ => None, }.map_or(String::new(), |def| format!("{} ", def.kind_name())); - (mod_prefix, format!("`{}`", names_to_string(mod_path))) + (mod_prefix, format!("`{}`", names_and_ids_to_string(mod_path))) }; (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), format!("not found in {}", mod_str), @@ -3045,7 +3070,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } // Try to lookup the name in more relaxed fashion for better error reporting. - let ident = *path.last().unwrap(); + let ident = path.last().unwrap().0; let candidates = this.lookup_import_candidates(ident.name, ns, is_expected); if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) { let enum_candidates = @@ -3072,7 +3097,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } if path.len() == 1 && this.self_type_is_available(span) { if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) { - let self_is_available = this.self_value_is_available(path[0].span, span); + let self_is_available = this.self_value_is_available(path[0].0.span, span); match candidate { AssocSuggestion::Field => { err.span_suggestion_with_applicability( @@ -3307,7 +3332,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // or `::A::B`. If `B` should be resolved in value namespace then // it needs to be added to the trait map. if ns == ValueNS { - let item_name = *path.last().unwrap(); + let item_name = path.last().unwrap().0; let traits = self.get_traits_containing_item(item_name, ns); self.trait_map.insert(id, traits); } @@ -3377,7 +3402,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_qpath_anywhere(&mut self, id: NodeId, qself: Option<&QSelf>, - path: &[Ident], + path: &[(Ident, Option)], primary_ns: Namespace, span: Span, defer_to_typeck: bool, @@ -3399,10 +3424,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } if primary_ns != MacroNS && - (self.macro_names.contains(&path[0].modern()) || - self.builtin_macros.get(&path[0].name).cloned() + (self.macro_names.contains(&path[0].0.modern()) || + self.builtin_macros.get(&path[0].0.name).cloned() .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang) || - self.macro_use_prelude.get(&path[0].name).cloned() + self.macro_use_prelude.get(&path[0].0.name).cloned() .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang)) { // Return some dummy definition, it's enough for error reporting. return Some( @@ -3416,7 +3441,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_qpath(&mut self, id: NodeId, qself: Option<&QSelf>, - path: &[Ident], + path: &[(Ident, Option)], ns: Namespace, span: Span, global_by_default: bool, @@ -3506,8 +3531,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { PathResult::Failed(..) if (ns == TypeNS || path.len() > 1) && self.primitive_type_table.primitive_types - .contains_key(&path[0].name) => { - let prim = self.primitive_type_table.primitive_types[&path[0].name]; + .contains_key(&path[0].0.name) => { + let prim = self.primitive_type_table.primitive_types[&path[0].0.name]; PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1) } PathResult::Module(ModuleOrUniformRoot::Module(module)) => @@ -3522,8 +3547,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { }; if path.len() > 1 && !global_by_default && result.base_def() != Def::Err && - path[0].name != keywords::CrateRoot.name() && - path[0].name != keywords::DollarCrate.name() { + path[0].0.name != keywords::CrateRoot.name() && + path[0].0.name != keywords::DollarCrate.name() { let unqualified_result = { match self.resolve_path( None, @@ -3551,7 +3576,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_path( &mut self, base_module: Option>, - path: &[Ident], + path: &[(Ident, Option)], opt_ns: Option, // `None` indicates a module path record_used: bool, path_span: Span, @@ -3587,7 +3612,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { crate_lint, ); - for (i, &ident) in path.iter().enumerate() { + 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 }; @@ -3648,7 +3673,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } else { format!("`{}`", name) }; - let msg = if i == 1 && path[0].name == keywords::CrateRoot.name() { + let msg = if i == 1 && path[0].0.name == keywords::CrateRoot.name() { format!("global paths cannot start with {}", name_str) } else { format!("{} in paths can only be used in start position", name_str) @@ -3688,6 +3713,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 let Some(id) = 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() { let def = Def::NonMacroAttr(NonMacroAttrKind::Tool); return PathResult::NonModule(PathResolution::new(def)); @@ -3737,7 +3768,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } else if i == 0 { format!("Use of undeclared type or module `{}`", ident) } else { - format!("Could not find `{}` in `{}`", ident, path[i - 1]) + format!("Could not find `{}` in `{}`", ident, path[i - 1].0) }; return PathResult::Failed(ident.span, msg, is_last); } @@ -3755,7 +3786,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn lint_if_path_starts_with_module( &self, crate_lint: CrateLint, - path: &[Ident], + path: &[(Ident, Option)], path_span: Span, second_binding: Option<&NameBinding>, ) { @@ -3772,7 +3803,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { }; let first_name = match path.get(0) { - Some(ident) => ident.name, + Some(ident) => ident.0.name, None => return, }; @@ -3784,7 +3815,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { match path.get(1) { // If this import looks like `crate::...` it's already good - Some(ident) if ident.name == keywords::Crate.name() => return, + Some((ident, _)) if ident.name == keywords::Crate.name() => return, // Otherwise go below to see if it's an extern crate Some(_) => {} // If the path has length one (and it's `CrateRoot` most likely) @@ -3977,7 +4008,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn lookup_typo_candidate(&mut self, - path: &[Ident], + path: &[(Ident, Option)], ns: Namespace, filter_fn: FilterFn, span: Span) @@ -4041,7 +4072,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } - let name = path[path.len() - 1].name; + let name = path[path.len() - 1].0.name; // Make sure error reporting is deterministic. names.sort_by_cached_key(|name| name.as_str()); match find_best_match_for_name(names.iter(), &name.as_str(), None) { @@ -4558,7 +4589,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ast::VisibilityKind::Restricted { ref path, id, .. } => { // Visibilities are resolved as global by default, add starting root segment. let segments = path.make_root().iter().chain(path.segments.iter()) - .map(|seg| seg.ident) + .map(|seg| (seg.ident, Some(seg.id))) .collect::>(); let def = self.smart_resolve_path_fragment( id, @@ -4851,12 +4882,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } -fn is_self_type(path: &[Ident], namespace: Namespace) -> bool { - namespace == TypeNS && path.len() == 1 && path[0].name == keywords::SelfType.name() +fn is_self_type(path: &[(Ident, Option)], namespace: Namespace) -> bool { + namespace == TypeNS && path.len() == 1 && path[0].0.name == keywords::SelfType.name() } -fn is_self_value(path: &[Ident], namespace: Namespace) -> bool { - namespace == ValueNS && path.len() == 1 && path[0].name == keywords::SelfValue.name() +fn is_self_value(path: &[(Ident, Option)], namespace: Namespace) -> bool { + namespace == ValueNS && path.len() == 1 && path[0].0.name == keywords::SelfValue.name() } fn names_to_string(idents: &[Ident]) -> String { @@ -4872,6 +4903,12 @@ fn names_to_string(idents: &[Ident]) -> String { result } +fn names_and_ids_to_string(segments: &[(Ident, Option)]) -> String { + names_to_string(&segments.iter() + .map(|seg| seg.0) + .collect::>()) +} + fn path_names_to_string(path: &Path) -> String { names_to_string(&path.segments.iter() .map(|seg| seg.ident) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 3345e01a929c7..f462542f1d3e0 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -462,13 +462,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { force: bool, ) -> Result { let ast::Path { ref segments, span } = *path; - let mut path: Vec<_> = segments.iter().map(|seg| seg.ident).collect(); + let mut path: Vec<_> = segments.iter().map(|seg| (seg.ident, Some(seg.id))).collect(); // Possibly apply the macro helper hack if kind == MacroKind::Bang && path.len() == 1 && - path[0].span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) { - let root = Ident::new(keywords::DollarCrate.name(), path[0].span); - path.insert(0, root); + path[0].0.span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) { + let root = Ident::new(keywords::DollarCrate.name(), path[0].0.span); + path.insert(0, (root, None)); } if path.len() > 1 { @@ -496,12 +496,16 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }; parent_scope.module.macro_resolutions.borrow_mut() - .push((path.into_boxed_slice(), span)); + .push((path + .iter() + .map(|(ident, _)| *ident) + .collect::>() + .into_boxed_slice(), span)); def } else { let binding = self.early_resolve_ident_in_lexical_scope( - path[0], MacroNS, Some(kind), parent_scope, false, force, span + path[0].0, MacroNS, Some(kind), parent_scope, false, force, span ); match binding { Ok(..) => {} @@ -510,7 +514,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } parent_scope.module.legacy_macro_resolutions.borrow_mut() - .push((path[0], kind, parent_scope.clone(), binding.ok())); + .push((path[0].0, kind, parent_scope.clone(), binding.ok())); binding.map(|binding| binding.def_ignoring_ambiguity()) } @@ -846,6 +850,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { pub fn finalize_current_module_macro_resolutions(&mut self) { let module = self.current_module; for &(ref path, span) in module.macro_resolutions.borrow().iter() { + let path = path + .iter() + .map(|ident| (*ident, None)) + .collect::)>>(); match self.resolve_path(None, &path, Some(MacroNS), true, span, CrateLint::No) { PathResult::NonModule(_) => {}, PathResult::Failed(span, msg, _) => { @@ -938,7 +946,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } }; let ident = Ident::new(Symbol::intern(name), span); - self.lookup_typo_candidate(&[ident], MacroNS, is_macro, span) + self.lookup_typo_candidate(&[(ident, None)], MacroNS, is_macro, span) }); if let Some(suggestion) = suggestion { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 6c73f1bd0f8c5..4d3a67d4a892e 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -14,7 +14,7 @@ use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; use Resolver; -use {names_to_string, module_to_string}; +use {names_to_string, names_and_ids_to_string, module_to_string}; use {resolve_error, ResolutionError}; use rustc_data_structures::ptr_key::PtrKey; @@ -89,7 +89,7 @@ pub struct ImportDirective<'a> { pub root_span: Span, pub parent: Module<'a>, - pub module_path: Vec, + pub module_path: Vec<(Ident, Option)>, /// The resolution of `module_path`. pub imported_module: Cell>>, pub subclass: ImportDirectiveSubclass<'a>, @@ -393,7 +393,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // Add an import directive to the current module. pub fn add_import_directive(&mut self, - module_path: Vec, + module_path: Vec<(Ident, Option)>, subclass: ImportDirectiveSubclass<'a>, span: Span, id: NodeId, @@ -679,7 +679,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let has_explicit_self = !import.module_path.is_empty() && - import.module_path[0].name == keywords::SelfValue.name(); + import.module_path[0].0.name == keywords::SelfValue.name(); self.per_ns(|_, ns| { if let Some(result) = result[ns].get().ok() { @@ -728,9 +728,11 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { self.throw_unresolved_import_error(empty_vec, None); } if !seen_spans.contains(&span) { - let path = import_path_to_string(&import.module_path[..], - &import.subclass, - span); + let path = import_path_to_string( + &import.module_path.iter().map(|(ident, _)| *ident).collect::>(), + &import.subclass, + span, + ); error_vec.push((span, path, err)); seen_spans.insert(span); prev_root_id = import.root_id; @@ -851,7 +853,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { /// If successful, the resolved bindings are written into the module. fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { debug!("(resolving import for module) resolving import `{}::...` in `{}`", - names_to_string(&directive.module_path[..]), + names_and_ids_to_string(&directive.module_path[..]), module_to_string(self.current_module).unwrap_or_else(|| "???".to_string())); self.current_module = directive.parent; @@ -982,7 +984,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = module_path.clone(); - full_path.push(keywords::Invalid.ident()); + full_path.push((keywords::Invalid.ident(), None)); self.lint_if_path_starts_with_module( directive.crate_lint(), &full_path, @@ -1146,7 +1148,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = module_path.clone(); - full_path.push(ident); + full_path.push((ident, None)); self.per_ns(|this, ns| { if let Ok(binding) = result[ns].get() { this.lint_if_path_starts_with_module( @@ -1288,7 +1290,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let resolutions = imported_module.parent.expect("parent should exist") .resolutions.borrow(); let enum_path_segment_index = directive.module_path.len() - 1; - let enum_ident = directive.module_path[enum_path_segment_index]; + let enum_ident = directive.module_path[enum_path_segment_index].0; let enum_resolution = resolutions.get(&(enum_ident, TypeNS)) .expect("resolution should exist"); @@ -1311,6 +1313,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { "consider making the enum public", suggestion); err.emit(); + } } } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 7548c2988547b..d33077b336b46 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -147,7 +147,7 @@ impl PathSegment { pub fn crate_root(span: Span) -> Self { PathSegment { ident: Ident::new(keywords::CrateRoot.name(), span), - id: CRATE_NODE_ID, + id: DUMMY_NODE_ID, args: None, } } From c2bb7cadf24e82b80f403c09e800fe5fad504caf Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 10 Sep 2018 12:54:36 +1200 Subject: [PATCH 03/10] save-analysis: remove hacky, unnecessary code now that we have spans for every ident --- src/librustc_save_analysis/dump_visitor.rs | 169 ++++++++----------- src/librustc_save_analysis/lib.rs | 116 +++++-------- src/librustc_save_analysis/span_utils.rs | 184 ++------------------- 3 files changed, 124 insertions(+), 345 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 97bdb9e5fa30c..d05f37cc0a125 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -34,7 +34,6 @@ use std::env; use syntax::ast::{self, Attribute, NodeId, PatKind, CRATE_NODE_ID}; use syntax::parse::token; -use syntax::symbol::keywords; use syntax::visit::{self, Visitor}; use syntax::print::pprust::{ bounds_to_string, @@ -323,7 +322,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.visit_pat(&arg.pat); let mut collector = PathCollector::new(); collector.visit_pat(&arg.pat); - let span_utils = self.span.clone(); for (id, ident, ..) in collector.collected_idents { let hir_id = self.tcx.hir.node_to_hir_id(id); @@ -331,10 +329,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { Some(s) => s.to_string(), None => continue, }; - let sub_span = span_utils.span_for_last_ident(ident.span); - if !self.span.filter_generated(sub_span, ident.span) { + if !self.span.filter_generated(ident.span) { let id = ::id_from_node_id(id, &self.save_ctxt); - let span = self.span_from_span(sub_span.expect("No span found for variable")); + let span = self.span_from_span(ident.span); self.dumper.dump_def( &Access { @@ -373,7 +370,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ) { debug!("process_method: {}:{}", id, ident); - if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident.name, span) { + if let Some(mut method_data) = self.save_ctxt.get_method_data(id, ident, span) { let sig_str = ::make_signature(&sig.decl, &generics); if body.is_some() { self.nest_tables( @@ -382,7 +379,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ); } - self.process_generic_params(&generics, span, &method_data.qualname, id); + self.process_generic_params(&generics, &method_data.qualname, id); method_data.value = sig_str; method_data.sig = sig::method_signature(id, ident, generics, sig, &self.save_ctxt); @@ -415,7 +412,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_generic_params( &mut self, generics: &'l ast::Generics, - full_span: Span, prefix: &str, id: NodeId, ) { @@ -427,7 +423,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { 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(Some(param_ss), full_span) { + if !self.span.filter_generated(param_ss) { let id = ::id_from_node_id(param.id, &self.save_ctxt); let span = self.span_from_span(param_ss); @@ -471,7 +467,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { item.id, |v| v.process_formals(&decl.inputs, &fn_data.qualname), ); - self.process_generic_params(ty_params, item.span, &fn_data.qualname, item.id); + self.process_generic_params(ty_params, &fn_data.qualname, item.id); self.dumper.dump_def(&access_from!(self.save_ctxt, item), fn_data); } @@ -505,8 +501,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { fn process_assoc_const( &mut self, id: ast::NodeId, - name: ast::Name, - span: Span, + ident: ast::Ident, typ: &'l ast::Ty, expr: Option<&'l ast::Expr>, parent_id: DefId, @@ -515,11 +510,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ) { let qualname = format!("::{}", self.tcx.node_path_str(id)); - let sub_span = self.span.sub_span_after_keyword(span, keywords::Const); - - if !self.span.filter_generated(sub_span, span) { - let sig = sig::assoc_const_signature(id, name, typ, expr, &self.save_ctxt); - let span = self.span_from_span(sub_span.expect("No span found for variable")); + if !self.span.filter_generated(ident.span) { + let sig = sig::assoc_const_signature(id, ident.name, typ, expr, &self.save_ctxt); + let span = self.span_from_span(ident.span); self.dumper.dump_def( &access_from!(self.save_ctxt, vis, id), @@ -527,7 +520,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { kind: DefKind::Const, id: ::id_from_node_id(id, &self.save_ctxt), span, - name: name.to_string(), + name: ident.name.to_string(), qualname, value: ty_to_string(&typ), parent: Some(::id_from_def_id(parent_id)), @@ -558,13 +551,12 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let name = item.ident.to_string(); let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let (kind, keyword) = match item.node { - ast::ItemKind::Struct(_, _) => (DefKind::Struct, keywords::Struct), - ast::ItemKind::Union(_, _) => (DefKind::Union, keywords::Union), + let kind = match item.node { + ast::ItemKind::Struct(_, _) => DefKind::Struct, + ast::ItemKind::Union(_, _) => DefKind::Union, _ => unreachable!(), }; - let sub_span = self.span.sub_span_after_keyword(item.span, keyword); let (value, fields) = match item.node { ast::ItemKind::Struct(ast::VariantData::Struct(ref fields, _), _) | ast::ItemKind::Union(ast::VariantData::Struct(ref fields, _), _) => { @@ -595,8 +587,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { _ => (String::new(), vec![]), }; - if !self.span.filter_generated(sub_span, item.span) { - let span = self.span_from_span(sub_span.expect("No span found for struct")); + 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), Def { @@ -621,7 +613,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.visit_ty(&field.ty); } - self.process_generic_params(ty_params, item.span, &qualname, item.id); + self.process_generic_params(ty_params, &qualname, item.id); } fn process_enum( @@ -642,10 +634,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { for variant in &enum_definition.variants { let name = variant.node.ident.name.to_string(); let qualname = format!("{}::{}", enum_data.qualname, name); + let name_span = variant.node.ident.span; match variant.node.data { ast::VariantData::Struct(ref fields, _) => { - let sub_span = self.span.span_for_first_ident(variant.span); let fields_str = fields .iter() .enumerate() @@ -655,9 +647,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .collect::>() .join(", "); let value = format!("{}::{} {{ {} }}", enum_data.name, name, fields_str); - if !self.span.filter_generated(sub_span, variant.span) { - let span = self - .span_from_span(sub_span.expect("No span found for struct variant")); + if !self.span.filter_generated(name_span) { + let span = self.span_from_span(name_span); let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt); let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); @@ -684,7 +675,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } } ref v => { - let sub_span = self.span.span_for_first_ident(variant.span); let mut value = format!("{}::{}", enum_data.name, name); if let &ast::VariantData::Tuple(ref fields, _) = v { value.push('('); @@ -695,9 +685,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .join(", ")); value.push(')'); } - if !self.span.filter_generated(sub_span, variant.span) { - let span = - self.span_from_span(sub_span.expect("No span found for tuple variant")); + if !self.span.filter_generated(name_span) { + let span = self.span_from_span(name_span); let id = ::id_from_node_id(variant.node.data.id(), &self.save_ctxt); let parent = Some(::id_from_node_id(item.id, &self.save_ctxt)); @@ -731,7 +720,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.visit_ty(&field.ty); } } - self.process_generic_params(ty_params, item.span, &enum_data.qualname, item.id); + self.process_generic_params(ty_params, &enum_data.qualname, item.id); self.dumper.dump_def(&access, enum_data); } @@ -755,7 +744,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { if let &Some(ref trait_ref) = trait_ref { self.process_path(trait_ref.ref_id, &trait_ref.path); } - self.process_generic_params(type_parameters, item.span, "", item.id); + self.process_generic_params(type_parameters, "", item.id); for impl_item in impl_items { let map = &self.tcx.hir; self.process_impl_item(impl_item, map.local_def_id(item.id)); @@ -779,10 +768,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { val.push_str(": "); val.push_str(&bounds_to_string(trait_refs)); } - let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Trait); - if !self.span.filter_generated(sub_span, item.span) { + if !self.span.filter_generated(item.ident.span) { let id = ::id_from_node_id(item.id, &self.save_ctxt); - let span = self.span_from_span(sub_span.expect("No span found for trait")); + let span = self.span_from_span(item.ident.span); let children = methods .iter() .map(|i| ::id_from_node_id(i.id, &self.save_ctxt)) @@ -815,21 +803,18 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { let trait_ref = &trait_ref.trait_ref; if let Some(id) = self.lookup_def_id(trait_ref.ref_id) { - let sub_span = self.span.sub_span_for_type_name(trait_ref.path.span); - if !self.span.filter_generated(sub_span, trait_ref.path.span) { - let span = self.span_from_span(sub_span.expect("No span found for trait ref")); + 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); self.dumper.dump_ref(Ref { kind: RefKind::Type, - span, + span: span.clone(), ref_id: ::id_from_def_id(id), }); - } - if !self.span.filter_generated(sub_span, trait_ref.path.span) { - let sub_span = self.span_from_span(sub_span.expect("No span for inheritance")); self.dumper.dump_relation(Relation { kind: RelationKind::SuperTrait, - span: sub_span, + span, from: ::id_from_def_id(id), to: ::id_from_node_id(item.id, &self.save_ctxt), }); @@ -838,7 +823,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } // walk generics and methods - self.process_generic_params(generics, item.span, &qualname, item.id); + self.process_generic_params(generics, &qualname, item.id); for method in methods { let map = &self.tcx.hir; self.process_trait_item(method, map.local_def_id(item.id)) @@ -988,12 +973,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { }; let variant = adt.variant_of_def(self.save_ctxt.get_path_def(p.id)); - for &Spanned { node: ref field, span } in fields { - let sub_span = self.span.span_for_first_ident(span); + for &Spanned { node: ref field, .. } in fields { if let Some(index) = self.tcx.find_field_index(field.ident, variant) { - if !self.span.filter_generated(sub_span, span) { - let span = - self.span_from_span(sub_span.expect("No span fund for var ref")); + if !self.span.filter_generated(field.ident.span) { + let span = self.span_from_span(field.ident.span); self.dumper.dump_ref(Ref { kind: RefKind::Variable, span, @@ -1034,7 +1017,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { value.push_str(": "); value.push_str(&typ); - if !self.span.filter_generated(Some(ident.span), ident.span) { + 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 span = self.span_from_span(ident.span); @@ -1109,14 +1092,11 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { None => String::new(), }; - // Get the span only for the name of the variable (I hope the path - // is only ever a variable name, but who knows?). - let sub_span = self.span.span_for_last_ident(ident.span); // Rust uses the id of the pattern for var lookups, so we'll use it too. - if !self.span.filter_generated(sub_span, ident.span) { + 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 span = self.span_from_span(sub_span.expect("No span found for variable")); + let span = self.span_from_span(ident.span); self.dumper.dump_def( &Access { @@ -1190,8 +1170,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ast::TraitItemKind::Const(ref ty, ref expr) => { self.process_assoc_const( trait_item.id, - trait_item.ident.name, - trait_item.span, + trait_item.ident, &ty, expr.as_ref().map(|e| &**e), trait_id, @@ -1214,11 +1193,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { // FIXME do something with _bounds (for type refs) let name = trait_item.ident.name.to_string(); let qualname = format!("::{}", self.tcx.node_path_str(trait_item.id)); - let sub_span = self.span - .sub_span_after_keyword(trait_item.span, keywords::Type); - if !self.span.filter_generated(sub_span, trait_item.span) { - let span = self.span_from_span(sub_span.expect("No span found for assoc type")); + 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); self.dumper.dump_def( @@ -1263,8 +1240,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { ast::ImplItemKind::Const(ref ty, ref expr) => { self.process_assoc_const( impl_item.id, - impl_item.ident.name, - impl_item.span, + impl_item.ident, &ty, Some(expr), impl_id, @@ -1328,7 +1304,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { .map(::id_from_def_id); match use_tree.kind { - ast::UseTreeKind::Simple(..) => { + ast::UseTreeKind::Simple(alias, ..) => { let ident = use_tree.ident(); let path = ast::Path { segments: prefix.segments @@ -1339,16 +1315,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { span: path.span, }; - let sub_span = self.span.span_for_last_ident(path.span); - let alias_span = self.span.sub_span_after_keyword(use_tree.span, keywords::As); - let ref_id = self.lookup_def_id(id); - - if !self.span.filter_generated(sub_span, path.span) { - let span = self.span_from_span(sub_span.expect("No span found for use")); - let alias_span = alias_span.map(|sp| self.span_from_span(sp)); + 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| ::id_from_def_id(id)); + let alias_span = alias.map(|i| self.span_from_span(i.span)); + let span = self.span_from_span(sub_span); self.dumper.import(&access, Import { kind: ImportKind::Use, - ref_id: ref_id.map(|id| ::id_from_def_id(id)), + ref_id, span, alias_span, name: ident.to_string(), @@ -1377,9 +1351,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { Vec::new() }; - let sub_span = self.span.sub_span_of_token(use_tree.span, - token::BinOp(token::Star)); - if !self.span.filter_generated(sub_span, use_tree.span) { + let sub_span = + self.span.sub_span_of_token(use_tree.span, token::BinOp(token::Star)); + if !self.span.filter_generated(use_tree.span) { let span = self.span_from_span(sub_span.expect("No span found for use glob")); self.dumper.import(&access, Import { @@ -1471,11 +1445,9 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc self.process_use_tree(use_tree, item.id, item, &prefix); } ExternCrate(_) => { - let alias_span = self.span.span_for_last_ident(item.span); - - if !self.span.filter_generated(alias_span, item.span) { - let span = - self.span_from_span(alias_span.expect("No span found for extern crate")); + let name_span = item.ident.span; + if !self.span.filter_generated(name_span) { + let span = self.span_from_span(name_span); let parent = self.save_ctxt.tcx.hir.opt_local_def_id(item.id) .and_then(|id| self.save_ctxt.tcx.parent_def_id(id)) .map(::id_from_def_id); @@ -1518,9 +1490,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc Ty(ref ty, ref ty_params) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); let value = ty_to_string(&ty); - let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type); - if !self.span.filter_generated(sub_span, item.span) { - let span = self.span_from_span(sub_span.expect("No span found for typedef")); + 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); self.dumper.dump_def( @@ -1543,15 +1514,14 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } self.visit_ty(&ty); - self.process_generic_params(ty_params, item.span, &qualname, item.id); + self.process_generic_params(ty_params, &qualname, item.id); } Existential(ref _bounds, ref ty_params) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); // FIXME do something with _bounds let value = String::new(); - let sub_span = self.span.sub_span_after_keyword(item.span, keywords::Type); - if !self.span.filter_generated(sub_span, item.span) { - let span = self.span_from_span(sub_span.expect("No span found for typedef")); + 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); self.dumper.dump_def( @@ -1573,7 +1543,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc ); } - self.process_generic_params(ty_params, item.span, &qualname, item.id); + self.process_generic_params(ty_params, &qualname, item.id); } Mac(_) => (), _ => visit::walk_item(self, item), @@ -1606,14 +1576,13 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc } if let Some(id) = self.lookup_def_id(t.id) { - if let Some(sub_span) = self.span.sub_span_for_type_name(t.span) { - let span = self.span_from_span(sub_span); - self.dumper.dump_ref(Ref { - kind: RefKind::Type, - span, - ref_id: ::id_from_def_id(id), - }); - } + let sub_span = path.segments.last().unwrap().ident.span; + let span = self.span_from_span(sub_span); + self.dumper.dump_ref(Ref { + kind: RefKind::Type, + span, + ref_id: ::id_from_def_id(id), + }); } self.write_sub_paths_truncated(path); @@ -1757,7 +1726,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc item.id, |v| v.process_formals(&decl.inputs, &fn_data.qualname), ); - self.process_generic_params(generics, item.span, &fn_data.qualname, item.id); + self.process_generic_params(generics, &fn_data.qualname, item.id); self.dumper.dump_def(&access, fn_data); } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 4b43a1a6270f8..991172370148e 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -60,9 +60,7 @@ use std::path::{Path, PathBuf}; use syntax::ast::{self, Attribute, NodeId, PatKind}; use syntax::source_map::Spanned; use syntax::parse::lexer::comments::strip_doc_comment_decoration; -use syntax::parse::token; use syntax::print::pprust; -use syntax::symbol::keywords; use syntax::visit::{self, Visitor}; use syntax::print::pprust::{arg_to_string, ty_to_string}; use syntax::source_map::MacroAttribute; @@ -162,14 +160,12 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); match item.node { ast::ForeignItemKind::Fn(ref decl, ref generics) => { - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Fn); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::ForeignFunction, id: id_from_node_id(item.id, self), - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), name: item.ident.to_string(), qualname, value: make_signature(decl, generics), @@ -181,13 +177,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ForeignItemKind::Static(ref ty, m) => { - let keyword = if m { keywords::Mut } else { keywords::Static }; - let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword); - filter!(self.span_utils, sub_span, item.span, None); + ast::ForeignItemKind::Static(ref ty, _) => { + filter!(self.span_utils, item.ident.span); let id = ::id_from_node_id(item.id, self); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { kind: DefKind::ForeignStatic, @@ -214,13 +208,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { match item.node { ast::ItemKind::Fn(ref decl, .., ref generics, _) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Fn); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::Function, id: id_from_node_id(item.id, self), - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), name: item.ident.to_string(), qualname, value: make_signature(decl, generics), @@ -232,19 +224,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Static(ref typ, mt, _) => { + ast::ItemKind::Static(ref typ, ..) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let keyword = match mt { - ast::Mutability::Mutable => keywords::Mut, - ast::Mutability::Immutable => keywords::Static, - }; - - let sub_span = self.span_utils.sub_span_after_keyword(item.span, keyword); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { kind: DefKind::Static, @@ -263,12 +249,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } ast::ItemKind::Const(ref typ, _) => { let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Const); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); let id = id_from_node_id(item.id, self); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(item.ident.span); Some(Data::DefData(Def { kind: DefKind::Const, @@ -291,16 +275,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let cm = self.tcx.sess.source_map(); let filename = cm.span_to_filename(m.inner); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Mod); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); Some(Data::DefData(Def { kind: DefKind::Mod, id: id_from_node_id(item.id, self), name: item.ident.to_string(), qualname, - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), value: filename.to_string(), parent: None, children: m.items @@ -316,9 +298,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ast::ItemKind::Enum(ref def, _) => { let name = item.ident.to_string(); let qualname = format!("::{}", self.tcx.node_path_str(item.id)); - let sub_span = self.span_utils - .sub_span_after_keyword(item.span, keywords::Enum); - filter!(self.span_utils, sub_span, item.span, None); + filter!(self.span_utils, item.ident.span); let variants_str = def.variants .iter() .map(|v| v.node.ident.to_string()) @@ -328,7 +308,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { Some(Data::DefData(Def { kind: DefKind::Enum, id: id_from_node_id(item.id, self), - span: self.span_from_span(sub_span.unwrap()), + span: self.span_from_span(item.ident.span), name, qualname, value, @@ -349,11 +329,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if generated_code(path.span) { return None; } - let sub_span = self.span_utils.sub_span_for_type_name(path.span); - filter!(self.span_utils, sub_span, typ.span, None); + let sub_span = path.segments.last().unwrap().ident.span; + filter!(self.span_utils, sub_span); let impl_id = self.next_impl_id(); - let span = self.span_from_span(sub_span.unwrap()); + let span = self.span_from_span(sub_span); let type_data = self.lookup_ref_id(typ.id); type_data.map(|type_data| { @@ -402,15 +382,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if let Some(ident) = field.ident { let name = ident.to_string(); let qualname = format!("::{}::{}", self.tcx.node_path_str(scope), ident); - let sub_span = self.span_utils - .sub_span_before_token(field.span, token::Colon); - filter!(self.span_utils, sub_span, field.span, None); + filter!(self.span_utils, ident.span); let def_id = self.tcx.hir.local_def_id(field.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(sub_span.unwrap()); + let span = self.span_from_span(ident.span); Some(Def { kind: DefKind::Field, @@ -433,7 +411,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { // 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, name: ast::Name, span: Span) -> Option { + pub fn get_method_data(&self, id: ast::NodeId, ident: ast::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) = @@ -459,7 +437,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { qualname.push_str(&self.tcx.item_path_str(def_id)); self.tcx .associated_items(def_id) - .find(|item| item.ident.name == name) + .find(|item| item.ident.name == ident.name) .map(|item| decl_id = Some(item.def_id)); } qualname.push_str(">"); @@ -512,16 +490,15 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { }, }; - let qualname = format!("{}::{}", qualname, name); + let qualname = format!("{}::{}", qualname, ident.name); - let sub_span = self.span_utils.sub_span_after_keyword(span, keywords::Fn); - filter!(self.span_utils, sub_span, span, None); + filter!(self.span_utils, ident.span); Some(Def { kind: DefKind::Method, id: id_from_node_id(id, self), - span: self.span_from_span(sub_span.unwrap()), - name: name.to_string(), + span: self.span_from_span(ident.span), + name: ident.name.to_string(), qualname, // FIXME you get better data here by using the visitor. value: String::new(), @@ -540,9 +517,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { if generated_code(span) { return None; } - let sub_span = self.span_utils.sub_span_for_type_name(span).or(Some(span)); - filter!(self.span_utils, sub_span, span, None); - let span = self.span_from_span(sub_span.unwrap()); + let sub_span = trait_ref.path.segments.last().unwrap().ident.span; + filter!(self.span_utils, sub_span); + let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Type, span, @@ -574,9 +551,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ty::Adt(def, _) if !def.is_enum() => { let variant = &def.non_enum_variant(); let index = self.tcx.find_field_index(ident, variant).unwrap(); - let sub_span = self.span_utils.span_for_last_ident(expr.span); - filter!(self.span_utils, sub_span, expr.span, None); - let span = self.span_from_span(sub_span.unwrap()); + filter!(self.span_utils, ident.span); + let span = self.span_from_span(ident.span); return Some(Data::RefData(Ref { kind: RefKind::Variable, span, @@ -593,9 +569,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ast::ExprKind::Struct(ref path, ..) => { match self.tables.expr_ty_adjusted(&hir_node).sty { ty::Adt(def, _) if !def.is_enum() => { - let sub_span = self.span_utils.span_for_last_ident(path.span); - filter!(self.span_utils, sub_span, path.span, None); - let span = self.span_from_span(sub_span.unwrap()); + let sub_span = path.segments.last().unwrap().ident.span; + filter!(self.span_utils, sub_span); + let span = self.span_from_span(sub_span); Some(Data::RefData(Ref { kind: RefKind::Type, span, @@ -624,7 +600,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { ty::TraitContainer(_) => (None, Some(method_id)), }; let sub_span = seg.ident.span; - filter!(self.span_utils, Some(sub_span), expr.span, None); + filter!(self.span_utils, sub_span); let span = self.span_from_span(sub_span); Some(Data::RefData(Ref { kind: RefKind::Function, @@ -729,7 +705,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let def = self.get_path_def(id); let last_seg = &path.segments[path.segments.len() - 1]; let sub_span = last_seg.ident.span; - filter!(self.span_utils, Some(sub_span), path.span, None); + filter!(self.span_utils, sub_span); match def { HirDef::Upvar(id, ..) | HirDef::Local(id) => { let span = self.span_from_span(sub_span); @@ -753,13 +729,11 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { HirDef::Trait(def_id) if fn_type(path) => { // Function type bounds are desugared in the parser, so we have to // special case them here. - let fn_span = self.span_utils.span_for_first_ident(path.span); - fn_span.map(|span| { - Ref { - kind: RefKind::Type, - span: self.span_from_span(span), - ref_id: id_from_def_id(def_id), - } + let fn_span = path.segments.first().unwrap().ident.span; + Some(Ref { + kind: RefKind::Type, + span: self.span_from_span(fn_span), + ref_id: id_from_def_id(def_id), }) } HirDef::Struct(def_id) | @@ -844,10 +818,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { variant: &ty::VariantDef, ) -> Option { let index = self.tcx.find_field_index(field_ref.ident, variant).unwrap(); - // We don't really need a sub-span here, but no harm done - let sub_span = self.span_utils.span_for_last_ident(field_ref.ident.span); - filter!(self.span_utils, sub_span, field_ref.ident.span, None); - let span = self.span_from_span(sub_span.unwrap()); + filter!(self.span_utils, field_ref.ident.span); + let span = self.span_from_span(field_ref.ident.span); Some(Ref { kind: RefKind::Variable, span, diff --git a/src/librustc_save_analysis/span_utils.rs b/src/librustc_save_analysis/span_utils.rs index 47677a751712e..902353da13f76 100644 --- a/src/librustc_save_analysis/span_utils.rs +++ b/src/librustc_save_analysis/span_utils.rs @@ -16,7 +16,6 @@ use std::cell::Cell; use syntax::parse::lexer::{self, StringReader}; use syntax::parse::token::{self, Token}; -use syntax::symbol::keywords; use syntax_pos::*; #[derive(Clone)] @@ -67,131 +66,6 @@ impl<'a> SpanUtils<'a> { lexer::StringReader::retokenize(&self.sess.parse_sess, span) } - // Re-parses a path and returns the span for the last identifier in the path - pub fn span_for_last_ident(&self, span: Span) -> Option { - let mut result = None; - - let mut toks = self.retokenise_span(span); - let mut bracket_count = 0; - loop { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return result; - } - if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) { - result = Some(ts.sp); - } - - bracket_count += match ts.tok { - token::Lt => 1, - token::Gt => -1, - token::BinOp(token::Shr) => -2, - _ => 0, - } - } - } - - // Return the span for the first identifier in the path. - pub fn span_for_first_ident(&self, span: Span) -> Option { - let mut toks = self.retokenise_span(span); - let mut bracket_count = 0; - loop { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return None; - } - if bracket_count == 0 && (ts.tok.is_ident() || ts.tok.is_keyword(keywords::SelfValue)) { - return Some(ts.sp); - } - - bracket_count += match ts.tok { - token::Lt => 1, - token::Gt => -1, - token::BinOp(token::Shr) => -2, - _ => 0, - } - } - } - - // Return the span for the last ident before a `<` and outside any - // angle brackets, or the last span. - pub fn sub_span_for_type_name(&self, span: Span) -> Option { - let mut toks = self.retokenise_span(span); - let mut prev = toks.real_token(); - let mut result = None; - - // We keep track of the following two counts - the depth of nesting of - // angle brackets, and the depth of nesting of square brackets. For the - // angle bracket count, we only count tokens which occur outside of any - // square brackets (i.e. bracket_count == 0). The intuition here is - // that we want to count angle brackets in the type, but not any which - // could be in expression context (because these could mean 'less than', - // etc.). - let mut angle_count = 0; - let mut bracket_count = 0; - loop { - let next = toks.real_token(); - - if (next.tok == token::Lt || next.tok == token::Colon) && angle_count == 0 - && bracket_count == 0 && prev.tok.is_ident() - { - result = Some(prev.sp); - } - - if bracket_count == 0 { - angle_count += match prev.tok { - token::Lt => 1, - token::Gt => -1, - token::BinOp(token::Shl) => 2, - token::BinOp(token::Shr) => -2, - _ => 0, - }; - } - - bracket_count += match prev.tok { - token::OpenDelim(token::Bracket) => 1, - token::CloseDelim(token::Bracket) => -1, - _ => 0, - }; - - if next.tok == token::Eof { - break; - } - prev = next; - } - #[cfg(debug_assertions)] { - if angle_count != 0 || bracket_count != 0 { - let loc = self.sess.source_map().lookup_char_pos(span.lo()); - span_bug!( - span, - "Mis-counted brackets when breaking path? Parsing '{}' in {}, line {}", - self.snippet(span), - loc.file.name, - loc.line - ); - } - } - if result.is_none() && prev.tok.is_ident() { - return Some(prev.sp); - } - result - } - - pub fn sub_span_before_token(&self, span: Span, tok: Token) -> Option { - let mut toks = self.retokenise_span(span); - let mut prev = toks.real_token(); - loop { - if prev.tok == token::Eof { - return None; - } - let next = toks.real_token(); - if next.tok == tok { - return Some(prev.sp); - } - prev = next; - } - } - pub fn sub_span_of_token(&self, span: Span, tok: Token) -> Option { let mut toks = self.retokenise_span(span); loop { @@ -205,28 +79,6 @@ impl<'a> SpanUtils<'a> { } } - pub fn sub_span_after_keyword(&self, span: Span, keyword: keywords::Keyword) -> Option { - self.sub_span_after(span, |t| t.is_keyword(keyword)) - } - - fn sub_span_after bool>(&self, span: Span, f: F) -> Option { - let mut toks = self.retokenise_span(span); - loop { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return None; - } - if f(ts.tok) { - let ts = toks.real_token(); - if ts.tok == token::Eof { - return None; - } else { - return Some(ts.sp); - } - } - } - } - // // Return the name for a macro definition (identifier after first `!`) // pub fn span_for_macro_def_name(&self, span: Span) -> Option { // let mut toks = self.retokenise_span(span); @@ -271,42 +123,28 @@ impl<'a> SpanUtils<'a> { /// /// Used to filter out spans of minimal value, /// such as references to macro internal variables. - pub fn filter_generated(&self, sub_span: Option, parent: Span) -> bool { - if !generated_code(parent) { - // Edge case - this occurs on generated code with incorrect expansion info. - return sub_span.is_none() + pub fn filter_generated(&self, span: Span) -> bool { + if span.is_dummy() { + return true; + } + + if !generated_code(span) { + return false; } - // If sub_span is none, filter out generated code. - let sub_span = match sub_span { - Some(ss) => ss, - None => return true, - }; //If the span comes from a fake source_file, filter it. - if !self.sess + !self.sess .source_map() - .lookup_char_pos(parent.lo()) + .lookup_char_pos(span.lo()) .file .is_real_file() - { - return true; - } - - // Otherwise, a generated span is deemed invalid if it is not a sub-span of the root - // callsite. This filters out macro internal variables and most malformed spans. - !parent.source_callsite().contains(sub_span) } } macro_rules! filter { - ($util: expr, $span: expr, $parent: expr, None) => { - if $util.filter_generated($span, $parent) { + ($util: expr, $parent: expr) => { + if $util.filter_generated($parent) { return None; } }; - ($util: expr, $span: ident, $parent: expr) => { - if $util.filter_generated($span, $parent) { - return; - } - }; } From 609d0bd8ac3f339697a0b036062ba7784ab41232 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Mon, 10 Sep 2018 15:26:47 +1200 Subject: [PATCH 04/10] dump data for prefix path segments --- src/librustc_save_analysis/dump_visitor.rs | 115 ++------------------- src/librustc_save_analysis/lib.rs | 38 +++---- 2 files changed, 22 insertions(+), 131 deletions(-) diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index d05f37cc0a125..49b871e767783 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -38,7 +38,6 @@ use syntax::visit::{self, Visitor}; use syntax::print::pprust::{ bounds_to_string, generic_params_to_string, - path_to_string, ty_to_string }; use syntax::ptr::P; @@ -218,95 +217,21 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { self.dumper.compilation_opts(data); } - // Return all non-empty prefixes of a path. - // For each prefix, we return the span for the last segment in the prefix and - // a str representation of the entire prefix. - fn process_path_prefixes(&self, path: &ast::Path) -> Vec<(Span, String)> { - let segments = &path.segments[if path.is_global() { 1 } else { 0 }..]; - - let mut result = Vec::with_capacity(segments.len()); - let mut segs = Vec::with_capacity(segments.len()); - - for (i, seg) in segments.iter().enumerate() { - segs.push(seg.clone()); - let sub_path = ast::Path { - span: seg.ident.span, // span for the last segment - segments: segs, - }; - let qualname = if i == 0 && path.is_global() { - format!("::{}", path_to_string(&sub_path)) - } else { - path_to_string(&sub_path) - }; - result.push((seg.ident.span, qualname)); - segs = sub_path.segments; - } - - result - } - fn write_sub_paths(&mut self, path: &ast::Path) { - let sub_paths = self.process_path_prefixes(path); - for (span, _) in sub_paths { - let span = self.span_from_span(span); - self.dumper.dump_ref(Ref { - kind: RefKind::Mod, - span, - ref_id: ::null_id(), - }); + for seg in &path.segments { + if let Some(data) = self.save_ctxt.get_path_segment_data(seg) { + self.dumper.dump_ref(data); + } } } // 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) { - let sub_paths = self.process_path_prefixes(path); - let len = sub_paths.len(); - if len <= 1 { - return; - } - - for (span, _) in sub_paths.into_iter().take(len - 1) { - let span = self.span_from_span(span); - self.dumper.dump_ref(Ref { - kind: RefKind::Mod, - span, - ref_id: ::null_id(), - }); - } - } - - // As write_sub_paths, but expects a path of the form module_path::trait::method - // Where trait could actually be a struct too. - fn write_sub_path_trait_truncated(&mut self, path: &ast::Path) { - let sub_paths = self.process_path_prefixes(path); - let len = sub_paths.len(); - if len <= 1 { - return; - } - let sub_paths = &sub_paths[..(len - 1)]; - - // write the trait part of the sub-path - let (ref span, _) = sub_paths[len - 2]; - let span = self.span_from_span(*span); - self.dumper.dump_ref(Ref { - kind: RefKind::Type, - ref_id: ::null_id(), - span, - }); - - // write the other sub-paths - if len <= 2 { - return; - } - let sub_paths = &sub_paths[..len - 2]; - for &(ref span, _) in sub_paths { - let span = self.span_from_span(*span); - self.dumper.dump_ref(Ref { - kind: RefKind::Mod, - span, - ref_id: ::null_id(), - }); + 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); + } } } @@ -876,29 +801,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> { } } - // Modules or types in the path prefix. - match self.save_ctxt.get_path_def(id) { - HirDef::Method(did) => { - let ti = self.tcx.associated_item(did); - if ti.kind == ty::AssociatedKind::Method && ti.method_has_self_argument { - self.write_sub_path_trait_truncated(path); - } - } - HirDef::Fn(..) | - HirDef::Const(..) | - HirDef::Static(..) | - HirDef::StructCtor(..) | - HirDef::VariantCtor(..) | - HirDef::AssociatedConst(..) | - HirDef::Local(..) | - HirDef::Upvar(..) | - HirDef::Struct(..) | - HirDef::Union(..) | - HirDef::Variant(..) | - HirDef::TyAlias(..) | - HirDef::AssociatedTy(..) => self.write_sub_paths_truncated(path), - _ => {} - } + self.write_sub_paths_truncated(path); } fn process_struct_lit( diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 991172370148e..c4777393a9897 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -684,13 +684,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } } - pub fn get_path_data(&self, id: NodeId, path: &ast::Path) -> Option { + pub fn get_path_data(&self, _id: NodeId, path: &ast::Path) -> Option { + path.segments.last().and_then(|seg| self.get_path_segment_data(seg)) + } + + pub fn get_path_segment_data(&self, path_seg: &ast::PathSegment) -> Option { // Returns true if the path is function type sugar, e.g., `Fn(A) -> B`. - fn fn_type(path: &ast::Path) -> bool { - if path.segments.len() != 1 { - return false; - } - if let Some(ref generic_args) = path.segments[0].args { + fn fn_type(seg: &ast::PathSegment) -> bool { + if let Some(ref generic_args) = seg.args { if let ast::GenericArgs::Parenthesized(_) = **generic_args { return true; } @@ -698,17 +699,13 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { false } - if path.segments.is_empty() { - return None; - } + let def = self.get_path_def(path_seg.id); + let span = path_seg.ident.span; + filter!(self.span_utils, span); + let span = self.span_from_span(span); - let def = self.get_path_def(id); - let last_seg = &path.segments[path.segments.len() - 1]; - let sub_span = last_seg.ident.span; - filter!(self.span_utils, sub_span); match def { HirDef::Upvar(id, ..) | HirDef::Local(id) => { - let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Variable, span, @@ -719,20 +716,16 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { HirDef::Const(..) | HirDef::AssociatedConst(..) | HirDef::VariantCtor(..) => { - let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Variable, span, ref_id: id_from_def_id(def.def_id()), }) } - HirDef::Trait(def_id) if fn_type(path) => { - // Function type bounds are desugared in the parser, so we have to - // special case them here. - let fn_span = path.segments.first().unwrap().ident.span; + HirDef::Trait(def_id) if fn_type(path_seg) => { Some(Ref { kind: RefKind::Type, - span: self.span_from_span(fn_span), + span, ref_id: id_from_def_id(def_id), }) } @@ -748,7 +741,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { HirDef::Trait(def_id) | HirDef::Existential(def_id) | HirDef::TyParam(def_id) => { - let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Type, span, @@ -759,7 +751,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { // This is a reference to a tuple struct where the def_id points // to an invisible constructor function. That is not a very useful // def, so adjust to point to the tuple struct itself. - let span = self.span_from_span(sub_span); let parent_def_id = self.tcx.parent_def_id(def_id).unwrap(); Some(Ref { kind: RefKind::Type, @@ -778,7 +769,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { } else { None }; - let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Function, span, @@ -786,7 +776,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { }) } HirDef::Fn(def_id) => { - let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Function, span, @@ -794,7 +783,6 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { }) } HirDef::Mod(def_id) => { - let span = self.span_from_span(sub_span); Some(Ref { kind: RefKind::Mod, span, From c4803863919212812c626f796f9b393ab98c7e37 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Tue, 11 Sep 2018 15:08:47 +1200 Subject: [PATCH 05/10] dump refs for path segments in save-analysis Requires adding path segments to the hir map --- src/librustc/hir/lowering.rs | 1 + src/librustc/hir/map/collector.rs | 7 +++++++ src/librustc/hir/map/mod.rs | 8 +++++++- src/librustc/hir/mod.rs | 12 ++++++++++- src/librustc/ich/impls_hir.rs | 1 + src/librustc_resolve/build_reduced_graph.rs | 22 ++++++++++----------- src/librustc_resolve/lib.rs | 9 ++++++--- src/librustc_save_analysis/dump_visitor.rs | 7 +++---- src/librustc_save_analysis/lib.rs | 4 ++++ 9 files changed, 51 insertions(+), 20 deletions(-) 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, ..), .. From cdcbdfdf0ad46f534f45997fdd42409492ac000c Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 12 Sep 2018 13:44:22 +1200 Subject: [PATCH 06/10] Fix tests and rustdoc --- src/librustdoc/clean/mod.rs | 2 ++ src/librustdoc/core.rs | 2 ++ src/test/mir-opt/end_region_5.rs | 6 +++--- src/test/mir-opt/end_region_6.rs | 6 +++--- src/test/mir-opt/end_region_7.rs | 6 +++--- src/test/mir-opt/end_region_8.rs | 6 +++--- src/test/mir-opt/inline-closure-borrows-arg.rs | 2 +- src/test/mir-opt/inline-closure.rs | 2 +- src/test/mir-opt/validate_1.rs | 4 ++-- src/test/mir-opt/validate_4.rs | 12 ++++++------ src/test/mir-opt/validate_5.rs | 4 ++-- 11 files changed, 28 insertions(+), 24 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 2e6cc4bd54c61..9b2720717c9b3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -4012,6 +4012,8 @@ where F: Fn(DefId) -> Def { def: def_ctor(def_id), segments: hir::HirVec::from_vec(apb.names.iter().map(|s| hir::PathSegment { ident: ast::Ident::from_str(&s), + id: None, + def: None, args: None, infer_types: false, }).collect()) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 8f9c3fa4b7f20..d6b0127e44d01 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -186,6 +186,8 @@ impl<'a, 'tcx, 'rcx, 'cstore> DocContext<'a, 'tcx, 'rcx, 'cstore> { segments.push(hir::PathSegment::new( real_name.unwrap_or(last.ident), + None, + None, self.generics_to_path_params(generics.clone()), false, )); diff --git a/src/test/mir-opt/end_region_5.rs b/src/test/mir-opt/end_region_5.rs index 7a5d71ee21b93..98cd67459e068 100644 --- a/src/test/mir-opt/end_region_5.rs +++ b/src/test/mir-opt/end_region_5.rs @@ -33,7 +33,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _1: D; // ... // let mut _2: (); -// let mut _3: [closure@NodeId(18) d:&'14s D]; +// let mut _3: [closure@NodeId(28) d:&'14s D]; // let mut _4: &'14s D; // bb0: { // StorageLive(_1); @@ -42,7 +42,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // StorageLive(_3); // StorageLive(_4); // _4 = &'14s _1; -// _3 = [closure@NodeId(18)] { d: move _4 }; +// _3 = [closure@NodeId(28)] { d: move _4 }; // StorageDead(_4); // _2 = const foo(move _3) -> [return: bb2, unwind: bb3]; // } @@ -67,7 +67,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(18) d:&'14s D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(28) d:&'14s D]) -> i32 { // let mut _0: i32; // // bb0: { diff --git a/src/test/mir-opt/end_region_6.rs b/src/test/mir-opt/end_region_6.rs index b9162f85fa71e..48f3a83506d7c 100644 --- a/src/test/mir-opt/end_region_6.rs +++ b/src/test/mir-opt/end_region_6.rs @@ -33,7 +33,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _1: D; // ... // let mut _2: (); -// let mut _3: [closure@NodeId(22) d:&'19s D]; +// let mut _3: [closure@NodeId(33) d:&'19s D]; // let mut _4: &'19s D; // bb0: { // StorageLive(_1); @@ -42,7 +42,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // StorageLive(_3); // StorageLive(_4); // _4 = &'19s _1; -// _3 = [closure@NodeId(22)] { d: move _4 }; +// _3 = [closure@NodeId(33)] { d: move _4 }; // StorageDead(_4); // _2 = const foo(move _3) -> [return: bb2, unwind: bb3]; // } @@ -66,7 +66,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(22) d:&'19s D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(33) d:&'19s D]) -> i32 { // let mut _0: i32; // ... // let _2: &'16_0rs D; diff --git a/src/test/mir-opt/end_region_7.rs b/src/test/mir-opt/end_region_7.rs index 4deea75e56b04..062d89a7c7e2f 100644 --- a/src/test/mir-opt/end_region_7.rs +++ b/src/test/mir-opt/end_region_7.rs @@ -33,13 +33,13 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _1: D; // ... // let mut _2: (); -// let mut _3: [closure@NodeId(22) d:D]; +// let mut _3: [closure@NodeId(33) d:D]; // bb0: { // StorageLive(_1); // _1 = D::{{constructor}}(const 0i32,); // FakeRead(ForLet, _1); // StorageLive(_3); -// _3 = [closure@NodeId(22)] { d: move _1 }; +// _3 = [closure@NodeId(33)] { d: move _1 }; // _2 = const foo(move _3) -> [return: bb2, unwind: bb4]; // } // bb1: { @@ -67,7 +67,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(22) d:D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(33) d:D]) -> i32 { // let mut _0: i32; // ... // let _2: &'16_0rs D; diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs index 6f899a0db15d9..207901720577a 100644 --- a/src/test/mir-opt/end_region_8.rs +++ b/src/test/mir-opt/end_region_8.rs @@ -36,7 +36,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _1: D; // ... // let mut _3: (); -// let mut _4: [closure@NodeId(22) r:&'19s D]; +// let mut _4: [closure@NodeId(33) r:&'19s D]; // bb0: { // StorageLive(_1); // _1 = D::{{constructor}}(const 0i32,); @@ -45,7 +45,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // _2 = &'21_1rs _1; // FakeRead(ForLet, _2); // StorageLive(_4); -// _4 = [closure@NodeId(22)] { r: _2 }; +// _4 = [closure@NodeId(33)] { r: _2 }; // _3 = const foo(move _4) -> [return: bb2, unwind: bb3]; // } // bb1: { @@ -72,7 +72,7 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(22) r:&'19s D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(33) r:&'19s D]) -> i32 { // let mut _0: i32; // // bb0: { diff --git a/src/test/mir-opt/inline-closure-borrows-arg.rs b/src/test/mir-opt/inline-closure-borrows-arg.rs index aab432ddc8700..ba1712f4ca398 100644 --- a/src/test/mir-opt/inline-closure-borrows-arg.rs +++ b/src/test/mir-opt/inline-closure-borrows-arg.rs @@ -30,7 +30,7 @@ fn foo(_t: T, q: &i32) -> i32 { // ... // bb0: { // ... -// _3 = [closure@NodeId(39)]; +// _3 = [closure@NodeId(53)]; // ... // _4 = &_3; // ... diff --git a/src/test/mir-opt/inline-closure.rs b/src/test/mir-opt/inline-closure.rs index 22e7de31e90cf..9cb0a4dc2bfac 100644 --- a/src/test/mir-opt/inline-closure.rs +++ b/src/test/mir-opt/inline-closure.rs @@ -26,7 +26,7 @@ fn foo(_t: T, q: i32) -> i32 { // ... // bb0: { // ... -// _3 = [closure@NodeId(28)]; +// _3 = [closure@NodeId(39)]; // ... // _4 = &_3; // ... diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs index 882579c571086..66538c57f6545 100644 --- a/src/test/mir-opt/validate_1.rs +++ b/src/test/mir-opt/validate_1.rs @@ -59,10 +59,10 @@ fn main() { // } // END rustc.main.EraseRegions.after.mir // START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &ReErased [closure@NodeId(50)], _2: &ReErased mut i32) -> i32 { +// fn main::{{closure}}(_1: &ReErased [closure@NodeId(65)], _2: &ReErased mut i32) -> i32 { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(50)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(65)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); // Validate(Suspend(ReScope(Remainder { block: ItemLocalId(25), first_statement_index: 0 })), [(*_2): i32]); // _3 = &ReErased (*_2); diff --git a/src/test/mir-opt/validate_4.rs b/src/test/mir-opt/validate_4.rs index 24a4ebd8429df..542ac8a42411f 100644 --- a/src/test/mir-opt/validate_4.rs +++ b/src/test/mir-opt/validate_4.rs @@ -48,11 +48,11 @@ fn main() { // } // END rustc.write_42.EraseRegions.after.mir // START rustc.write_42-{{closure}}.EraseRegions.after.mir -// fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(22)], _2: *mut i32) -> () { +// fn write_42::{{closure}}(_1: &ReErased [closure@NodeId(32)], _2: *mut i32) -> () { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(22)], _2: *mut i32]); -// Validate(Release, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(22)], _2: *mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(32)], _2: *mut i32]); +// Validate(Release, [_1: &ReFree(DefId(0/1:9 ~ validate_4[317d]::write_42[0]::{{closure}}[0]), BrEnv) [closure@NodeId(32)], _2: *mut i32]); // (*_2) = const 23i32; // _0 = (); // return; @@ -76,11 +76,11 @@ fn main() { // } // END rustc.test.EraseRegions.after.mir // START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &ReErased [closure@NodeId(60)], _2: &ReErased mut i32) -> bool { +// fn main::{{closure}}(_1: &ReErased [closure@NodeId(80)], _2: &ReErased mut i32) -> bool { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); -// Validate(Release, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(60)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(80)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); +// Validate(Release, [_1: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(80)], _2: &ReFree(DefId(0/1:10 ~ validate_4[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); // ... // _0 = const write_42(move _3) -> bb1; diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index b4d4479bab94a..8016a3d4cce4c 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -46,10 +46,10 @@ fn main() { // } // END rustc.test.EraseRegions.after.mir // START rustc.main-{{closure}}.EraseRegions.after.mir -// fn main::{{closure}}(_1: &ReErased [closure@NodeId(46)], _2: &ReErased mut i32) -> bool { +// fn main::{{closure}}(_1: &ReErased [closure@NodeId(62)], _2: &ReErased mut i32) -> bool { // ... // bb0: { -// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(46)], _2: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); +// Validate(Acquire, [_1: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(62)], _2: &ReFree(DefId(0/1:9 ~ validate_5[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); // StorageLive(_4); // StorageLive(_5); From 8ac32726100c58ca66f3da6e35b423c17fc96a4f Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 12 Sep 2018 14:05:08 +1200 Subject: [PATCH 07/10] save-analysis: handle missing field names FIxes https://github.com/rust-lang-nursery/rls/issues/1031 --- src/librustc_save_analysis/lib.rs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 23eab3e15f643..9e0233149cc28 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -809,13 +809,14 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { field_ref: &ast::Field, variant: &ty::VariantDef, ) -> Option { - let index = self.tcx.find_field_index(field_ref.ident, variant).unwrap(); filter!(self.span_utils, field_ref.ident.span); - let span = self.span_from_span(field_ref.ident.span); - Some(Ref { - kind: RefKind::Variable, - span, - ref_id: id_from_def_id(variant.fields[index].did), + self.tcx.find_field_index(field_ref.ident, variant).map(|index| { + let span = self.span_from_span(field_ref.ident.span); + Ref { + kind: RefKind::Variable, + span, + ref_id: id_from_def_id(variant.fields[index].did), + } }) } From 59cb1705d790ac15d336525c4e2aa5bf5c9cf104 Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Wed, 12 Sep 2018 15:21:50 +1200 Subject: [PATCH 08/10] rebasing and reviewer changes Primarily refactoring `(Ident, Option)` to `Segment` --- src/librustc/hir/lowering.rs | 1 - src/librustc_resolve/build_reduced_graph.rs | 73 ++++++----- src/librustc_resolve/error_reporting.rs | 36 +++--- src/librustc_resolve/lib.rs | 129 ++++++++++++-------- src/librustc_resolve/macros.rs | 26 ++-- src/librustc_resolve/resolve_imports.rs | 23 ++-- src/libsyntax/parse/parser.rs | 2 +- 7 files changed, 157 insertions(+), 133 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1ac0d3946386a..58d860d9d983b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1385,7 +1385,6 @@ impl<'a> LoweringContext<'a> { // does not actually exist in the AST. lctx.items.insert(exist_ty_id.node_id, exist_ty_item); - let def = Def::Existential(DefId::local(exist_ty_def_index)); // `impl Trait` now just becomes `Foo<'a, 'b, ..>` hir::TyKind::Def(hir::ItemId { id: exist_ty_id.node_id }, lifetimes) }) diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index cdb6e9a23182c..b7ed3ef59b4c8 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -16,7 +16,7 @@ use macros::{InvocationData, ParentScope, LegacyScope}; use resolve_imports::ImportDirective; use resolve_imports::ImportDirectiveSubclass::{self, GlobImport, SingleImport}; -use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, ToNameBinding}; +use {Module, ModuleData, ModuleKind, NameBinding, NameBindingKind, Segment, ToNameBinding}; use {ModuleOrUniformRoot, PerNS, Resolver, ResolverArenas, ExternPreludeEntry}; use Namespace::{self, TypeNS, ValueNS, MacroNS}; use {resolve_error, resolve_struct_error, ResolutionError}; @@ -122,7 +122,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { use_tree: &ast::UseTree, id: NodeId, vis: ty::Visibility, - parent_prefix: &[Ident], + parent_prefix: &[Segment], mut uniform_paths_canary_emitted: bool, nested: bool, item: &Item, @@ -139,10 +139,10 @@ impl<'a, 'cl> Resolver<'a, 'cl> { self.session.features_untracked().uniform_paths; let prefix_iter = || parent_prefix.iter().cloned() - .chain(use_tree.prefix.segments.iter().map(|seg| seg.ident)); + .chain(use_tree.prefix.segments.iter().map(|seg| seg.into())); let prefix_start = prefix_iter().next(); - let starts_with_non_keyword = prefix_start.map_or(false, |(ident, _)| { - !ident.is_path_segment_keyword() + let starts_with_non_keyword = prefix_start.map_or(false, |seg| { + !seg.ident.is_path_segment_keyword() }); // Imports are resolved as global by default, prepend `CrateRoot`, @@ -156,7 +156,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }; let root = if inject_crate_root { let span = use_tree.prefix.span.shrink_to_lo(); - Some(Ident::new(keywords::CrateRoot.name(), span)) + Some(Segment::from_ident(Ident::new(keywords::CrateRoot.name(), span))) } else { None }; @@ -202,13 +202,13 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let source = prefix_start.unwrap(); // Helper closure to emit a canary with the given base path. - let emit = |this: &mut Self, base: Option<(Ident, Option)>| { + let emit = |this: &mut Self, base: Option| { let subclass = SingleImport { target: Ident { name: keywords::Underscore.name().gensymed(), - span: source.0.span, + span: source.ident.span, }, - source: source.0, + source: source.ident, result: PerNS { type_ns: Cell::new(Err(Undetermined)), value_ns: Cell::new(Err(Undetermined)), @@ -219,7 +219,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { this.add_import_directive( base.into_iter().collect(), subclass.clone(), - source.0.span, + source.ident.span, id, root_use_tree.span, root_id, @@ -230,15 +230,18 @@ impl<'a, 'cl> Resolver<'a, 'cl> { }; // A single simple `self::x` canary. - emit(self, Some((Ident { - name: keywords::SelfValue.name(), - span: source.0.span, - }, source.1))); + emit(self, Some(Segment { + ident: Ident { + name: keywords::SelfValue.name(), + span: source.ident.span, + }, + id: source.id + })); // One special unprefixed canary per block scope around // the import, to detect items unreachable by `self::x`. let orig_current_module = self.current_module; - let mut span = source.0.span.modern(); + let mut span = source.ident.span.modern(); loop { match self.current_module.kind { ModuleKind::Block(..) => emit(self, None), @@ -265,11 +268,11 @@ impl<'a, 'cl> Resolver<'a, 'cl> { if nested { // Correctly handle `self` - if source.0.name == keywords::SelfValue.name() { + if source.ident.name == keywords::SelfValue.name() { type_ns_only = true; - let empty_prefix = module_path.last().map_or(true, |(ident, _)| { - ident.name == keywords::CrateRoot.name() + let empty_prefix = module_path.last().map_or(true, |seg| { + seg.ident.name == keywords::CrateRoot.name() }); if empty_prefix { resolve_error( @@ -284,20 +287,20 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // Replace `use foo::self;` with `use foo;` source = module_path.pop().unwrap(); if rename.is_none() { - ident = source.0; + ident = source.ident; } } } else { // Disallow `self` - if source.0.name == keywords::SelfValue.name() { + if source.ident.name == keywords::SelfValue.name() { resolve_error(self, use_tree.span, ResolutionError::SelfImportsOnlyAllowedWithin); } // Disallow `use $crate;` - if source.0.name == keywords::DollarCrate.name() && module_path.is_empty() { - let crate_root = self.resolve_crate_root(source.0); + if source.ident.name == keywords::DollarCrate.name() && module_path.is_empty() { + let crate_root = self.resolve_crate_root(source.ident); let crate_name = match crate_root.kind { ModuleKind::Def(_, name) => name, ModuleKind::Block(..) => unreachable!(), @@ -307,11 +310,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> { // while the current crate doesn't have a valid `crate_name`. if crate_name != keywords::Invalid.name() { // `crate_name` should not be interpreted as relative. - module_path.push((Ident { - name: keywords::CrateRoot.name(), - span: source.0.span, - }, Some(self.session.next_node_id()))); - source.0.name = crate_name; + module_path.push(Segment { + ident: Ident { + name: keywords::CrateRoot.name(), + span: source.ident.span, + }, + id: Some(self.session.next_node_id()), + }); + source.ident.name = crate_name; } if rename.is_none() { ident.name = crate_name; @@ -332,7 +338,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { let subclass = SingleImport { target: ident, - source: source.0, + source: source.ident, result: PerNS { type_ns: Cell::new(Err(Undetermined)), value_ns: Cell::new(Err(Undetermined)), @@ -392,17 +398,6 @@ impl<'a, 'cl> Resolver<'a, 'cl> { e.emit(); } - 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, diff --git a/src/librustc_resolve/error_reporting.rs b/src/librustc_resolve/error_reporting.rs index 6fcee4051ac37..d77b1868ed72e 100644 --- a/src/librustc_resolve/error_reporting.rs +++ b/src/librustc_resolve/error_reporting.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use {CrateLint, PathResult}; +use {CrateLint, PathResult, Segment}; use std::collections::BTreeSet; @@ -23,8 +23,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { pub(crate) fn make_path_suggestion( &mut self, span: Span, - path: Vec - ) -> Option> { + path: Vec + ) -> Option> { debug!("make_path_suggestion: span={:?} path={:?}", span, path); // If we don't have a path to suggest changes to, then return. if path.is_empty() { @@ -37,13 +37,13 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { match (path.get(0), path.get(1)) { // Make suggestions that require at least two non-special path segments. - (Some(fst), Some(snd)) if !is_special(*fst) && !is_special(*snd) => { + (Some(fst), Some(snd)) if !is_special(fst.ident) && !is_special(snd.ident) => { debug!("make_path_suggestion: fst={:?} snd={:?}", fst, snd); self.make_missing_self_suggestion(span, path.clone()) .or_else(|| self.make_missing_crate_suggestion(span, path.clone())) .or_else(|| self.make_missing_super_suggestion(span, path.clone())) - .or_else(|| self.make_external_crate_suggestion(span, path.clone())) + .or_else(|| self.make_external_crate_suggestion(span, path)) }, _ => None, } @@ -59,10 +59,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { fn make_missing_self_suggestion( &mut self, span: Span, - mut path: Vec - ) -> Option> { + mut path: Vec + ) -> Option> { // Replace first ident with `self` and check if that is valid. - path[0].name = keywords::SelfValue.name(); + path[0].ident.name = keywords::SelfValue.name(); let result = self.resolve_path(None, &path, None, false, span, CrateLint::No); debug!("make_missing_self_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { @@ -82,10 +82,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { fn make_missing_crate_suggestion( &mut self, span: Span, - mut path: Vec - ) -> Option> { + mut path: Vec + ) -> Option> { // Replace first ident with `crate` and check if that is valid. - path[0].name = keywords::Crate.name(); + path[0].ident.name = keywords::Crate.name(); let result = self.resolve_path(None, &path, None, false, span, CrateLint::No); debug!("make_missing_crate_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { @@ -105,10 +105,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { fn make_missing_super_suggestion( &mut self, span: Span, - mut path: Vec - ) -> Option> { + mut path: Vec + ) -> Option> { // Replace first ident with `crate` and check if that is valid. - path[0].name = keywords::Super.name(); + path[0].ident.name = keywords::Super.name(); let result = self.resolve_path(None, &path, None, false, span, CrateLint::No); debug!("make_missing_super_suggestion: path={:?} result={:?}", path, result); if let PathResult::Module(..) = result { @@ -131,8 +131,8 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { fn make_external_crate_suggestion( &mut self, span: Span, - mut path: Vec - ) -> Option> { + mut path: Vec + ) -> Option> { // Need to clone else we can't call `resolve_path` without a borrow error. We also store // into a `BTreeMap` so we can get consistent ordering (and therefore the same diagnostic) // each time. @@ -148,7 +148,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { for name in external_crate_names.iter().rev() { // Replace the first after root (a placeholder we inserted) with a crate name // and check if that is valid. - path[1].name = *name; + path[1].ident.name = *name; let result = self.resolve_path(None, &path, None, false, span, CrateLint::No); debug!("make_external_crate_suggestion: name={:?} path={:?} result={:?}", name, path, result); @@ -157,8 +157,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } } - // Remove our placeholder segment. - path.remove(1); None } } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 4eb40320c4abb..58e39e900ac91 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -632,6 +632,43 @@ impl<'a> PathSource<'a> { } } +// A minimal representation of a path segment. We use this in resolve because +// we synthesize 'path segments' which don't have the rest of an AST or HIR +// PathSegment. +#[derive(Clone, Copy, Debug)] +pub struct Segment { + ident: Ident, + id: Option, +} + +impl Segment { + fn from_path(path: &Path) -> Vec { + path.segments.iter().map(|s| s.into()).collect() + } + + fn from_ident(ident: Ident) -> Segment { + Segment { + ident, + id: None, + } + } + + fn names_to_string(segments: &[Segment]) -> String { + names_to_string(&segments.iter() + .map(|seg| seg.ident) + .collect::>()) + } +} + +impl<'a> From<&'a ast::PathSegment> for Segment { + fn from(seg: &'a ast::PathSegment) -> Segment { + Segment { + ident: seg.ident, + id: Some(seg.id), + } + } +} + struct UsePlacementFinder { target_module: NodeId, span: Option, @@ -1632,7 +1669,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { let namespace = if is_value { ValueNS } else { TypeNS }; let span = path.span; let segments = &path.segments; - let path: Vec<_> = segments.iter().map(|seg| (seg.ident, Some(seg.id))).collect(); + let path = Segment::from_path(&path); // FIXME (Manishearth): Intra doc links won't get warned of epoch changes let def = match self.resolve_path(None, &path, Some(namespace), true, span, CrateLint::No) { PathResult::Module(ModuleOrUniformRoot::Module(module)) => @@ -2482,9 +2519,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let mut new_val = None; let mut new_id = None; if let Some(trait_ref) = opt_trait_ref { - let path: Vec<_> = trait_ref.path.segments.iter() - .map(|seg| (seg.ident, Some(seg.id))) - .collect(); + let path: Vec<_> = Segment::from_path(&trait_ref.path); let def = self.smart_resolve_path_fragment( trait_ref.ref_id, None, @@ -2980,21 +3015,25 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { source: PathSource, crate_lint: CrateLint ) -> PathResolution { - let segments = &path.segments.iter() - .map(|seg| (seg.ident, Some(seg.id))) - .collect::>(); - self.smart_resolve_path_fragment(id, qself, segments, path.span, source, crate_lint) + self.smart_resolve_path_fragment( + id, + qself, + &Segment::from_path(path), + path.span, + source, + crate_lint, + ) } fn smart_resolve_path_fragment(&mut self, id: NodeId, qself: Option<&QSelf>, - path: &[(Ident, Option)], + path: &[Segment], span: Span, source: PathSource, crate_lint: CrateLint) -> PathResolution { - let ident_span = path.last().map_or(span, |ident| ident.0.span); + let ident_span = path.last().map_or(span, |ident| ident.ident.span); let ns = source.namespace(); let is_expected = &|def| source.is_expected(def); let is_enum_variant = &|def| if let Def::Variant(..) = def { true } else { false }; @@ -3004,17 +3043,17 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // Make the base error. let expected = source.descr_expected(); let path_str = names_to_string(path); - let item_str = path.last().unwrap().0; + let item_str = path.last().unwrap().ident; let code = source.error_code(def.is_some()); let (base_msg, fallback_label, base_span) = if let Some(def) = def { (format!("expected {}, found {} `{}`", expected, def.kind_name(), path_str), format!("not a {}", expected), span) } else { - let item_span = path.last().unwrap().0.span; + let item_span = path.last().unwrap().ident.span; let (mod_prefix, mod_str) = if path.len() == 1 { (String::new(), "this scope".to_string()) - } else if path.len() == 2 && path[0].0.name == keywords::CrateRoot.name() { + } else if path.len() == 2 && path[0].ident.name == keywords::CrateRoot.name() { (String::new(), "the crate root".to_string()) } else { let mod_path = &path[..path.len() - 1]; @@ -3024,7 +3063,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { module.def(), _ => None, }.map_or(String::new(), |def| format!("{} ", def.kind_name())); - (mod_prefix, format!("`{}`", names_and_ids_to_string(mod_path))) + (mod_prefix, format!("`{}`", Segment::names_to_string(mod_path))) }; (format!("cannot find {} `{}` in {}{}", expected, item_str, mod_prefix, mod_str), format!("not found in {}", mod_str), @@ -3035,7 +3074,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // Emit help message for fake-self from other languages like `this`(javascript) if ["this", "my"].contains(&&*item_str.as_str()) - && this.self_value_is_available(path[0].span, span) { + && this.self_value_is_available(path[0].ident.span, span) { err.span_suggestion_with_applicability( span, "did you mean", @@ -3070,7 +3109,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } // Try to lookup the name in more relaxed fashion for better error reporting. - let ident = path.last().unwrap().0; + let ident = path.last().unwrap().ident; let candidates = this.lookup_import_candidates(ident.name, ns, is_expected); if candidates.is_empty() && is_expected(Def::Enum(DefId::local(CRATE_DEF_INDEX))) { let enum_candidates = @@ -3097,7 +3136,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } if path.len() == 1 && this.self_type_is_available(span) { if let Some(candidate) = this.lookup_assoc_candidate(ident, ns, is_expected) { - let self_is_available = this.self_value_is_available(path[0].0.span, span); + let self_is_available = this.self_value_is_available(path[0].ident.span, span); match candidate { AssocSuggestion::Field => { err.span_suggestion_with_applicability( @@ -3332,7 +3371,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { // or `::A::B`. If `B` should be resolved in value namespace then // it needs to be added to the trait map. if ns == ValueNS { - let item_name = path.last().unwrap().0; + let item_name = path.last().unwrap().ident; let traits = self.get_traits_containing_item(item_name, ns); self.trait_map.insert(id, traits); } @@ -3402,7 +3441,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_qpath_anywhere(&mut self, id: NodeId, qself: Option<&QSelf>, - path: &[(Ident, Option)], + path: &[Segment], primary_ns: Namespace, span: Span, defer_to_typeck: bool, @@ -3424,10 +3463,10 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } if primary_ns != MacroNS && - (self.macro_names.contains(&path[0].0.modern()) || - self.builtin_macros.get(&path[0].0.name).cloned() + (self.macro_names.contains(&path[0].ident.modern()) || + self.builtin_macros.get(&path[0].ident.name).cloned() .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang) || - self.macro_use_prelude.get(&path[0].0.name).cloned() + self.macro_use_prelude.get(&path[0].ident.name).cloned() .and_then(NameBinding::macro_kind) == Some(MacroKind::Bang)) { // Return some dummy definition, it's enough for error reporting. return Some( @@ -3441,7 +3480,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_qpath(&mut self, id: NodeId, qself: Option<&QSelf>, - path: &[(Ident, Option)], + path: &[Segment], ns: Namespace, span: Span, global_by_default: bool, @@ -3531,8 +3570,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { PathResult::Failed(..) if (ns == TypeNS || path.len() > 1) && self.primitive_type_table.primitive_types - .contains_key(&path[0].0.name) => { - let prim = self.primitive_type_table.primitive_types[&path[0].0.name]; + .contains_key(&path[0].ident.name) => { + let prim = self.primitive_type_table.primitive_types[&path[0].ident.name]; PathResolution::with_unresolved_segments(Def::PrimTy(prim), path.len() - 1) } PathResult::Module(ModuleOrUniformRoot::Module(module)) => @@ -3547,8 +3586,8 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { }; if path.len() > 1 && !global_by_default && result.base_def() != Def::Err && - path[0].0.name != keywords::CrateRoot.name() && - path[0].0.name != keywords::DollarCrate.name() { + path[0].ident.name != keywords::CrateRoot.name() && + path[0].ident.name != keywords::DollarCrate.name() { let unqualified_result = { match self.resolve_path( None, @@ -3576,7 +3615,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_path( &mut self, base_module: Option>, - path: &[(Ident, Option)], + path: &[Segment], opt_ns: Option, // `None` indicates a module path record_used: bool, path_span: Span, @@ -3590,7 +3629,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn resolve_path_with_parent_scope( &mut self, base_module: Option>, - path: &[Ident], + path: &[Segment], opt_ns: Option, // `None` indicates a module path parent_scope: &ParentScope<'a>, record_used: bool, @@ -3612,7 +3651,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { crate_lint, ); - for (i, &(ident, id)) in path.iter().enumerate() { + for (i, &Segment { ident, id }) in path.iter().enumerate() { debug!("resolve_path ident {} {:?}", i, ident); let is_last = i == path.len() - 1; @@ -3674,7 +3713,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } else { format!("`{}`", name) }; - let msg = if i == 1 && path[0].0.name == keywords::CrateRoot.name() { + let msg = if i == 1 && path[0].ident.name == keywords::CrateRoot.name() { format!("global paths cannot start with {}", name_str) } else { format!("{} in paths can only be used in start position", name_str) @@ -3771,7 +3810,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } else if i == 0 { format!("Use of undeclared type or module `{}`", ident) } else { - format!("Could not find `{}` in `{}`", ident, path[i - 1].0) + format!("Could not find `{}` in `{}`", ident, path[i - 1].ident) }; return PathResult::Failed(ident.span, msg, is_last); } @@ -3789,7 +3828,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { fn lint_if_path_starts_with_module( &self, crate_lint: CrateLint, - path: &[(Ident, Option)], + path: &[Segment], path_span: Span, second_binding: Option<&NameBinding>, ) { @@ -3806,7 +3845,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { }; let first_name = match path.get(0) { - Some(ident) => ident.0.name, + Some(ident) => ident.ident.name, None => return, }; @@ -3818,7 +3857,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { match path.get(1) { // If this import looks like `crate::...` it's already good - Some((ident, _)) if ident.name == keywords::Crate.name() => return, + Some(Segment { ident, .. }) if ident.name == keywords::Crate.name() => return, // Otherwise go below to see if it's an extern crate Some(_) => {} // If the path has length one (and it's `CrateRoot` most likely) @@ -4011,7 +4050,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } fn lookup_typo_candidate(&mut self, - path: &[(Ident, Option)], + path: &[Segment], ns: Namespace, filter_fn: FilterFn, span: Span) @@ -4075,7 +4114,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } - let name = path[path.len() - 1].0.name; + let name = path[path.len() - 1].ident.name; // Make sure error reporting is deterministic. names.sort_by_cached_key(|name| name.as_str()); match find_best_match_for_name(names.iter(), &name.as_str(), None) { @@ -4592,7 +4631,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { ast::VisibilityKind::Restricted { ref path, id, .. } => { // Visibilities are resolved as global by default, add starting root segment. let segments = path.make_root().iter().chain(path.segments.iter()) - .map(|seg| (seg.ident, Some(seg.id))) + .map(|seg| Segment { ident: seg.ident, id: Some(seg.id) }) .collect::>(); let def = self.smart_resolve_path_fragment( id, @@ -4885,12 +4924,12 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { } } -fn is_self_type(path: &[(Ident, Option)], namespace: Namespace) -> bool { - namespace == TypeNS && path.len() == 1 && path[0].0.name == keywords::SelfType.name() +fn is_self_type(path: &[Segment], namespace: Namespace) -> bool { + namespace == TypeNS && path.len() == 1 && path[0].ident.name == keywords::SelfType.name() } -fn is_self_value(path: &[(Ident, Option)], namespace: Namespace) -> bool { - namespace == ValueNS && path.len() == 1 && path[0].0.name == keywords::SelfValue.name() +fn is_self_value(path: &[Segment], namespace: Namespace) -> bool { + namespace == ValueNS && path.len() == 1 && path[0].ident.name == keywords::SelfValue.name() } fn names_to_string(idents: &[Ident]) -> String { @@ -4906,12 +4945,6 @@ fn names_to_string(idents: &[Ident]) -> String { result } -fn names_and_ids_to_string(segments: &[(Ident, Option)]) -> String { - names_to_string(&segments.iter() - .map(|seg| seg.0) - .collect::>()) -} - fn path_names_to_string(path: &Path) -> String { names_to_string(&path.segments.iter() .map(|seg| seg.ident) diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index f462542f1d3e0..68b3a6be29282 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -9,7 +9,7 @@ // except according to those terms. use {AmbiguityError, CrateLint, Resolver, ResolutionError, is_known_tool, resolve_error}; -use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, ToNameBinding}; +use {Module, ModuleKind, NameBinding, NameBindingKind, PathResult, Segment, ToNameBinding}; use ModuleOrUniformRoot; use Namespace::{self, *}; use build_reduced_graph::{BuildReducedGraphVisitor, IsMacroExport}; @@ -461,14 +461,15 @@ impl<'a, 'cl> Resolver<'a, 'cl> { parent_scope: &ParentScope<'a>, force: bool, ) -> Result { - let ast::Path { ref segments, span } = *path; - let mut path: Vec<_> = segments.iter().map(|seg| (seg.ident, Some(seg.id))).collect(); + let span = path.span; + let mut path = Segment::from_path(path); // Possibly apply the macro helper hack if kind == MacroKind::Bang && path.len() == 1 && - path[0].0.span.ctxt().outer().expn_info().map_or(false, |info| info.local_inner_macros) { - let root = Ident::new(keywords::DollarCrate.name(), path[0].0.span); - path.insert(0, (root, None)); + path[0].ident.span.ctxt().outer().expn_info() + .map_or(false, |info| info.local_inner_macros) { + let root = Ident::new(keywords::DollarCrate.name(), path[0].ident.span); + path.insert(0, Segment::from_ident(root)); } if path.len() > 1 { @@ -498,14 +499,14 @@ impl<'a, 'cl> Resolver<'a, 'cl> { parent_scope.module.macro_resolutions.borrow_mut() .push((path .iter() - .map(|(ident, _)| *ident) + .map(|seg| seg.ident) .collect::>() .into_boxed_slice(), span)); def } else { let binding = self.early_resolve_ident_in_lexical_scope( - path[0].0, MacroNS, Some(kind), parent_scope, false, force, span + path[0].ident, MacroNS, Some(kind), parent_scope, false, force, span ); match binding { Ok(..) => {} @@ -514,7 +515,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } parent_scope.module.legacy_macro_resolutions.borrow_mut() - .push((path[0].0, kind, parent_scope.clone(), binding.ok())); + .push((path[0].ident, kind, parent_scope.clone(), binding.ok())); binding.map(|binding| binding.def_ignoring_ambiguity()) } @@ -850,10 +851,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { pub fn finalize_current_module_macro_resolutions(&mut self) { let module = self.current_module; for &(ref path, span) in module.macro_resolutions.borrow().iter() { - let path = path - .iter() - .map(|ident| (*ident, None)) - .collect::)>>(); + let path: Vec<_> = path.iter().map(|&ident| Segment::from_ident(ident)).collect(); match self.resolve_path(None, &path, Some(MacroNS), true, span, CrateLint::No) { PathResult::NonModule(_) => {}, PathResult::Failed(span, msg, _) => { @@ -946,7 +944,7 @@ impl<'a, 'cl> Resolver<'a, 'cl> { } }; let ident = Ident::new(Symbol::intern(name), span); - self.lookup_typo_candidate(&[(ident, None)], MacroNS, is_macro, span) + self.lookup_typo_candidate(&[Segment::from_ident(ident)], MacroNS, is_macro, span) }); if let Some(suggestion) = suggestion { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 4d3a67d4a892e..bd968f1cbec25 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -13,8 +13,8 @@ use self::ImportDirectiveSubclass::*; use {AmbiguityError, CrateLint, Module, ModuleOrUniformRoot, PerNS}; use Namespace::{self, TypeNS, MacroNS}; use {NameBinding, NameBindingKind, ToNameBinding, PathResult, PrivacyError}; -use Resolver; -use {names_to_string, names_and_ids_to_string, module_to_string}; +use {Resolver, Segment}; +use {names_to_string, module_to_string}; use {resolve_error, ResolutionError}; use rustc_data_structures::ptr_key::PtrKey; @@ -89,7 +89,7 @@ pub struct ImportDirective<'a> { pub root_span: Span, pub parent: Module<'a>, - pub module_path: Vec<(Ident, Option)>, + pub module_path: Vec, /// The resolution of `module_path`. pub imported_module: Cell>>, pub subclass: ImportDirectiveSubclass<'a>, @@ -393,7 +393,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { // Add an import directive to the current module. pub fn add_import_directive(&mut self, - module_path: Vec<(Ident, Option)>, + module_path: Vec, subclass: ImportDirectiveSubclass<'a>, span: Span, id: NodeId, @@ -679,7 +679,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let has_explicit_self = !import.module_path.is_empty() && - import.module_path[0].0.name == keywords::SelfValue.name(); + import.module_path[0].ident.name == keywords::SelfValue.name(); self.per_ns(|_, ns| { if let Some(result) = result[ns].get().ok() { @@ -729,7 +729,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { } if !seen_spans.contains(&span) { let path = import_path_to_string( - &import.module_path.iter().map(|(ident, _)| *ident).collect::>(), + &import.module_path.iter().map(|seg| seg.ident).collect::>(), &import.subclass, span, ); @@ -853,9 +853,10 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { /// If successful, the resolved bindings are written into the module. fn resolve_import(&mut self, directive: &'b ImportDirective<'b>) -> bool { debug!("(resolving import for module) resolving import `{}::...` in `{}`", - names_and_ids_to_string(&directive.module_path[..]), + Segment::names_to_string(&directive.module_path[..]), module_to_string(self.current_module).unwrap_or_else(|| "???".to_string())); + self.current_module = directive.parent; let module = if let Some(module) = directive.imported_module.get() { @@ -968,7 +969,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { ) { Some(( span, - format!("Did you mean `{}`?", names_to_string(&suggested_path[..])) + format!("Did you mean `{}`?", Segment::names_to_string(&suggested_path)) )) } else { Some((span, msg)) @@ -984,7 +985,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = module_path.clone(); - full_path.push((keywords::Invalid.ident(), None)); + full_path.push(Segment::from_ident(keywords::Invalid.ident())); self.lint_if_path_starts_with_module( directive.crate_lint(), &full_path, @@ -1148,7 +1149,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // HACK(eddyb) `lint_if_path_starts_with_module` needs at least // 2 segments, so the `resolve_path` above won't trigger it. let mut full_path = module_path.clone(); - full_path.push((ident, None)); + full_path.push(Segment::from_ident(ident)); self.per_ns(|this, ns| { if let Ok(binding) = result[ns].get() { this.lint_if_path_starts_with_module( @@ -1290,7 +1291,7 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { let resolutions = imported_module.parent.expect("parent should exist") .resolutions.borrow(); let enum_path_segment_index = directive.module_path.len() - 1; - let enum_ident = directive.module_path[enum_path_segment_index].0; + let enum_ident = directive.module_path[enum_path_segment_index].ident; let enum_resolution = resolutions.get(&(enum_ident, TypeNS)) .expect("resolution should exist"); diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 619a53e1c7c95..589b3e30fcfbc 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2137,7 +2137,7 @@ impl<'a> Parser<'a> { PathSegment { ident, args, id: ast::DUMMY_NODE_ID } } else { // Generic arguments are not found. - PathSegment::from_ident(ident,) + PathSegment::from_ident(ident) }) } From 63ac2aae51034f93c23cffde7be711a86f9d139f Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 11 Oct 2018 21:15:18 +1300 Subject: [PATCH 09/10] Fix tests and assertions; add some comments --- src/librustc/hir/intravisit.rs | 17 ++- src/librustc/hir/lowering.rs | 110 +++++++++++++----- src/librustc/hir/map/collector.rs | 15 ++- src/librustc/hir/map/hir_id_validator.rs | 12 +- src/librustc/hir/map/mod.rs | 2 +- src/librustc/hir/mod.rs | 5 + src/librustc/hir/print.rs | 11 ++ src/librustc_resolve/lib.rs | 10 +- src/librustc_resolve/resolve_imports.rs | 1 - src/librustc_save_analysis/dump_visitor.rs | 4 - src/librustc_save_analysis/lib.rs | 6 +- .../incremental/hashes/closure_expressions.rs | 2 +- src/test/mir-opt/end_region_1.rs | 6 +- src/test/mir-opt/end_region_2.rs | 14 +-- src/test/mir-opt/end_region_3.rs | 14 +-- src/test/mir-opt/end_region_4.rs | 14 +-- src/test/mir-opt/end_region_5.rs | 14 +-- src/test/mir-opt/end_region_6.rs | 18 +-- src/test/mir-opt/end_region_7.rs | 6 +- src/test/mir-opt/end_region_8.rs | 18 +-- src/test/mir-opt/end_region_9.rs | 6 +- src/test/mir-opt/end_region_cyclic.rs | 50 ++++---- .../end_region_destruction_extents_1.rs | 64 +++++----- src/test/mir-opt/validate_1.rs | 18 +-- src/test/mir-opt/validate_3.rs | 18 +-- src/test/mir-opt/validate_5.rs | 6 +- 26 files changed, 274 insertions(+), 187 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 95b73d5f87b39..dcc0f8545e5d7 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -298,6 +298,9 @@ pub trait Visitor<'v> : Sized { fn visit_fn(&mut self, fk: FnKind<'v>, fd: &'v FnDecl, b: BodyId, s: Span, id: NodeId) { walk_fn(self, fk, fd, b, s, id) } + fn visit_use(&mut self, path: &'v Path, id: NodeId, hir_id: HirId) { + walk_use(self, path, id, hir_id) + } fn visit_trait_item(&mut self, ti: &'v TraitItem) { walk_trait_item(self, ti) } @@ -471,8 +474,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { } } ItemKind::Use(ref path, _) => { - visitor.visit_id(item.id); - visitor.visit_path(path, item.hir_id); + visitor.visit_use(path, item.id, item.hir_id); } ItemKind::Static(ref typ, _, body) | ItemKind::Const(ref typ, body) => { @@ -554,6 +556,14 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { walk_list!(visitor, visit_attribute, &item.attrs); } +pub fn walk_use<'v, V: Visitor<'v>>(visitor: &mut V, + path: &'v Path, + item_id: NodeId, + hir_id: HirId) { + visitor.visit_id(item_id); + visitor.visit_path(path, hir_id); +} + pub fn walk_enum_def<'v, V: Visitor<'v>>(visitor: &mut V, enum_definition: &'v EnumDef, generics: &'v Generics, @@ -652,6 +662,9 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V, path_span: Span, segment: &'v PathSegment) { visitor.visit_ident(segment.ident); + if let Some(id) = segment.id { + visitor.visit_id(id); + } if let Some(ref args) = segment.args { visitor.visit_generic_args(path_span, args); } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 58d860d9d983b..3aea26c6829a5 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1069,6 +1069,9 @@ impl<'a> LoweringContext<'a> { } fn lower_attr(&mut self, attr: &Attribute) -> Attribute { + // Note that we explicitly do not walk the path. Since we don't really + // lower attributes (we use the AST version) there is nowhere to keep + // the HirIds. We don't actually need HIR version of attributes anyway. Attribute { id: attr.id, style: attr.style, @@ -1682,6 +1685,7 @@ impl<'a> LoweringContext<'a> { num_lifetimes, parenthesized_generic_args, itctx.reborrow(), + None, ) }) .collect(), @@ -1725,6 +1729,7 @@ impl<'a> LoweringContext<'a> { 0, ParenthesizedGenericArgs::Warn, itctx.reborrow(), + None, )); let qpath = hir::QPath::TypeRelative(ty, segment); @@ -1753,6 +1758,7 @@ impl<'a> LoweringContext<'a> { p: &Path, ident: Option, param_mode: ParamMode, + explicit_owner: Option, ) -> hir::Path { hir::Path { def, @@ -1766,6 +1772,7 @@ impl<'a> LoweringContext<'a> { 0, ParenthesizedGenericArgs::Err, ImplTraitContext::disallowed(), + explicit_owner, ) }) .chain(ident.map(|ident| hir::PathSegment::from_ident(ident))) @@ -1776,7 +1783,7 @@ impl<'a> LoweringContext<'a> { fn lower_path(&mut self, id: NodeId, p: &Path, param_mode: ParamMode) -> hir::Path { let def = self.expect_full_def(id); - self.lower_path_extra(def, p, None, param_mode) + self.lower_path_extra(def, p, None, param_mode, None) } fn lower_path_segment( @@ -1787,6 +1794,7 @@ impl<'a> LoweringContext<'a> { expected_lifetimes: usize, parenthesized_generic_args: ParenthesizedGenericArgs, itctx: ImplTraitContext<'_>, + explicit_owner: Option, ) -> hir::PathSegment { let (mut generic_args, infer_types) = if let Some(ref generic_args) = segment.args { let msg = "parenthesized parameters may only be used with a trait"; @@ -1858,9 +1866,15 @@ impl<'a> LoweringContext<'a> { } let def = self.expect_full_def(segment.id); + let id = if let Some(owner) = explicit_owner { + self.lower_node_id_with_owner(segment.id, owner) + } else { + self.lower_node_id(segment.id) + }; + hir::PathSegment::new( segment.ident, - Some(segment.id), + Some(id.node_id), Some(def), generic_args, infer_types, @@ -2944,6 +2958,12 @@ impl<'a> LoweringContext<'a> { attrs: &hir::HirVec, ) -> hir::ItemKind { let path = &tree.prefix; + let segments = prefix + .segments + .iter() + .chain(path.segments.iter()) + .cloned() + .collect(); match tree.kind { UseTreeKind::Simple(rename, id1, id2) => { @@ -2951,12 +2971,7 @@ impl<'a> LoweringContext<'a> { // First apply the prefix to the path let mut path = Path { - segments: prefix - .segments - .iter() - .chain(path.segments.iter()) - .cloned() - .collect(), + segments, span: path.span, }; @@ -2976,9 +2991,18 @@ impl<'a> LoweringContext<'a> { // for later let ret_def = defs.next().unwrap_or(Def::Err); + // Here, we are looping over namespaces, if they exist for the definition + // being imported. We only handle type and value namespaces because we + // won't be dealing with macros in the rest of the compiler. + // Essentially a single `use` which imports two names is desugared into + // two imports. for (def, &new_node_id) in defs.zip([id1, id2].iter()) { let vis = vis.clone(); let name = name.clone(); + let mut path = path.clone(); + for seg in &mut path.segments { + seg.id = self.sess.next_node_id(); + } let span = path.span; self.resolver.definitions().create_def_with_parent( parent_def_index, @@ -2991,7 +3015,8 @@ impl<'a> LoweringContext<'a> { self.with_hir_id_owner(new_node_id, |this| { let new_id = this.lower_node_id(new_node_id); - let path = this.lower_path_extra(def, &path, None, ParamMode::Explicit); + let path = + this.lower_path_extra(def, &path, None, ParamMode::Explicit, None); let item = hir::ItemKind::Use(P(path), hir::UseKind::Single); let vis_kind = match vis.node { hir::VisibilityKind::Public => hir::VisibilityKind::Public, @@ -3001,7 +3026,6 @@ impl<'a> LoweringContext<'a> { let id = this.next_id(); hir::VisibilityKind::Restricted { path: path.clone(), - // We are allocating a new NodeId here id: id.node_id, hir_id: id.hir_id, } @@ -3024,19 +3048,15 @@ impl<'a> LoweringContext<'a> { }); } - let path = P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit)); + let path = + P(self.lower_path_extra(ret_def, &path, None, ParamMode::Explicit, None)); hir::ItemKind::Use(path, hir::UseKind::Single) } UseTreeKind::Glob => { let path = P(self.lower_path( id, &Path { - segments: prefix - .segments - .iter() - .chain(path.segments.iter()) - .cloned() - .collect(), + segments, span: path.span, }, ParamMode::Explicit, @@ -3044,19 +3064,17 @@ impl<'a> LoweringContext<'a> { hir::ItemKind::Use(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { + // Nested imports are desugared into simple imports. + let prefix = Path { - segments: prefix - .segments - .iter() - .chain(path.segments.iter()) - .cloned() - .collect(), + segments, span: prefix.span.to(path.span), }; - // Add all the nested PathListItems in the HIR + // Add all the nested PathListItems to the HIR. for &(ref use_tree, id) in trees { self.allocate_hir_id_counter(id, &use_tree); + let LoweredNodeId { node_id: new_id, hir_id: new_hir_id, @@ -3064,10 +3082,26 @@ impl<'a> LoweringContext<'a> { let mut vis = vis.clone(); let mut name = name.clone(); - let item = - self.lower_use_tree(use_tree, &prefix, new_id, &mut vis, &mut name, &attrs); + let mut prefix = prefix.clone(); + // Give the segments new ids since they are being cloned. + for seg in &mut prefix.segments { + seg.id = self.sess.next_node_id(); + } + + // Each `use` import is an item and thus are owners of the + // names in the path. Up to this point the nested import is + // the current owner, since we want each desugared import to + // own its own names, we have to adjust the owner before + // lowering the rest of the import. self.with_hir_id_owner(new_id, |this| { + let item = this.lower_use_tree(use_tree, + &prefix, + new_id, + &mut vis, + &mut name, + attrs); + let vis_kind = match vis.node { hir::VisibilityKind::Public => hir::VisibilityKind::Public, hir::VisibilityKind::Crate(sugar) => hir::VisibilityKind::Crate(sugar), @@ -3076,7 +3110,6 @@ impl<'a> LoweringContext<'a> { let id = this.next_id(); hir::VisibilityKind::Restricted { path: path.clone(), - // We are allocating a new NodeId here id: id.node_id, hir_id: id.hir_id, } @@ -3089,7 +3122,7 @@ impl<'a> LoweringContext<'a> { hir::Item { id: new_id, hir_id: new_hir_id, - name: name, + name, attrs: attrs.clone(), node: item, vis, @@ -3653,6 +3686,7 @@ impl<'a> LoweringContext<'a> { 0, ParenthesizedGenericArgs::Err, ImplTraitContext::disallowed(), + None, ); let args = args.iter().map(|x| self.lower_expr(x)).collect(); hir::ExprKind::MethodCall(hir_seg, seg.ident.span, args) @@ -4506,8 +4540,15 @@ impl<'a> LoweringContext<'a> { } else { self.lower_node_id(id) }; + let def = self.expect_full_def(id); hir::VisibilityKind::Restricted { - path: P(self.lower_path(id, path, ParamMode::Explicit)), + path: P(self.lower_path_extra( + def, + path, + None, + ParamMode::Explicit, + explicit_owner, + )), id: lowered_id.node_id, hir_id: lowered_id.hir_id, } @@ -4814,8 +4855,15 @@ impl<'a> LoweringContext<'a> { params: Option>, is_value: bool ) -> hir::Path { - self.resolver - .resolve_str_path(span, self.crate_root, components, params, is_value) + let mut path = self.resolver + .resolve_str_path(span, self.crate_root, components, params, is_value); + + for seg in path.segments.iter_mut() { + if let Some(id) = seg.id { + seg.id = Some(self.lower_node_id(id).node_id); + } + } + path } fn ty_path(&mut self, id: LoweredNodeId, span: Span, qpath: hir::QPath) -> hir::Ty { diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index 7e5dd3f3756f7..8c701d9e4188f 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -210,17 +210,22 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { None => format!("{:?}", node) }; - if hir_id == ::hir::DUMMY_HIR_ID { - debug!("Maybe you forgot to lower the node id {:?}?", id); - } + let forgot_str = if hir_id == ::hir::DUMMY_HIR_ID { + format!("\nMaybe you forgot to lower the node id {:?}?", id) + } else { + String::new() + }; bug!("inconsistent DepNode for `{}`: \ - current_dep_node_owner={}, hir_id.owner={}", + current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?}) {}", node_str, self.definitions .def_path(self.current_dep_node_owner) .to_string_no_crate(), - self.definitions.def_path(hir_id.owner).to_string_no_crate()) + self.current_dep_node_owner, + self.definitions.def_path(hir_id.owner).to_string_no_crate(), + hir_id.owner, + forgot_str) } } diff --git a/src/librustc/hir/map/hir_id_validator.rs b/src/librustc/hir/map/hir_id_validator.rs index 087efbd4a22dd..896a6163eba64 100644 --- a/src/librustc/hir/map/hir_id_validator.rs +++ b/src/librustc/hir/map/hir_id_validator.rs @@ -88,7 +88,7 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> { walk(self); if owner_def_index == CRATE_DEF_INDEX { - return + return; } // There's always at least one entry for the owning item itself @@ -129,13 +129,16 @@ impl<'a, 'hir: 'a> HirIdValidator<'a, 'hir> { local_id, self.hir_map.node_to_string(node_id))); } - self.errors.push(format!( "ItemLocalIds not assigned densely in {}. \ - Max ItemLocalId = {}, missing IDs = {:?}", + Max ItemLocalId = {}, missing IDs = {:?}; seens IDs = {:?}", self.hir_map.def_path(DefId::local(owner_def_index)).to_string_no_crate(), max, - missing_items)); + missing_items, + self.hir_ids_seen + .values() + .map(|n| format!("({:?} {})", n, self.hir_map.node_to_string(*n))) + .collect::>())); } } } @@ -155,6 +158,7 @@ impl<'a, 'hir: 'a> intravisit::Visitor<'hir> for HirIdValidator<'a, 'hir> { self.errors.push(format!("HirIdValidator: No HirId assigned for NodeId {}: {:?}", node_id, self.hir_map.node_to_string(node_id))); + return; } if owner != stable_id.owner { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d89bb5db12f26..7a20146130d94 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1100,7 +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::PathSegment(a) => self.print_path_segment(&a), Node::Ty(a) => self.print_type(&a), Node::TraitRef(a) => self.print_trait_ref(&a), Node::Binding(a) | diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index c72a4a6dfc2b2..a2095ff40c040 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -347,6 +347,11 @@ impl fmt::Display for Path { pub struct PathSegment { /// The identifier portion of this path segment. pub ident: Ident, + // `id` and `def` are optional. We currently only use these in save-analysis, + // any path segments without these will not have save-analysis info and + // therefore will not have 'jump to def' in IDEs, but otherwise will not be + // affected. (In general, we don't bother to get the defs for synthesized + // segments, only for segments which have come from the AST). pub id: Option, pub def: Option, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index ad2fa48610b0e..e69d32ad1deaf 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1633,6 +1633,17 @@ impl<'a> State<'a> { Ok(()) } + pub fn print_path_segment(&mut self, segment: &hir::PathSegment) -> io::Result<()> { + if segment.ident.name != keywords::CrateRoot.name() && + segment.ident.name != keywords::DollarCrate.name() { + self.print_ident(segment.ident)?; + segment.with_generic_args(|generic_args| { + self.print_generic_args(generic_args, segment.infer_types, false) + })?; + } + Ok(()) + } + pub fn print_qpath(&mut self, qpath: &hir::QPath, colons_before_params: bool) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 58e39e900ac91..0285a3c568cc1 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1675,8 +1675,8 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { PathResult::Module(ModuleOrUniformRoot::Module(module)) => module.def().unwrap(), PathResult::NonModule(path_res) if path_res.unresolved_segments() == 0 => - *def = path_res.base_def(), - PathResult::NonModule(..) => + path_res.base_def(), + PathResult::NonModule(..) => { if let PathResult::Failed(span, msg, _) = self.resolve_path( None, &path, @@ -1686,7 +1686,9 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { CrateLint::No, ) { error_callback(self, span, ResolutionError::FailedToResolve(&msg)); - }, + } + Def::Err + } PathResult::Module(ModuleOrUniformRoot::UniformRoot(_)) | PathResult::Indeterminate => unreachable!(), PathResult::Failed(span, msg, _) => { @@ -3042,7 +3044,7 @@ impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { let report_errors = |this: &mut Self, def: Option| { // Make the base error. let expected = source.descr_expected(); - let path_str = names_to_string(path); + let path_str = Segment::names_to_string(path); let item_str = path.last().unwrap().ident; let code = source.error_code(def.is_some()); let (base_msg, fallback_label, base_span) = if let Some(def) = def { diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index bd968f1cbec25..810aff7f9b0a8 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -1314,7 +1314,6 @@ impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { "consider making the enum public", suggestion); err.emit(); - } } } } diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 7ba1783400664..a7fe1bb421c37 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1624,10 +1624,6 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc if let Some(fn_data) = self.save_ctxt.get_extern_item_data(item) { down_cast_data!(fn_data, DefData, item.span); - self.nest_tables( - item.id, - |v| v.process_formals(&decl.inputs, &fn_data.qualname), - ); self.process_generic_params(generics, &fn_data.qualname, item.id); self.dumper.dump_def(&access, fn_data); } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 9e0233149cc28..7689406b59a04 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -57,7 +57,7 @@ use std::env; use std::fs::File; use std::path::{Path, PathBuf}; -use syntax::ast::{self, Attribute, NodeId, PatKind}; +use syntax::ast::{self, Attribute, DUMMY_NODE_ID, NodeId, PatKind}; use syntax::source_map::Spanned; use syntax::parse::lexer::comments::strip_doc_comment_decoration; use syntax::print::pprust; @@ -703,6 +703,10 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { false } + if path_seg.id == DUMMY_NODE_ID { + return None; + } + let def = self.get_path_def(path_seg.id); let span = path_seg.ident.span; filter!(self.span_utils, span); diff --git a/src/test/incremental/hashes/closure_expressions.rs b/src/test/incremental/hashes/closure_expressions.rs index 8469f0aa6645d..85d1f3df05b1d 100644 --- a/src/test/incremental/hashes/closure_expressions.rs +++ b/src/test/incremental/hashes/closure_expressions.rs @@ -95,7 +95,7 @@ pub fn add_type_ascription_to_parameter() { } #[cfg(not(cfail1))] -#[rustc_clean(cfg="cfail2", except="HirBody, TypeckTables")] +#[rustc_clean(cfg="cfail2", except="HirBody, MirValidated, TypeckTables")] #[rustc_clean(cfg="cfail3")] pub fn add_type_ascription_to_parameter() { let closure = |x: u32| x + 1u32; diff --git a/src/test/mir-opt/end_region_1.rs b/src/test/mir-opt/end_region_1.rs index 23c00c3bce1d8..dd1c2bd51260b 100644 --- a/src/test/mir-opt/end_region_1.rs +++ b/src/test/mir-opt/end_region_1.rs @@ -22,7 +22,7 @@ fn main() { // START rustc.main.SimplifyCfg-qualify-consts.after.mir // let mut _0: (); // ... -// let _2: &'10_1rs i32; +// let _2: &'11_1rs i32; // ... // let _1: i32; // ... @@ -31,10 +31,10 @@ fn main() { // _1 = const 3i32; // FakeRead(ForLet, _1); // StorageLive(_2); -// _2 = &'10_1rs _1; +// _2 = &'11_1rs _1; // FakeRead(ForLet, _2); // _0 = (); -// EndRegion('10_1rs); +// EndRegion('11_1rs); // StorageDead(_2); // StorageDead(_1); // return; diff --git a/src/test/mir-opt/end_region_2.rs b/src/test/mir-opt/end_region_2.rs index 08de5320a2b32..6b0a28b811007 100644 --- a/src/test/mir-opt/end_region_2.rs +++ b/src/test/mir-opt/end_region_2.rs @@ -27,9 +27,9 @@ fn main() { // START rustc.main.SimplifyCfg-qualify-consts.after.mir // let mut _0: (); // ... -// let _7: &'23_3rs bool; +// let _7: &'26_3rs bool; // ... -// let _3: &'23_1rs bool; +// let _3: &'26_1rs bool; // ... // let _2: bool; // ... @@ -47,7 +47,7 @@ fn main() { // _2 = const true; // FakeRead(ForLet, _2); // StorageLive(_3); -// _3 = &'23_1rs _2; +// _3 = &'26_1rs _2; // FakeRead(ForLet, _3); // StorageLive(_5); // _5 = _2; @@ -59,7 +59,7 @@ fn main() { // bb4: { // _0 = (); // StorageDead(_5); -// EndRegion('23_1rs); +// EndRegion('26_1rs); // StorageDead(_3); // StorageDead(_2); // return; @@ -68,12 +68,12 @@ fn main() { // _4 = (); // StorageDead(_5); // StorageLive(_7); -// _7 = &'23_3rs _2; +// _7 = &'26_3rs _2; // FakeRead(ForLet, _7); // _1 = (); -// EndRegion('23_3rs); +// EndRegion('26_3rs); // StorageDead(_7); -// EndRegion('23_1rs); +// EndRegion('26_1rs); // StorageDead(_3); // StorageDead(_2); // goto -> bb1; diff --git a/src/test/mir-opt/end_region_3.rs b/src/test/mir-opt/end_region_3.rs index 189154332b85a..d8d48358e53fc 100644 --- a/src/test/mir-opt/end_region_3.rs +++ b/src/test/mir-opt/end_region_3.rs @@ -28,9 +28,9 @@ fn main() { // START rustc.main.SimplifyCfg-qualify-consts.after.mir // let mut _0: (); // ... -// let _7: &'26_3rs bool; +// let _7: &'30_3rs bool; // ... -// let _3: &'26_1rs bool; +// let _3: &'30_1rs bool; // ... // let mut _1: bool; // ... @@ -48,7 +48,7 @@ fn main() { // bb2: { // _1 = const true; // StorageLive(_3); -// _3 = &'26_1rs _1; +// _3 = &'30_1rs _1; // FakeRead(ForLet, _3); // StorageLive(_5); // _5 = _1; @@ -60,7 +60,7 @@ fn main() { // bb4: { // _0 = (); // StorageDead(_5); -// EndRegion('26_1rs); +// EndRegion('30_1rs); // StorageDead(_3); // StorageDead(_1); // return; @@ -69,12 +69,12 @@ fn main() { // _4 = (); // StorageDead(_5); // StorageLive(_7); -// _7 = &'26_3rs _1; +// _7 = &'30_3rs _1; // FakeRead(ForLet, _7); // _2 = (); -// EndRegion('26_3rs); +// EndRegion('30_3rs); // StorageDead(_7); -// EndRegion('26_1rs); +// EndRegion('30_1rs); // StorageDead(_3); // goto -> bb1; // } diff --git a/src/test/mir-opt/end_region_4.rs b/src/test/mir-opt/end_region_4.rs index d5701669d2bdd..359ed07a9c095 100644 --- a/src/test/mir-opt/end_region_4.rs +++ b/src/test/mir-opt/end_region_4.rs @@ -32,9 +32,9 @@ fn foo(i: i32) { // START rustc.main.SimplifyCfg-qualify-consts.after.mir // let mut _0: (); // ... -// let _6: &'26_4rs i32; +// let _6: &'31_4rs i32; // ... -// let _3: &'26_2rs i32; +// let _3: &'31_2rs i32; // ... // let _2: i32; // ... @@ -50,7 +50,7 @@ fn foo(i: i32) { // _2 = const 0i32; // FakeRead(ForLet, _2); // StorageLive(_3); -// _3 = &'26_2rs _2; +// _3 = &'31_2rs _2; // FakeRead(ForLet, _3); // StorageLive(_5); // _5 = (*_3); @@ -62,18 +62,18 @@ fn foo(i: i32) { // bb2: { // StorageDead(_5); // StorageLive(_6); -// _6 = &'26_4rs _2; +// _6 = &'31_4rs _2; // FakeRead(ForLet, _6); // _0 = (); -// EndRegion('26_4rs); +// EndRegion('31_4rs); // StorageDead(_6); -// EndRegion('26_2rs); +// EndRegion('31_2rs); // StorageDead(_3); // StorageDead(_2); // drop(_1) -> [return: bb4, unwind: bb1]; // } // bb3: { -// EndRegion('26_2rs); +// EndRegion('31_2rs); // drop(_1) -> bb1; // } // bb4: { diff --git a/src/test/mir-opt/end_region_5.rs b/src/test/mir-opt/end_region_5.rs index 98cd67459e068..3b632e198cd66 100644 --- a/src/test/mir-opt/end_region_5.rs +++ b/src/test/mir-opt/end_region_5.rs @@ -33,15 +33,15 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _1: D; // ... // let mut _2: (); -// let mut _3: [closure@NodeId(28) d:&'14s D]; -// let mut _4: &'14s D; +// let mut _3: [closure@NodeId(28) d:&'18s D]; +// let mut _4: &'18s D; // bb0: { // StorageLive(_1); // _1 = D::{{constructor}}(const 0i32,); // FakeRead(ForLet, _1); // StorageLive(_3); // StorageLive(_4); -// _4 = &'14s _1; +// _4 = &'18s _1; // _3 = [closure@NodeId(28)] { d: move _4 }; // StorageDead(_4); // _2 = const foo(move _3) -> [return: bb2, unwind: bb3]; @@ -50,13 +50,13 @@ fn foo(f: F) where F: FnOnce() -> i32 { // resume; // } // bb2: { -// EndRegion('14s); +// EndRegion('18s); // StorageDead(_3); // _0 = (); // drop(_1) -> [return: bb4, unwind: bb1]; // } // bb3: { -// EndRegion('14s); +// EndRegion('18s); // drop(_1) -> bb1; // } // bb4: { @@ -67,11 +67,11 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(28) d:&'14s D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(28) d:&'18s D]) -> i32 { // let mut _0: i32; // // bb0: { -// _0 = ((*(_1.0: &'14s D)).0: i32); +// _0 = ((*(_1.0: &'18s D)).0: i32); // return; // } // END rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir diff --git a/src/test/mir-opt/end_region_6.rs b/src/test/mir-opt/end_region_6.rs index 48f3a83506d7c..03c7de02ec111 100644 --- a/src/test/mir-opt/end_region_6.rs +++ b/src/test/mir-opt/end_region_6.rs @@ -33,15 +33,15 @@ fn foo(f: F) where F: FnOnce() -> i32 { // let _1: D; // ... // let mut _2: (); -// let mut _3: [closure@NodeId(33) d:&'19s D]; -// let mut _4: &'19s D; +// let mut _3: [closure@NodeId(33) d:&'24s D]; +// let mut _4: &'24s D; // bb0: { // StorageLive(_1); // _1 = D::{{constructor}}(const 0i32,); // FakeRead(ForLet, _1); // StorageLive(_3); // StorageLive(_4); -// _4 = &'19s _1; +// _4 = &'24s _1; // _3 = [closure@NodeId(33)] { d: move _4 }; // StorageDead(_4); // _2 = const foo(move _3) -> [return: bb2, unwind: bb3]; @@ -50,13 +50,13 @@ fn foo(f: F) where F: FnOnce() -> i32 { // resume; // } // bb2: { -// EndRegion('19s); +// EndRegion('24s); // StorageDead(_3); // _0 = (); // drop(_1) -> [return: bb4, unwind: bb1]; // } // bb3: { -// EndRegion('19s); +// EndRegion('24s); // drop(_1) -> bb1; // } // bb4: { @@ -66,17 +66,17 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(33) d:&'19s D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(33) d:&'24s D]) -> i32 { // let mut _0: i32; // ... -// let _2: &'16_0rs D; +// let _2: &'21_0rs D; // ... // bb0: { // StorageLive(_2); -// _2 = &'16_0rs (*(_1.0: &'19s D)); +// _2 = &'21_0rs (*(_1.0: &'24s D)); // FakeRead(ForLet, _2); // _0 = ((*_2).0: i32); -// EndRegion('16_0rs); +// EndRegion('21_0rs); // StorageDead(_2); // return; // } diff --git a/src/test/mir-opt/end_region_7.rs b/src/test/mir-opt/end_region_7.rs index 062d89a7c7e2f..56e3e0aa6f7a9 100644 --- a/src/test/mir-opt/end_region_7.rs +++ b/src/test/mir-opt/end_region_7.rs @@ -70,14 +70,14 @@ fn foo(f: F) where F: FnOnce() -> i32 { // fn main::{{closure}}(_1: [closure@NodeId(33) d:D]) -> i32 { // let mut _0: i32; // ... -// let _2: &'16_0rs D; +// let _2: &'21_0rs D; // ... // bb0: { // StorageLive(_2); -// _2 = &'16_0rs (_1.0: D); +// _2 = &'21_0rs (_1.0: D); // FakeRead(ForLet, _2); // _0 = ((*_2).0: i32); -// EndRegion('16_0rs); +// EndRegion('21_0rs); // StorageDead(_2); // drop(_1) -> [return: bb2, unwind: bb1]; // } diff --git a/src/test/mir-opt/end_region_8.rs b/src/test/mir-opt/end_region_8.rs index 207901720577a..0a54dcaa0d33f 100644 --- a/src/test/mir-opt/end_region_8.rs +++ b/src/test/mir-opt/end_region_8.rs @@ -31,18 +31,18 @@ fn foo(f: F) where F: FnOnce() -> i32 { // fn main() -> () { // let mut _0: (); // ... -// let _2: &'21_1rs D; +// let _2: &'26_1rs D; // ... // let _1: D; // ... // let mut _3: (); -// let mut _4: [closure@NodeId(33) r:&'19s D]; +// let mut _4: [closure@NodeId(33) r:&'24s D]; // bb0: { // StorageLive(_1); // _1 = D::{{constructor}}(const 0i32,); // FakeRead(ForLet, _1); // StorageLive(_2); -// _2 = &'21_1rs _1; +// _2 = &'26_1rs _1; // FakeRead(ForLet, _2); // StorageLive(_4); // _4 = [closure@NodeId(33)] { r: _2 }; @@ -52,16 +52,16 @@ fn foo(f: F) where F: FnOnce() -> i32 { // resume; // } // bb2: { -// EndRegion('19s); +// EndRegion('24s); // StorageDead(_4); // _0 = (); -// EndRegion('21_1rs); +// EndRegion('26_1rs); // StorageDead(_2); // drop(_1) -> [return: bb4, unwind: bb1]; // } // bb3: { -// EndRegion('19s); -// EndRegion('21_1rs); +// EndRegion('24s); +// EndRegion('26_1rs); // drop(_1) -> bb1; // } // bb4: { @@ -72,11 +72,11 @@ fn foo(f: F) where F: FnOnce() -> i32 { // END rustc.main.SimplifyCfg-qualify-consts.after.mir // START rustc.main-{{closure}}.SimplifyCfg-qualify-consts.after.mir -// fn main::{{closure}}(_1: [closure@NodeId(33) r:&'19s D]) -> i32 { +// fn main::{{closure}}(_1: [closure@NodeId(33) r:&'24s D]) -> i32 { // let mut _0: i32; // // bb0: { -// _0 = ((*(_1.0: &'21_1rs D)).0: i32); +// _0 = ((*(_1.0: &'26_1rs D)).0: i32); // return; // } // } diff --git a/src/test/mir-opt/end_region_9.rs b/src/test/mir-opt/end_region_9.rs index b43f25e6f548c..ef2d949d3074e 100644 --- a/src/test/mir-opt/end_region_9.rs +++ b/src/test/mir-opt/end_region_9.rs @@ -41,7 +41,7 @@ fn main() { // fn main() -> () { // let mut _0: (); // ... -// let mut _4: &'33_0rs i32; +// let mut _4: &'37_0rs i32; // ... // let _2: i32; // ... @@ -79,14 +79,14 @@ fn main() { // bb5: { // _0 = (); // StorageDead(_7); -// EndRegion('33_0rs); +// EndRegion('37_0rs); // StorageDead(_4); // StorageDead(_2); // StorageDead(_1); // return; // } // bb6: { -// _4 = &'33_0rs _2; +// _4 = &'37_0rs _2; // _6 = (); // StorageDead(_7); // _1 = const true; diff --git a/src/test/mir-opt/end_region_cyclic.rs b/src/test/mir-opt/end_region_cyclic.rs index 75cfb5c2f6239..3dbc73caf65d8 100644 --- a/src/test/mir-opt/end_region_cyclic.rs +++ b/src/test/mir-opt/end_region_cyclic.rs @@ -45,24 +45,24 @@ fn query() -> bool { true } // scope 1 { // } // scope 2 { -// let _2: S<'36_0rs>; +// let _2: S<'49_0rs>; // } // let mut _1: (); -// let mut _3: std::cell::Cell>>; -// let mut _4: std::option::Option<&'36_0rs S<'36_0rs>>; +// let mut _3: std::cell::Cell>>; +// let mut _4: std::option::Option<&'49_0rs S<'49_0rs>>; // let mut _5: (); -// let mut _6: &'17s std::cell::Cell>>; -// let mut _7: std::option::Option<&'36_0rs S<'36_0rs>>; -// let mut _8: &'36_0rs S<'36_0rs>; -// let mut _9: &'36_0rs S<'36_0rs>; +// let mut _6: &'25s std::cell::Cell>>; +// let mut _7: std::option::Option<&'49_0rs S<'49_0rs>>; +// let mut _8: &'49_0rs S<'49_0rs>; +// let mut _9: &'49_0rs S<'49_0rs>; // let mut _10: (); // let mut _11: bool; // let mut _12: !; // let mut _13: (); -// let mut _14: &'34s std::cell::Cell>>; -// let mut _15: std::option::Option<&'36_0rs S<'36_0rs>>; -// let mut _16: &'36_0rs S<'36_0rs>; -// let mut _17: &'36_0rs S<'36_0rs>; +// let mut _14: &'47s std::cell::Cell>>; +// let mut _15: std::option::Option<&'49_0rs S<'49_0rs>>; +// let mut _16: &'49_0rs S<'49_0rs>; +// let mut _17: &'49_0rs S<'49_0rs>; // bb0: { // goto -> bb1; // } @@ -73,7 +73,7 @@ fn query() -> bool { true } // StorageLive(_2); // StorageLive(_3); // StorageLive(_4); -// _4 = std::option::Option<&'36_0rs S<'36_0rs>>::None; +// _4 = std::option::Option<&'49_0rs S<'49_0rs>>::None; // _3 = const >::new(move _4) -> [return: bb4, unwind: bb3]; // } // bb3: { @@ -81,22 +81,22 @@ fn query() -> bool { true } // } // bb4: { // StorageDead(_4); -// _2 = S<'36_0rs> { r: move _3 }; +// _2 = S<'49_0rs> { r: move _3 }; // StorageDead(_3); // FakeRead(ForLet, _2); // StorageLive(_6); -// _6 = &'17s (_2.0: std::cell::Cell>>); +// _6 = &'25s (_2.0: std::cell::Cell>>); // StorageLive(_7); // StorageLive(_8); // StorageLive(_9); -// _9 = &'36_0rs _2; -// _8 = &'36_0rs (*_9); -// _7 = std::option::Option<&'36_0rs S<'36_0rs>>::Some(move _8,); +// _9 = &'49_0rs _2; +// _8 = &'49_0rs (*_9); +// _7 = std::option::Option<&'49_0rs S<'49_0rs>>::Some(move _8,); // StorageDead(_8); // _5 = const >::set(move _6, move _7) -> [return: bb5, unwind: bb3]; // } // bb5: { -// EndRegion('17s); +// EndRegion('25s); // StorageDead(_7); // StorageDead(_6); // StorageDead(_9); @@ -109,7 +109,7 @@ fn query() -> bool { true } // bb7: { // _0 = (); // StorageDead(_11); -// EndRegion('36_0rs); +// EndRegion('49_0rs); // StorageDead(_2); // return; // } @@ -117,23 +117,23 @@ fn query() -> bool { true } // _10 = (); // StorageDead(_11); // StorageLive(_14); -// _14 = &'34s (_2.0: std::cell::Cell>>); +// _14 = &'47s (_2.0: std::cell::Cell>>); // StorageLive(_15); // StorageLive(_16); // StorageLive(_17); -// _17 = &'36_0rs _2; -// _16 = &'36_0rs (*_17); -// _15 = std::option::Option<&'36_0rs S<'36_0rs>>::Some(move _16,); +// _17 = &'49_0rs _2; +// _16 = &'49_0rs (*_17); +// _15 = std::option::Option<&'49_0rs S<'49_0rs>>::Some(move _16,); // StorageDead(_16); // _13 = const >::set(move _14, move _15) -> [return: bb9, unwind: bb3]; // } // bb9: { -// EndRegion('34s); +// EndRegion('47s); // StorageDead(_15); // StorageDead(_14); // StorageDead(_17); // _1 = (); -// EndRegion('36_0rs); +// EndRegion('49_0rs); // StorageDead(_2); // goto -> bb1; // } diff --git a/src/test/mir-opt/end_region_destruction_extents_1.rs b/src/test/mir-opt/end_region_destruction_extents_1.rs index 16e2fe046fb69..a5107d304386f 100644 --- a/src/test/mir-opt/end_region_destruction_extents_1.rs +++ b/src/test/mir-opt/end_region_destruction_extents_1.rs @@ -41,16 +41,16 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // Notes on the MIR output below: // -// 1. The `EndRegion('10s)` is allowed to precede the `drop(_3)` +// 1. The `EndRegion('13s)` is allowed to precede the `drop(_3)` // solely because of the #[may_dangle] mentioned above. // -// 2. Regarding the occurrence of `EndRegion('12ds)` *after* `StorageDead(_6)` -// (where we have borrows `&'12ds _6`): Eventually: +// 2. Regarding the occurrence of `EndRegion('15ds)` *after* `StorageDead(_6)` +// (where we have borrows `&'15ds _6`): Eventually: // // i. this code should be rejected (by mir-borrowck), or // // ii. the MIR code generation should be changed so that the -// EndRegion('12ds)` precedes `StorageDead(_6)` in the +// EndRegion('15ds)` precedes `StorageDead(_6)` in the // control-flow. (Note: arielb1 views drop+storagedead as one // unit, and does not see this option as a useful avenue to // explore.), or @@ -66,13 +66,13 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // START rustc.main.QualifyAndPromoteConstants.before.mir // fn main() -> () { // let mut _0: (); -// let mut _1: &'12ds S1; -// let mut _2: D1<'12ds, '10s>; -// let mut _3: &'12ds S1; -// let mut _4: &'12ds S1; +// let mut _1: &'15ds S1; +// let mut _2: D1<'15ds, '13s>; +// let mut _3: &'15ds S1; +// let mut _4: &'15ds S1; // let _5: S1; -// let mut _6: &'10s S1; -// let mut _7: &'10s S1; +// let mut _6: &'13s S1; +// let mut _7: &'13s S1; // let _8: S1; // bb0: { // StorageLive(_2); @@ -80,19 +80,19 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // StorageLive(_4); // StorageLive(_5); // _5 = S1::{{constructor}}(const "ex1",); -// _4 = &'12ds _5; -// _3 = &'12ds (*_4); +// _4 = &'15ds _5; +// _3 = &'15ds (*_4); // StorageLive(_6); // StorageLive(_7); // StorageLive(_8); // _8 = S1::{{constructor}}(const "dang1",); -// _7 = &'10s _8; -// _6 = &'10s (*_7); -// _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6); -// EndRegion('10s); +// _7 = &'13s _8; +// _6 = &'13s (*_7); +// _2 = D1<'15ds, '13s>::{{constructor}}(move _3, move _6); +// EndRegion('13s); // StorageDead(_6); // StorageDead(_3); -// _1 = (_2.0: &'12ds S1); +// _1 = (_2.0: &'15ds S1); // drop(_2) -> [return: bb2, unwind: bb1]; // } // bb1: { @@ -104,7 +104,7 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // StorageDead(_8); // StorageDead(_4); // StorageDead(_5); -// EndRegion('12ds); +// EndRegion('15ds); // _0 = (); // return; // } @@ -114,29 +114,29 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // START rustc.main.QualifyAndPromoteConstants.after.mir // fn main() -> (){ // let mut _0: (); -// let mut _1: &'12ds S1; -// let mut _2: D1<'12ds, '10s>; -// let mut _3: &'12ds S1; -// let mut _4: &'12ds S1; +// let mut _1: &'15ds S1; +// let mut _2: D1<'15ds, '13s>; +// let mut _3: &'15ds S1; +// let mut _4: &'15ds S1; // let _5: S1; -// let mut _6: &'10s S1; -// let mut _7: &'10s S1; +// let mut _6: &'13s S1; +// let mut _7: &'13s S1; // let _8: S1; // bb0: { // StorageLive(_2); // StorageLive(_3); // StorageLive(_4); -// _4 = &'12ds (promoted[1]: S1); -// _3 = &'12ds (*_4); +// _4 = &'15ds (promoted[1]: S1); +// _3 = &'15ds (*_4); // StorageLive(_6); // StorageLive(_7); -// _7 = &'10s (promoted[0]: S1); -// _6 = &'10s (*_7); -// _2 = D1<'12ds, '10s>::{{constructor}}(move _3, move _6); -// EndRegion('10s); +// _7 = &'13s (promoted[0]: S1); +// _6 = &'13s (*_7); +// _2 = D1<'15ds, '13s>::{{constructor}}(move _3, move _6); +// EndRegion('13s); // StorageDead(_6); // StorageDead(_3); -// _1 = (_2.0: &'12ds S1); +// _1 = (_2.0: &'15ds S1); // drop(_2) -> [return: bb2, unwind: bb1]; // } // bb1: { @@ -146,7 +146,7 @@ unsafe impl<'a, #[may_dangle] 'b> Drop for D1<'a, 'b> { // StorageDead(_2); // StorageDead(_7); // StorageDead(_4); -// EndRegion('12ds); +// EndRegion('15ds); // _0 = (); // return; // } diff --git a/src/test/mir-opt/validate_1.rs b/src/test/mir-opt/validate_1.rs index 66538c57f6545..f1544968adb6a 100644 --- a/src/test/mir-opt/validate_1.rs +++ b/src/test/mir-opt/validate_1.rs @@ -40,19 +40,19 @@ fn main() { // ... // bb0: { // ... -// Validate(Suspend(ReScope(Node(ItemLocalId(10)))), [_1: i32]); +// Validate(Suspend(ReScope(Node(ItemLocalId(13)))), [_1: i32]); // _6 = &ReErased mut _1; -// Validate(Acquire, [(*_6): i32/ReScope(Node(ItemLocalId(10)))]); -// Validate(Suspend(ReScope(Node(ItemLocalId(10)))), [(*_6): i32/ReScope(Node(ItemLocalId(10)))]); +// Validate(Acquire, [(*_6): i32/ReScope(Node(ItemLocalId(13)))]); +// Validate(Suspend(ReScope(Node(ItemLocalId(13)))), [(*_6): i32/ReScope(Node(ItemLocalId(13)))]); // _5 = &ReErased mut (*_6); -// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(10)))]); -// Validate(Release, [_2: (), _3: &ReScope(Node(ItemLocalId(10))) Test, _5: &ReScope(Node(ItemLocalId(10))) mut i32]); +// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(13)))]); +// Validate(Release, [_2: (), _3: &ReScope(Node(ItemLocalId(13))) Test, _5: &ReScope(Node(ItemLocalId(13))) mut i32]); // _2 = const Test::foo(move _3, move _5) -> bb1; // } // // bb1: { // Validate(Acquire, [_2: ()]); -// EndRegion(ReScope(Node(ItemLocalId(10)))); +// EndRegion(ReScope(Node(ItemLocalId(13)))); // ... // return; // } @@ -64,11 +64,11 @@ fn main() { // bb0: { // Validate(Acquire, [_1: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrEnv) [closure@NodeId(65)], _2: &ReFree(DefId(0/1:11 ~ validate_1[317d]::main[0]::{{closure}}[0]), BrAnon(0)) mut i32]); // StorageLive(_3); -// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(25), first_statement_index: 0 })), [(*_2): i32]); +// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(31), first_statement_index: 0 })), [(*_2): i32]); // _3 = &ReErased (*_2); -// Validate(Acquire, [(*_3): i32/ReScope(Remainder { block: ItemLocalId(25), first_statement_index: 0 }) (imm)]); +// Validate(Acquire, [(*_3): i32/ReScope(Remainder { block: ItemLocalId(31), first_statement_index: 0 }) (imm)]); // _0 = (*_3); -// EndRegion(ReScope(Remainder { block: ItemLocalId(25), first_statement_index: 0 })); +// EndRegion(ReScope(Remainder { block: ItemLocalId(31), first_statement_index: 0 })); // StorageDead(_3); // return; // } diff --git a/src/test/mir-opt/validate_3.rs b/src/test/mir-opt/validate_3.rs index 07f5b2aa84b7d..ce840397713ad 100644 --- a/src/test/mir-opt/validate_3.rs +++ b/src/test/mir-opt/validate_3.rs @@ -48,27 +48,27 @@ fn main() { // StorageLive(_1); // _1 = Test { x: const 0i32 }; // StorageLive(_2); -// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(20), first_statement_index: 3 })), [_1: Test]); +// Validate(Suspend(ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 })), [_1: Test]); // _2 = &ReErased _1; -// Validate(Acquire, [(*_2): Test/ReScope(Remainder { block: ItemLocalId(20), first_statement_index: 3 }) (imm)]); +// Validate(Acquire, [(*_2): Test/ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 }) (imm)]); // StorageLive(_4); // StorageLive(_5); -// Validate(Suspend(ReScope(Node(ItemLocalId(18)))), [((*_2).0: i32): i32/ReScope(Remainder { block: ItemLocalId(20), first_statement_index: 3 }) (imm)]); +// Validate(Suspend(ReScope(Node(ItemLocalId(22)))), [((*_2).0: i32): i32/ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 }) (imm)]); // _5 = &ReErased ((*_2).0: i32); -// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(18))) (imm)]); -// Validate(Suspend(ReScope(Node(ItemLocalId(18)))), [(*_5): i32/ReScope(Node(ItemLocalId(18))) (imm)]); +// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(22))) (imm)]); +// Validate(Suspend(ReScope(Node(ItemLocalId(22)))), [(*_5): i32/ReScope(Node(ItemLocalId(22))) (imm)]); // _4 = &ReErased (*_5); -// Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(18))) (imm)]); -// Validate(Release, [_3: (), _4: &ReScope(Node(ItemLocalId(18))) i32]); +// Validate(Acquire, [(*_4): i32/ReScope(Node(ItemLocalId(22))) (imm)]); +// Validate(Release, [_3: (), _4: &ReScope(Node(ItemLocalId(22))) i32]); // _3 = const foo(move _4) -> bb1; // } // bb1: { // Validate(Acquire, [_3: ()]); -// EndRegion(ReScope(Node(ItemLocalId(18)))); +// EndRegion(ReScope(Node(ItemLocalId(22)))); // StorageDead(_4); // StorageDead(_5); // _0 = (); -// EndRegion(ReScope(Remainder { block: ItemLocalId(20), first_statement_index: 3 })); +// EndRegion(ReScope(Remainder { block: ItemLocalId(24), first_statement_index: 3 })); // StorageDead(_2); // StorageDead(_1); // return; diff --git a/src/test/mir-opt/validate_5.rs b/src/test/mir-opt/validate_5.rs index 8016a3d4cce4c..955de0c3bad04 100644 --- a/src/test/mir-opt/validate_5.rs +++ b/src/test/mir-opt/validate_5.rs @@ -53,12 +53,12 @@ fn main() { // StorageLive(_3); // StorageLive(_4); // StorageLive(_5); -// Validate(Suspend(ReScope(Node(ItemLocalId(12)))), [(*_2): i32]); +// Validate(Suspend(ReScope(Node(ItemLocalId(16)))), [(*_2): i32]); // _5 = &ReErased mut (*_2); -// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(12)))]); +// Validate(Acquire, [(*_5): i32/ReScope(Node(ItemLocalId(16)))]); // _4 = move _5 as *mut i32 (Misc); // _3 = move _4; -// EndRegion(ReScope(Node(ItemLocalId(12)))); +// EndRegion(ReScope(Node(ItemLocalId(16)))); // StorageDead(_4); // StorageDead(_5); // Validate(Release, [_0: bool, _3: *mut i32]); From 6dd5bb18d7a832add3f0cadb70897da6fd44892b Mon Sep 17 00:00:00 2001 From: Nick Cameron Date: Thu, 25 Oct 2018 15:23:45 +1300 Subject: [PATCH 10/10] more reviewer changes --- src/librustc/hir/lowering.rs | 6 +++--- src/librustc_resolve/lib.rs | 12 ++++-------- src/libsyntax/ast.rs | 6 +----- 3 files changed, 8 insertions(+), 16 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 3aea26c6829a5..6370a52018338 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -147,7 +147,6 @@ pub trait Resolver { fn resolve_hir_path( &mut self, path: &ast::Path, - args: Option>, is_value: bool, ) -> hir::Path; @@ -168,7 +167,6 @@ pub trait Resolver { span: Span, crate_root: Option<&str>, components: &[&str], - args: Option>, is_value: bool, ) -> hir::Path; } @@ -4856,7 +4854,9 @@ impl<'a> LoweringContext<'a> { is_value: bool ) -> hir::Path { let mut path = self.resolver - .resolve_str_path(span, self.crate_root, components, params, is_value); + .resolve_str_path(span, self.crate_root, components, is_value); + path.segments.last_mut().unwrap().args = params; + for seg in path.segments.iter_mut() { if let Some(id) = seg.id { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 0285a3c568cc1..546c5a5ed3d6c 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1574,10 +1574,9 @@ impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> { fn resolve_hir_path( &mut self, path: &ast::Path, - args: Option>, is_value: bool, ) -> hir::Path { - self.resolve_hir_path_cb(path, args, is_value, + self.resolve_hir_path_cb(path, is_value, |resolver, span, error| resolve_error(resolver, span, error)) } @@ -1586,7 +1585,6 @@ impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> { span: Span, crate_root: Option<&str>, components: &[&str], - args: Option>, is_value: bool ) -> hir::Path { let segments = iter::once(keywords::CrateRoot.ident()) @@ -1602,7 +1600,7 @@ impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> { segments, }; - self.resolve_hir_path(&path, args, is_value) + self.resolve_hir_path(&path, is_value) } fn get_resolution(&mut self, id: NodeId) -> Option { @@ -1648,7 +1646,7 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { .collect(), } }; - let path = self.resolve_hir_path_cb(&path, None, is_value, |_, _, _| errored = true); + let path = self.resolve_hir_path_cb(&path, is_value, |_, _, _| errored = true); if errored || path.def == Def::Err { Err(()) } else { @@ -1660,7 +1658,6 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { fn resolve_hir_path_cb( &mut self, path: &ast::Path, - args: Option>, is_value: bool, error_callback: F, ) -> hir::Path @@ -1697,12 +1694,11 @@ impl<'a, 'crateloader> Resolver<'a, 'crateloader> { } }; - let mut segments: Vec<_> = segments.iter().map(|seg| { + let segments: Vec<_> = segments.iter().map(|seg| { let mut hir_seg = hir::PathSegment::from_ident(seg.ident); hir_seg.def = Some(self.def_map.get(&seg.id).map_or(Def::Err, |p| p.base_def())); hir_seg }).collect(); - segments.last_mut().unwrap().args = args; hir::Path { span, def, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index d33077b336b46..ee82b9860058a 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -145,11 +145,7 @@ impl PathSegment { PathSegment { ident, id: DUMMY_NODE_ID, args: None } } pub fn crate_root(span: Span) -> Self { - PathSegment { - ident: Ident::new(keywords::CrateRoot.name(), span), - id: DUMMY_NODE_ID, - args: None, - } + PathSegment::from_ident(Ident::new(keywords::CrateRoot.name(), span)) } }