Auto merge of - jseyfried:resolve, r=nikomatsakis

Replace `TypeNsDef` and `ValueNsDef` with a more general type `NsDef`.

Define a newtype `NameBinding` for `Rc<RefCell<Option<NsDef>>>` and refactor `NameBindings` to be a `NameBinding` for each namespace.

Replace uses of `NameBindings` with `NameBinding` where only one binding is being used (in `NamespaceResult`, `Target,` etc).

Refactor away `resolve_definition_of_name_in_module` and `NameDefinition`, fixing issue .
This commit is contained in:
bors 2015-11-23 17:31:19 +00:00
commit 8e9a97529d
6 changed files with 389 additions and 837 deletions

@ -18,18 +18,15 @@ use resolve_imports::ImportDirective;
use resolve_imports::ImportDirectiveSubclass::{self, SingleImport, GlobImport};
use resolve_imports::ImportResolution;
use Module;
use ModuleKind::*;
use Namespace::{TypeNS, ValueNS};
use NameBindings;
use {names_to_string, module_to_string};
use ParentLink::{self, ModuleParentLink, BlockParentLink};
use Resolver;
use resolve_imports::Shadowable;
use TypeNsDef;
use {resolve_error, ResolutionError};
use self::DuplicateCheckingMode::*;
use self::NamespaceError::*;
use rustc::metadata::csearch;
use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
@ -62,29 +59,12 @@ use std::rc::Rc;
// another item exists with the same name in some namespace.
#[derive(Copy, Clone, PartialEq)]
enum DuplicateCheckingMode {
ForbidDuplicateModules,
ForbidDuplicateTypesAndModules,
ForbidDuplicateTypes,
ForbidDuplicateValues,
ForbidDuplicateTypesAndValues,
OverwriteDuplicates,
}
#[derive(Copy, Clone, PartialEq)]
enum NamespaceError {
NoError,
ModuleError,
TypeError,
ValueError,
}
fn namespace_error_to_string(ns: NamespaceError) -> &'static str {
match ns {
NoError => "",
ModuleError | TypeError => "type or module",
ValueError => "value",
}
}
struct GraphBuilder<'a, 'b: 'a, 'tcx: 'b> {
resolver: &'a mut Resolver<'b, 'tcx>,
}
@ -106,121 +86,63 @@ impl<'a, 'b:'a, 'tcx:'b> DerefMut for GraphBuilder<'a, 'b, 'tcx> {
impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
/// Constructs the reduced graph for the entire crate.
fn build_reduced_graph(self, krate: &hir::Crate) {
let parent = self.graph_root.get_module();
let mut visitor = BuildReducedGraphVisitor {
parent: self.graph_root.clone(),
builder: self,
parent: parent,
};
intravisit::walk_crate(&mut visitor, krate);
}
/// Adds a new child item to the module definition of the parent node and
/// returns its corresponding name bindings as well as the current parent.
/// Or, if we're inside a block, creates (or reuses) an anonymous module
/// corresponding to the innermost block ID and returns the name bindings
/// as well as the newly-created parent.
///
/// # Panics
///
/// Panics if this node does not have a module definition and we are not inside
/// a block.
/// Adds a new child item to the module definition of the parent node,
/// or if there is already a child, does duplicate checking on the child.
/// Returns the child's corresponding name bindings.
fn add_child(&self,
name: Name,
parent: &Rc<Module>,
duplicate_checking_mode: DuplicateCheckingMode,
// For printing errors
sp: Span)
-> Rc<NameBindings> {
// If this is the immediate descendant of a module, then we add the
// child name directly. Otherwise, we create or reuse an anonymous
// module and add the child to that.
-> NameBindings {
self.check_for_conflicts_between_external_crates_and_items(&**parent, name, sp);
// Add or reuse the child.
let child = parent.children.borrow().get(&name).cloned();
match child {
None => {
let child = Rc::new(NameBindings::new());
let child = NameBindings::new();
parent.children.borrow_mut().insert(name, child.clone());
child
}
Some(child) => {
// Enforce the duplicate checking mode:
//
// * If we're requesting duplicate module checking, check that
// there isn't a module in the module with the same name.
//
// * If we're requesting duplicate type checking, check that
// there isn't a type in the module with the same name.
// the name isn't defined in the type namespace.
//
// * If we're requesting duplicate value checking, check that
// there isn't a value in the module with the same name.
// the name isn't defined in the value namespace.
//
// * If we're requesting duplicate type checking and duplicate
// value checking, check that there isn't a duplicate type
// and a duplicate value with the same name.
// * If we're requesting duplicate type and value checking,
// check that the name isn't defined in either namespace.
//
// * If no duplicate checking was requested at all, do
// nothing.
let mut duplicate_type = NoError;
let ns = match duplicate_checking_mode {
ForbidDuplicateModules => {
if child.get_module_if_available().is_some() {
duplicate_type = ModuleError;
}
Some(TypeNS)
}
ForbidDuplicateTypesAndModules => {
if child.defined_in_namespace(TypeNS) {
duplicate_type = TypeError;
}
Some(TypeNS)
}
ForbidDuplicateValues => {
if child.defined_in_namespace(ValueNS) {
duplicate_type = ValueError;
}
Some(ValueNS)
}
ForbidDuplicateTypesAndValues => {
let mut n = None;
match child.def_for_namespace(TypeNS) {
Some(DefMod(_)) | None => {}
Some(_) => {
n = Some(TypeNS);
duplicate_type = TypeError;
}
}
if child.defined_in_namespace(ValueNS) {
duplicate_type = ValueError;
n = Some(ValueNS);
}
n
}
OverwriteDuplicates => None,
ForbidDuplicateTypes if child.type_ns.defined() => TypeNS,
ForbidDuplicateValues if child.value_ns.defined() => ValueNS,
ForbidDuplicateTypesAndValues if child.type_ns.defined() => TypeNS,
ForbidDuplicateTypesAndValues if child.value_ns.defined() => ValueNS,
_ => return child,
};
if duplicate_type != NoError {
// Return an error here by looking up the namespace that
// had the duplicate.
let ns = ns.unwrap();
resolve_error(
self,
sp,
ResolutionError::DuplicateDefinition(
namespace_error_to_string(duplicate_type),
name)
);
{
let r = child.span_for_namespace(ns);
if let Some(sp) = r {
self.session.span_note(sp,
&format!("first definition of {} `{}` here",
namespace_error_to_string(duplicate_type),
name));
}
}
// Record an error here by looking up the namespace that had the duplicate
let ns_str = match ns { TypeNS => "type or module", ValueNS => "value" };
resolve_error(self, sp, ResolutionError::DuplicateDefinition(ns_str, name));
if let Some(sp) = child[ns].span() {
let note = format!("first definition of {} `{}` here", ns_str, name);
self.session.span_note(sp, &note);
}
child
}
@ -395,11 +317,9 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
};
self.external_exports.insert(def_id);
let parent_link = ModuleParentLink(Rc::downgrade(parent), name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
false,
true));
let def = DefMod(def_id);
let external_module = Module::new(parent_link, Some(def), false, true);
debug!("(build reduced graph for item) found extern `{}`",
module_to_string(&*external_module));
self.check_for_conflicts_between_external_crates(&**parent, name, sp);
@ -412,40 +332,13 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
ItemMod(..) => {
let child = parent.children.borrow().get(&name).cloned();
if let Some(child) = child {
// check if there's struct of the same name already defined
if child.defined_in_namespace(TypeNS) &&
child.get_module_if_available().is_none() {
self.session.span_warn(sp,
&format!("duplicate definition of {} `{}`. \
Defining a module and a struct with \
the same name will be disallowed soon.",
namespace_error_to_string(TypeError),
name));
{
let r = child.span_for_namespace(TypeNS);
if let Some(sp) = r {
self.session.span_note(sp,
&format!("first definition of {} `{}` here",
namespace_error_to_string(TypeError),
name));
}
}
}
}
let name_bindings = self.add_child(name, parent, ForbidDuplicateModules, sp);
let name_bindings = self.add_child(name, parent, ForbidDuplicateTypes, sp);
let parent_link = self.get_parent_link(parent, name);
let def_id = self.ast_map.local_def_id(item.id);
name_bindings.define_module(parent_link,
Some(def_id),
NormalModuleKind,
false,
is_public,
sp);
name_bindings.get_module()
let def = DefMod(self.ast_map.local_def_id(item.id));
let module = Module::new(parent_link, Some(def), false, is_public);
name_bindings.define_module(module.clone(), sp);
module
}
ItemForeignMod(..) => parent.clone(),
@ -477,42 +370,26 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
ItemTy(..) => {
let name_bindings = self.add_child(name,
parent,
ForbidDuplicateTypesAndModules,
ForbidDuplicateTypes,
sp);
name_bindings.define_type(DefTy(self.ast_map.local_def_id(item.id), false),
sp,
modifiers);
let parent_link = self.get_parent_link(parent, name);
name_bindings.set_module_kind(parent_link,
Some(self.ast_map.local_def_id(item.id)),
TypeModuleKind,
false,
is_public,
sp);
let def = DefTy(self.ast_map.local_def_id(item.id), false);
let module = Module::new(parent_link, Some(def), false, is_public);
name_bindings.define_module(module, sp);
parent.clone()
}
ItemEnum(ref enum_definition, _) => {
let name_bindings = self.add_child(name,
parent,
ForbidDuplicateTypesAndModules,
ForbidDuplicateTypes,
sp);
name_bindings.define_type(DefTy(self.ast_map.local_def_id(item.id), true),
sp,
modifiers);
let parent_link = self.get_parent_link(parent, name);
name_bindings.set_module_kind(parent_link,
Some(self.ast_map.local_def_id(item.id)),
EnumModuleKind,
false,
is_public,
sp);
let module = name_bindings.get_module();
let def = DefTy(self.ast_map.local_def_id(item.id), true);
let module = Module::new(parent_link, Some(def), false, is_public);
name_bindings.define_module(module.clone(), sp);
for variant in &(*enum_definition).variants {
let item_def_id = self.ast_map.local_def_id(item.id);
@ -525,31 +402,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
ItemStruct(ref struct_def, _) => {
// Adding to both Type and Value namespaces or just Type?
let (forbid, ctor_id) = if struct_def.is_struct() {
(ForbidDuplicateTypesAndModules, None)
(ForbidDuplicateTypes, None)
} else {
let child = parent.children.borrow().get(&name).cloned();
if let Some(child) = child {
// check if theres a DefMod
if let Some(DefMod(_)) = child.def_for_namespace(TypeNS) {
self.session.span_warn(sp,
&format!("duplicate definition of {} `{}`. \
Defining a module and a struct \
with the same name will be \
disallowed soon.",
namespace_error_to_string(TypeError),
name));
{
let r = child.span_for_namespace(TypeNS);
if let Some(sp) = r {
self.session
.span_note(sp,
&format!("first definition of {} `{}` here",
namespace_error_to_string(TypeError),
name));
}
}
}
}
(ForbidDuplicateTypesAndValues, Some(struct_def.id()))
};
@ -590,20 +444,16 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
ItemTrait(_, _, _, ref items) => {
let name_bindings = self.add_child(name,
parent,
ForbidDuplicateTypesAndModules,
ForbidDuplicateTypes,
sp);
let def_id = self.ast_map.local_def_id(item.id);
// Add all the items within to a new module.
let parent_link = self.get_parent_link(parent, name);
name_bindings.define_module(parent_link,
Some(self.ast_map.local_def_id(item.id)),
TraitModuleKind,
false,
is_public,
sp);
let module_parent = name_bindings.get_module();
let def_id = self.ast_map.local_def_id(item.id);
let def = DefTrait(def_id);
let module_parent = Module::new(parent_link, Some(def), false, is_public);
name_bindings.define_module(module_parent.clone(), sp);
// Add the names of all the items to the trait info.
for trait_item in items {
@ -635,7 +485,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
self.trait_item_map.insert((trait_item.name, def_id), trait_item_def_id);
}
name_bindings.define_type(DefTrait(def_id), sp, modifiers);
parent.clone()
}
}
@ -704,11 +553,8 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
{}",
block_id);
let new_module = Rc::new(Module::new(BlockParentLink(Rc::downgrade(parent), block_id),
None,
AnonymousModuleKind,
false,
false));
let parent_link = BlockParentLink(Rc::downgrade(parent), block_id);
let new_module = Module::new(parent_link, None, false, false);
parent.anonymous_children.borrow_mut().insert(block_id, new_module.clone());
new_module
} else {
@ -733,7 +579,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
DefModifiers::empty()
} | DefModifiers::IMPORTABLE;
let is_exported = is_public &&
match new_parent.def_id.get() {
match new_parent.def_id() {
None => true,
Some(did) => self.external_exports.contains(&did),
};
@ -741,37 +587,21 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
self.external_exports.insert(def.def_id());
}
let kind = match def {
DefTy(_, true) => EnumModuleKind,
DefTy(_, false) | DefStruct(..) => TypeModuleKind,
_ => NormalModuleKind,
};
match def {
DefMod(def_id) |
DefForeignMod(def_id) |
DefStruct(def_id) |
DefTy(def_id, _) => {
let type_def = child_name_bindings.type_def.borrow().clone();
match type_def {
Some(TypeNsDef { module_def: Some(module_def), .. }) => {
debug!("(building reduced graph for external crate) already created \
module");
module_def.def_id.set(Some(def_id));
}
Some(_) | None => {
debug!("(building reduced graph for external crate) building module {} {}",
final_ident,
is_public);
let parent_link = self.get_parent_link(new_parent, name);
child_name_bindings.define_module(parent_link,
Some(def_id),
kind,
true,
is_public,
DUMMY_SP);
}
DefMod(_) |
DefForeignMod(_) |
DefStruct(_) |
DefTy(..) => {
if let Some(module_def) = child_name_bindings.type_ns.module() {
debug!("(building reduced graph for external crate) already created module");
module_def.def.set(Some(def));
} else {
debug!("(building reduced graph for external crate) building module {} {}",
final_ident,
is_public);
let parent_link = self.get_parent_link(new_parent, name);
let module = Module::new(parent_link, Some(def), true, is_public);
child_name_bindings.define_module(module, DUMMY_SP);
}
}
_ => {}
@ -807,12 +637,12 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
final_ident);
// impl methods have already been defined with the correct importability
// modifier
let mut modifiers = match *child_name_bindings.value_def.borrow() {
let mut modifiers = match *child_name_bindings.value_ns.borrow() {
Some(ref def) => (modifiers & !DefModifiers::IMPORTABLE) |
(def.modifiers & DefModifiers::IMPORTABLE),
None => modifiers,
};
if new_parent.kind.get() != NormalModuleKind {
if !new_parent.is_normal() {
modifiers = modifiers & !DefModifiers::IMPORTABLE;
}
child_name_bindings.define_value(def, DUMMY_SP, modifiers);
@ -841,33 +671,30 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
}
}
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
// Define a module if necessary.
let parent_link = self.get_parent_link(new_parent, name);
child_name_bindings.set_module_kind(parent_link,
Some(def_id),
TraitModuleKind,
true,
is_public,
DUMMY_SP)
let module = Module::new(parent_link, Some(def), true, is_public);
child_name_bindings.define_module(module, DUMMY_SP);
}
DefTy(..) | DefAssociatedTy(..) => {
debug!("(building reduced graph for external crate) building type {}",
final_ident);
let modifiers = match new_parent.kind.get() {
NormalModuleKind => modifiers,
let modifiers = match new_parent.is_normal() {
true => modifiers,
_ => modifiers & !DefModifiers::IMPORTABLE,
};
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
if let DefTy(..) = def {
child_name_bindings.type_ns.set_modifiers(modifiers);
} else {
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
}
}
DefStruct(def_id) => {
debug!("(building reduced graph for external crate) building type and value for \
{}",
final_ident);
child_name_bindings.define_type(def, DUMMY_SP, modifiers);
let fields = csearch::get_struct_field_names(&self.session.cstore, def_id);
if fields.is_empty() {
@ -922,7 +749,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
self.handle_external_def(def,
def_visibility,
&*child_name_bindings,
&child_name_bindings,
&name.as_str(),
name,
root);
@ -943,7 +770,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
debug!("(populating external module) attempting to populate {}",
module_to_string(&**module));
let def_id = match module.def_id.get() {
let def_id = match module.def_id() {
None => {
debug!("(populating external module) ... no def ID!");
return;
@ -977,8 +804,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
/// crate.
fn build_reduced_graph_for_external_crate(&mut self, root: &Rc<Module>) {
csearch::each_top_level_item_of_crate(&self.session.cstore,
root.def_id
.get()
root.def_id()
.unwrap()
.krate,
|def_like, name, visibility| {

File diff suppressed because it is too large Load Diff

@ -18,8 +18,8 @@
// Then this operation can simply be performed as part of item (or import)
// processing.
use {Module, NameBindings, Resolver};
use Namespace::{self, TypeNS, ValueNS};
use {Module, NameBinding, Resolver};
use Namespace::{TypeNS, ValueNS};
use build_reduced_graph;
use module_to_string;
@ -54,7 +54,7 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
// If this isn't a local krate, then bail out. We don't need to record
// exports for nonlocal crates.
match module_.def_id.get() {
match module_.def_id() {
Some(def_id) if def_id.is_local() => {
// OK. Continue.
debug!("(recording exports for module subtree) recording exports for local \
@ -79,7 +79,7 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
for (_, child_name_bindings) in module_.children.borrow().iter() {
match child_name_bindings.get_module_if_available() {
match child_name_bindings.type_ns.module() {
None => {
// Nothing to do.
}
@ -98,7 +98,7 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
let mut exports = Vec::new();
self.add_exports_for_module(&mut exports, module_);
match module_.def_id.get() {
match module_.def_id() {
Some(def_id) => {
let node_id = self.ast_map.as_local_node_id(def_id).unwrap();
self.export_map.insert(node_id, exports);
@ -108,12 +108,11 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
}
}
fn add_exports_of_namebindings(&mut self,
exports: &mut Vec<Export>,
name: ast::Name,
namebindings: &NameBindings,
ns: Namespace) {
match namebindings.def_for_namespace(ns) {
fn add_export_of_namebinding(&mut self,
exports: &mut Vec<Export>,
name: ast::Name,
namebinding: &NameBinding) {
match namebinding.def() {
Some(d) => {
debug!("(computing exports) YES: export '{}' => {:?}",
name,
@ -139,7 +138,7 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
match import_resolution.target_for_namespace(ns) {
Some(target) => {
debug!("(computing exports) maybe export '{}'", name);
self.add_exports_of_namebindings(exports, *name, &*target.bindings, ns)
self.add_export_of_namebinding(exports, *name, &target.binding)
}
_ => (),
}
@ -150,6 +149,6 @@ impl<'a, 'b, 'tcx> ExportRecorder<'a, 'b, 'tcx> {
pub fn record(resolver: &mut Resolver) {
let mut recorder = ExportRecorder { resolver: resolver };
let root_module = recorder.graph_root.get_module();
let root_module = recorder.graph_root.clone();
recorder.record_exports_for_module_subtree(root_module);
}

@ -12,9 +12,8 @@ use self::ImportDirectiveSubclass::*;
use DefModifiers;
use Module;
use ModuleKind;
use Namespace::{self, TypeNS, ValueNS};
use NameBindings;
use {NameBindings, NameBinding};
use NamespaceResult::{BoundResult, UnboundResult, UnknownResult};
use NamespaceResult;
use NameSearchType;
@ -86,18 +85,18 @@ impl ImportDirective {
#[derive(Clone,Debug)]
pub struct Target {
pub target_module: Rc<Module>,
pub bindings: Rc<NameBindings>,
pub binding: NameBinding,
pub shadowable: Shadowable,
}
impl Target {
pub fn new(target_module: Rc<Module>,
bindings: Rc<NameBindings>,
binding: NameBinding,
shadowable: Shadowable)
-> Target {
Target {
target_module: target_module,
bindings: bindings,
binding: binding,
shadowable: shadowable,
}
}
@ -210,7 +209,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
i,
self.resolver.unresolved_imports);
let module_root = self.resolver.graph_root.get_module();
let module_root = self.resolver.graph_root.clone();
let errors = self.resolve_imports_for_module_subtree(module_root.clone());
if self.resolver.unresolved_imports == 0 {
@ -255,7 +254,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
for (_, child_node) in module_.children.borrow().iter() {
match child_node.get_module_if_available() {
match child_node.type_ns.module() {
None => {
// Nothing to do.
}
@ -338,7 +337,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
// First, resolve the module path for the directive, if necessary.
let container = if module_path.is_empty() {
// Use the crate root.
Some((self.resolver.graph_root.get_module(), LastMod(AllPublic)))
Some((self.resolver.graph_root.clone(), LastMod(AllPublic)))
} else {
match self.resolver.resolve_module_path(module_.clone(),
&module_path[..],
@ -459,11 +458,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
Some(ref child_name_bindings) => {
// pub_err makes sure we don't give the same error twice.
let mut pub_err = false;
if child_name_bindings.defined_in_namespace(ValueNS) {
if child_name_bindings.value_ns.defined() {
debug!("(resolving single import) found value binding");
value_result = BoundResult(target_module.clone(),
(*child_name_bindings).clone());
if directive.is_public && !child_name_bindings.is_public(ValueNS) {
child_name_bindings.value_ns.clone());
if directive.is_public && !child_name_bindings.value_ns.is_public() {
let msg = format!("`{}` is private, and cannot be reexported", source);
let note_msg = format!("Consider marking `{}` as `pub` in the imported \
module",
@ -473,11 +472,12 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
pub_err = true;
}
}
if child_name_bindings.defined_in_namespace(TypeNS) {
if child_name_bindings.type_ns.defined() {
debug!("(resolving single import) found type binding");
type_result = BoundResult(target_module.clone(),
(*child_name_bindings).clone());
if !pub_err && directive.is_public && !child_name_bindings.is_public(TypeNS) {
child_name_bindings.type_ns.clone());
if !pub_err && directive.is_public &&
!child_name_bindings.type_ns.is_public() {
let msg = format!("`{}` is private, and cannot be reexported", source);
let note_msg = format!("Consider declaring module `{}` as a `pub mod`",
source);
@ -540,7 +540,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
}
Some(Target {
target_module,
bindings,
binding,
shadowable: _
}) => {
debug!("(resolving single import) found import in ns {:?}",
@ -549,13 +549,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
// track used imports and extern crates as well
this.used_imports.insert((id, namespace));
this.record_import_use(id, source);
match target_module.def_id.get() {
match target_module.def_id() {
Some(DefId{krate: kid, ..}) => {
this.used_crates.insert(kid);
}
_ => {}
}
return BoundResult(target_module, bindings);
return BoundResult(target_module, binding);
}
}
}
@ -591,7 +591,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
// In this case we continue as if we resolved the import and let the
// check_for_conflicts_between_imports_and_items call below handle
// the conflict
match (module_.def_id.get(), target_module.def_id.get()) {
match (module_.def_id(), target_module.def_id()) {
(Some(id1), Some(id2)) if id1 == id2 => {
if value_result.is_unknown() {
value_result = UnboundResult;
@ -624,15 +624,14 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
Some(module) => {
debug!("(resolving single import) found external module");
// track the module as used.
match module.def_id.get() {
match module.def_id() {
Some(DefId{krate: kid, ..}) => {
self.resolver.used_crates.insert(kid);
}
_ => {}
}
let name_bindings =
Rc::new(Resolver::create_name_bindings_from_module(module));
type_result = BoundResult(target_module.clone(), name_bindings);
let name_binding = NameBinding::create_from_module(module);
type_result = BoundResult(target_module.clone(), name_binding);
type_used_public = true;
}
}
@ -651,26 +650,25 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
};
match *result {
BoundResult(ref target_module, ref name_bindings) => {
BoundResult(ref target_module, ref name_binding) => {
debug!("(resolving single import) found {:?} target: {:?}",
namespace_name,
name_bindings.def_for_namespace(namespace));
name_binding.def());
self.check_for_conflicting_import(&import_resolution,
directive.span,
target,
namespace);
self.check_that_import_is_importable(&**name_bindings,
self.check_that_import_is_importable(&name_binding,
directive.span,
target,
namespace);
target);
let target = Some(Target::new(target_module.clone(),
name_bindings.clone(),
name_binding.clone(),
directive.shadowable));
import_resolution.set_target_and_id(namespace, target, directive.id);
import_resolution.is_public = directive.is_public;
*used_public = name_bindings.defined_in_public_namespace(namespace);
*used_public = name_binding.is_public();
}
UnboundResult => {
// Continue.
@ -705,7 +703,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
// this may resolve to either a value or a type, but for documentation
// purposes it's good enough to just favor one over the other.
let value_def_and_priv = import_resolution.value_target.as_ref().map(|target| {
let def = target.bindings.def_for_namespace(ValueNS).unwrap();
let def = target.binding.def().unwrap();
(def,
if value_used_public {
lp
@ -714,7 +712,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
})
});
let type_def_and_priv = import_resolution.type_target.as_ref().map(|target| {
let def = target.bindings.def_for_namespace(TypeNS).unwrap();
let def = target.binding.def().unwrap();
(def,
if type_used_public {
lp
@ -857,16 +855,15 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
// Add external module children from the containing module.
for (&name, module) in target_module.external_module_children.borrow().iter() {
let name_bindings = Rc::new(Resolver::create_name_bindings_from_module(module.clone()));
self.merge_import_resolution(module_,
target_module.clone(),
import_directive,
name,
name_bindings);
NameBindings::create_from_module(module.clone()));
}
// Record the destination of this import
if let Some(did) = target_module.def_id.get() {
if let Some(did) = target_module.def_id() {
self.resolver.def_map.borrow_mut().insert(id,
PathResolution {
base_def: DefMod(did),
@ -884,7 +881,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
containing_module: Rc<Module>,
import_directive: &ImportDirective,
name: Name,
name_bindings: Rc<NameBindings>) {
name_bindings: NameBindings) {
let id = import_directive.id;
let is_public = import_directive.is_public;
@ -904,7 +901,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
let mut merge_child_item = |namespace| {
let modifier = DefModifiers::IMPORTABLE | DefModifiers::PUBLIC;
if name_bindings.defined_in_namespace_with(namespace, modifier) {
if name_bindings[namespace].defined_with(modifier) {
let namespace_name = match namespace {
TypeNS => "type",
ValueNS => "value",
@ -922,7 +919,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
msg);
} else {
let target = Target::new(containing_module.clone(),
name_bindings.clone(),
name_bindings[namespace].clone(),
import_directive.shadowable);
dest_import_resolution.set_target_and_id(namespace, Some(target), id);
}
@ -955,16 +952,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
Some(ref target) if target.shadowable != Shadowable::Always => {
let ns_word = match namespace {
TypeNS => {
if let Some(ref ty_def) = *target.bindings.type_def.borrow() {
match ty_def.module_def {
Some(ref module) if module.kind.get() ==
ModuleKind::NormalModuleKind => "module",
Some(ref module) if module.kind.get() ==
ModuleKind::TraitModuleKind => "trait",
_ => "type",
}
} else {
"type"
match target.binding.module() {
Some(ref module) if module.is_normal() => "module",
Some(ref module) if module.is_trait() => "trait",
_ => "type",
}
}
ValueNS => "value",
@ -989,11 +980,10 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
/// Checks that an import is actually importable
fn check_that_import_is_importable(&mut self,
name_bindings: &NameBindings,
name_binding: &NameBinding,
import_span: Span,
name: Name,
namespace: Namespace) {
if !name_bindings.defined_in_namespace_with(namespace, DefModifiers::IMPORTABLE) {
name: Name) {
if !name_binding.defined_with(DefModifiers::IMPORTABLE) {
let msg = format!("`{}` is not directly importable", name);
span_err!(self.resolver.session, import_span, E0253, "{}", &msg[..]);
}
@ -1032,13 +1022,13 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
match import_resolution.value_target {
Some(ref target) if target.shadowable != Shadowable::Always => {
if let Some(ref value) = *name_bindings.value_def.borrow() {
if let Some(ref value) = *name_bindings.value_ns.borrow() {
span_err!(self.resolver.session,
import_span,
E0255,
"import `{}` conflicts with value in this module",
name);
if let Some(span) = value.value_span {
if let Some(span) = value.span {
self.resolver.session.span_note(span, "conflicting value here");
}
}
@ -1048,11 +1038,11 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
match import_resolution.type_target {
Some(ref target) if target.shadowable != Shadowable::Always => {
if let Some(ref ty) = *name_bindings.type_def.borrow() {
let (what, note) = match ty.module_def {
Some(ref module) if module.kind.get() == ModuleKind::NormalModuleKind =>
if let Some(ref ty) = *name_bindings.type_ns.borrow() {
let (what, note) = match ty.module() {
Some(ref module) if module.is_normal() =>
("existing submodule", "note conflicting module here"),
Some(ref module) if module.kind.get() == ModuleKind::TraitModuleKind =>
Some(ref module) if module.is_trait() =>
("trait in this module", "note conflicting trait here"),
_ => ("type in this module", "note conflicting type here"),
};
@ -1062,7 +1052,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
"import `{}` conflicts with {}",
name,
what);
if let Some(span) = ty.type_span {
if let Some(span) = ty.span {
self.resolver.session.span_note(span, note);
}
}

@ -13,7 +13,7 @@ mod Foo {
}
enum Foo { //~ ERROR duplicate definition of type or module `Foo`
X //~ ERROR duplicate definition of value `X`
X
}
fn main() {}

@ -16,7 +16,7 @@ mod Foo { }
#[allow(dead_code)]
struct Foo;
//~^ WARNING duplicate definition of type or module `Foo`
//~^ ERROR duplicate definition of type or module `Foo`
#[allow(non_snake_case)]
@ -25,7 +25,7 @@ mod Bar { }
#[allow(dead_code)]
struct Bar(i32);
//~^ WARNING duplicate definition of type or module `Bar`
//~^ ERROR duplicate definition of type or module `Bar`
#[allow(dead_code)]
@ -34,7 +34,7 @@ struct Baz(i32);
#[allow(non_snake_case)]
mod Baz { }
//~^ WARNING duplicate definition of type or module `Baz`
//~^ ERROR duplicate definition of type or module `Baz`
#[allow(dead_code)]
@ -43,7 +43,7 @@ struct Qux { x: bool }
#[allow(non_snake_case)]
mod Qux { }
//~^ WARNING duplicate definition of type or module `Qux`
//~^ ERROR duplicate definition of type or module `Qux`
#[allow(dead_code)]
@ -52,7 +52,7 @@ struct Quux;
#[allow(non_snake_case)]
mod Quux { }
//~^ WARNING duplicate definition of type or module `Quux`
//~^ ERROR duplicate definition of type or module `Quux`
#[allow(dead_code)]