rustc: Make name resolution errors less fatal

Failure happens at the end of name resolution

Issue #440
This commit is contained in:
Brian Anderson 2011-06-19 02:04:08 -07:00
parent c5238d57eb
commit 6cf9b17086

View file

@ -236,8 +236,11 @@ fn map_crate(&@env e, &@ast::crate c) {
case ( case (
//if it really is a glob import, that is //if it really is a glob import, that is
ast::view_item_import_glob(?path, _)) { ast::view_item_import_glob(?path, _)) {
auto imp = follow_import(*e, sc, path, vi.span);
if (option::is_some(imp)) {
find_mod(e, sc).glob_imports += find_mod(e, sc).glob_imports +=
[follow_import(*e, sc, path, vi.span)]; [option::get(imp)];
}
} }
case (_) { } case (_) { }
} }
@ -266,14 +269,15 @@ fn resolve_names(&@env e, &@ast::crate c) {
visit_fn=bind visit_fn_with_scope(e, _, _, _, _, _, _, _, _) visit_fn=bind visit_fn_with_scope(e, _, _, _, _, _, _, _, _)
with *visit::default_visitor()); with *visit::default_visitor());
visit::visit_crate(*c, cons(scope_crate(c), @nil), visit::vtor(v)); visit::visit_crate(*c, cons(scope_crate(c), @nil), visit::vtor(v));
e.sess.abort_if_errors();
fn walk_expr(@env e, &@ast::expr exp, &scopes sc, &vt[scopes] v) { fn walk_expr(@env e, &@ast::expr exp, &scopes sc, &vt[scopes] v) {
visit_expr_with_scope(exp, sc, v); visit_expr_with_scope(exp, sc, v);
alt (exp.node) { alt (exp.node) {
case (ast::expr_path(?p, ?a)) { case (ast::expr_path(?p, ?a)) {
auto df = maybe_insert(e, a.id,
lookup_path_strict(*e, sc, exp.span, p.node.idents, lookup_path_strict(*e, sc, exp.span,
ns_value); p.node.idents, ns_value));
e.def_map.insert(a.id, df);
} }
case (_) { } case (_) { }
} }
@ -282,19 +286,17 @@ fn resolve_names(&@env e, &@ast::crate c) {
visit::visit_ty(t, sc, v); visit::visit_ty(t, sc, v);
alt (t.node) { alt (t.node) {
case (ast::ty_path(?p, ?a)) { case (ast::ty_path(?p, ?a)) {
auto new_def = maybe_insert(e, a.id,
lookup_path_strict(*e, sc, t.span, p.node.idents, lookup_path_strict(*e, sc, t.span,
ns_type); p.node.idents, ns_type));
e.def_map.insert(a.id, new_def);
} }
case (_) { } case (_) { }
} }
} }
fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) { fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) {
auto new_def = maybe_insert(e, c.node.ann.id,
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents, lookup_path_strict(*e, sc, c.span,
ns_value); c.node.path.node.idents, ns_value));
e.def_map.insert(c.node.ann.id, new_def);
} }
fn walk_arm(@env e, &ast::arm a, &scopes sc, &vt[scopes] v) { fn walk_arm(@env e, &ast::arm a, &scopes sc, &vt[scopes] v) {
walk_pat(*e, sc, a.pat); walk_pat(*e, sc, a.pat);
@ -306,21 +308,32 @@ fn resolve_names(&@env e, &@ast::crate c) {
auto fnd = auto fnd =
lookup_path_strict(e, sc, p.span, p.node.idents, lookup_path_strict(e, sc, p.span, p.node.idents,
ns_value); ns_value);
alt (fnd) { if (option::is_some(fnd)) {
alt (option::get(fnd)) {
case (ast::def_variant(?did, ?vid)) { case (ast::def_variant(?did, ?vid)) {
e.def_map.insert(a.id, fnd); e.def_map.insert(a.id, option::get(fnd));
for (@ast::pat child in children) {
walk_pat(e, sc, child);
}
} }
case (_) { case (_) {
e.sess.span_fatal(p.span, e.sess.span_err(p.span,
"not a tag variant: " + "not a tag variant: " +
ast::path_name(p)); ast::path_name(p));
} }
} }
for (@ast::pat child in children) { walk_pat(e, sc, child); } }
} }
case (_) { } case (_) { }
} }
} }
fn maybe_insert(@env e, uint id,
option::t[def] def) {
if (option::is_some(def)) {
e.def_map.insert(id, option::get(def));
}
}
} }
@ -370,32 +383,40 @@ fn visit_expr_with_scope(&@ast::expr x, &scopes sc, &vt[scopes] v) {
visit::visit_expr(x, new_sc, v); visit::visit_expr(x, new_sc, v);
} }
fn follow_import(&env e, &scopes sc, vec[ident] path, &span sp) -> def { fn follow_import(&env e, &scopes sc,
vec[ident] path, &span sp) -> option::t[def] {
auto path_len = vec::len(path); auto path_len = vec::len(path);
auto dcur = lookup_in_scope_strict(e, sc, sp, path.(0), ns_module); auto dcur = lookup_in_scope_strict(e, sc, sp, path.(0), ns_module);
auto i = 1u; auto i = 1u;
while (true) { while (true && option::is_some(dcur)) {
if (i == path_len) { break; } if (i == path_len) { break; }
dcur = dcur =
lookup_in_mod_strict(e, dcur, sp, path.(i), ns_module, outside); lookup_in_mod_strict(e, option::get(dcur),
sp, path.(i), ns_module, outside);
i += 1u; i += 1u;
} }
alt (dcur) { if (i == path_len) {
alt (option::get(dcur)) {
case (ast::def_mod(?def_id)) { ret dcur; } case (ast::def_mod(?def_id)) { ret dcur; }
case (ast::def_native_mod(?def_id)) { ret dcur; } case (ast::def_native_mod(?def_id)) { ret dcur; }
case (_) { case (_) {
e.sess.span_fatal(sp, e.sess.span_err(sp,
str::connect(path, "::") + str::connect(path, "::") +
" does not name a module."); " does not name a module.");
ret none;
} }
} }
} else {
ret none;
}
} }
fn resolve_constr(@env e, &def_id d_id, &@ast::constr c, &scopes sc, fn resolve_constr(@env e, &def_id d_id, &@ast::constr c, &scopes sc,
&vt[scopes] v) { &vt[scopes] v) {
let def new_def = auto new_def =
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents, ns_value); lookup_path_strict(*e, sc, c.span, c.node.path.node.idents, ns_value);
alt (new_def) { if (option::is_some(new_def)) {
alt (option::get(new_def)) {
case (ast::def_fn(?pred_id)) { case (ast::def_fn(?pred_id)) {
let ty::constr_general[uint] c_ = let ty::constr_general[uint] c_ =
rec(path=c.node.path, args=c.node.args, id=pred_id); rec(path=c.node.path, args=c.node.args, id=pred_id);
@ -403,11 +424,12 @@ fn resolve_constr(@env e, &def_id d_id, &@ast::constr c, &scopes sc,
add_constr(e, d_id, new_constr); add_constr(e, d_id, new_constr);
} }
case (_) { case (_) {
e.sess.span_fatal(c.span, e.sess.span_err(c.span,
"Non-predicate in constraint: " + "Non-predicate in constraint: " +
ty::path_to_str(c.node.path)); ty::path_to_str(c.node.path));
} }
} }
}
} }
fn add_constr(&@env e, &def_id d_id, &ty::constr_def c) { fn add_constr(&@env e, &def_id d_id, &ty::constr_def c) {
@ -529,24 +551,28 @@ fn mk_unresolved_msg(&ident id, &str kind) -> str {
// 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,
namespace ns) -> def { namespace ns) -> option::t[def] {
auto n_idents = vec::len(idents); auto n_idents = vec::len(idents);
auto headns = if (n_idents == 1u) { ns } else { ns_module }; auto headns = if (n_idents == 1u) { ns } else { ns_module };
auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), headns); auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), headns);
auto i = 1u; auto i = 1u;
while (i < n_idents) { while (i < n_idents && option::is_some(dcur)) {
auto curns = if (n_idents == i + 1u) { ns } else { ns_module }; auto curns = if (n_idents == i + 1u) { ns } else { ns_module };
dcur = lookup_in_mod_strict(e, dcur, sp, idents.(i), curns, outside); dcur = lookup_in_mod_strict(e, option::get(dcur),
sp, idents.(i), curns, outside);
i += 1u; i += 1u;
} }
ret dcur; ret dcur;
} }
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) -> option::t[def] {
alt (lookup_in_scope(e, sc, sp, id, ns)) { alt (lookup_in_scope(e, sc, sp, id, ns)) {
case (none) { unresolved_fatal(e, sp, id, ns_name(ns)); } case (none) {
case (some(?d)) { ret d; } unresolved_err(e, sp, id, ns_name(ns));
ret none;
}
case (some(?d)) { ret some(d); }
} }
} }
@ -796,10 +822,13 @@ 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) -> option::t[def] {
alt (lookup_in_mod(e, m, sp, id, ns, dr)) { alt (lookup_in_mod(e, m, sp, id, ns, dr)) {
case (none) { unresolved_fatal(e, sp, id, ns_name(ns)); } case (none) {
case (some(?d)) { ret d; } unresolved_err(e, sp, id, ns_name(ns));
ret none;
}
case (some(?d)) { ret some(d); }
} }
} }