rustc: Make import resolution errors less fatal

Failure happens at the end of import resolution

Issue #440
This commit is contained in:
Brian Anderson 2011-06-18 23:28:29 -07:00
parent 4539a2cf7a
commit 92a8ae94b9

View file

@ -251,6 +251,7 @@ fn resolve_imports(&env e) {
case (resolved(_, _, _)) { } case (resolved(_, _, _)) { }
} }
} }
e.sess.abort_if_errors();
} }
fn resolve_names(&@env e, &@ast::crate c) { fn resolve_names(&@env e, &@ast::crate c) {
@ -437,9 +438,18 @@ fn resolve_import(&env e, &@ast::view_item it, &scopes sc) {
lookup_in_scope(e, next_sc, it.span, end_id, ns_value), lookup_in_scope(e, next_sc, it.span, end_id, ns_value),
lookup_in_scope(e, next_sc, it.span, end_id, ns_type), lookup_in_scope(e, next_sc, it.span, end_id, ns_type),
lookup_in_scope(e, next_sc, it.span, end_id, ns_module)); lookup_in_scope(e, next_sc, it.span, end_id, ns_module));
remove_if_unresolved(e.imports, defid._1);
} else { } else {
auto dcur = auto dcur = alt(lookup_in_scope(e, sc, it.span, ids.(0), ns_module)) {
lookup_in_scope_strict(e, sc, it.span, ids.(0), ns_module); case (some(?dcur)) {
dcur
}
case (none) {
unresolved_err(e, it.span, ids.(0), ns_name(ns_module));
remove_if_unresolved(e.imports, defid._1);
ret () // FIXME (issue #521)
}
};
auto i = 1u; auto i = 1u;
while (true) { while (true) {
if (i == n_idents - 1u) { if (i == n_idents - 1u) {
@ -450,11 +460,21 @@ fn resolve_import(&env e, &@ast::view_item it, &scopes sc) {
outside), outside),
lookup_in_mod(e, dcur, it.span, end_id, ns_module, lookup_in_mod(e, dcur, it.span, end_id, ns_module,
outside)); outside));
remove_if_unresolved(e.imports, defid._1);
break; break;
} else { } else {
dcur = dcur = alt (lookup_in_mod(e, dcur, it.span, ids.(i),
lookup_in_mod_strict(e, dcur, it.span, ids.(i), ns_module, ns_module, outside)) {
outside); case (some(?dcur)) {
dcur
}
case (none) {
unresolved_err(e, it.span, ids.(i),
ns_name(ns_module));
remove_if_unresolved(e.imports, defid._1);
ret () // FIXME (issue #521)
}
};
i += 1u; i += 1u;
} }
} }
@ -464,10 +484,25 @@ fn resolve_import(&env e, &@ast::view_item it, &scopes sc) {
&option::t[def] md) { &option::t[def] md) {
if (option::is_none(val) && option::is_none(typ) && if (option::is_none(val) && option::is_none(typ) &&
option::is_none(md)) { option::is_none(md)) {
unresolved(e, sp, id, "import"); unresolved_err(e, sp, id, "import");
} } else {
e.imports.insert(defid._1, resolved(val, typ, md)); e.imports.insert(defid._1, resolved(val, typ, md));
} }
}
fn remove_if_unresolved(hashmap[ast::def_num, import_state] imports,
ast::def_num def_num) {
// If we couldn't resolve the import, don't leave it in a partially
// resolved state, to avoid having it reported later as a cyclic
// import
if (imports.contains_key(def_num)) {
alt (imports.get(def_num)) {
case (resolving(_)) {
imports.remove(def_num);
}
case (_) { }
}
}
}
} }
@ -480,10 +515,17 @@ fn ns_name(namespace ns) -> str {
} }
} }
fn unresolved(&env e, &span sp, &ident id, &str kind) -> ! { fn unresolved_err(&env e, &span sp, &ident id, &str kind) {
e.sess.span_fatal(sp, "unresolved " + kind + ": " + id); e.sess.span_err(sp, mk_unresolved_msg(id, kind));
} }
fn unresolved_fatal(&env e, &span sp, &ident id, &str kind) -> ! {
e.sess.span_fatal(sp, mk_unresolved_msg(id, kind));
}
fn mk_unresolved_msg(&ident id, &str kind) -> str {
ret #fmt("unresolved %s: %s", kind, id);
}
// Lookup helpers // Lookup helpers
fn lookup_path_strict(&env e, &scopes sc, &span sp, vec[ident] idents, fn lookup_path_strict(&env e, &scopes sc, &span sp, vec[ident] idents,
@ -503,7 +545,7 @@ fn lookup_path_strict(&env e, &scopes sc, &span sp, vec[ident] idents,
fn lookup_in_scope_strict(&env e, scopes sc, &span sp, &ident id, fn lookup_in_scope_strict(&env e, scopes sc, &span sp, &ident id,
namespace ns) -> def { namespace ns) -> def {
alt (lookup_in_scope(e, sc, sp, id, ns)) { alt (lookup_in_scope(e, sc, sp, id, ns)) {
case (none) { unresolved(e, sp, id, ns_name(ns)); } case (none) { unresolved_fatal(e, sp, id, ns_name(ns)); }
case (some(?d)) { ret d; } case (some(?d)) { ret d; }
} }
} }
@ -756,7 +798,7 @@ fn found_def_item(&@ast::item i, namespace ns) -> option::t[def] {
fn lookup_in_mod_strict(&env e, def m, &span sp, &ident id, namespace ns, fn lookup_in_mod_strict(&env e, def m, &span sp, &ident id, namespace ns,
dir dr) -> def { dir dr) -> def {
alt (lookup_in_mod(e, m, sp, id, ns, dr)) { alt (lookup_in_mod(e, m, sp, id, ns, dr)) {
case (none) { unresolved(e, sp, id, ns_name(ns)); } case (none) { unresolved_fatal(e, sp, id, ns_name(ns)); }
case (some(?d)) { ret d; } case (some(?d)) { ret d; }
} }
} }
@ -809,7 +851,10 @@ fn lookup_import(&env e, def_id defid, namespace ns) -> option::t[def] {
resolve_import(e, item, sc); resolve_import(e, item, sc);
ret lookup_import(e, defid, ns); ret lookup_import(e, defid, ns);
} }
case (resolving(?sp)) { e.sess.span_fatal(sp, "cyclic import"); } case (resolving(?sp)) {
e.sess.span_err(sp, "cyclic import");
ret none;
}
case (resolved(?val, ?typ, ?md)) { case (resolved(?val, ?typ, ?md)) {
ret alt (ns) { ret alt (ns) {
case (ns_value) { val } case (ns_value) { val }