extern crate log;
#[macro_use]
extern crate syntax;
+extern crate arena;
#[macro_use]
#[no_link]
extern crate rustc_bitflags;
use std::cell::{Cell, RefCell};
use std::fmt;
use std::mem::replace;
-use std::rc::{Rc, Weak};
+use std::rc::Rc;
use resolve_imports::{Target, ImportDirective, ImportResolutionPerNamespace};
use resolve_imports::Shadowable;
pub mod diagnostics;
mod check_unused;
-mod record_exports;
mod build_reduced_graph;
mod resolve_imports;
}
pub enum ResolutionError<'a> {
+ /// error E0260: name conflicts with an extern crate
+ NameConflictsWithExternCrate(Name),
/// error E0401: can't use type parameters from outer function
TypeParametersFromOuterFunction,
/// error E0402: cannot use an outer type parameter in this context
}
match resolution_error {
+ ResolutionError::NameConflictsWithExternCrate(name) => {
+ struct_span_err!(resolver.session,
+ span,
+ E0260,
+ "the name `{}` conflicts with an external crate \
+ that has been imported into this module",
+ name)
+ }
ResolutionError::TypeParametersFromOuterFunction => {
struct_span_err!(resolver.session,
span,
/// a particular namespace. The result is either definitely-resolved,
/// definitely- unresolved, or unknown.
#[derive(Clone)]
-enum NamespaceResult {
+enum NamespaceResult<'a> {
/// Means that resolve hasn't gathered enough information yet to determine
/// whether the name is bound in this namespace. (That is, it hasn't
/// resolved all `use` directives yet.)
UnboundResult,
/// Means that resolve has determined that the name is bound in the Module
/// argument, and specified by the NameBinding argument.
- BoundResult(Rc<Module>, NameBinding),
+ BoundResult(Module<'a>, NameBinding<'a>),
}
-impl NamespaceResult {
+impl<'a> NamespaceResult<'a> {
fn is_unknown(&self) -> bool {
match *self {
UnknownResult => true,
}
// The rib kind controls the translation of local
-// definitions (`DefLocal`) to upvars (`DefUpvar`).
+// definitions (`Def::Local`) to upvars (`Def::Upvar`).
#[derive(Copy, Clone, Debug)]
enum RibKind {
// No translation needs to be applied.
UseLexicalScope,
}
-enum ModulePrefixResult {
+enum ModulePrefixResult<'a> {
NoPrefixFound,
- PrefixFound(Rc<Module>, usize),
+ PrefixFound(Module<'a>, usize),
}
#[derive(Copy, Clone)]
/// The link from a module up to its nearest parent node.
#[derive(Clone,Debug)]
-enum ParentLink {
+enum ParentLink<'a> {
NoParentLink,
- ModuleParentLink(Weak<Module>, Name),
- BlockParentLink(Weak<Module>, NodeId),
+ ModuleParentLink(Module<'a>, Name),
+ BlockParentLink(Module<'a>, NodeId),
}
/// One node in the tree of modules.
-pub struct Module {
- parent_link: ParentLink,
+pub struct ModuleS<'a> {
+ parent_link: ParentLink<'a>,
def: Cell<Option<Def>>,
is_public: bool,
- children: RefCell<HashMap<Name, NameBindings>>,
+ children: RefCell<HashMap<Name, NameBindings<'a>>>,
imports: RefCell<Vec<ImportDirective>>,
// The external module children of this node that were declared with
// `extern crate`.
- external_module_children: RefCell<HashMap<Name, Rc<Module>>>,
+ external_module_children: RefCell<HashMap<Name, Module<'a>>>,
// The anonymous children of this node. Anonymous children are pseudo-
// modules that are implicitly created around items contained within
//
// There will be an anonymous module created around `g` with the ID of the
// entry block for `f`.
- anonymous_children: RefCell<NodeMap<Rc<Module>>>,
+ anonymous_children: RefCell<NodeMap<Module<'a>>>,
// The status of resolving each import in this module.
- import_resolutions: RefCell<HashMap<Name, ImportResolutionPerNamespace>>,
+ import_resolutions: RefCell<HashMap<Name, ImportResolutionPerNamespace<'a>>>,
// The number of unresolved globs that this module exports.
glob_count: Cell<usize>,
populated: Cell<bool>,
}
-impl Module {
- fn new(parent_link: ParentLink,
- def: Option<Def>,
- external: bool,
- is_public: bool)
- -> Rc<Module> {
- Rc::new(Module {
+pub type Module<'a> = &'a ModuleS<'a>;
+
+impl<'a> ModuleS<'a> {
+ fn new(parent_link: ParentLink<'a>, def: Option<Def>, external: bool, is_public: bool) -> Self {
+ ModuleS {
parent_link: parent_link,
def: Cell::new(def),
is_public: is_public,
pub_glob_count: Cell::new(0),
resolved_import_count: Cell::new(0),
populated: Cell::new(!external),
- })
+ }
}
fn def_id(&self) -> Option<DefId> {
fn is_normal(&self) -> bool {
match self.def.get() {
- Some(DefMod(_)) | Some(DefForeignMod(_)) => true,
+ Some(Def::Mod(_)) | Some(Def::ForeignMod(_)) => true,
_ => false,
}
}
fn is_trait(&self) -> bool {
match self.def.get() {
- Some(DefTrait(_)) => true,
+ Some(Def::Trait(_)) => true,
_ => false,
}
}
self.imports.borrow().len() == self.resolved_import_count.get()
}
}
-}
-impl Module {
pub fn inc_glob_count(&self) {
self.glob_count.set(self.glob_count.get() + 1);
}
}
}
-impl fmt::Debug for Module {
+impl<'a> fmt::Debug for ModuleS<'a> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f,
"{:?}, {}",
// Records a possibly-private value, type, or module definition.
#[derive(Debug)]
-struct NsDef {
+struct NsDef<'a> {
modifiers: DefModifiers, // see note in ImportResolutionPerNamespace about how to use this
- def_or_module: DefOrModule,
+ def_or_module: DefOrModule<'a>,
span: Option<Span>,
}
#[derive(Debug)]
-enum DefOrModule {
+enum DefOrModule<'a> {
Def(Def),
- Module(Rc<Module>),
+ Module(Module<'a>),
}
-impl NsDef {
- fn create_from_module(module: Rc<Module>, span: Option<Span>) -> Self {
+impl<'a> NsDef<'a> {
+ fn create_from_module(module: Module<'a>, span: Option<Span>) -> Self {
let modifiers = if module.is_public {
DefModifiers::PUBLIC
} else {
NsDef { modifiers: modifiers, def_or_module: DefOrModule::Def(def), span: span }
}
- fn module(&self) -> Option<Rc<Module>> {
+ fn module(&self) -> Option<Module<'a>> {
match self.def_or_module {
- DefOrModule::Module(ref module) => Some(module.clone()),
+ DefOrModule::Module(ref module) => Some(module),
DefOrModule::Def(_) => None,
}
}
// Records at most one definition that a name in a namespace is bound to
#[derive(Clone,Debug)]
-pub struct NameBinding(Rc<RefCell<Option<NsDef>>>);
+pub struct NameBinding<'a>(Rc<RefCell<Option<NsDef<'a>>>>);
-impl NameBinding {
+impl<'a> NameBinding<'a> {
fn new() -> Self {
NameBinding(Rc::new(RefCell::new(None)))
}
- fn create_from_module(module: Rc<Module>) -> Self {
+ fn create_from_module(module: Module<'a>) -> Self {
NameBinding(Rc::new(RefCell::new(Some(NsDef::create_from_module(module, None)))))
}
- fn set(&self, ns_def: NsDef) {
+ fn set(&self, ns_def: NsDef<'a>) {
*self.0.borrow_mut() = Some(ns_def);
}
}
}
- fn borrow(&self) -> ::std::cell::Ref<Option<NsDef>> {
+ fn borrow(&self) -> ::std::cell::Ref<Option<NsDef<'a>>> {
self.0.borrow()
}
fn def(&self) -> Option<Def> {
self.borrow().as_ref().and_then(NsDef::def)
}
- fn module(&self) -> Option<Rc<Module>> {
+ fn module(&self) -> Option<Module<'a>> {
self.borrow().as_ref().and_then(NsDef::module)
}
fn span(&self) -> Option<Span> {
// Records the definitions (at most one for each namespace) that a name is
// bound to.
#[derive(Clone,Debug)]
-pub struct NameBindings {
- type_ns: NameBinding, // < Meaning in type namespace.
- value_ns: NameBinding, // < Meaning in value namespace.
+pub struct NameBindings<'a> {
+ type_ns: NameBinding<'a>, // < Meaning in type namespace.
+ value_ns: NameBinding<'a>, // < Meaning in value namespace.
}
-impl ::std::ops::Index<Namespace> for NameBindings {
- type Output = NameBinding;
- fn index(&self, namespace: Namespace) -> &NameBinding {
+impl<'a> ::std::ops::Index<Namespace> for NameBindings<'a> {
+ type Output = NameBinding<'a>;
+ fn index(&self, namespace: Namespace) -> &NameBinding<'a> {
match namespace { TypeNS => &self.type_ns, ValueNS => &self.value_ns }
}
}
-impl NameBindings {
- fn new() -> NameBindings {
+impl<'a> NameBindings<'a> {
+ fn new() -> Self {
NameBindings {
type_ns: NameBinding::new(),
value_ns: NameBinding::new(),
}
/// Creates a new module in this set of name bindings.
- fn define_module(&self, module: Rc<Module>, sp: Span) {
+ fn define_module(&self, module: Module<'a>, sp: Span) {
self.type_ns.set(NsDef::create_from_module(module, Some(sp)));
}
ast_map: &'a hir_map::Map<'tcx>,
- graph_root: Rc<Module>,
+ graph_root: Module<'a>,
trait_item_map: FnvHashMap<(Name, DefId), DefId>,
unresolved_imports: usize,
// The module that represents the current item scope.
- current_module: Rc<Module>,
+ current_module: Module<'a>,
// The current set of local scopes, for values.
// FIXME #4948: Reuse ribs to avoid allocation.
// The intention is that the callback modifies this flag.
// Once set, the resolver falls out of the walk, preserving the ribs.
resolved: bool,
+
+ arenas: &'a ResolverArenas<'a>,
+}
+
+pub struct ResolverArenas<'a> {
+ modules: arena::TypedArena<ModuleS<'a>>,
}
#[derive(PartialEq)]
impl<'a, 'tcx> Resolver<'a, 'tcx> {
fn new(session: &'a Session,
ast_map: &'a hir_map::Map<'tcx>,
- make_glob_map: MakeGlobMap)
+ make_glob_map: MakeGlobMap,
+ arenas: &'a ResolverArenas<'a>)
-> Resolver<'a, 'tcx> {
let root_def_id = ast_map.local_def_id(CRATE_NODE_ID);
- let graph_root = Module::new(NoParentLink, Some(DefMod(root_def_id)), false, true);
+ let graph_root = ModuleS::new(NoParentLink, Some(Def::Mod(root_def_id)), false, true);
+ let graph_root = arenas.modules.alloc(graph_root);
Resolver {
session: session,
// The outermost module has def ID 0; this is not reflected in the
// AST.
- graph_root: graph_root.clone(),
+ graph_root: graph_root,
trait_item_map: FnvHashMap(),
structs: FnvHashMap(),
callback: None,
resolved: false,
+
+ arenas: arenas,
}
}
+ fn arenas() -> ResolverArenas<'a> {
+ ResolverArenas {
+ modules: arena::TypedArena::new(),
+ }
+ }
+
+ fn new_module(&self,
+ parent_link: ParentLink<'a>,
+ def: Option<Def>,
+ external: bool,
+ is_public: bool) -> Module<'a> {
+ self.arenas.modules.alloc(ModuleS::new(parent_link, def, external, is_public))
+ }
+
#[inline]
fn record_import_use(&mut self, import_id: NodeId, name: Name) {
if !self.make_glob_map {
}
}
- /// Checks that the names of external crates don't collide with other
- /// external crates.
- fn check_for_conflicts_between_external_crates(&self,
- module: &Module,
- name: Name,
- span: Span) {
+ /// Check that an external crate doesn't collide with items or other external crates.
+ fn check_for_conflicts_for_external_crate(&self, module: Module<'a>, name: Name, span: Span) {
if module.external_module_children.borrow().contains_key(&name) {
span_err!(self.session,
span,
"an external crate named `{}` has already been imported into this module",
name);
}
+ match module.children.borrow().get(&name) {
+ Some(name_bindings) if name_bindings.type_ns.defined() => {
+ resolve_error(self,
+ name_bindings.type_ns.span().unwrap_or(codemap::DUMMY_SP),
+ ResolutionError::NameConflictsWithExternCrate(name));
+ }
+ _ => {},
+ }
}
/// Checks that the names of items don't collide with external crates.
fn check_for_conflicts_between_external_crates_and_items(&self,
- module: &Module,
+ module: Module<'a>,
name: Name,
span: Span) {
if module.external_module_children.borrow().contains_key(&name) {
- span_err!(self.session,
- span,
- E0260,
- "the name `{}` conflicts with an external crate that has been imported \
- into this module",
- name);
+ resolve_error(self, span, ResolutionError::NameConflictsWithExternCrate(name));
}
}
/// Resolves the given module path from the given root `module_`.
fn resolve_module_path_from_root(&mut self,
- module_: Rc<Module>,
+ module_: Module<'a>,
module_path: &[Name],
index: usize,
span: Span,
name_search_type: NameSearchType,
lp: LastPrivate)
- -> ResolveResult<(Rc<Module>, LastPrivate)> {
- fn search_parent_externals(needle: Name, module: &Rc<Module>) -> Option<Rc<Module>> {
+ -> ResolveResult<(Module<'a>, LastPrivate)> {
+ fn search_parent_externals<'a>(needle: Name, module: Module<'a>)
+ -> Option<Module<'a>> {
match module.external_module_children.borrow().get(&needle) {
- Some(_) => Some(module.clone()),
+ Some(_) => Some(module),
None => match module.parent_link {
ModuleParentLink(ref parent, _) => {
- search_parent_externals(needle, &parent.upgrade().unwrap())
+ search_parent_externals(needle, parent)
}
_ => None,
},
// modules as we go.
while index < module_path_len {
let name = module_path[index];
- match self.resolve_name_in_module(search_module.clone(),
+ match self.resolve_name_in_module(search_module,
name,
TypeNS,
name_search_type,
false) {
Failed(None) => {
let segment_name = name.as_str();
- let module_name = module_to_string(&*search_module);
+ let module_name = module_to_string(search_module);
let mut span = span;
let msg = if "???" == &module_name[..] {
span.hi = span.lo + Pos::from_usize(segment_name.len());
/// On success, returns the resolved module, and the closest *private*
/// module found to the destination when resolving this path.
fn resolve_module_path(&mut self,
- module_: Rc<Module>,
+ module_: Module<'a>,
module_path: &[Name],
use_lexical_scope: UseLexicalScopeFlag,
span: Span,
name_search_type: NameSearchType)
- -> ResolveResult<(Rc<Module>, LastPrivate)> {
+ -> ResolveResult<(Module<'a>, LastPrivate)> {
let module_path_len = module_path.len();
assert!(module_path_len > 0);
module_to_string(&*module_));
// Resolve the module prefix, if any.
- let module_prefix_result = self.resolve_module_prefix(module_.clone(), module_path);
+ let module_prefix_result = self.resolve_module_prefix(module_, module_path);
let search_module;
let start_index;
DontUseLexicalScope => {
// This is a crate-relative path. We will start the
// resolution process at index zero.
- search_module = self.graph_root.clone();
+ search_module = self.graph_root;
start_index = 0;
last_private = LastMod(AllPublic);
}
}
}
Success(PrefixFound(ref containing_module, index)) => {
- search_module = containing_module.clone();
+ search_module = containing_module;
start_index = index;
last_private = LastMod(DependsOn(containing_module.def_id()
.unwrap()));
/// Invariant: This must only be called during main resolution, not during
/// import resolution.
fn resolve_item_in_lexical_scope(&mut self,
- module_: Rc<Module>,
+ module_: Module<'a>,
name: Name,
namespace: Namespace,
record_used: bool)
- -> ResolveResult<(Target, bool)> {
+ -> ResolveResult<(Target<'a>, bool)> {
debug!("(resolving item in lexical scope) resolving `{}` in namespace {:?} in `{}`",
name,
namespace,
match module_.children.borrow().get(&name) {
Some(name_bindings) if name_bindings[namespace].defined() => {
debug!("top name bindings succeeded");
- return Success((Target::new(module_.clone(),
+ return Success((Target::new(module_,
name_bindings[namespace].clone(),
Shadowable::Never),
false));
// Search for external modules.
if namespace == TypeNS {
- // FIXME (21114): In principle unclear `child` *has* to be lifted.
- let child = module_.external_module_children.borrow().get(&name).cloned();
- if let Some(module) = child {
+ let children = module_.external_module_children.borrow();
+ if let Some(module) = children.get(&name) {
let name_binding = NameBinding::create_from_module(module);
debug!("lower name bindings succeeded");
return Success((Target::new(module_, name_binding, Shadowable::Never),
let mut search_module = module_;
loop {
// Go to the next parent.
- match search_module.parent_link.clone() {
+ match search_module.parent_link {
NoParentLink => {
// No more parents. This module was unresolved.
debug!("(resolving item in lexical scope) unresolved module");
searching through module parents");
return Failed(None);
} else {
- search_module = parent_module_node.upgrade().unwrap();
+ search_module = parent_module_node;
}
}
- BlockParentLink(ref parent_module_node, _) => {
- search_module = parent_module_node.upgrade().unwrap();
+ BlockParentLink(parent_module_node, _) => {
+ search_module = parent_module_node;
}
}
// Resolve the name in the parent module.
- match self.resolve_name_in_module(search_module.clone(),
+ match self.resolve_name_in_module(search_module,
name,
namespace,
PathSearch,
/// Resolves a module name in the current lexical scope.
fn resolve_module_in_lexical_scope(&mut self,
- module_: Rc<Module>,
+ module_: Module<'a>,
name: Name)
- -> ResolveResult<Rc<Module>> {
+ -> ResolveResult<Module<'a>> {
// If this module is an anonymous module, resolve the item in the
// lexical scope. Otherwise, resolve the item from the crate root.
let resolve_result = self.resolve_item_in_lexical_scope(module_, name, TypeNS, true);
}
/// Returns the nearest normal module parent of the given module.
- fn get_nearest_normal_module_parent(&mut self, module_: Rc<Module>) -> Option<Rc<Module>> {
+ fn get_nearest_normal_module_parent(&mut self, module_: Module<'a>) -> Option<Module<'a>> {
let mut module_ = module_;
loop {
- match module_.parent_link.clone() {
+ match module_.parent_link {
NoParentLink => return None,
ModuleParentLink(new_module, _) |
BlockParentLink(new_module, _) => {
- let new_module = new_module.upgrade().unwrap();
+ let new_module = new_module;
if new_module.is_normal() {
return Some(new_module);
}
/// Returns the nearest normal module parent of the given module, or the
/// module itself if it is a normal module.
- fn get_nearest_normal_module_parent_or_self(&mut self, module_: Rc<Module>) -> Rc<Module> {
+ fn get_nearest_normal_module_parent_or_self(&mut self, module_: Module<'a>) -> Module<'a> {
if module_.is_normal() {
return module_;
}
- match self.get_nearest_normal_module_parent(module_.clone()) {
+ match self.get_nearest_normal_module_parent(module_) {
None => module_,
Some(new_module) => new_module,
}
/// (b) some chain of `super::`.
/// grammar: (SELF MOD_SEP ) ? (SUPER MOD_SEP) *
fn resolve_module_prefix(&mut self,
- module_: Rc<Module>,
+ module_: Module<'a>,
module_path: &[Name])
- -> ResolveResult<ModulePrefixResult> {
+ -> ResolveResult<ModulePrefixResult<'a>> {
// Start at the current module if we see `self` or `super`, or at the
// top of the crate otherwise.
let mut i = match &*module_path[0].as_str() {
/// The boolean returned on success is an indicator of whether this lookup
/// passed through a public re-export proxy.
fn resolve_name_in_module(&mut self,
- module_: Rc<Module>,
+ module_: Module<'a>,
name: Name,
namespace: Namespace,
name_search_type: NameSearchType,
allow_private_imports: bool)
- -> ResolveResult<(Target, bool)> {
+ -> ResolveResult<(Target<'a>, bool)> {
debug!("(resolving name in module) resolving `{}` in `{}`",
name,
module_to_string(&*module_));
// First, check the direct children of the module.
build_reduced_graph::populate_module_if_necessary(self, &module_);
- match module_.children.borrow().get(&name) {
+ let children = module_.children.borrow();
+ match children.get(&name) {
Some(name_bindings) if name_bindings[namespace].defined() => {
debug!("(resolving name in module) found node as child");
- return Success((Target::new(module_.clone(),
+ return Success((Target::new(module_,
name_bindings[namespace].clone(),
Shadowable::Never),
false));
}
// Check the list of resolved imports.
- match module_.import_resolutions.borrow().get(&name) {
+ let children = module_.import_resolutions.borrow();
+ match children.get(&name) {
Some(import_resolution) if allow_private_imports ||
import_resolution[namespace].is_public => {
// Finally, search through external children.
if namespace == TypeNS {
- // FIXME (21114): In principle unclear `child` *has* to be lifted.
- let child = module_.external_module_children.borrow().get(&name).cloned();
- if let Some(module) = child {
+ let children = module_.external_module_children.borrow();
+ if let Some(module) = children.get(&name) {
let name_binding = NameBinding::create_from_module(module);
return Success((Target::new(module_, name_binding, Shadowable::Never),
false));
return Failed(None);
}
- fn report_unresolved_imports(&mut self, module_: Rc<Module>) {
+ fn report_unresolved_imports(&mut self, module_: Module<'a>) {
let index = module_.resolved_import_count.get();
let imports = module_.imports.borrow();
let import_count = imports.len();
}
for (_, module_) in module_.anonymous_children.borrow().iter() {
- self.report_unresolved_imports(module_.clone());
+ self.report_unresolved_imports(module_);
}
}
fn with_scope<F>(&mut self, name: Option<Name>, f: F)
where F: FnOnce(&mut Resolver)
{
- let orig_module = self.current_module.clone();
+ let orig_module = self.current_module;
// Move down in the graph.
match name {
ItemRibKind),
|this| {
let local_def_id = this.ast_map.local_def_id(item.id);
- this.with_self_rib(DefSelfTy(Some(local_def_id), None), |this| {
+ this.with_self_rib(Def::SelfTy(Some(local_def_id), None), |this| {
this.visit_generics(generics);
walk_list!(this, visit_ty_param_bound, bounds);
// check for imports shadowing primitive types
let check_rename = |this: &Self, id, name| {
match this.def_map.borrow().get(&id).map(|d| d.full_def()) {
- Some(DefTy(..)) | Some(DefStruct(..)) | Some(DefTrait(..)) | None => {
+ Some(Def::Enum(..)) | Some(Def::TyAlias(..)) | Some(Def::Struct(..)) |
+ Some(Def::Trait(..)) | None => {
this.check_if_primitive_type_name(name, item.span);
}
_ => {}
// plain insert (no renaming)
function_type_rib.bindings
.insert(name,
- DlDef(DefTyParam(space,
+ DlDef(Def::TyParam(space,
index as u32,
self.ast_map
.local_def_id(type_parameter.id),
path_depth: usize)
-> Result<PathResolution, ()> {
if let Some(path_res) = self.resolve_path(id, trait_path, path_depth, TypeNS, true) {
- if let DefTrait(_) = path_res.base_def {
+ if let Def::Trait(_) = path_res.base_def {
debug!("(resolving trait) found trait def: {:?}", path_res);
Ok(path_res)
} else {
path_depth)));
// If it's a typedef, give a note
- if let DefTy(..) = path_res.base_def {
+ if let Def::TyAlias(..) = path_res.base_def {
err.span_note(trait_path.span,
"`type` aliases cannot be used for traits");
}
&hir::WherePredicate::RegionPredicate(_) => {}
&hir::WherePredicate::EqPredicate(ref eq_pred) => {
let path_res = self.resolve_path(eq_pred.id, &eq_pred.path, 0, TypeNS, true);
- if let Some(PathResolution { base_def: DefTyParam(..), .. }) = path_res {
+ if let Some(PathResolution { base_def: Def::TyParam(..), .. }) = path_res {
self.record_def(eq_pred.id, path_res.unwrap());
} else {
resolve_error(self,
// Resolve the self type.
this.visit_ty(self_type);
- this.with_self_rib(DefSelfTy(trait_id, Some((item_id, self_type.id))), |this| {
+ this.with_self_rib(Def::SelfTy(trait_id, Some((item_id, self_type.id))), |this| {
this.with_current_self_type(self_type, |this| {
for impl_item in impl_items {
match impl_item.node {
self.value_ribs.push(Rib::new(NormalRibKind));
// Move down in the graph, if there's an anonymous module rooted here.
- let orig_module = self.current_module.clone();
+ let orig_module = self.current_module;
match orig_module.anonymous_children.borrow().get(&block.id) {
None => {
// Nothing to do.
}
Some(anonymous_module) => {
debug!("(resolving block) found anonymous module, moving down");
- self.current_module = anonymous_module.clone();
+ self.current_module = anonymous_module;
}
}
debug!("(resolving pattern) binding `{}`", renamed);
let def_id = self.ast_map.local_def_id(pattern.id);
- let def = DefLocal(def_id, pattern.id);
+ let def = Def::Local(def_id, pattern.id);
// Record the definition so that later passes
// will be able to distinguish variants from
};
if let Some(path_res) = resolution {
match path_res.base_def {
- DefVariant(..) | DefStruct(..) | DefConst(..) => {
+ Def::Struct(..) if path_res.depth == 0 => {
self.record_def(pattern.id, path_res);
}
- DefStatic(..) => {
+ Def::Variant(..) | Def::Const(..) => {
+ self.record_def(pattern.id, path_res);
+ }
+ Def::Static(..) => {
resolve_error(&self,
path.span,
ResolutionError::StaticVariableReference);
match path_res.base_def {
// All `<T as Trait>::CONST` should end up here, and
// have the trait already selected.
- DefAssociatedConst(..) => {
+ Def::AssociatedConst(..) => {
self.record_def(pattern.id, path_res);
}
_ => {
name: Name,
span: Span)
-> BareIdentifierPatternResolution {
- let module = self.current_module.clone();
+ let module = self.current_module;
match self.resolve_item_in_lexical_scope(module, name, ValueNS, true) {
Success((target, _)) => {
debug!("(resolve bare identifier pattern) succeeded in finding {} at {:?}",
// For the two success cases, this lookup can be
// considered as not having a private component because
// the lookup happened only within the current module.
- Some(def @ DefVariant(..)) | Some(def @ DefStruct(..)) => {
+ Some(def @ Def::Variant(..)) | Some(def @ Def::Struct(..)) => {
return FoundStructOrEnumVariant(def, LastMod(AllPublic));
}
- Some(def @ DefConst(..)) | Some(def @ DefAssociatedConst(..)) => {
+ Some(def @ Def::Const(..)) | Some(def @ Def::AssociatedConst(..)) => {
return FoundConst(def, LastMod(AllPublic), name);
}
- Some(DefStatic(..)) => {
+ Some(Def::Static(..)) => {
resolve_error(self, span, ResolutionError::StaticVariableReference);
return BareIdentifierPatternUnresolved;
}
resolution = this.resolve_path(id, path, depth, TypeNS, true);
});
}
- if let Some(DefMod(_)) = resolution.map(|r| r.base_def) {
+ if let Some(Def::Mod(_)) = resolution.map(|r| r.base_def) {
// A module is not a valid type or value.
resolution = None;
}
check_ribs: bool,
record_used: bool)
-> Option<LocalDef> {
+ if identifier.name == special_idents::invalid.name {
+ return Some(LocalDef::from_def(Def::Err));
+ }
+
// First, check to see whether the name is a primitive type.
if namespace == TypeNS {
if let Some(&prim_ty) = self.primitive_type_table
.primitive_types
.get(&identifier.unhygienic_name) {
- return Some(LocalDef::from_def(DefPrimTy(prim_ty)));
+ return Some(LocalDef::from_def(Def::PrimTy(prim_ty)));
}
}
};
let mut def = local_def.def;
match def {
- DefUpvar(..) => {
+ Def::Upvar(..) => {
self.session.span_bug(span, &format!("unexpected {:?} in bindings", def))
}
- DefLocal(_, node_id) => {
+ Def::Local(_, node_id) => {
for rib in ribs {
match rib.kind {
NormalRibKind => {
.entry(function_id)
.or_insert_with(|| NodeMap());
if let Some(&index) = seen.get(&node_id) {
- def = DefUpvar(node_def_id, node_id, index, function_id);
+ def = Def::Upvar(node_def_id, node_id, index, function_id);
continue;
}
let vec = self.freevars
span: span,
});
- def = DefUpvar(node_def_id, node_id, depth, function_id);
+ def = Def::Upvar(node_def_id, node_id, depth, function_id);
seen.insert(node_id, depth);
}
ItemRibKind | MethodRibKind => {
}
}
}
- DefTyParam(..) | DefSelfTy(..) => {
+ Def::TyParam(..) | Def::SelfTy(..) => {
for rib in ribs {
match rib.kind {
NormalRibKind | MethodRibKind | ClosureRibKind(..) => {
let containing_module;
let last_private;
- let current_module = self.current_module.clone();
+ let current_module = self.current_module;
match self.resolve_module_path(current_module,
&module_path[..],
UseLexicalScope,
}
let name = segments.last().unwrap().identifier.name;
- let def = match self.resolve_name_in_module(containing_module.clone(),
+ let def = match self.resolve_name_in_module(containing_module,
name,
namespace,
NameSearchType::PathSearch,
.map(|ps| ps.identifier.name)
.collect::<Vec<_>>();
- let root_module = self.graph_root.clone();
+ let root_module = self.graph_root;
let containing_module;
let last_private;
record_used: bool)
-> Option<Def> {
// Check the items.
- let module = self.current_module.clone();
+ let module = self.current_module;
match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
Success((target, _)) => {
match target.binding.def() {
}
}
- fn get_module(this: &mut Resolver,
- span: Span,
- name_path: &[ast::Name])
- -> Option<Rc<Module>> {
- let root = this.current_module.clone();
+ fn get_module<'a, 'tcx>(this: &mut Resolver<'a, 'tcx>,
+ span: Span,
+ name_path: &[ast::Name])
+ -> Option<Module<'a>> {
+ let root = this.current_module;
let last_name = name_path.last().unwrap();
if name_path.len() == 1 {
if allowed == Everything {
// Look for a field with the same name in the current self_type.
match self.def_map.borrow().get(&node_id).map(|d| d.full_def()) {
- Some(DefTy(did, _)) |
- Some(DefStruct(did)) |
- Some(DefVariant(_, did, _)) => match self.structs.get(&did) {
+ Some(Def::Enum(did)) |
+ Some(Def::TyAlias(did)) |
+ Some(Def::Struct(did)) |
+ Some(Def::Variant(_, did)) => match self.structs.get(&did) {
None => {}
Some(fields) => {
if fields.iter().any(|&field_name| name == field_name) {
// Look for a method in the current self type's impl module.
if let Some(module) = get_module(self, path.span, &name_path) {
if let Some(binding) = module.children.borrow().get(&name) {
- if let Some(DefMethod(did)) = binding.value_ns.def() {
+ if let Some(Def::Method(did)) = binding.value_ns.def() {
if is_static_method(self, did) {
return StaticMethod(path_names_to_string(&path, 0));
}
// scopes looking for it.
if let Some(path_res) = resolution {
// Check if struct variant
- if let DefVariant(_, _, true) = path_res.base_def {
+ let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def {
+ self.structs.contains_key(&variant_id)
+ } else {
+ false
+ };
+ if is_struct_variant {
+ let _ = self.structs.contains_key(&path_res.base_def.def_id());
let path_name = path_names_to_string(path, 0);
let mut err = resolve_struct_error(self,
self.record_def(expr.id, err_path_resolution());
match type_res.map(|r| r.base_def) {
- Some(DefTy(struct_id, _)) if self.structs.contains_key(&struct_id) => {
+ Some(Def::Struct(..)) => {
let mut err = resolve_struct_error(self,
expr.span,
ResolutionError::StructVariantUsedAsFunction(&*path_name));
let name_path = path.segments.iter()
.map(|seg| seg.identifier.name)
.collect::<Vec<_>>();
- let current_module = self.current_module.clone();
+ let current_module = self.current_module;
match self.resolve_module_path(current_module,
&name_path[..],
ExprLoop(_, Some(label)) | ExprWhile(_, _, Some(label)) => {
self.with_label_rib(|this| {
- let def_like = DlDef(DefLabel(expr.id));
+ let def_like = DlDef(Def::Label(expr.id));
{
let rib = this.label_ribs.last_mut().unwrap();
label.span,
ResolutionError::UndeclaredLabel(&label.node.name.as_str()))
}
- Some(DlDef(def @ DefLabel(_))) => {
+ Some(DlDef(def @ Def::Label(_))) => {
// Since this def is a label, it is never read.
self.record_def(expr.id,
PathResolution {
}
let mut found_traits = Vec::new();
- let mut search_module = self.current_module.clone();
+ let mut search_module = self.current_module;
loop {
// Look for the current trait.
match self.current_trait_ref {
None => continue,
};
let trait_def_id = match def {
- DefTrait(trait_def_id) => trait_def_id,
+ Def::Trait(trait_def_id) => trait_def_id,
_ => continue,
};
if self.trait_item_map.contains_key(&(name, trait_def_id)) {
Some(ref target) => target,
};
let did = match target.binding.def() {
- Some(DefTrait(trait_def_id)) => trait_def_id,
+ Some(Def::Trait(trait_def_id)) => trait_def_id,
Some(..) | None => continue,
};
if self.trait_item_map.contains_key(&(name, did)) {
}
}
- match search_module.parent_link.clone() {
+ match search_module.parent_link {
NoParentLink | ModuleParentLink(..) => break,
BlockParentLink(parent_module, _) => {
- search_module = parent_module.upgrade().unwrap();
+ search_module = parent_module;
}
}
}
//
#[allow(dead_code)] // useful for debugging
- fn dump_module(&mut self, module_: Rc<Module>) {
+ fn dump_module(&mut self, module_: Module<'a>) {
debug!("Dump of module `{}`:", module_to_string(&*module_));
debug!("Children:");
}
/// A somewhat inefficient routine to obtain the name of a module.
-fn module_to_string(module: &Module) -> String {
+fn module_to_string<'a>(module: Module<'a>) -> String {
let mut names = Vec::new();
- fn collect_mod(names: &mut Vec<ast::Name>, module: &Module) {
+ fn collect_mod<'a>(names: &mut Vec<ast::Name>, module: Module<'a>) {
match module.parent_link {
NoParentLink => {}
ModuleParentLink(ref module, name) => {
names.push(name);
- collect_mod(names, &*module.upgrade().unwrap());
+ collect_mod(names, module);
}
BlockParentLink(ref module, _) => {
// danger, shouldn't be ident?
names.push(special_idents::opaque.name);
- collect_mod(names, &*module.upgrade().unwrap());
+ collect_mod(names, module);
}
}
}
fn err_path_resolution() -> PathResolution {
PathResolution {
- base_def: DefErr,
+ base_def: Def::Err,
last_private: LastMod(AllPublic),
depth: 0,
}
make_glob_map: MakeGlobMap)
-> CrateMap {
let krate = ast_map.krate();
- let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, None);
+ let arenas = Resolver::arenas();
+ let mut resolver = create_resolver(session, ast_map, krate, make_glob_map, &arenas, None);
resolver.resolve_crate(krate);
ast_map: &'a hir_map::Map<'tcx>,
krate: &'a Crate,
make_glob_map: MakeGlobMap,
+ arenas: &'a ResolverArenas<'a>,
callback: Option<Box<Fn(hir_map::Node, &mut bool) -> bool>>)
-> Resolver<'a, 'tcx> {
- let mut resolver = Resolver::new(session, ast_map, make_glob_map);
+ let mut resolver = Resolver::new(session, ast_map, make_glob_map, arenas);
resolver.callback = callback;
build_reduced_graph::build_reduced_graph(&mut resolver, krate);
- session.abort_if_errors();
resolve_imports::resolve_imports(&mut resolver);
- session.abort_if_errors();
-
- record_exports::record(&mut resolver);
- session.abort_if_errors();
resolver
}