Skip to content

Commit b8ab9ea

Browse files
committed
rustc: Make name resolution errors less fatal
Failure happens at the end of name resolution Issue #440
1 parent 92a8ae9 commit b8ab9ea

File tree

1 file changed

+80
-51
lines changed

1 file changed

+80
-51
lines changed

src/comp/middle/resolve.rs

Lines changed: 80 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -236,8 +236,11 @@ fn map_crate(&@env e, &@ast::crate c) {
236236
case (
237237
//if it really is a glob import, that is
238238
ast::view_item_import_glob(?path, _)) {
239-
find_mod(e, sc).glob_imports +=
240-
[follow_import(*e, sc, path, vi.span)];
239+
auto imp = follow_import(*e, sc, path, vi.span);
240+
if (option::is_some(imp)) {
241+
find_mod(e, sc).glob_imports +=
242+
[option::get(imp)];
243+
}
241244
}
242245
case (_) { }
243246
}
@@ -266,14 +269,15 @@ fn resolve_names(&@env e, &@ast::crate c) {
266269
visit_fn=bind visit_fn_with_scope(e, _, _, _, _, _, _, _, _)
267270
with *visit::default_visitor());
268271
visit::visit_crate(*c, cons(scope_crate(c), @nil), visit::vtor(v));
272+
e.sess.abort_if_errors();
273+
269274
fn walk_expr(@env e, &@ast::expr exp, &scopes sc, &vt[scopes] v) {
270275
visit_expr_with_scope(exp, sc, v);
271276
alt (exp.node) {
272277
case (ast::expr_path(?p, ?a)) {
273-
auto df =
274-
lookup_path_strict(*e, sc, exp.span, p.node.idents,
275-
ns_value);
276-
e.def_map.insert(a.id, df);
278+
maybe_insert(e, a.id,
279+
lookup_path_strict(*e, sc, exp.span,
280+
p.node.idents, ns_value));
277281
}
278282
case (_) { }
279283
}
@@ -282,19 +286,17 @@ fn resolve_names(&@env e, &@ast::crate c) {
282286
visit::visit_ty(t, sc, v);
283287
alt (t.node) {
284288
case (ast::ty_path(?p, ?a)) {
285-
auto new_def =
286-
lookup_path_strict(*e, sc, t.span, p.node.idents,
287-
ns_type);
288-
e.def_map.insert(a.id, new_def);
289+
maybe_insert(e, a.id,
290+
lookup_path_strict(*e, sc, t.span,
291+
p.node.idents, ns_type));
289292
}
290293
case (_) { }
291294
}
292295
}
293296
fn walk_constr(@env e, &@ast::constr c, &scopes sc, &vt[scopes] v) {
294-
auto new_def =
295-
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents,
296-
ns_value);
297-
e.def_map.insert(c.node.ann.id, new_def);
297+
maybe_insert(e, c.node.ann.id,
298+
lookup_path_strict(*e, sc, c.span,
299+
c.node.path.node.idents, ns_value));
298300
}
299301
fn walk_arm(@env e, &ast::arm a, &scopes sc, &vt[scopes] v) {
300302
walk_pat(*e, sc, a.pat);
@@ -306,21 +308,32 @@ fn resolve_names(&@env e, &@ast::crate c) {
306308
auto fnd =
307309
lookup_path_strict(e, sc, p.span, p.node.idents,
308310
ns_value);
309-
alt (fnd) {
310-
case (ast::def_variant(?did, ?vid)) {
311-
e.def_map.insert(a.id, fnd);
312-
}
313-
case (_) {
314-
e.sess.span_fatal(p.span,
315-
"not a tag variant: " +
311+
if (option::is_some(fnd)) {
312+
alt (option::get(fnd)) {
313+
case (ast::def_variant(?did, ?vid)) {
314+
e.def_map.insert(a.id, option::get(fnd));
315+
for (@ast::pat child in children) {
316+
walk_pat(e, sc, child);
317+
}
318+
}
319+
case (_) {
320+
e.sess.span_err(p.span,
321+
"not a tag variant: " +
316322
ast::path_name(p));
323+
}
317324
}
318325
}
319-
for (@ast::pat child in children) { walk_pat(e, sc, child); }
320326
}
321327
case (_) { }
322328
}
323329
}
330+
331+
fn maybe_insert(@env e, uint id,
332+
option::t[def] def) {
333+
if (option::is_some(def)) {
334+
e.def_map.insert(id, option::get(def));
335+
}
336+
}
324337
}
325338

326339

@@ -370,42 +383,51 @@ fn visit_expr_with_scope(&@ast::expr x, &scopes sc, &vt[scopes] v) {
370383
visit::visit_expr(x, new_sc, v);
371384
}
372385

373-
fn follow_import(&env e, &scopes sc, vec[ident] path, &span sp) -> def {
386+
fn follow_import(&env e, &scopes sc,
387+
vec[ident] path, &span sp) -> option::t[def] {
374388
auto path_len = vec::len(path);
375389
auto dcur = lookup_in_scope_strict(e, sc, sp, path.(0), ns_module);
376390
auto i = 1u;
377-
while (true) {
391+
while (true && option::is_some(dcur)) {
378392
if (i == path_len) { break; }
379393
dcur =
380-
lookup_in_mod_strict(e, dcur, sp, path.(i), ns_module, outside);
394+
lookup_in_mod_strict(e, option::get(dcur),
395+
sp, path.(i), ns_module, outside);
381396
i += 1u;
382397
}
383-
alt (dcur) {
384-
case (ast::def_mod(?def_id)) { ret dcur; }
385-
case (ast::def_native_mod(?def_id)) { ret dcur; }
386-
case (_) {
387-
e.sess.span_fatal(sp,
388-
str::connect(path, "::") +
398+
if (i == path_len) {
399+
alt (option::get(dcur)) {
400+
case (ast::def_mod(?def_id)) { ret dcur; }
401+
case (ast::def_native_mod(?def_id)) { ret dcur; }
402+
case (_) {
403+
e.sess.span_err(sp,
404+
str::connect(path, "::") +
389405
" does not name a module.");
406+
ret none;
407+
}
390408
}
409+
} else {
410+
ret none;
391411
}
392412
}
393413

394414
fn resolve_constr(@env e, &def_id d_id, &@ast::constr c, &scopes sc,
395415
&vt[scopes] v) {
396-
let def new_def =
416+
auto new_def =
397417
lookup_path_strict(*e, sc, c.span, c.node.path.node.idents, ns_value);
398-
alt (new_def) {
399-
case (ast::def_fn(?pred_id)) {
400-
let ty::constr_general[uint] c_ =
401-
rec(path=c.node.path, args=c.node.args, id=pred_id);
402-
let ty::constr_def new_constr = respan(c.span, c_);
403-
add_constr(e, d_id, new_constr);
404-
}
405-
case (_) {
406-
e.sess.span_fatal(c.span,
407-
"Non-predicate in constraint: " +
418+
if (option::is_some(new_def)) {
419+
alt (option::get(new_def)) {
420+
case (ast::def_fn(?pred_id)) {
421+
let ty::constr_general[uint] c_ =
422+
rec(path=c.node.path, args=c.node.args, id=pred_id);
423+
let ty::constr_def new_constr = respan(c.span, c_);
424+
add_constr(e, d_id, new_constr);
425+
}
426+
case (_) {
427+
e.sess.span_err(c.span,
428+
"Non-predicate in constraint: " +
408429
ty::path_to_str(c.node.path));
430+
}
409431
}
410432
}
411433
}
@@ -529,24 +551,28 @@ fn mk_unresolved_msg(&ident id, &str kind) -> str {
529551

530552
// Lookup helpers
531553
fn lookup_path_strict(&env e, &scopes sc, &span sp, vec[ident] idents,
532-
namespace ns) -> def {
554+
namespace ns) -> option::t[def] {
533555
auto n_idents = vec::len(idents);
534556
auto headns = if (n_idents == 1u) { ns } else { ns_module };
535557
auto dcur = lookup_in_scope_strict(e, sc, sp, idents.(0), headns);
536558
auto i = 1u;
537-
while (i < n_idents) {
559+
while (i < n_idents && option::is_some(dcur)) {
538560
auto curns = if (n_idents == i + 1u) { ns } else { ns_module };
539-
dcur = lookup_in_mod_strict(e, dcur, sp, idents.(i), curns, outside);
561+
dcur = lookup_in_mod_strict(e, option::get(dcur),
562+
sp, idents.(i), curns, outside);
540563
i += 1u;
541564
}
542565
ret dcur;
543566
}
544567

545568
fn lookup_in_scope_strict(&env e, scopes sc, &span sp, &ident id,
546-
namespace ns) -> def {
569+
namespace ns) -> option::t[def] {
547570
alt (lookup_in_scope(e, sc, sp, id, ns)) {
548-
case (none) { unresolved_fatal(e, sp, id, ns_name(ns)); }
549-
case (some(?d)) { ret d; }
571+
case (none) {
572+
unresolved_err(e, sp, id, ns_name(ns));
573+
ret none;
574+
}
575+
case (some(?d)) { ret some(d); }
550576
}
551577
}
552578

@@ -796,10 +822,13 @@ fn found_def_item(&@ast::item i, namespace ns) -> option::t[def] {
796822
}
797823

798824
fn lookup_in_mod_strict(&env e, def m, &span sp, &ident id, namespace ns,
799-
dir dr) -> def {
825+
dir dr) -> option::t[def] {
800826
alt (lookup_in_mod(e, m, sp, id, ns, dr)) {
801-
case (none) { unresolved_fatal(e, sp, id, ns_name(ns)); }
802-
case (some(?d)) { ret d; }
827+
case (none) {
828+
unresolved_err(e, sp, id, ns_name(ns));
829+
ret none;
830+
}
831+
case (some(?d)) { ret some(d); }
803832
}
804833
}
805834

0 commit comments

Comments
 (0)