Move resolution to before lowering
This commit is contained in:
parent
16c8f2cca8
commit
8428447253
@ -1438,7 +1438,8 @@ pub fn lower_expr(lctx: &LoweringContext, e: &Expr) -> P<hir::Expr> {
|
||||
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<hir::Expr> {
|
||||
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 = {
|
||||
|
@ -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<ast::NodeId> {
|
||||
if def_id.krate == LOCAL_CRATE {
|
||||
assert!(def_id.index.as_usize() < self.data.len());
|
||||
|
@ -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<DefMap>,
|
||||
freevars: FreevarMap,
|
||||
trait_map: TraitMap,
|
||||
maybe_unused_trait_imports: NodeSet,
|
||||
f: F)
|
||||
-> Result<R, usize>
|
||||
where F: FnOnce(&TyCtxt<'tcx>, Option<MirMap<'tcx>>, 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,
|
||||
|
@ -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| {
|
||||
let mod_spans = source_items.iter().filter_map(|item| {
|
||||
match item.node {
|
||||
PathListMod { .. } => Some(item.span),
|
||||
PathListItemKind::Mod { .. } => Some(item.span),
|
||||
_ => None,
|
||||
}
|
||||
})
|
||||
.collect::<Vec<Span>>();
|
||||
}).collect::<Vec<Span>>();
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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>,
|
||||
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>,
|
||||
fn resolve_struct_error<'b, 'a: 'b, 'c>(resolver: &'b Resolver<'a>,
|
||||
span: syntax::codemap::Span,
|
||||
resolution_error: ResolutionError<'b>)
|
||||
-> DiagnosticBuilder<'c> {
|
||||
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<LexicalScopeBinding<'a>> {
|
||||
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<T, F>(&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> {
|
||||
// `<T>::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<Name, NodeId>) {
|
||||
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<LocalDef> {
|
||||
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<NodeId> {
|
||||
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<ast::Ident>, 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,8 +3579,9 @@ pub enum MakeGlobMap {
|
||||
}
|
||||
|
||||
/// Entry point to crate resolution.
|
||||
pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
|
||||
ast_map: &'a hir_map::Map<'tcx>,
|
||||
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
|
||||
@ -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>,
|
||||
fn create_resolver<'a>(session: &'a Session,
|
||||
definitions: &'a Definitions,
|
||||
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);
|
||||
-> Resolver<'a> {
|
||||
let mut resolver = Resolver::new(session, definitions, make_glob_map, arenas);
|
||||
|
||||
resolver.build_reduced_graph(krate);
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -551,6 +551,44 @@ impl fmt::Debug for Pat {
|
||||
}
|
||||
}
|
||||
|
||||
impl Pat {
|
||||
pub fn walk<F>(&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 }`
|
||||
|
Loading…
Reference in New Issue
Block a user