Skip to content

Commit

Permalink
rustc: Add self/super hint for extern crate resolve errors.
Browse files Browse the repository at this point in the history
  • Loading branch information
Ryman committed Jun 17, 2014
1 parent db29814 commit 207bfee
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 30 deletions.
82 changes: 56 additions & 26 deletions src/librustc/middle/resolve.rs
Expand Up @@ -1485,26 +1485,21 @@ impl<'a> Resolver<'a> {

ViewItemExternCrate(name, _, node_id) => {
// n.b. we don't need to look at the path option here, because cstore already did
match self.session.cstore.find_extern_mod_stmt_cnum(node_id) {
Some(crate_id) => {
let def_id = DefId { krate: crate_id, node: 0 };
self.external_exports.insert(def_id);
let parent_link = ModuleParentLink
(parent.module().downgrade(), name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
false,
true));

parent.module().external_module_children
.borrow_mut().insert(name.name,
external_module.clone());

self.build_reduced_graph_for_external_crate(
external_module);
}
None => {} // Ignore.
for &crate_id in self.session.cstore.find_extern_mod_stmt_cnum(node_id).iter() {
let def_id = DefId { krate: crate_id, node: 0 };
self.external_exports.insert(def_id);
let parent_link = ModuleParentLink(parent.module().downgrade(), name);
let external_module = Rc::new(Module::new(parent_link,
Some(def_id),
NormalModuleKind,
false,
true));
debug!("(build reduced graph for item) found extern `{}`",
self.module_to_str(&*external_module));
parent.module().external_module_children.borrow_mut()
.insert(name.name,
external_module.clone());
self.build_reduced_graph_for_external_crate(external_module);
}
}
}
Expand Down Expand Up @@ -1997,7 +1992,9 @@ impl<'a> Resolver<'a> {
fn resolve_imports_for_module_subtree(&mut self, module_: Rc<Module>) {
debug!("(resolving imports for module subtree) resolving {}",
self.module_to_str(&*module_));
let orig_module = replace(&mut self.current_module, module_.clone());
self.resolve_imports_for_module(module_.clone());
self.current_module = orig_module;

self.populate_module_if_necessary(&module_);
for (_, child_node) in module_.children.borrow().iter() {
Expand Down Expand Up @@ -2611,6 +2608,22 @@ impl<'a> Resolver<'a> {
name_search_type: NameSearchType,
lp: LastPrivate)
-> ResolveResult<(Rc<Module>, LastPrivate)> {
fn search_parent_externals(needle: Name, module: &Rc<Module>)
-> Option<Rc<Module>> {
module.external_module_children.borrow()
.find_copy(&needle)
.map(|_| module.clone())
.or_else(|| {
match module.parent_link.clone() {
ModuleParentLink(parent, _) => {
search_parent_externals(needle,
&parent.upgrade().unwrap())
}
_ => None
}
})
}

let mut search_module = module_;
let mut index = index;
let module_path_len = module_path.len();
Expand All @@ -2635,11 +2648,28 @@ impl<'a> Resolver<'a> {
hi: span.lo + Pos::from_uint(segment_name.get().len()),
expn_info: span.expn_info,
};
self.resolve_error(span,
format!("unresolved import. maybe \
a missing `extern crate \
{}`?",
segment_name).as_slice());

match search_parent_externals(name.name, &self.current_module) {
Some(module) => {
let path_str = self.idents_to_str(module_path);
let target_mod_str = self.module_to_str(&*module);
let current_mod_str = self.module_to_str(&*self.current_module);

let prefix = if target_mod_str == current_mod_str {
"self::".to_string()
} else {
format!("{}::", target_mod_str)
};

self.resolve_error(span, format!("unresolved import. Did you mean \
`{}{}`?",
prefix, path_str).as_slice());
},
None => self.resolve_error(span, format!("unresolved import. Maybe a \
missing `extern crate {}`?",
segment_name).as_slice()),
}

return Failed;
}
self.resolve_error(span,
Expand Down Expand Up @@ -5480,7 +5510,7 @@ impl<'a> Resolver<'a> {
//

/// A somewhat inefficient routine to obtain the name of a module.
fn module_to_str(&mut self, module: &Module) -> String {
fn module_to_str(&self, module: &Module) -> String {
let mut idents = Vec::new();

fn collect_mod(idents: &mut Vec<ast::Ident>, module: &Module) {
Expand Down
4 changes: 2 additions & 2 deletions src/test/compile-fail/issue-1697.rs
@@ -1,4 +1,4 @@
// Copyright 2012 The Rust Project Developers. See the COPYRIGHT
// Copyright 2012-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -12,7 +12,7 @@

#![feature(globs)]

use unresolved::*; //~ ERROR unresolved import. maybe a missing
use unresolved::*; //~ ERROR unresolved import. Maybe a missing
//~^ ERROR failed to resolve import

fn main() {
Expand Down
32 changes: 32 additions & 0 deletions src/test/compile-fail/resolve_self_super_hint.rs
@@ -0,0 +1,32 @@
// Copyright 2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

mod a {
extern crate collections;
use collections::HashMap;
//~^ ERROR unresolved import. Did you mean `self::collections`?
//~^^ ERROR failed to resolve import `collections::HashMap`

mod b {
use collections::HashMap;
//~^ ERROR unresolved import. Did you mean `a::collections`?
//~^^ ERROR failed to resolve import `collections::HashMap`
mod c {
use collections::HashMap;
//~^ ERROR unresolved import. Did you mean `a::collections`?
//~^^ ERROR failed to resolve import `collections::HashMap`
mod d {
use collections::HashMap;
//~^ ERROR unresolved import. Did you mean `a::collections`
//~^^ ERROR failed to resolve import `collections::HashMap`
}
}
}
}
4 changes: 2 additions & 2 deletions src/test/compile-fail/unresolved-import.rs
@@ -1,4 +1,4 @@
// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
Expand All @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use foo::bar; //~ ERROR unresolved import. maybe a missing `extern crate foo`?
use foo::bar; //~ ERROR unresolved import. Maybe a missing `extern crate foo`?
//~^ ERROR failed to resolve import `foo::bar`
use x = bar::baz; //~ ERROR unresolved import: there is no `baz` in `bar`
//~^ ERROR failed to resolve import `bar::baz`
Expand Down

0 comments on commit 207bfee

Please sign in to comment.