Auto merge of #31321 - jseyfried:cleanup, r=nrc
The first commit improves detection of unused imports -- it should have been part of #30325. Right now, the unused import in the changed test would not be reported. The rest of the commits are miscellaneous, independent clean-ups in resolve that I didn't think warranted individual PRs. r? @nrc
This commit is contained in:
commit
dcf8ef2723
@ -20,7 +20,7 @@ use front::map as ast_map;
|
||||
use session::Session;
|
||||
use util::nodemap::{FnvHashMap, NodeMap, NodeSet};
|
||||
use middle::cstore::InlinedItem;
|
||||
use middle::ty::{self, Ty};
|
||||
use middle::ty;
|
||||
|
||||
use std::cell::RefCell;
|
||||
use std::collections::hash_map::Entry;
|
||||
|
@ -26,7 +26,6 @@ use std::{i8, i16, i32, i64, u8, u16, u32, u64, f32, f64};
|
||||
use syntax::{abi, ast};
|
||||
use syntax::attr::{self, AttrMetaMethods};
|
||||
use syntax::codemap::{self, Span};
|
||||
use syntax::ast::{TyIs, TyUs, TyI8, TyU8, TyI16, TyU16, TyI32, TyU32, TyI64, TyU64};
|
||||
|
||||
use rustc_front::hir;
|
||||
use rustc_front::intravisit::{self, Visitor};
|
||||
|
@ -142,29 +142,17 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||
}
|
||||
|
||||
fn block_needs_anonymous_module(&mut self, block: &Block) -> bool {
|
||||
// Check each statement.
|
||||
for statement in &block.stmts {
|
||||
match statement.node {
|
||||
StmtDecl(ref declaration, _) => {
|
||||
match declaration.node {
|
||||
DeclItem(_) => {
|
||||
return true;
|
||||
}
|
||||
_ => {
|
||||
// Keep searching.
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
// Keep searching.
|
||||
fn is_item(statement: &hir::Stmt) -> bool {
|
||||
if let StmtDecl(ref declaration, _) = statement.node {
|
||||
if let DeclItem(_) = declaration.node {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
false
|
||||
}
|
||||
|
||||
// If we found no items, we don't need to create
|
||||
// an anonymous module.
|
||||
|
||||
return false;
|
||||
// If any statements are items, we need to create an anonymous module
|
||||
block.stmts.iter().any(is_item)
|
||||
}
|
||||
|
||||
/// Constructs the reduced graph for one item.
|
||||
@ -309,7 +297,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||
let external_module = self.new_extern_crate_module(parent_link, def);
|
||||
self.define(parent, name, TypeNS, (external_module, sp));
|
||||
|
||||
self.build_reduced_graph_for_external_crate(&external_module);
|
||||
self.build_reduced_graph_for_external_crate(external_module);
|
||||
}
|
||||
parent
|
||||
}
|
||||
@ -365,7 +353,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||
for variant in &(*enum_definition).variants {
|
||||
let item_def_id = self.ast_map.local_def_id(item.id);
|
||||
self.build_reduced_graph_for_variant(variant, item_def_id,
|
||||
&module, variant_modifiers);
|
||||
module, variant_modifiers);
|
||||
}
|
||||
parent
|
||||
}
|
||||
@ -421,7 +409,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
|
||||
};
|
||||
|
||||
let modifiers = DefModifiers::PUBLIC; // NB: not DefModifiers::IMPORTABLE
|
||||
self.define(&module_parent, item.name, ns, (def, item.span, modifiers));
|
||||
self.define(module_parent, item.name, ns, (def, item.span, modifiers));
|
||||
|
||||
self.trait_item_map.insert((item.name, def_id), item_def_id);
|
||||
}
|
||||
|
@ -662,10 +662,11 @@ enum ResolveResult<T> {
|
||||
}
|
||||
|
||||
impl<T> ResolveResult<T> {
|
||||
fn success(&self) -> bool {
|
||||
match *self {
|
||||
Success(_) => true,
|
||||
_ => false,
|
||||
fn and_then<U, F: FnOnce(T) -> ResolveResult<U>>(self, f: F) -> ResolveResult<U> {
|
||||
match self {
|
||||
Failed(msg) => Failed(msg),
|
||||
Indeterminate => Indeterminate,
|
||||
Success(t) => f(t),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -789,7 +790,7 @@ enum ParentLink<'a> {
|
||||
/// One node in the tree of modules.
|
||||
pub struct ModuleS<'a> {
|
||||
parent_link: ParentLink<'a>,
|
||||
def: Cell<Option<Def>>,
|
||||
def: Option<Def>,
|
||||
is_public: bool,
|
||||
is_extern_crate: bool,
|
||||
|
||||
@ -839,7 +840,7 @@ 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),
|
||||
def: def,
|
||||
is_public: is_public,
|
||||
is_extern_crate: false,
|
||||
children: RefCell::new(HashMap::new()),
|
||||
@ -877,18 +878,18 @@ impl<'a> ModuleS<'a> {
|
||||
}
|
||||
|
||||
fn def_id(&self) -> Option<DefId> {
|
||||
self.def.get().as_ref().map(Def::def_id)
|
||||
self.def.as_ref().map(Def::def_id)
|
||||
}
|
||||
|
||||
fn is_normal(&self) -> bool {
|
||||
match self.def.get() {
|
||||
match self.def {
|
||||
Some(Def::Mod(_)) | Some(Def::ForeignMod(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
fn is_trait(&self) -> bool {
|
||||
match self.def.get() {
|
||||
match self.def {
|
||||
Some(Def::Trait(_)) => true,
|
||||
_ => false,
|
||||
}
|
||||
@ -987,7 +988,7 @@ impl<'a> NameBinding<'a> {
|
||||
fn def(&self) -> Option<Def> {
|
||||
match self.def_or_module {
|
||||
DefOrModule::Def(def) => Some(def),
|
||||
DefOrModule::Module(ref module) => module.def.get(),
|
||||
DefOrModule::Module(ref module) => module.def,
|
||||
}
|
||||
}
|
||||
|
||||
@ -1197,7 +1198,14 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn record_import_use(&mut self, import_id: NodeId, name: Name) {
|
||||
fn record_import_use(&mut self, name: Name, ns: Namespace, resolution: &ImportResolution<'a>) {
|
||||
let import_id = resolution.id;
|
||||
self.used_imports.insert((import_id, ns));
|
||||
match resolution.target.as_ref().and_then(|target| target.target_module.def_id()) {
|
||||
Some(DefId { krate, .. }) => { self.used_crates.insert(krate); }
|
||||
_ => {}
|
||||
};
|
||||
|
||||
if !self.make_glob_map {
|
||||
return;
|
||||
}
|
||||
@ -1249,12 +1257,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
// modules as we go.
|
||||
while index < module_path_len {
|
||||
let name = module_path[index];
|
||||
match self.resolve_name_in_module(search_module, name, TypeNS, false) {
|
||||
match self.resolve_name_in_module(search_module, name, TypeNS, false, true) {
|
||||
Failed(None) => {
|
||||
let segment_name = name.as_str();
|
||||
let module_name = module_to_string(search_module);
|
||||
let mut span = span;
|
||||
let msg = if "???" == &module_name[..] {
|
||||
let msg = if "???" == &module_name {
|
||||
span.hi = span.lo + Pos::from_usize(segment_name.len());
|
||||
|
||||
match search_parent_externals(name, &self.current_module) {
|
||||
@ -1328,8 +1336,9 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
use_lexical_scope: UseLexicalScopeFlag,
|
||||
span: Span)
|
||||
-> ResolveResult<(Module<'a>, LastPrivate)> {
|
||||
let module_path_len = module_path.len();
|
||||
assert!(module_path_len > 0);
|
||||
if module_path.len() == 0 {
|
||||
return Success((self.graph_root, LastMod(AllPublic))) // Use the crate root
|
||||
}
|
||||
|
||||
debug!("(resolving module path for import) processing `{}` rooted at `{}`",
|
||||
names_to_string(module_path),
|
||||
@ -1380,16 +1389,22 @@ 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.
|
||||
match self.resolve_module_in_lexical_scope(module_, module_path[0]) {
|
||||
match self.resolve_item_in_lexical_scope(module_,
|
||||
module_path[0],
|
||||
TypeNS,
|
||||
true) {
|
||||
Failed(err) => return Failed(err),
|
||||
Indeterminate => {
|
||||
debug!("(resolving module path for import) indeterminate; bailing");
|
||||
return Indeterminate;
|
||||
}
|
||||
Success(containing_module) => {
|
||||
search_module = containing_module;
|
||||
start_index = 1;
|
||||
last_private = LastMod(AllPublic);
|
||||
Success((target, _)) => match target.binding.module() {
|
||||
Some(containing_module) => {
|
||||
search_module = containing_module;
|
||||
start_index = 1;
|
||||
last_private = LastMod(AllPublic);
|
||||
}
|
||||
None => return Failed(None),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1423,47 +1438,29 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
namespace,
|
||||
module_to_string(&*module_));
|
||||
|
||||
// The current module node is handled specially. First, check for
|
||||
// its immediate children.
|
||||
build_reduced_graph::populate_module_if_necessary(self, &module_);
|
||||
|
||||
if let Some(binding) = module_.get_child(name, namespace) {
|
||||
debug!("top name bindings succeeded");
|
||||
return Success((Target::new(module_, binding, Shadowable::Never), false));
|
||||
}
|
||||
|
||||
// Now check for its import directives. We don't have to have resolved
|
||||
// all its imports in the usual way; this is because chains of
|
||||
// adjacent import statements are processed as though they mutated the
|
||||
// current scope.
|
||||
if let Some(import_resolution) =
|
||||
module_.import_resolutions.borrow().get(&(name, namespace)) {
|
||||
match import_resolution.target.clone() {
|
||||
None => {
|
||||
// Not found; continue.
|
||||
debug!("(resolving item in lexical scope) found import resolution, but not \
|
||||
in namespace {:?}",
|
||||
namespace);
|
||||
}
|
||||
Some(target) => {
|
||||
debug!("(resolving item in lexical scope) using import resolution");
|
||||
// track used imports and extern crates as well
|
||||
let id = import_resolution.id;
|
||||
if record_used {
|
||||
self.used_imports.insert((id, namespace));
|
||||
self.record_import_use(id, name);
|
||||
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
|
||||
self.used_crates.insert(kid);
|
||||
}
|
||||
}
|
||||
return Success((target, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Finally, proceed up the scope chain looking for parent modules.
|
||||
// Proceed up the scope chain looking for parent modules.
|
||||
let mut search_module = module_;
|
||||
loop {
|
||||
// Resolve the name in the parent module.
|
||||
match self.resolve_name_in_module(search_module, name, namespace, true, record_used) {
|
||||
Failed(Some((span, msg))) => {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
|
||||
}
|
||||
Failed(None) => (), // Continue up the search chain.
|
||||
Indeterminate => {
|
||||
// We couldn't see through the higher scope because of an
|
||||
// unresolved import higher up. Bail.
|
||||
|
||||
debug!("(resolving item in lexical scope) indeterminate higher scope; bailing");
|
||||
return Indeterminate;
|
||||
}
|
||||
Success((target, used_reexport)) => {
|
||||
// We found the module.
|
||||
debug!("(resolving item in lexical scope) found name in module, done");
|
||||
return Success((target, used_reexport));
|
||||
}
|
||||
}
|
||||
|
||||
// Go to the next parent.
|
||||
match search_module.parent_link {
|
||||
NoParentLink => {
|
||||
@ -1485,55 +1482,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
search_module = parent_module_node;
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve the name in the parent module.
|
||||
match self.resolve_name_in_module(search_module, name, namespace, true) {
|
||||
Failed(Some((span, msg))) => {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
|
||||
}
|
||||
Failed(None) => (), // Continue up the search chain.
|
||||
Indeterminate => {
|
||||
// We couldn't see through the higher scope because of an
|
||||
// unresolved import higher up. Bail.
|
||||
|
||||
debug!("(resolving item in lexical scope) indeterminate higher scope; bailing");
|
||||
return Indeterminate;
|
||||
}
|
||||
Success((target, used_reexport)) => {
|
||||
// We found the module.
|
||||
debug!("(resolving item in lexical scope) found name in module, done");
|
||||
return Success((target, used_reexport));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Resolves a module name in the current lexical scope.
|
||||
fn resolve_module_in_lexical_scope(&mut self,
|
||||
module_: Module<'a>,
|
||||
name: Name)
|
||||
-> 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);
|
||||
match resolve_result {
|
||||
Success((target, _)) => {
|
||||
if let Some(module_def) = target.binding.module() {
|
||||
return Success(module_def)
|
||||
} else {
|
||||
debug!("!!! (resolving module in lexical scope) module \
|
||||
wasn't actually a module!");
|
||||
return Failed(None);
|
||||
}
|
||||
}
|
||||
Indeterminate => {
|
||||
debug!("(resolving module in lexical scope) indeterminate; bailing");
|
||||
return Indeterminate;
|
||||
}
|
||||
Failed(err) => {
|
||||
debug!("(resolving module in lexical scope) failed to resolve");
|
||||
return Failed(err);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1612,14 +1560,15 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
module_: Module<'a>,
|
||||
name: Name,
|
||||
namespace: Namespace,
|
||||
allow_private_imports: bool)
|
||||
allow_private_imports: bool,
|
||||
record_used: 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_);
|
||||
build_reduced_graph::populate_module_if_necessary(self, module_);
|
||||
|
||||
if let Some(binding) = module_.get_child(name, namespace) {
|
||||
debug!("(resolving name in module) found node as child");
|
||||
@ -1633,22 +1582,12 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
debug!("(resolving name in module) import unresolved; bailing out");
|
||||
return Indeterminate;
|
||||
}
|
||||
match import_resolution.target.clone() {
|
||||
None => {
|
||||
debug!("(resolving name in module) name found, but not in namespace {:?}",
|
||||
namespace);
|
||||
}
|
||||
Some(target) => {
|
||||
debug!("(resolving name in module) resolved to import");
|
||||
// track used imports and extern crates as well
|
||||
let id = import_resolution.id;
|
||||
self.used_imports.insert((id, namespace));
|
||||
self.record_import_use(id, name);
|
||||
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
|
||||
self.used_crates.insert(kid);
|
||||
}
|
||||
return Success((target, true));
|
||||
if let Some(target) = import_resolution.target.clone() {
|
||||
debug!("(resolving name in module) resolved to import");
|
||||
if record_used {
|
||||
self.record_import_use(name, namespace, &import_resolution);
|
||||
}
|
||||
return Success((target, true));
|
||||
}
|
||||
}
|
||||
Some(..) | None => {} // Continue.
|
||||
@ -1670,7 +1609,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
// Descend into children and anonymous children.
|
||||
build_reduced_graph::populate_module_if_necessary(self, &module_);
|
||||
build_reduced_graph::populate_module_if_necessary(self, module_);
|
||||
|
||||
module_.for_each_local_child(|_, _, child_node| {
|
||||
match child_node.module() {
|
||||
@ -2835,9 +2774,17 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
// Check the items.
|
||||
let module = self.current_module;
|
||||
let name = identifier.unhygienic_name;
|
||||
self.resolve_item_by_name_in_lexical_scope(name, namespace, record_used)
|
||||
.map(LocalDef::from_def)
|
||||
match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
|
||||
Success((target, _)) => target.binding.def().map(LocalDef::from_def),
|
||||
Failed(Some((span, msg))) => {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg));
|
||||
None
|
||||
}
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve a local definition, potentially adjusting for closures.
|
||||
@ -2967,7 +2914,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let name = segments.last().unwrap().identifier.name;
|
||||
let def = match self.resolve_name_in_module(containing_module, name, namespace, false) {
|
||||
let result = self.resolve_name_in_module(containing_module, name, namespace, false, true);
|
||||
let def = match result {
|
||||
Success((Target { binding, .. }, _)) => {
|
||||
let (def, lp) = binding.def_and_lp();
|
||||
(def, last_private.or(lp))
|
||||
@ -2999,7 +2947,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
let containing_module;
|
||||
let last_private;
|
||||
match self.resolve_module_path_from_root(root_module,
|
||||
&module_path[..],
|
||||
&module_path,
|
||||
0,
|
||||
span,
|
||||
LastMod(AllPublic)) {
|
||||
@ -3008,7 +2956,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
Some((span, msg)) => (span, msg),
|
||||
None => {
|
||||
let msg = format!("Use of undeclared module `::{}`",
|
||||
names_to_string(&module_path[..]));
|
||||
names_to_string(&module_path));
|
||||
(span, msg)
|
||||
}
|
||||
};
|
||||
@ -3026,7 +2974,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
}
|
||||
|
||||
let name = segments.last().unwrap().identifier.name;
|
||||
match self.resolve_name_in_module(containing_module, name, namespace, false) {
|
||||
match self.resolve_name_in_module(containing_module, name, namespace, false, true) {
|
||||
Success((Target { binding, .. }, _)) => {
|
||||
let (def, lp) = binding.def_and_lp();
|
||||
Some((def, last_private.or(lp)))
|
||||
@ -3068,6 +3016,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
if let Success((target, _)) = self.resolve_name_in_module(module,
|
||||
ident.unhygienic_name,
|
||||
namespace,
|
||||
true,
|
||||
true) {
|
||||
if let Some(def) = target.binding.def() {
|
||||
return Some(LocalDef::from_def(def));
|
||||
@ -3079,49 +3028,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
None
|
||||
}
|
||||
|
||||
fn resolve_item_by_name_in_lexical_scope(&mut self,
|
||||
name: Name,
|
||||
namespace: Namespace,
|
||||
record_used: bool)
|
||||
-> Option<Def> {
|
||||
// Check the items.
|
||||
let module = self.current_module;
|
||||
match self.resolve_item_in_lexical_scope(module, name, namespace, record_used) {
|
||||
Success((target, _)) => {
|
||||
match target.binding.def() {
|
||||
None => {
|
||||
// This can happen if we were looking for a type and
|
||||
// found a module instead. Modules don't have defs.
|
||||
debug!("(resolving item path by identifier in lexical scope) failed to \
|
||||
resolve {} after success...",
|
||||
name);
|
||||
None
|
||||
}
|
||||
Some(def) => {
|
||||
debug!("(resolving item path in lexical scope) resolved `{}` to item",
|
||||
name);
|
||||
// This lookup is "all public" because it only searched
|
||||
// for one identifier in the current module (couldn't
|
||||
// have passed through reexports or anything like that.
|
||||
Some(def)
|
||||
}
|
||||
}
|
||||
}
|
||||
Indeterminate => None,
|
||||
Failed(err) => {
|
||||
debug!("(resolving item path by identifier in lexical scope) failed to \
|
||||
resolve `{}`",
|
||||
name);
|
||||
|
||||
if let Some((span, msg)) = err {
|
||||
resolve_error(self, span, ResolutionError::FailedToResolve(&*msg))
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn with_no_errors<T, F>(&mut self, f: F) -> T
|
||||
where F: FnOnce(&mut Resolver) -> T
|
||||
{
|
||||
@ -3564,13 +3470,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
|
||||
};
|
||||
if self.trait_item_map.contains_key(&(name, did)) {
|
||||
add_trait_info(&mut found_traits, did, name);
|
||||
let id = import.id;
|
||||
self.used_imports.insert((id, TypeNS));
|
||||
let trait_name = self.get_trait_name(did);
|
||||
self.record_import_use(id, trait_name);
|
||||
if let Some(DefId{krate: kid, ..}) = target.target_module.def_id() {
|
||||
self.used_crates.insert(kid);
|
||||
}
|
||||
self.record_import_use(trait_name, TypeNS, &import);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -257,7 +257,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
errors.extend(self.resolve_imports_for_module(module_));
|
||||
self.resolver.current_module = orig_module;
|
||||
|
||||
build_reduced_graph::populate_module_if_necessary(self.resolver, &module_);
|
||||
build_reduced_graph::populate_module_if_necessary(self.resolver, module_);
|
||||
module_.for_each_local_child(|_, _, child_node| {
|
||||
match child_node.module() {
|
||||
None => {
|
||||
@ -332,92 +332,45 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
module_: Module<'b>,
|
||||
import_directive: &ImportDirective)
|
||||
-> ResolveResult<()> {
|
||||
let mut resolution_result = ResolveResult::Failed(None);
|
||||
let module_path = &import_directive.module_path;
|
||||
|
||||
debug!("(resolving import for module) resolving import `{}::...` in `{}`",
|
||||
names_to_string(&module_path[..]),
|
||||
names_to_string(&import_directive.module_path),
|
||||
module_to_string(&*module_));
|
||||
|
||||
// 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, LastMod(AllPublic)))
|
||||
} else {
|
||||
match self.resolver.resolve_module_path(module_,
|
||||
&module_path[..],
|
||||
UseLexicalScopeFlag::DontUseLexicalScope,
|
||||
import_directive.span) {
|
||||
ResolveResult::Failed(err) => {
|
||||
resolution_result = ResolveResult::Failed(err);
|
||||
None
|
||||
}
|
||||
ResolveResult::Indeterminate => {
|
||||
resolution_result = ResolveResult::Indeterminate;
|
||||
None
|
||||
}
|
||||
ResolveResult::Success(container) => Some(container),
|
||||
}
|
||||
};
|
||||
|
||||
match container {
|
||||
None => {}
|
||||
Some((containing_module, lp)) => {
|
||||
self.resolver
|
||||
.resolve_module_path(module_,
|
||||
&import_directive.module_path,
|
||||
UseLexicalScopeFlag::DontUseLexicalScope,
|
||||
import_directive.span)
|
||||
.and_then(|(containing_module, lp)| {
|
||||
// We found the module that the target is contained
|
||||
// within. Attempt to resolve the import within it.
|
||||
|
||||
match import_directive.subclass {
|
||||
SingleImport(target, source) => {
|
||||
resolution_result = self.resolve_single_import(&module_,
|
||||
containing_module,
|
||||
target,
|
||||
source,
|
||||
import_directive,
|
||||
lp);
|
||||
}
|
||||
GlobImport => {
|
||||
resolution_result = self.resolve_glob_import(&module_,
|
||||
containing_module,
|
||||
import_directive,
|
||||
lp);
|
||||
}
|
||||
if let SingleImport(target, source) = import_directive.subclass {
|
||||
self.resolve_single_import(module_,
|
||||
containing_module,
|
||||
target,
|
||||
source,
|
||||
import_directive,
|
||||
lp)
|
||||
} else {
|
||||
self.resolve_glob_import(module_, containing_module, import_directive, lp)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Decrement the count of unresolved imports.
|
||||
match resolution_result {
|
||||
ResolveResult::Success(()) => {
|
||||
})
|
||||
.and_then(|()| {
|
||||
// Decrement the count of unresolved imports.
|
||||
assert!(self.resolver.unresolved_imports >= 1);
|
||||
self.resolver.unresolved_imports -= 1;
|
||||
}
|
||||
_ => {
|
||||
// Nothing to do here; just return the error.
|
||||
}
|
||||
}
|
||||
|
||||
// Decrement the count of unresolved globs if necessary. But only if
|
||||
// the resolution result is a success -- other cases will
|
||||
// be handled by the main loop.
|
||||
|
||||
if resolution_result.success() {
|
||||
match import_directive.subclass {
|
||||
GlobImport => {
|
||||
if let GlobImport = import_directive.subclass {
|
||||
module_.dec_glob_count();
|
||||
if import_directive.is_public {
|
||||
module_.dec_pub_glob_count();
|
||||
}
|
||||
}
|
||||
SingleImport(..) => {
|
||||
// Ignore.
|
||||
if import_directive.is_public {
|
||||
module_.dec_pub_count();
|
||||
}
|
||||
}
|
||||
if import_directive.is_public {
|
||||
module_.dec_pub_count();
|
||||
}
|
||||
}
|
||||
|
||||
return resolution_result;
|
||||
Success(())
|
||||
})
|
||||
}
|
||||
|
||||
/// Resolves the name in the namespace of the module because it is being imported by
|
||||
@ -460,12 +413,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
|
||||
let target = resolution.target.clone();
|
||||
if let Some(Target { target_module, binding, shadowable: _ }) = target {
|
||||
// track used imports and extern crates as well
|
||||
self.resolver.used_imports.insert((resolution.id, ns));
|
||||
self.resolver.record_import_use(resolution.id, name);
|
||||
if let Some(DefId { krate, .. }) = target_module.def_id() {
|
||||
self.resolver.used_crates.insert(krate);
|
||||
}
|
||||
self.resolver.record_import_use(name, ns, &resolution);
|
||||
(Success((target_module, binding)), true)
|
||||
} else {
|
||||
(Failed(None), false)
|
||||
@ -517,9 +465,9 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
|
||||
// We need to resolve both namespaces for this to succeed.
|
||||
let (value_result, value_used_reexport) =
|
||||
self.resolve_name_in_module(&target_module, source, ValueNS, module_);
|
||||
self.resolve_name_in_module(target_module, source, ValueNS, module_);
|
||||
let (type_result, type_used_reexport) =
|
||||
self.resolve_name_in_module(&target_module, source, TypeNS, module_);
|
||||
self.resolve_name_in_module(target_module, source, TypeNS, module_);
|
||||
|
||||
match (&value_result, &type_result) {
|
||||
(&Success((_, ref name_binding)), _) if !value_used_reexport &&
|
||||
@ -637,7 +585,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
if let (&Failed(_), &Failed(_)) = (&value_result, &type_result) {
|
||||
let msg = format!("There is no `{}` in `{}`{}",
|
||||
source,
|
||||
module_to_string(&target_module), lev_suggestion);
|
||||
module_to_string(target_module), lev_suggestion);
|
||||
return Failed(Some((directive.span, msg)));
|
||||
}
|
||||
|
||||
@ -763,7 +711,7 @@ impl<'a, 'b:'a, 'tcx:'b> ImportResolver<'a, 'b, 'tcx> {
|
||||
}
|
||||
|
||||
// Add all children from the containing module.
|
||||
build_reduced_graph::populate_module_if_necessary(self.resolver, &target_module);
|
||||
build_reduced_graph::populate_module_if_necessary(self.resolver, target_module);
|
||||
|
||||
target_module.for_each_local_child(|name, ns, name_binding| {
|
||||
self.merge_import_resolution(module_,
|
||||
|
@ -26,7 +26,7 @@ use llvm::debuginfo::{DIType, DIFile, DIScope, DIDescriptor, DICompositeType};
|
||||
use middle::def_id::DefId;
|
||||
use middle::infer;
|
||||
use middle::pat_util;
|
||||
use middle::subst::{self, Substs};
|
||||
use middle::subst;
|
||||
use rustc::front::map as hir_map;
|
||||
use rustc_front::hir;
|
||||
use trans::{type_of, adt, machine, monomorphize};
|
||||
|
@ -15,7 +15,7 @@ use super::namespace::crate_root_namespace;
|
||||
use trans::common::CrateContext;
|
||||
use middle::def_id::DefId;
|
||||
use middle::infer;
|
||||
use middle::subst::{self, Substs};
|
||||
use middle::subst;
|
||||
use middle::ty::{self, Ty};
|
||||
|
||||
use rustc_front::hir;
|
||||
|
@ -50,7 +50,6 @@ use middle::ty::cast::{CastKind, CastTy};
|
||||
use syntax::codemap::Span;
|
||||
use rustc_front::hir;
|
||||
use syntax::ast;
|
||||
use syntax::ast::UintTy::TyU8;
|
||||
|
||||
|
||||
/// Reifies a cast check to be checked once we have full type information for
|
||||
|
@ -17,7 +17,7 @@ use astconv::AstConv;
|
||||
use check::{self, FnCtxt};
|
||||
use front::map as hir_map;
|
||||
use middle::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable};
|
||||
use middle::cstore::{self, CrateStore, DefLike};
|
||||
use middle::cstore::{self, CrateStore};
|
||||
use middle::def::Def;
|
||||
use middle::def_id::DefId;
|
||||
use middle::lang_items::FnOnceTraitLangItem;
|
||||
|
@ -92,7 +92,7 @@ use middle::infer;
|
||||
use middle::infer::{TypeOrigin, type_variable};
|
||||
use middle::pat_util::{self, pat_id_map};
|
||||
use middle::privacy::{AllPublic, LastMod};
|
||||
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
|
||||
use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace};
|
||||
use middle::traits::{self, report_fulfillment_errors};
|
||||
use middle::ty::{GenericPredicates, TypeScheme};
|
||||
use middle::ty::{Disr, ParamTy, ParameterEnvironment};
|
||||
|
@ -56,7 +56,10 @@ mod bar {
|
||||
use foo::Point;
|
||||
use foo::Square; //~ ERROR unused import
|
||||
pub fn cc(_p: Point) -> super::Square {
|
||||
super::Square
|
||||
fn f() -> super::Square {
|
||||
super::Square
|
||||
}
|
||||
f()
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user