提交 8e9a9752 编写于 作者: B bors

Auto merge of #29530 - 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 #4952.
此差异已折叠。
......@@ -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 @@ fn record_exports_for_module_subtree(&mut self, module_: Rc<Module>) {
// 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 @@ fn record_exports_for_module_subtree(&mut self, module_: Rc<Module>) {
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 @@ fn record_exports_for_module(&mut self, module_: &Module) {
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 @@ fn record_exports_for_module(&mut self, module_: &Module) {
}
}
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 @@ fn add_exports_for_module(&mut self, exports: &mut Vec<Export>, module_: &Module
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 @@ fn add_exports_for_module(&mut self, exports: &mut Vec<Export>, module_: &Module
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 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 @@ pub fn new(module_path: Vec<Name>,
#[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 @@ fn resolve_imports(&mut self) {
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 @@ fn resolve_imports_for_module_subtree(&mut self,
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 @@ fn resolve_import_for_module(&mut self,
// 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 @@ fn resolve_single_import(&mut self,
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 @@ fn resolve_single_import(&mut self,
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 @@ fn get_binding(this: &mut Resolver,
}
Some(Target {
target_module,
bindings,
binding,
shadowable: _
}) => {
debug!("(resolving single import) found import in ns {:?}",
......@@ -549,13 +549,13 @@ fn get_binding(this: &mut Resolver,
// 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 @@ fn get_binding(this: &mut Resolver,
// 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 @@ fn get_binding(this: &mut Resolver,
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 @@ fn get_binding(this: &mut Resolver,
};
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 @@ fn get_binding(this: &mut Resolver,
// 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 @@ fn get_binding(this: &mut Resolver,
})
});
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 @@ fn resolve_glob_import(&mut self,
// 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 @@ fn merge_import_resolution(&mut self,
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 @@ fn merge_import_resolution(&mut self,
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 @@ fn merge_import_resolution(&mut self,
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 @@ fn check_for_conflicting_import(&mut self,
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 @@ fn check_for_conflicting_import(&mut self,
/// 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 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
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 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
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 @@ fn check_for_conflicts_between_imports_and_items(&mut self,
"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 @@ mod Bar { }
#[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 @@ mod Qux { }
#[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)]
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册