diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 0876e609396..25ccfb8d6bc 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1438,7 +1438,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { let loop_expr = hir::ExprLoop(loop_block, opt_ident.map(|ident| lower_ident(lctx, ident))); // add attributes to the outer returned expr node - return expr(lctx, e.span, loop_expr, e.attrs.clone()); + let attrs = e.attrs.clone(); + return P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: attrs }); } // Desugar ExprForLoop @@ -1515,7 +1516,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P { let loop_block = block_expr(lctx, match_expr); let loop_expr = hir::ExprLoop(loop_block, opt_ident.map(|ident| lower_ident(lctx, ident))); - let loop_expr = expr(lctx, e.span, loop_expr, None); + let loop_expr = + P(hir::Expr { id: e.id, node: loop_expr, span: e.span, attrs: None }); // `mut iter => { ... }` let iter_arm = { diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index a2f0f30b62c..358301ab404 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -195,6 +195,10 @@ impl Definitions { self.opt_def_index(node).map(DefId::local) } + pub fn local_def_id(&self, node: ast::NodeId) -> DefId { + self.opt_local_def_id(node).unwrap() + } + pub fn as_local_node_id(&self, def_id: DefId) -> Option { if def_id.krate == LOCAL_CRATE { assert!(def_id.index.as_usize() < self.data.len()); diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index e791a351252..35dad578e0e 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -10,7 +10,8 @@ use rustc::dep_graph::DepGraph; use rustc::hir; -use rustc::hir::map as hir_map; +use rustc::hir::{map as hir_map, FreevarMap, TraitMap}; +use rustc::hir::def::DefMap; use rustc_mir as mir; use rustc::mir::mir_map::MirMap; use rustc::session::{Session, CompileResult, compile_result_from_err_count}; @@ -139,9 +140,32 @@ pub fn compile_input(sess: &Session, time(sess.time_passes(), "external crate/lib resolution", - || LocalCrateReader::new(sess, &cstore, &defs, &expanded_crate, &id) + || LocalCrateReader::new(sess, &cstore, defs, &expanded_crate, &id) .read_crates(&dep_graph)); + time(sess.time_passes(), + "early lint checks", + || lint::check_ast_crate(sess, &expanded_crate)); + + let resolve::CrateMap { + def_map, + freevars, + maybe_unused_trait_imports, + export_map, + trait_map, + glob_map, + } = time(sess.time_passes(), "name resolution", || { + resolve::resolve_crate(sess, &expanded_crate, &defs.borrow(), control.make_glob_map) + }); + + let analysis = ty::CrateAnalysis { + export_map: export_map, + access_levels: AccessLevels::default(), + reachable: NodeSet(), + name: &id, + glob_map: glob_map, + }; + // Lower ast -> hir. let lcx = LoweringContext::new(sess, Some(&expanded_crate), defs); let hir_forest = &mut time(sess.time_passes(), @@ -185,10 +209,6 @@ pub fn compile_input(sess: &Session, hir::check_attr::check_crate(sess, &expanded_crate); }); - time(sess.time_passes(), - "early lint checks", - || lint::check_ast_crate(sess, &expanded_crate)); - let opt_crate = if keep_ast(sess) { Some(&expanded_crate) } else { @@ -200,7 +220,11 @@ pub fn compile_input(sess: &Session, hir_map, &arenas, &id, - control.make_glob_map, + analysis, + def_map, + freevars, + trait_map, + maybe_unused_trait_imports, |tcx, mir_map, analysis, result| { { // Eventually, we will want to track plugins. @@ -763,7 +787,11 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, hir_map: hir_map::Map<'tcx>, arenas: &'tcx ty::CtxtArenas<'tcx>, name: &str, - make_glob_map: resolve::MakeGlobMap, + mut analysis: ty::CrateAnalysis, + def_map: RefCell, + freevars: FreevarMap, + trait_map: TraitMap, + maybe_unused_trait_imports: NodeSet, f: F) -> Result where F: FnOnce(&TyCtxt<'tcx>, Option>, ty::CrateAnalysis, CompileResult) -> R @@ -788,25 +816,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session, }) })?; - let resolve::CrateMap { - def_map, - freevars, - maybe_unused_trait_imports, - export_map, - trait_map, - glob_map, - } = time(sess.time_passes(), - "name resolution", - || resolve::resolve_crate(sess, &hir_map, make_glob_map)); - - let mut analysis = ty::CrateAnalysis { - export_map: export_map, - access_levels: AccessLevels::default(), - reachable: NodeSet(), - name: name, - glob_map: glob_map, - }; - let named_region_map = time(time_passes, "lifetime resolution", || middle::resolve_lifetime::krate(sess, diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index f5e72195bc3..f56b22f9248 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -29,18 +29,15 @@ use rustc::ty::{self, VariantKind}; use syntax::ast::{Name, NodeId}; use syntax::attr::AttrMetaMethods; -use syntax::parse::token::keywords; +use syntax::parse::token::{self, keywords}; use syntax::codemap::{Span, DUMMY_SP}; -use rustc::hir; -use rustc::hir::{Block, DeclItem}; -use rustc::hir::{ForeignItem, ForeignItemFn, ForeignItemStatic}; -use rustc::hir::{Item, ItemConst, ItemEnum, ItemExternCrate, ItemFn}; -use rustc::hir::{ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}; -use rustc::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse}; -use rustc::hir::{PathListIdent, PathListMod, StmtDecl}; -use rustc::hir::{Variant, ViewPathGlob, ViewPathList, ViewPathSimple}; -use rustc::hir::intravisit::{self, Visitor}; +use syntax::ast::{Block, Crate, DeclKind}; +use syntax::ast::{ForeignItem, ForeignItemKind, Item, ItemKind}; +use syntax::ast::{Mutability, PathListItemKind}; +use syntax::ast::{SelfKind, Stmt, StmtKind, TraitItemKind}; +use syntax::ast::{Variant, ViewPath, ViewPathGlob, ViewPathList, ViewPathSimple}; +use syntax::visit::{self, Visitor}; trait ToNameBinding<'a> { fn to_name_binding(self) -> NameBinding<'a>; @@ -58,14 +55,14 @@ impl<'a> ToNameBinding<'a> for (Def, Span, ty::Visibility) { } } -impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { +impl<'b> Resolver<'b> { /// Constructs the reduced graph for the entire crate. - pub fn build_reduced_graph(&mut self, krate: &hir::Crate) { + pub fn build_reduced_graph(&mut self, krate: &Crate) { let mut visitor = BuildReducedGraphVisitor { parent: self.graph_root, resolver: self, }; - intravisit::walk_crate(&mut visitor, krate); + visit::walk_crate(&mut visitor, krate); } /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined. @@ -85,9 +82,9 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { } fn block_needs_anonymous_module(&mut self, block: &Block) -> bool { - fn is_item(statement: &hir::Stmt) -> bool { - if let StmtDecl(ref declaration, _) = statement.node { - if let DeclItem(_) = declaration.node { + fn is_item(statement: &Stmt) -> bool { + if let StmtKind::Decl(ref declaration, _) = statement.node { + if let DeclKind::Item(_) = declaration.node { return true; } } @@ -98,7 +95,7 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { block.stmts.iter().any(is_item) } - fn sanity_check_import(&self, view_path: &hir::ViewPath, id: NodeId) { + fn sanity_check_import(&self, view_path: &ViewPath, id: NodeId) { let path = match view_path.node { ViewPathSimple(_, ref path) | ViewPathGlob (ref path) | @@ -131,13 +128,13 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { /// Constructs the reduced graph for one item. fn build_reduced_graph_for_item(&mut self, item: &Item, parent_ref: &mut Module<'b>) { let parent = *parent_ref; - let name = item.name; + let name = item.ident.name; let sp = item.span; self.current_module = parent; let vis = self.resolve_visibility(&item.vis); match item.node { - ItemUse(ref view_path) => { + ItemKind::Use(ref view_path) => { // Extract and intern the module part of the path. For // globs and lists, the path is found directly in the AST; // for simple paths we have to munge the path a little. @@ -175,21 +172,20 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { ResolutionError::SelfImportsOnlyAllowedWithin); } - let subclass = ImportDirectiveSubclass::single(binding, source_name); + let subclass = ImportDirectiveSubclass::single(binding.name, source_name); let span = view_path.span; parent.add_import_directive(module_path, subclass, span, item.id, vis); self.unresolved_imports += 1; } ViewPathList(_, ref source_items) => { // Make sure there's at most one `mod` import in the list. - let mod_spans = source_items.iter() - .filter_map(|item| { - match item.node { - PathListMod { .. } => Some(item.span), - _ => None, - } - }) - .collect::>(); + let mod_spans = source_items.iter().filter_map(|item| { + match item.node { + PathListItemKind::Mod { .. } => Some(item.span), + _ => None, + } + }).collect::>(); + if mod_spans.len() > 1 { let mut e = resolve_struct_error(self, mod_spans[0], @@ -202,9 +198,9 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { for source_item in source_items { let (module_path, name, rename) = match source_item.node { - PathListIdent { name, rename, .. } => - (module_path.clone(), name, rename.unwrap_or(name)), - PathListMod { rename, .. } => { + PathListItemKind::Ident { name, rename, .. } => + (module_path.clone(), name.name, rename.unwrap_or(name).name), + PathListItemKind::Mod { rename, .. } => { let name = match module_path.last() { Some(name) => *name, None => { @@ -218,7 +214,7 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { } }; let module_path = module_path.split_last().unwrap().1; - let rename = rename.unwrap_or(name); + let rename = rename.map(|i| i.name).unwrap_or(name); (module_path.to_vec(), name, rename) } }; @@ -237,7 +233,7 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { } } - ItemExternCrate(_) => { + ItemKind::ExternCrate(_) => { // n.b. we don't need to look at the path option here, because cstore already // did if let Some(crate_id) = self.session.cstore.extern_mod_stmt_cnum(item.id) { @@ -254,76 +250,77 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { } } - ItemMod(..) => { + ItemKind::Mod(..) => { let parent_link = ModuleParentLink(parent, name); - let def = Def::Mod(self.ast_map.local_def_id(item.id)); + let def = Def::Mod(self.definitions.local_def_id(item.id)); let module = self.new_module(parent_link, Some(def), false); self.define(parent, name, TypeNS, (module, sp, vis)); self.module_map.insert(item.id, module); *parent_ref = module; } - ItemForeignMod(..) => {} + ItemKind::ForeignMod(..) => {} // These items live in the value namespace. - ItemStatic(_, m, _) => { - let mutbl = m == hir::MutMutable; - let def = Def::Static(self.ast_map.local_def_id(item.id), mutbl); + ItemKind::Static(_, m, _) => { + let mutbl = m == Mutability::Mutable; + let def = Def::Static(self.definitions.local_def_id(item.id), mutbl); self.define(parent, name, ValueNS, (def, sp, vis)); } - ItemConst(_, _) => { - let def = Def::Const(self.ast_map.local_def_id(item.id)); + ItemKind::Const(_, _) => { + let def = Def::Const(self.definitions.local_def_id(item.id)); self.define(parent, name, ValueNS, (def, sp, vis)); } - ItemFn(_, _, _, _, _, _) => { - let def = Def::Fn(self.ast_map.local_def_id(item.id)); + ItemKind::Fn(_, _, _, _, _, _) => { + let def = Def::Fn(self.definitions.local_def_id(item.id)); self.define(parent, name, ValueNS, (def, sp, vis)); } // These items live in the type namespace. - ItemTy(..) => { - let def = Def::TyAlias(self.ast_map.local_def_id(item.id)); + ItemKind::Ty(..) => { + let def = Def::TyAlias(self.definitions.local_def_id(item.id)); self.define(parent, name, TypeNS, (def, sp, vis)); } - ItemEnum(ref enum_definition, _) => { + ItemKind::Enum(ref enum_definition, _) => { let parent_link = ModuleParentLink(parent, name); - let def = Def::Enum(self.ast_map.local_def_id(item.id)); + let def = Def::Enum(self.definitions.local_def_id(item.id)); let module = self.new_module(parent_link, Some(def), false); self.define(parent, name, TypeNS, (module, sp, vis)); for variant in &(*enum_definition).variants { - let item_def_id = self.ast_map.local_def_id(item.id); + let item_def_id = self.definitions.local_def_id(item.id); self.build_reduced_graph_for_variant(variant, item_def_id, module, vis); } } // These items live in both the type and value namespaces. - ItemStruct(ref struct_def, _) => { + ItemKind::Struct(ref struct_def, _) => { // Define a name in the type namespace. - let def = Def::Struct(self.ast_map.local_def_id(item.id)); + let def = Def::Struct(self.definitions.local_def_id(item.id)); self.define(parent, name, TypeNS, (def, sp, vis)); // If this is a newtype or unit-like struct, define a name // in the value namespace as well if !struct_def.is_struct() { - let def = Def::Struct(self.ast_map.local_def_id(struct_def.id())); + let def = Def::Struct(self.definitions.local_def_id(struct_def.id())); self.define(parent, name, ValueNS, (def, sp, vis)); } // Record the def ID and fields of this struct. - let field_names = struct_def.fields().iter().map(|field| { + let field_names = struct_def.fields().iter().enumerate().map(|(index, field)| { self.resolve_visibility(&field.vis); - field.name + field.ident.map(|ident| ident.name) + .unwrap_or_else(|| token::intern(&index.to_string())) }).collect(); - let item_def_id = self.ast_map.local_def_id(item.id); + let item_def_id = self.definitions.local_def_id(item.id); self.structs.insert(item_def_id, field_names); } - ItemDefaultImpl(_, _) | ItemImpl(..) => {} + ItemKind::DefaultImpl(_, _) | ItemKind::Impl(..) => {} - ItemTrait(_, _, _, ref items) => { - let def_id = self.ast_map.local_def_id(item.id); + ItemKind::Trait(_, _, _, ref items) => { + let def_id = self.definitions.local_def_id(item.id); // Add all the items within to a new module. let parent_link = ModuleParentLink(parent, name); @@ -333,22 +330,23 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { // Add the names of all the items to the trait info. for item in items { - let item_def_id = self.ast_map.local_def_id(item.id); + let item_def_id = self.definitions.local_def_id(item.id); let mut is_static_method = false; let (def, ns) = match item.node { - hir::ConstTraitItem(..) => (Def::AssociatedConst(item_def_id), ValueNS), - hir::MethodTraitItem(ref sig, _) => { - is_static_method = sig.explicit_self.node == hir::SelfStatic; + TraitItemKind::Const(..) => (Def::AssociatedConst(item_def_id), ValueNS), + TraitItemKind::Method(ref sig, _) => { + is_static_method = sig.explicit_self.node == SelfKind::Static; (Def::Method(item_def_id), ValueNS) } - hir::TypeTraitItem(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS), + TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS), }; - self.define(module_parent, item.name, ns, (def, item.span, vis)); + self.define(module_parent, item.ident.name, ns, (def, item.span, vis)); - self.trait_item_map.insert((item.name, def_id), is_static_method); + self.trait_item_map.insert((item.ident.name, def_id), is_static_method); } } + ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"), } } @@ -359,16 +357,16 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { item_id: DefId, parent: Module<'b>, vis: ty::Visibility) { - let name = variant.node.name; + let name = variant.node.name.name; if variant.node.data.is_struct() { // Not adding fields for variants as they are not accessed with a self receiver - let variant_def_id = self.ast_map.local_def_id(variant.node.data.id()); + let variant_def_id = self.definitions.local_def_id(variant.node.data.id()); self.structs.insert(variant_def_id, Vec::new()); } // Variants are always treated as importable to allow them to be glob used. // All variants are defined in both type and value namespaces as future-proofing. - let def = Def::Variant(item_id, self.ast_map.local_def_id(variant.node.data.id())); + let def = Def::Variant(item_id, self.definitions.local_def_id(variant.node.data.id())); self.define(parent, name, ValueNS, (def, variant.span, vis)); self.define(parent, name, TypeNS, (def, variant.span, vis)); } @@ -377,14 +375,14 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { fn build_reduced_graph_for_foreign_item(&mut self, foreign_item: &ForeignItem, parent: Module<'b>) { - let name = foreign_item.name; + let name = foreign_item.ident.name; let def = match foreign_item.node { - ForeignItemFn(..) => { - Def::Fn(self.ast_map.local_def_id(foreign_item.id)) + ForeignItemKind::Fn(..) => { + Def::Fn(self.definitions.local_def_id(foreign_item.id)) } - ForeignItemStatic(_, m) => { - Def::Static(self.ast_map.local_def_id(foreign_item.id), m) + ForeignItemKind::Static(_, m) => { + Def::Static(self.definitions.local_def_id(foreign_item.id), m) } }; self.current_module = parent; @@ -526,20 +524,16 @@ impl<'b, 'tcx:'b> Resolver<'b, 'tcx> { } } -struct BuildReducedGraphVisitor<'a, 'b: 'a, 'tcx: 'b> { - resolver: &'a mut Resolver<'b, 'tcx>, +struct BuildReducedGraphVisitor<'a, 'b: 'a> { + resolver: &'a mut Resolver<'b>, parent: Module<'b>, } -impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { - fn visit_nested_item(&mut self, item: hir::ItemId) { - self.visit_item(self.resolver.ast_map.expect_item(item.id)) - } - +impl<'a, 'b, 'v> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b> { fn visit_item(&mut self, item: &Item) { let old_parent = self.parent; self.resolver.build_reduced_graph_for_item(item, &mut self.parent); - intravisit::walk_item(self, item); + visit::walk_item(self, item); self.parent = old_parent; } @@ -550,7 +544,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for BuildReducedGraphVisitor<'a, 'b, 'tcx> { fn visit_block(&mut self, block: &Block) { let old_parent = self.parent; self.resolver.build_reduced_graph_for_block(block, &mut self.parent); - intravisit::walk_block(self, block); + visit::walk_block(self, block); self.parent = old_parent; } } diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index e213a51fb38..64347d7b84d 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -25,33 +25,31 @@ use Resolver; use Namespace::{TypeNS, ValueNS}; use rustc::lint; -use syntax::ast; +use syntax::ast::{self, ViewPathGlob, ViewPathList, ViewPathSimple}; +use syntax::visit::{self, Visitor}; use syntax::codemap::{Span, DUMMY_SP}; -use rustc::hir; -use rustc::hir::{ViewPathGlob, ViewPathList, ViewPathSimple}; -use rustc::hir::intravisit::Visitor; -struct UnusedImportCheckVisitor<'a, 'b: 'a, 'tcx: 'b> { - resolver: &'a mut Resolver<'b, 'tcx>, +struct UnusedImportCheckVisitor<'a, 'b: 'a> { + resolver: &'a mut Resolver<'b>, } // Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver. -impl<'a, 'b, 'tcx:'b> Deref for UnusedImportCheckVisitor<'a, 'b, 'tcx> { - type Target = Resolver<'b, 'tcx>; +impl<'a, 'b> Deref for UnusedImportCheckVisitor<'a, 'b> { + type Target = Resolver<'b>; - fn deref<'c>(&'c self) -> &'c Resolver<'b, 'tcx> { + fn deref<'c>(&'c self) -> &'c Resolver<'b> { &*self.resolver } } -impl<'a, 'b, 'tcx:'b> DerefMut for UnusedImportCheckVisitor<'a, 'b, 'tcx> { - fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'tcx> { +impl<'a, 'b> DerefMut for UnusedImportCheckVisitor<'a, 'b> { + fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> { &mut *self.resolver } } -impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { +impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { // We have information about whether `use` (import) directives are actually // used now. If an import is not used at all, we signal a lint error. fn check_import(&mut self, id: ast::NodeId, span: Span) { @@ -73,18 +71,19 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { } } -impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { - fn visit_item(&mut self, item: &hir::Item) { +impl<'a, 'b, 'v> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b> { + fn visit_item(&mut self, item: &ast::Item) { + visit::walk_item(self, item); // Ignore is_public import statements because there's no way to be sure // whether they're used or not. Also ignore imports with a dummy span // because this means that they were generated in some fashion by the // compiler and we don't need to consider them. - if item.vis == hir::Public || item.span.source_equal(&DUMMY_SP) { + if item.vis == ast::Visibility::Public || item.span.source_equal(&DUMMY_SP) { return; } match item.node { - hir::ItemExternCrate(_) => { + ast::ItemKind::ExternCrate(_) => { if let Some(crate_num) = self.session.cstore.extern_mod_stmt_cnum(item.id) { if !self.used_crates.contains(&crate_num) { self.session.add_lint(lint::builtin::UNUSED_EXTERN_CRATES, @@ -94,7 +93,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { } } } - hir::ItemUse(ref p) => { + ast::ItemKind::Use(ref p) => { match p.node { ViewPathSimple(_, _) => { self.check_import(item.id, p.span) @@ -115,7 +114,7 @@ impl<'a, 'b, 'v, 'tcx> Visitor<'v> for UnusedImportCheckVisitor<'a, 'b, 'tcx> { } } -pub fn check_crate(resolver: &mut Resolver, krate: &hir::Crate) { +pub fn check_crate(resolver: &mut Resolver, krate: &ast::Crate) { let mut visitor = UnusedImportCheckVisitor { resolver: resolver }; - krate.visit_all_items(&mut visitor); + visit::walk_crate(&mut visitor, krate); } diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 2ed3c848673..f90f8481a25 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -43,18 +43,18 @@ use self::AssocItemResolveResult::*; use self::BareIdentifierPatternResolution::*; use self::ParentLink::*; -use rustc::dep_graph::DepNode; -use rustc::hir::map as hir_map; +use rustc::hir::map::Definitions; +use rustc::hir::{PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr}; use rustc::session::Session; use rustc::lint; use rustc::hir::def::*; use rustc::hir::def_id::DefId; -use rustc::hir::pat_util::pat_bindings; use rustc::ty; use rustc::ty::subst::{ParamSpace, FnSpace, TypeSpace}; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::util::nodemap::{NodeMap, NodeSet, FnvHashMap, FnvHashSet}; +use syntax::ext::mtwt; use syntax::ast::{self, FloatTy}; use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy}; use syntax::codemap::{self, Span, Pos}; @@ -62,23 +62,12 @@ use syntax::errors::DiagnosticBuilder; use syntax::parse::token::{self, keywords}; use syntax::util::lev_distance::find_best_match_for_name; -use rustc::hir::intravisit::{self, FnKind, Visitor}; -use rustc::hir; -use rustc::hir::{Arm, BindByRef, BindByValue, BindingMode, Block}; -use rustc::hir::Crate; -use rustc::hir::{Expr, ExprAgain, ExprBreak, ExprField}; -use rustc::hir::{ExprLoop, ExprWhile, ExprMethodCall}; -use rustc::hir::{ExprPath, ExprStruct, FnDecl}; -use rustc::hir::{ForeignItemFn, ForeignItemStatic, Generics}; -use rustc::hir::{ImplItem, Item, ItemConst, ItemEnum, ItemExternCrate}; -use rustc::hir::{ItemFn, ItemForeignMod, ItemImpl, ItemMod, ItemStatic, ItemDefaultImpl}; -use rustc::hir::{ItemStruct, ItemTrait, ItemTy, ItemUse}; -use rustc::hir::Local; -use rustc::hir::{Pat, PatKind, Path, PrimTy}; -use rustc::hir::{PathSegment, PathParameters}; -use rustc::hir::HirVec; -use rustc::hir::{TraitRef, Ty, TyBool, TyChar, TyFloat, TyInt}; -use rustc::hir::{TyRptr, TyStr, TyUint, TyPath}; +use syntax::visit::{self, FnKind, Visitor}; +use syntax::ast::{Arm, BindingMode, Block, Crate, Expr, ExprKind}; +use syntax::ast::{FnDecl, ForeignItem, ForeignItemKind, Generics}; +use syntax::ast::{Item, ItemKind, ImplItem, ImplItemKind}; +use syntax::ast::{Local, Pat, PatKind, Path}; +use syntax::ast::{PathSegment, PathParameters, TraitItemKind, TraitRef, Ty, TyKind}; use std::collections::{HashMap, HashSet}; use std::cell::{Cell, RefCell}; @@ -197,16 +186,16 @@ enum UnresolvedNameContext<'a> { Other, } -fn resolve_error<'b, 'a: 'b, 'tcx: 'a, 'c>(resolver: &'b Resolver<'a, 'tcx>, - span: syntax::codemap::Span, - resolution_error: ResolutionError<'c>) { +fn resolve_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, + span: syntax::codemap::Span, + resolution_error: ResolutionError<'c>) { resolve_struct_error(resolver, span, resolution_error).emit(); } -fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a, 'c>(resolver: &'b Resolver<'a, 'tcx>, - span: syntax::codemap::Span, - resolution_error: ResolutionError<'b>) - -> DiagnosticBuilder<'c> { +fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>, + span: syntax::codemap::Span, + resolution_error: ResolutionError<'c>) + -> DiagnosticBuilder<'a> { if !resolver.emit_errors { return resolver.session.diagnostic().struct_dummy(); } @@ -424,13 +413,13 @@ fn resolve_struct_error<'b, 'a: 'b, 'tcx: 'a, 'c>(resolver: &'b Resolver<'a, 'tc UnresolvedNameContext::Other => { } // no help available UnresolvedNameContext::PathIsMod(parent) => { err.help(&match parent.map(|parent| &parent.node) { - Some(&ExprField(_, ident)) => { + Some(&ExprKind::Field(_, ident)) => { format!("To reference an item from the `{module}` module, \ use `{module}::{ident}`", module = path, ident = ident.node) } - Some(&ExprMethodCall(ident, _, _)) => { + Some(&ExprKind::MethodCall(ident, _, _)) => { format!("To call a function from the `{module}` module, \ use `{module}::{ident}(..)`", module = path, @@ -528,10 +517,7 @@ pub enum Namespace { ValueNS, } -impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { - fn visit_nested_item(&mut self, item: hir::ItemId) { - self.visit_item(self.ast_map.expect_item(item.id)) - } +impl<'a, 'v> Visitor<'v> for Resolver<'a> { fn visit_item(&mut self, item: &Item) { self.resolve_item(item); } @@ -553,7 +539,7 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { fn visit_generics(&mut self, generics: &Generics) { self.resolve_generics(generics); } - fn visit_poly_trait_ref(&mut self, tref: &hir::PolyTraitRef, m: &hir::TraitBoundModifier) { + fn visit_poly_trait_ref(&mut self, tref: &ast::PolyTraitRef, m: &ast::TraitBoundModifier) { match self.resolve_trait_reference(tref.trait_ref.ref_id, &tref.trait_ref.path, 0) { Ok(def) => self.record_def(tref.trait_ref.ref_id, def), Err(_) => { @@ -561,10 +547,10 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { self.record_def(tref.trait_ref.ref_id, err_path_resolution()) } } - intravisit::walk_poly_trait_ref(self, tref, m); + visit::walk_poly_trait_ref(self, tref, m); } fn visit_variant(&mut self, - variant: &hir::Variant, + variant: &ast::Variant, generics: &Generics, item_id: ast::NodeId) { if let Some(ref dis_expr) = variant.node.disr_expr { @@ -574,22 +560,22 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { }); } - // `intravisit::walk_variant` without the discriminant expression. + // `visit::walk_variant` without the discriminant expression. self.visit_variant_data(&variant.node.data, variant.node.name, generics, item_id, variant.span); } - fn visit_foreign_item(&mut self, foreign_item: &hir::ForeignItem) { + fn visit_foreign_item(&mut self, foreign_item: &ForeignItem) { let type_parameters = match foreign_item.node { - ForeignItemFn(_, ref generics) => { + ForeignItemKind::Fn(_, ref generics) => { HasTypeParameters(generics, FnSpace, ItemRibKind) } - ForeignItemStatic(..) => NoTypeParameters, + ForeignItemKind::Static(..) => NoTypeParameters, }; self.with_type_parameter_rib(type_parameters, |this| { - intravisit::walk_foreign_item(this, foreign_item); + visit::walk_foreign_item(this, foreign_item); }); } fn visit_fn(&mut self, @@ -599,16 +585,16 @@ impl<'a, 'v, 'tcx> Visitor<'v> for Resolver<'a, 'tcx> { _: Span, node_id: NodeId) { let rib_kind = match function_kind { - FnKind::ItemFn(_, generics, _, _, _, _, _) => { + FnKind::ItemFn(_, generics, _, _, _, _) => { self.visit_generics(generics); ItemRibKind } - FnKind::Method(_, sig, _, _) => { + FnKind::Method(_, sig, _) => { self.visit_generics(&sig.generics); self.visit_explicit_self(&sig.explicit_self); MethodRibKind } - FnKind::Closure(_) => ClosureRibKind(node_id), + FnKind::Closure => ClosureRibKind(node_id), }; self.resolve_function(rib_kind, declaration, block); } @@ -648,17 +634,17 @@ enum FallbackSuggestion { } #[derive(Copy, Clone)] -enum TypeParameters<'tcx, 'a> { +enum TypeParameters<'a, 'b> { NoTypeParameters, HasTypeParameters(// Type parameters. - &'a Generics, + &'b Generics, // Identifies the things that these parameters // were declared on (type, fn, etc) ParamSpace, // The kind of the rib used for type parameters. - RibKind<'tcx>), + RibKind<'a>), } // The rib kind controls the translation of local @@ -973,10 +959,10 @@ impl PrimitiveTypeTable { } /// The main resolver class. -pub struct Resolver<'a, 'tcx: 'a> { +pub struct Resolver<'a> { session: &'a Session, - ast_map: &'a hir_map::Map<'tcx>, + definitions: &'a Definitions, graph_root: Module<'a>, @@ -1081,9 +1067,9 @@ impl<'a> ResolverArenas<'a> { } } -impl<'a, 'tcx> ty::NodeIdTree for Resolver<'a, 'tcx> { +impl<'a> ty::NodeIdTree for Resolver<'a> { fn is_descendant_of(&self, node: NodeId, ancestor: NodeId) -> bool { - let ancestor = self.ast_map.local_def_id(ancestor); + let ancestor = self.definitions.local_def_id(ancestor); let mut module = *self.module_map.get(&node).unwrap(); while module.def_id() != Some(ancestor) { let module_parent = match self.get_nearest_normal_module_parent(module) { @@ -1096,13 +1082,13 @@ impl<'a, 'tcx> ty::NodeIdTree for Resolver<'a, 'tcx> { } } -impl<'a, 'tcx> Resolver<'a, 'tcx> { +impl<'a> Resolver<'a> { fn new(session: &'a Session, - ast_map: &'a hir_map::Map<'tcx>, + definitions: &'a Definitions, make_glob_map: MakeGlobMap, arenas: &'a ResolverArenas<'a>) - -> Resolver<'a, 'tcx> { - let root_def_id = ast_map.local_def_id(CRATE_NODE_ID); + -> Resolver<'a> { + let root_def_id = definitions.local_def_id(CRATE_NODE_ID); let graph_root = ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, arenas); let graph_root = arenas.alloc_module(graph_root); @@ -1112,7 +1098,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { Resolver { session: session, - ast_map: ast_map, + definitions: definitions, // The outermost module has def ID 0; this is not reflected in the // AST. @@ -1335,7 +1321,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // This is not a crate-relative path. We resolve the // first component of the path in the current lexical // scope and then proceed to resolve below that. - let ident = hir::Ident::from_name(module_path[0]); + let ident = ast::Ident::with_empty_ctxt(module_path[0]); match self.resolve_ident_in_lexical_scope(ident, TypeNS, true) .and_then(LexicalScopeBinding::module) { None => return Failed(None), @@ -1377,11 +1363,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Invariant: This must only be called during main resolution, not during /// import resolution. fn resolve_ident_in_lexical_scope(&mut self, - ident: hir::Ident, + ident: ast::Ident, ns: Namespace, record_used: bool) -> Option> { - let name = match ns { ValueNS => ident.name, TypeNS => ident.unhygienic_name }; + let name = match ns { ValueNS => mtwt::resolve(ident), TypeNS => ident.name }; // Walk backwards up the ribs in scope. for i in (0 .. self.get_ribs(ns).len()).rev() { @@ -1394,7 +1380,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } if let ModuleRibKind(module) = self.get_ribs(ns)[i].kind { - let name = ident.unhygienic_name; + let name = ident.name; let item = self.resolve_name_in_module(module, name, ns, true, record_used); if let Success(binding) = item { // The ident resolves to an item. @@ -1563,77 +1549,76 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None } - fn resolve_crate(&mut self, krate: &hir::Crate) { + fn resolve_crate(&mut self, krate: &Crate) { debug!("(resolving crate) starting"); self.current_module = self.graph_root; - intravisit::walk_crate(self, krate); + visit::walk_crate(self, krate); } fn resolve_item(&mut self, item: &Item) { - let name = item.name; + let name = item.ident.name; debug!("(resolving item) resolving {}", name); match item.node { - ItemEnum(_, ref generics) | - ItemTy(_, ref generics) | - ItemStruct(_, ref generics) => { + ItemKind::Enum(_, ref generics) | + ItemKind::Ty(_, ref generics) | + ItemKind::Struct(_, ref generics) => { self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind), - |this| intravisit::walk_item(this, item)); + |this| visit::walk_item(this, item)); } - ItemFn(_, _, _, _, ref generics, _) => { + ItemKind::Fn(_, _, _, _, ref generics, _) => { self.with_type_parameter_rib(HasTypeParameters(generics, FnSpace, ItemRibKind), - |this| intravisit::walk_item(this, item)); + |this| visit::walk_item(this, item)); } - ItemDefaultImpl(_, ref trait_ref) => { + ItemKind::DefaultImpl(_, ref trait_ref) => { self.with_optional_trait_ref(Some(trait_ref), |_, _| {}); } - ItemImpl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => { + ItemKind::Impl(_, _, ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => self.resolve_implementation(generics, opt_trait_ref, &self_type, item.id, - impl_items); - } + impl_items), - ItemTrait(_, ref generics, ref bounds, ref trait_items) => { + ItemKind::Trait(_, ref generics, ref bounds, ref trait_items) => { // Create a new rib for the trait-wide type parameters. self.with_type_parameter_rib(HasTypeParameters(generics, TypeSpace, ItemRibKind), |this| { - let local_def_id = this.ast_map.local_def_id(item.id); + let local_def_id = this.definitions.local_def_id(item.id); this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| { this.visit_generics(generics); walk_list!(this, visit_ty_param_bound, bounds); for trait_item in trait_items { match trait_item.node { - hir::ConstTraitItem(_, ref default) => { + TraitItemKind::Const(_, ref default) => { // Only impose the restrictions of // ConstRibKind if there's an actual constant // expression in a provided default. if default.is_some() { this.with_constant_rib(|this| { - intravisit::walk_trait_item(this, trait_item) + visit::walk_trait_item(this, trait_item) }); } else { - intravisit::walk_trait_item(this, trait_item) + visit::walk_trait_item(this, trait_item) } } - hir::MethodTraitItem(ref sig, _) => { + TraitItemKind::Method(ref sig, _) => { let type_parameters = HasTypeParameters(&sig.generics, FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { - intravisit::walk_trait_item(this, trait_item) + visit::walk_trait_item(this, trait_item) }); } - hir::TypeTraitItem(..) => { + TraitItemKind::Type(..) => { this.with_type_parameter_rib(NoTypeParameters, |this| { - intravisit::walk_trait_item(this, trait_item) + visit::walk_trait_item(this, trait_item) }); } }; @@ -1642,21 +1627,21 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); } - ItemMod(_) | ItemForeignMod(_) => { + ItemKind::Mod(_) | ItemKind::ForeignMod(_) => { self.with_scope(item.id, |this| { - intravisit::walk_item(this, item); + visit::walk_item(this, item); }); } - ItemConst(..) | ItemStatic(..) => { + ItemKind::Const(..) | ItemKind::Static(..) => { self.with_constant_rib(|this| { - intravisit::walk_item(this, item); + visit::walk_item(this, item); }); } - ItemUse(ref view_path) => { + ItemKind::Use(ref view_path) => { match view_path.node { - hir::ViewPathList(ref prefix, ref items) => { + ast::ViewPathList(ref prefix, ref items) => { // Resolve prefix of an import with empty braces (issue #28388) if items.is_empty() && !prefix.segments.is_empty() { match self.resolve_crate_relative_path(prefix.span, @@ -1681,9 +1666,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - ItemExternCrate(_) => { + ItemKind::ExternCrate(_) => { // do nothing, these are just around to be encoded } + + ItemKind::Mac(_) => panic!("unexpanded macro in resolve!"), } } @@ -1695,7 +1682,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let mut function_type_rib = Rib::new(rib_kind); let mut seen_bindings = HashSet::new(); for (index, type_parameter) in generics.ty_params.iter().enumerate() { - let name = type_parameter.name; + let name = type_parameter.ident.name; debug!("with_type_parameter_rib: {}", type_parameter.id); if seen_bindings.contains(&name) { @@ -1706,7 +1693,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { seen_bindings.insert(name); // plain insert (no renaming) - let def_id = self.ast_map.local_def_id(type_parameter.id); + let def_id = self.definitions.local_def_id(type_parameter.id); let def = Def::TyParam(space, index as u32, def_id, name); function_type_rib.bindings.insert(name, def); } @@ -1759,7 +1746,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { debug!("(resolving function) recorded argument"); } - intravisit::walk_fn_ret_ty(self, &declaration.output); + visit::walk_fn_ret_ty(self, &declaration.output); // Resolve the function body. self.visit_block(block); @@ -1836,9 +1823,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_generics(&mut self, generics: &Generics) { for predicate in &generics.where_clause.predicates { match predicate { - &hir::WherePredicate::BoundPredicate(_) | - &hir::WherePredicate::RegionPredicate(_) => {} - &hir::WherePredicate::EqPredicate(ref eq_pred) => { + &ast::WherePredicate::BoundPredicate(_) | + &ast::WherePredicate::RegionPredicate(_) => {} + &ast::WherePredicate::EqPredicate(ref eq_pred) => { self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS).and_then(|path_res| { if let PathResolution { base_def: Def::TyParam(..), .. } = path_res { Ok(self.record_def(eq_pred.id, path_res)) @@ -1854,7 +1841,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } - intravisit::walk_generics(self, generics); + visit::walk_generics(self, generics); } fn with_current_self_type(&mut self, self_type: &Ty, f: F) -> T @@ -1883,7 +1870,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } else { self.record_def(trait_ref.ref_id, err_path_resolution()); } - intravisit::walk_trait_ref(self, trait_ref); + visit::walk_trait_ref(self, trait_ref); } let original_trait_ref = replace(&mut self.current_trait_ref, new_val); let result = f(self, new_id); @@ -1927,20 +1914,20 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { for impl_item in impl_items { this.resolve_visibility(&impl_item.vis); match impl_item.node { - hir::ImplItemKind::Const(..) => { + ImplItemKind::Const(..) => { // If this is a trait impl, ensure the const // exists in trait - this.check_trait_item(impl_item.name, + this.check_trait_item(impl_item.ident.name, impl_item.span, |n, s| ResolutionError::ConstNotMemberOfTrait(n, s)); this.with_constant_rib(|this| { - intravisit::walk_impl_item(this, impl_item); + visit::walk_impl_item(this, impl_item); }); } - hir::ImplItemKind::Method(ref sig, _) => { + ImplItemKind::Method(ref sig, _) => { // If this is a trait impl, ensure the method // exists in trait - this.check_trait_item(impl_item.name, + this.check_trait_item(impl_item.ident.name, impl_item.span, |n, s| ResolutionError::MethodNotMemberOfTrait(n, s)); @@ -1951,18 +1938,19 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { FnSpace, MethodRibKind); this.with_type_parameter_rib(type_parameters, |this| { - intravisit::walk_impl_item(this, impl_item); + visit::walk_impl_item(this, impl_item); }); } - hir::ImplItemKind::Type(ref ty) => { + ImplItemKind::Type(ref ty) => { // If this is a trait impl, ensure the type // exists in trait - this.check_trait_item(impl_item.name, + this.check_trait_item(impl_item.ident.name, impl_item.span, |n, s| ResolutionError::TypeNotMemberOfTrait(n, s)); this.visit_ty(ty); } + ImplItemKind::Macro(_) => panic!("unexpanded macro in resolve!"), } } }); @@ -2000,18 +1988,22 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // that expands into an or-pattern where one 'x' was from the // user and one 'x' came from the macro. fn binding_mode_map(&mut self, pat: &Pat) -> BindingMap { - let mut result = HashMap::new(); - let def_map = RefCell::new(::std::mem::replace(&mut self.def_map, NodeMap())); - pat_bindings(&def_map, pat, |binding_mode, _id, sp, path1| { - let name = path1.node; - result.insert(name, - BindingInfo { - span: sp, - binding_mode: binding_mode, - }); + let mut binding_map = HashMap::new(); + + pat.walk(&mut |pat| { + if let PatKind::Ident(binding_mode, ident, ref sub_pat) = pat.node { + if sub_pat.is_some() || match self.def_map.get(&pat.id) { + Some(&PathResolution { base_def: Def::Local(..), .. }) => true, + _ => false, + } { + let binding_info = BindingInfo { span: ident.span, binding_mode: binding_mode }; + binding_map.insert(mtwt::resolve(ident.node), binding_info); + } + } + true }); - self.def_map = def_map.into_inner(); - return result; + + binding_map } // check that all of the arms in an or-pattern have exactly the @@ -2086,7 +2078,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } // Descend into the block. - intravisit::walk_block(self, block); + visit::walk_block(self, block); // Move back up. self.current_module = orig_module; @@ -2099,7 +2091,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn resolve_type(&mut self, ty: &Ty) { match ty.node { - TyPath(ref maybe_qself, ref path) => { + TyKind::Path(ref maybe_qself, ref path) => { let resolution = match self.resolve_possibly_assoc_item(ty.id, maybe_qself.as_ref(), path, @@ -2107,7 +2099,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // `::a::b::c` is resolved by typeck alone. TypecheckRequired => { // Resolve embedded types. - intravisit::walk_ty(self, ty); + visit::walk_ty(self, ty); return; } ResolveAttempt(resolution) => resolution, @@ -2176,7 +2168,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { _ => {} } // Resolve embedded types. - intravisit::walk_ty(self, ty); + visit::walk_ty(self, ty); } fn resolve_pattern(&mut self, @@ -2186,7 +2178,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // pattern that binds them bindings_list: &mut HashMap) { let pat_id = pattern.id; - pattern.walk(|pattern| { + pattern.walk(&mut |pattern| { match pattern.node { PatKind::Ident(binding_mode, ref path1, ref at_rhs) => { // The meaning of PatKind::Ident with no type parameters @@ -2200,7 +2192,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let const_ok = mode == RefutableMode && at_rhs.is_none(); let ident = path1.node; - let renamed = ident.name; + let renamed = mtwt::resolve(ident); match self.resolve_bare_identifier_pattern(ident, pattern.span) { FoundStructOrEnumVariant(def) if const_ok => { @@ -2246,7 +2238,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { BareIdentifierPatternUnresolved => { debug!("(resolving pattern) binding `{}`", renamed); - let def_id = self.ast_map.local_def_id(pattern.id); + let def_id = self.definitions.local_def_id(pattern.id); let def = Def::Local(def_id, pattern.id); // Record the definition so that later passes @@ -2370,7 +2362,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ); self.record_def(pattern.id, err_path_resolution()); } - intravisit::walk_path(self, path); + visit::walk_path(self, path); } PatKind::QPath(ref qself, ref path) => { @@ -2390,7 +2382,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .name; let traits = self.get_traits_containing_item(const_name); self.trait_map.insert(pattern.id, traits); - intravisit::walk_pat(self, pattern); + visit::walk_pat(self, pattern); return true; } ResolveAttempt(resolution) => resolution, @@ -2424,7 +2416,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { .as_str())); self.record_def(pattern.id, err_path_resolution()); } - intravisit::walk_pat(self, pattern); + visit::walk_pat(self, pattern); } PatKind::Struct(ref path, _, _) => { @@ -2443,11 +2435,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.record_def(pattern.id, err_path_resolution()); } } - intravisit::walk_path(self, path); + visit::walk_path(self, path); } PatKind::Lit(_) | PatKind::Range(..) => { - intravisit::walk_pat(self, pattern); + visit::walk_pat(self, pattern); } _ => { @@ -2458,7 +2450,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { }); } - fn resolve_bare_identifier_pattern(&mut self, ident: hir::Ident, span: Span) + fn resolve_bare_identifier_pattern(&mut self, ident: ast::Ident, span: Span) -> BareIdentifierPatternResolution { let binding = match self.resolve_ident_in_lexical_scope(ident, ValueNS, true) { Some(LexicalScopeBinding::Item(binding)) => binding, @@ -2468,7 +2460,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { match def { Def::Variant(..) | Def::Struct(..) => FoundStructOrEnumVariant(def), - Def::Const(..) | Def::AssociatedConst(..) => FoundConst(def, ident.unhygienic_name), + Def::Const(..) | Def::AssociatedConst(..) => FoundConst(def, ident.name), Def::Static(..) => { let error = ResolutionError::StaticVariableReference(binding); resolve_error(self, span, error); @@ -2481,7 +2473,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// Handles paths that may refer to associated items fn resolve_possibly_assoc_item(&mut self, id: NodeId, - maybe_qself: Option<&hir::QSelf>, + maybe_qself: Option<&ast::QSelf>, path: &Path, namespace: Namespace) -> AssocItemResolveResult { @@ -2542,7 +2534,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { None | Some(LocalDef{def: Def::Mod(..), ..}) if namespace == TypeNS => this.primitive_type_table .primitive_types - .get(&last_ident.unhygienic_name) + .get(&last_ident.name) .map_or(def, |prim_ty| Some(LocalDef::from_def(Def::PrimTy(*prim_ty)))), _ => def } @@ -2583,11 +2575,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Resolve a single identifier fn resolve_identifier(&mut self, - identifier: hir::Ident, + identifier: ast::Ident, namespace: Namespace, record_used: bool) -> Option { - if identifier.unhygienic_name == keywords::Invalid.name() { + if identifier.name == keywords::Invalid.name() { return Some(LocalDef::from_def(Def::Err)); } @@ -2615,7 +2607,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } ClosureRibKind(function_id) => { let prev_def = def; - let node_def_id = self.ast_map.local_def_id(node_id); + let node_def_id = self.definitions.local_def_id(node_id); let seen = self.freevars_seen .entry(function_id) @@ -2687,7 +2679,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // resolve a "module-relative" path, e.g. a::b::c fn resolve_module_relative_path(&mut self, span: Span, - segments: &[hir::PathSegment], + segments: &[ast::PathSegment], namespace: Namespace) -> Result<&'a NameBinding<'a>, bool /* true if an error was reported */> { @@ -2731,7 +2723,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { /// import resolution. fn resolve_crate_relative_path(&mut self, span: Span, - segments: &[hir::PathSegment], + segments: &[ast::PathSegment], namespace: Namespace) -> Result<&'a NameBinding<'a>, bool /* true if an error was reported */> { @@ -2790,8 +2782,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn find_fallback_in_self_type(&mut self, name: Name) -> FallbackSuggestion { fn extract_node_id(t: &Ty) -> Option { match t.node { - TyPath(None, _) => Some(t.id), - TyRptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty), + TyKind::Path(None, _) => Some(t.id), + TyKind::Rptr(_, ref mut_ty) => extract_node_id(&mut_ty.ty), // This doesn't handle the remaining `Ty` variants as they are not // that commonly the self_type, it might be interesting to provide // support for those in future. @@ -2849,6 +2841,18 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } SuggestionType::NotFound } + fn resolve_labeled_block(&mut self, label: Option, id: NodeId, block: &Block) { + if let Some(label) = label { + let (label, def) = (mtwt::resolve(label), Def::Label(id)); + self.with_label_rib(|this| { + this.label_ribs.last_mut().unwrap().bindings.insert(label, def); + this.visit_block(block); + }); + } else { + self.visit_block(block); + } + } + fn resolve_expr(&mut self, expr: &Expr, parent: Option<&Expr>) { // First, record candidate traits for this expression if it could // result in the invocation of a method call. @@ -2857,7 +2861,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { // Next, resolve the node. match expr.node { - ExprPath(ref maybe_qself, ref path) => { + ExprKind::Path(ref maybe_qself, ref path) => { let resolution = match self.resolve_possibly_assoc_item(expr.id, maybe_qself.as_ref(), path, @@ -2867,7 +2871,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let method_name = path.segments.last().unwrap().identifier.name; let traits = self.get_traits_containing_item(method_name); self.trait_map.insert(expr.id, traits); - intravisit::walk_expr(self, expr); + visit::walk_expr(self, expr); return; } ResolveAttempt(resolution) => resolution, @@ -3009,10 +3013,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - intravisit::walk_expr(self, expr); + visit::walk_expr(self, expr); } - ExprStruct(ref path, _, _) => { + ExprKind::Struct(ref path, _, _) => { // Resolve the path to the structure it goes to. We don't // check to ensure that the path is actually a structure; that // is checked later during typeck. @@ -3031,24 +3035,24 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - intravisit::walk_expr(self, expr); + visit::walk_expr(self, expr); } - ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => { + ExprKind::Loop(_, Some(label)) | ExprKind::While(_, _, Some(label)) => { self.with_label_rib(|this| { let def = Def::Label(expr.id); { let rib = this.label_ribs.last_mut().unwrap(); - rib.bindings.insert(label.name, def); + rib.bindings.insert(mtwt::resolve(label), def); } - intravisit::walk_expr(this, expr); + visit::walk_expr(this, expr); }) } - ExprBreak(Some(label)) | ExprAgain(Some(label)) => { - match self.search_label(label.node.name) { + ExprKind::Break(Some(label)) | ExprKind::Again(Some(label)) => { + match self.search_label(mtwt::resolve(label.node)) { None => { self.record_def(expr.id, err_path_resolution()); resolve_error(self, @@ -3068,10 +3072,42 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } } - ExprField(ref subexpression, _) => { + + ExprKind::IfLet(ref pattern, ref subexpression, ref if_block, ref optional_else) => { + self.visit_expr(subexpression); + + self.value_ribs.push(Rib::new(NormalRibKind)); + self.resolve_pattern(pattern, RefutableMode, &mut HashMap::new()); + self.visit_block(if_block); + self.value_ribs.pop(); + + optional_else.as_ref().map(|expr| self.visit_expr(expr)); + } + + ExprKind::WhileLet(ref pattern, ref subexpression, ref block, label) => { + self.visit_expr(subexpression); + self.value_ribs.push(Rib::new(NormalRibKind)); + self.resolve_pattern(pattern, RefutableMode, &mut HashMap::new()); + + self.resolve_labeled_block(label, expr.id, block); + + self.value_ribs.pop(); + } + + ExprKind::ForLoop(ref pattern, ref subexpression, ref block, label) => { + self.visit_expr(subexpression); + self.value_ribs.push(Rib::new(NormalRibKind)); + self.resolve_pattern(pattern, LocalIrrefutableMode, &mut HashMap::new()); + + self.resolve_labeled_block(label, expr.id, block); + + self.value_ribs.pop(); + } + + ExprKind::Field(ref subexpression, _) => { self.resolve_expr(subexpression, Some(expr)); } - ExprMethodCall(_, ref types, ref arguments) => { + ExprKind::MethodCall(_, ref types, ref arguments) => { let mut arguments = arguments.iter(); self.resolve_expr(arguments.next().unwrap(), Some(expr)); for argument in arguments { @@ -3083,25 +3119,25 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } _ => { - intravisit::walk_expr(self, expr); + visit::walk_expr(self, expr); } } } fn record_candidate_traits_for_expr_if_necessary(&mut self, expr: &Expr) { match expr.node { - ExprField(_, name) => { + ExprKind::Field(_, name) => { // FIXME(#6890): Even though you can't treat a method like a // field, we need to add any trait methods we find that match // the field name so that we can do some nice error reporting // later on in typeck. - let traits = self.get_traits_containing_item(name.node); + let traits = self.get_traits_containing_item(name.node.name); self.trait_map.insert(expr.id, traits); } - ExprMethodCall(name, _, _) => { + ExprKind::MethodCall(name, _, _) => { debug!("(recording candidate traits for expr) recording traits for {}", expr.id); - let traits = self.get_traits_containing_item(name.node); + let traits = self.get_traits_containing_item(name.node.name); self.trait_map.insert(expr.id, traits); } _ => { @@ -3211,7 +3247,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { if let Some(def) = name_binding.def() { if name == lookup_name && ns == namespace && filter_fn(def) { // create the path - let ident = hir::Ident::from_name(name); + let ident = ast::Ident::with_empty_ctxt(name); let params = PathParameters::none(); let segment = PathSegment { identifier: ident, @@ -3220,7 +3256,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let span = name_binding.span; let mut segms = path_segments.clone(); segms.push(segment); - let segms = HirVec::from_vec(segms); let path = Path { span: span, global: true, @@ -3246,7 +3281,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { NoParentLink => path_segments.clone(), ModuleParentLink(_, name) => { let mut paths = path_segments.clone(); - let ident = hir::Ident::from_name(name); + let ident = ast::Ident::with_empty_ctxt(name); let params = PathParameters::none(); let segm = PathSegment { identifier: ident, @@ -3276,11 +3311,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn record_def(&mut self, node_id: NodeId, resolution: PathResolution) { debug!("(recording def) recording {:?} for {}", resolution, node_id); if let Some(prev_res) = self.def_map.insert(node_id, resolution) { - let span = self.ast_map.opt_span(node_id).unwrap_or(codemap::DUMMY_SP); - span_bug!(span, - "path resolved multiple times ({:?} before, {:?} now)", - prev_res, - resolution); + panic!("path resolved multiple times ({:?} before, {:?} now)", prev_res, resolution); } } @@ -3289,8 +3320,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { pat_binding_mode: BindingMode, descr: &str) { match pat_binding_mode { - BindByValue(_) => {} - BindByRef(..) => { + BindingMode::ByValue(_) => {} + BindingMode::ByRef(..) => { resolve_error(self, pat.span, ResolutionError::CannotUseRefBindingModeWith(descr)); @@ -3298,15 +3329,16 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { } } - fn resolve_visibility(&mut self, vis: &hir::Visibility) -> ty::Visibility { + fn resolve_visibility(&mut self, vis: &ast::Visibility) -> ty::Visibility { let (path, id) = match *vis { - hir::Public => return ty::Visibility::Public, - hir::Visibility::Crate => return ty::Visibility::Restricted(ast::CRATE_NODE_ID), - hir::Visibility::Restricted { ref path, id } => (path, id), - hir::Inherited => { + ast::Visibility::Public => return ty::Visibility::Public, + ast::Visibility::Crate(_) => return ty::Visibility::Restricted(ast::CRATE_NODE_ID), + ast::Visibility::Restricted { ref path, id } => (path, id), + ast::Visibility::Inherited => { let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module); - let id = self.ast_map.as_local_node_id(current_module.def_id().unwrap()).unwrap(); + let id = + self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap(); return ty::Visibility::Restricted(id); } }; @@ -3317,7 +3349,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { let def = module.def.unwrap(); let path_resolution = PathResolution { base_def: def, depth: 0 }; self.def_map.insert(id, path_resolution); - ty::Visibility::Restricted(self.ast_map.as_local_node_id(def.def_id()).unwrap()) + ty::Visibility::Restricted(self.definitions.as_local_node_id(def.def_id()).unwrap()) } Failed(Some((span, msg))) => { self.session.span_err(span, &format!("failed to resolve module path. {}", msg)); @@ -3337,7 +3369,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { fn is_accessible(&self, vis: ty::Visibility) -> bool { let current_module = self.get_nearest_normal_module_parent_or_self(self.current_module); - let node_id = self.ast_map.as_local_node_id(current_module.def_id().unwrap()).unwrap(); + let node_id = self.definitions.as_local_node_id(current_module.def_id().unwrap()).unwrap(); vis.is_accessible_from(node_id, self) } @@ -3547,10 +3579,11 @@ pub enum MakeGlobMap { } /// Entry point to crate resolution. -pub fn resolve_crate<'a, 'tcx>(session: &'a Session, - ast_map: &'a hir_map::Map<'tcx>, - make_glob_map: MakeGlobMap) - -> CrateMap { +pub fn resolve_crate<'a>(session: &'a Session, + krate: &'a Crate, + definitions: &'a Definitions, + make_glob_map: MakeGlobMap) + -> CrateMap { // Currently, we ignore the name resolution data structures for // the purposes of dependency tracking. Instead we will run name // resolution and include its output in the hash of each item, @@ -3558,11 +3591,9 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session, // reflects not just its contents but the results of name // resolution on those contents. Hopefully we'll push this back at // some point. - let _task = ast_map.dep_graph.in_task(DepNode::Resolve); - let krate = ast_map.krate(); let arenas = Resolver::arenas(); - let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas); + let mut resolver = create_resolver(session, definitions, krate, make_glob_map, &arenas); resolver.resolve_crate(krate); @@ -3584,13 +3615,13 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session, } /// Builds a name resolution walker. -fn create_resolver<'a, 'tcx>(session: &'a Session, - ast_map: &'a hir_map::Map<'tcx>, - krate: &'a Crate, - make_glob_map: MakeGlobMap, - arenas: &'a ResolverArenas<'a>) - -> Resolver<'a, 'tcx> { - let mut resolver = Resolver::new(session, ast_map, make_glob_map, arenas); +fn create_resolver<'a>(session: &'a Session, + definitions: &'a Definitions, + krate: &'a Crate, + make_glob_map: MakeGlobMap, + arenas: &'a ResolverArenas<'a>) + -> Resolver<'a> { + let mut resolver = Resolver::new(session, definitions, make_glob_map, arenas); resolver.build_reduced_graph(krate); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index a93b129a72b..9bd16117f9a 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -344,11 +344,11 @@ struct ImportResolvingError<'a> { help: String, } -struct ImportResolver<'a, 'b: 'a, 'tcx: 'b> { - resolver: &'a mut Resolver<'b, 'tcx>, +struct ImportResolver<'a, 'b: 'a> { + resolver: &'a mut Resolver<'b>, } -impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { +impl<'a, 'b:'a> ImportResolver<'a, 'b> { // Import resolution // // This is a fixed-point algorithm. We resolve imports until our efforts @@ -700,7 +700,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> { if reexports.len() > 0 { if let Some(def_id) = module.def_id() { - let node_id = self.resolver.ast_map.as_local_node_id(def_id).unwrap(); + let node_id = self.resolver.definitions.as_local_node_id(def_id).unwrap(); self.resolver.export_map.insert(node_id, reexports); } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index bf1c305e206..d1ad330c58c 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -551,6 +551,44 @@ impl fmt::Debug for Pat { } } +impl Pat { + pub fn walk(&self, it: &mut F) -> bool + where F: FnMut(&Pat) -> bool + { + if !it(self) { + return false; + } + + match self.node { + PatKind::Ident(_, _, Some(ref p)) => p.walk(it), + PatKind::Struct(_, ref fields, _) => { + fields.iter().all(|field| field.node.pat.walk(it)) + } + PatKind::TupleStruct(_, Some(ref s)) | PatKind::Tup(ref s) => { + s.iter().all(|p| p.walk(it)) + } + PatKind::Box(ref s) | PatKind::Ref(ref s, _) => { + s.walk(it) + } + PatKind::Vec(ref before, ref slice, ref after) => { + before.iter().all(|p| p.walk(it)) && + slice.iter().all(|p| p.walk(it)) && + after.iter().all(|p| p.walk(it)) + } + PatKind::Wild | + PatKind::Lit(_) | + PatKind::Range(_, _) | + PatKind::Ident(_, _, _) | + PatKind::TupleStruct(..) | + PatKind::Path(..) | + PatKind::QPath(_, _) | + PatKind::Mac(_) => { + true + } + } + } +} + /// A single field in a struct pattern /// /// Patterns like the fields of Foo `{ x, ref y, ref mut z }`