Include full module path in unresolved errors when looking in module

Closes #1228
This commit is contained in:
Marijn Haverbeke 2011-12-02 16:46:19 +01:00
parent 0f918ddd8b
commit 817c9f2a54

View File

@ -83,12 +83,13 @@ type mod_index = hashmap<ident, list<mod_index_entry>>;
// A tuple of an imported def and the import stmt that brung it
type glob_imp_def = {def: def, item: @ast::view_item};
type indexed_mod =
{m: option::t<ast::_mod>,
index: mod_index,
mutable glob_imports: [glob_imp_def],
glob_imported_names: hashmap<str, import_state>};
type indexed_mod = {
m: option::t<ast::_mod>,
index: mod_index,
mutable glob_imports: [glob_imp_def],
glob_imported_names: hashmap<str, import_state>,
path: str
};
/* native modules can't contain tags, and we don't store their ASTs because we
only need to look at them to determine exports, which they can't control.*/
@ -160,7 +161,8 @@ fn map_crate(e: @env, c: @ast::crate) {
@{m: some(c.node.module),
index: index_mod(c.node.module),
mutable glob_imports: [],
glob_imported_names: new_str_hash::<import_state>()});
glob_imported_names: new_str_hash::<import_state>(),
path: ""});
fn index_vi(e: @env, i: @ast::view_item, sc: scopes, _v: vt<scopes>) {
alt i.node {
ast::view_item_import(name, ids, id) {
@ -177,6 +179,16 @@ fn map_crate(e: @env, c: @ast::crate) {
_ { }
}
}
fn path_from_scope(sc: scopes, n: str) -> str {
let path = n + "::";
list::iter(sc) {|s|
alt s {
scope_item(i) { path = i.ident + "::" + path; }
_ {}
}
}
path
}
fn index_i(e: @env, i: @ast::item, sc: scopes, v: vt<scopes>) {
visit_item_with_scope(i, sc, v);
alt i.node {
@ -186,7 +198,8 @@ fn map_crate(e: @env, c: @ast::crate) {
@{m: some(md),
index: index_mod(md),
mutable glob_imports: [],
glob_imported_names: s});
glob_imported_names: s,
path: path_from_scope(sc, i.ident)});
}
ast::item_native_mod(nmd) {
let s = new_str_hash::<import_state>();
@ -194,7 +207,8 @@ fn map_crate(e: @env, c: @ast::crate) {
@{m: none::<ast::_mod>,
index: index_nmod(nmd),
mutable glob_imports: [],
glob_imported_names: s});
glob_imported_names: s,
path: path_from_scope(sc, i.ident)});
}
_ { }
}
@ -416,7 +430,7 @@ fn follow_import(e: env, sc: scopes, path: [ident], sp: span) ->
while true && option::is_some(dcur) {
if i == path_len { break; }
dcur =
lookup_in_mod_strict(e, sc, option::get(dcur), sp, path[i],
lookup_in_mod_strict(e, option::get(dcur), sp, path[i],
ns_module, outside);
i += 1u;
}
@ -452,12 +466,12 @@ fn resolve_constr(e: @env, c: @ast::constr, sc: scopes, _v: vt<scopes>) {
// Import resolution
fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
ids: [ast::ident], sp: codemap::span, sc: scopes) {
fn register(e: env, id: node_id, sc: scopes, sp: codemap::span,
fn register(e: env, id: node_id, cx: ctxt, sp: codemap::span,
name: ast::ident, lookup: block(namespace) -> option::t<def>){
let val = lookup(ns_value), typ = lookup(ns_type),
md = lookup(ns_module);
if is_none(val) && is_none(typ) && is_none(md) {
unresolved_err(e, sc, sp, name, "import");
unresolved_err(e, cx, sp, name, "import");
} else {
e.imports.insert(id, resolved(val, typ, md, name, sp));
}
@ -507,16 +521,18 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
let n_idents = vec::len(ids);
let end_id = ids[n_idents - 1u];
if n_idents == 1u {
register(e, defid.node, sc, sp, name,
register(e, defid.node, in_scope(sc), sp, name,
{|ns| lookup_in_scope(e, sc, sp, end_id, ns) });
} else {
alt lookup_in_scope(e, sc, sp, ids[0], ns_module) {
none. { unresolved_err(e, sc, sp, ids[0], ns_name(ns_module)); }
none. {
unresolved_err(e, in_scope(sc), sp, ids[0], ns_name(ns_module));
}
some(dcur_) {
let dcur = dcur_, i = 1u;
while true {
if i == n_idents - 1u {
register(e, defid.node, sc, sp, name, {|ns|
register(e, defid.node, in_mod(dcur), sp, name, {|ns|
lookup_in_mod(e, dcur, sp, end_id, ns, outside)
});
break;
@ -525,7 +541,8 @@ fn resolve_import(e: env, defid: ast::def_id, name: ast::ident,
outside) {
some(dcur) { dcur }
none. {
unresolved_err(e, sc, sp, ids[i], ns_name(ns_module));
unresolved_err(e, in_mod(dcur), sp, ids[i],
ns_name(ns_module));
break;
}
};
@ -557,7 +574,9 @@ fn ns_name(ns: namespace) -> str {
}
}
fn unresolved_err(e: env, sc: scopes, sp: span, name: ident, kind: str) {
tag ctxt { in_mod(def); in_scope(scopes); }
fn unresolved_err(e: env, cx: ctxt, sp: span, name: ident, kind: str) {
fn find_fn_or_mod_scope(sc: scopes) -> option::t<scope> {
let sc = sc;
while true {
@ -576,16 +595,24 @@ fn unresolved_err(e: env, sc: scopes, sp: span, name: ident, kind: str) {
}
fail;
}
alt find_fn_or_mod_scope(sc) {
some(err_scope) {
for rs: {ident: str, sc: scope} in e.reported {
if str::eq(rs.ident, name) && err_scope == rs.sc { ret; }
let path = name;
alt cx {
in_scope(sc) {
alt find_fn_or_mod_scope(sc) {
some(err_scope) {
for rs: {ident: str, sc: scope} in e.reported {
if str::eq(rs.ident, name) && err_scope == rs.sc { ret; }
}
e.reported += [{ident: name, sc: err_scope}];
}
_ {}
}
e.reported += [{ident: name, sc: err_scope}];
}
_ {}
in_mod(def) {
path = e.mod_map.get(ast_util::def_id_of_def(def).node).path + path;
}
}
e.sess.span_err(sp, mk_unresolved_msg(name, kind));
e.sess.span_err(sp, mk_unresolved_msg(path, kind));
}
fn unresolved_fatal(e: env, sp: span, id: ident, kind: str) -> ! {
@ -614,7 +641,7 @@ fn lookup_path_strict(e: env, sc: scopes, sp: span, pth: ast::path_,
while i < n_idents && option::is_some(dcur) {
let curns = if n_idents == i + 1u { ns } else { ns_module };
dcur =
lookup_in_mod_strict(e, sc, option::get(dcur), sp, pth.idents[i],
lookup_in_mod_strict(e, option::get(dcur), sp, pth.idents[i],
curns, outside);
i += 1u;
}
@ -624,7 +651,10 @@ fn lookup_path_strict(e: env, sc: scopes, sp: span, pth: ast::path_,
fn lookup_in_scope_strict(e: env, sc: scopes, sp: span, name: ident,
ns: namespace) -> option::t<def> {
alt lookup_in_scope(e, sc, sp, name, ns) {
none. { unresolved_err(e, sc, sp, name, ns_name(ns)); ret none; }
none. {
unresolved_err(e, in_scope(sc), sp, name, ns_name(ns));
ret none;
}
some(d) { ret some(d); }
}
}
@ -954,10 +984,13 @@ fn found_def_item(i: @ast::item, ns: namespace) -> option::t<def> {
ret none::<def>;
}
fn lookup_in_mod_strict(e: env, sc: scopes, m: def, sp: span, name: ident,
fn lookup_in_mod_strict(e: env, m: def, sp: span, name: ident,
ns: namespace, dr: dir) -> option::t<def> {
alt lookup_in_mod(e, m, sp, name, ns, dr) {
none. { unresolved_err(e, sc, sp, name, ns_name(ns)); ret none; }
none. {
unresolved_err(e, in_mod(m), sp, name, ns_name(ns));
ret none;
}
some(d) { ret some(d); }
}
}