Skip to content

Commit 16e5760

Browse files
committed
Fix bug in safe-reference checker
At some point, a refactor broke the code that handled local declarations to no longer descend into the initializer expressions. Closes #1846
1 parent 9ff5ba0 commit 16e5760

File tree

3 files changed

+24
-36
lines changed

3 files changed

+24
-36
lines changed

src/comp/middle/alias.rs

Lines changed: 16 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
112112
}
113113
ast::expr_alt(input, arms, _) { check_alt(*cx, input, arms, sc, v); }
114114
ast::expr_for(decl, seq, blk) {
115-
v.visit_expr(seq, sc, v);
115+
visit_expr(cx, seq, sc, v);
116116
check_loop(*cx, sc) {|| check_for(*cx, decl, seq, blk, sc, v); }
117117
}
118118
ast::expr_path(pt) {
@@ -125,11 +125,13 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
125125
handled = false;
126126
}
127127
ast::expr_move(dest, src) {
128-
check_assign(cx, dest, src, sc, v);
128+
visit_expr(cx, src, sc, v);
129+
check_lval(cx, dest, sc, v);
129130
check_lval(cx, src, sc, v);
130131
}
131132
ast::expr_assign(dest, src) | ast::expr_assign_op(_, dest, src) {
132-
check_assign(cx, dest, src, sc, v);
133+
visit_expr(cx, src, sc, v);
134+
check_lval(cx, dest, sc, v);
133135
}
134136
ast::expr_if(c, then, els) { check_if(c, then, els, sc, v); }
135137
ast::expr_while(_, _) | ast::expr_do_while(_, _) {
@@ -153,6 +155,8 @@ fn visit_block(cx: @ctx, b: ast::blk, sc: scope, v: vt<scope>) {
153155
some(init) {
154156
if init.op == ast::init_move {
155157
check_lval(cx, init.expr, sc, v);
158+
} else {
159+
visit_expr(cx, init.expr, sc, v);
156160
}
157161
}
158162
none { }
@@ -354,7 +358,7 @@ fn check_alt(cx: ctx, input: @ast::expr, arms: [ast::arm], sc: scope,
354358
}
355359
*sc.invalid = orig_invalid;
356360
visit::visit_arm(a, {bs: new_bs with sc}, v);
357-
all_invalid = append_invalid(all_invalid, *sc.invalid, orig_invalid);
361+
all_invalid = join_invalid(all_invalid, *sc.invalid);
358362
}
359363
*sc.invalid = all_invalid;
360364
}
@@ -423,12 +427,6 @@ fn check_lval(cx: @ctx, dest: @ast::expr, sc: scope, v: vt<scope>) {
423427
}
424428
}
425429

426-
fn check_assign(cx: @ctx, dest: @ast::expr, src: @ast::expr, sc: scope,
427-
v: vt<scope>) {
428-
visit_expr(cx, src, sc, v);
429-
check_lval(cx, dest, sc, v);
430-
}
431-
432430
fn check_if(c: @ast::expr, then: ast::blk, els: option<@ast::expr>,
433431
sc: scope, v: vt<scope>) {
434432
v.visit_expr(c, sc, v);
@@ -437,7 +435,7 @@ fn check_if(c: @ast::expr, then: ast::blk, els: option<@ast::expr>,
437435
let then_invalid = *sc.invalid;
438436
*sc.invalid = orig_invalid;
439437
visit::visit_expr_opt(els, sc, v);
440-
*sc.invalid = append_invalid(*sc.invalid, then_invalid, orig_invalid);
438+
*sc.invalid = join_invalid(*sc.invalid, then_invalid);
441439
}
442440

443441
fn check_loop(cx: ctx, sc: scope, checker: fn()) {
@@ -672,24 +670,14 @@ fn find_invalid(id: node_id, lst: list<@invalid>)
672670
ret none;
673671
}
674672

675-
fn append_invalid(dest: list<@invalid>, src: list<@invalid>,
676-
stop: list<@invalid>) -> list<@invalid> {
677-
let cur = src, dest = dest;
678-
while cur != stop {
679-
alt cur {
680-
list::cons(head, tail) {
681-
if is_none(find_invalid(head.node_id, dest)) {
682-
dest = list::cons(head, @dest);
683-
}
684-
cur = *tail;
685-
}
686-
list::nil {
687-
fail "append_invalid: stop doesn't appear to be \
688-
a postfix of src";
689-
}
690-
}
673+
fn join_invalid(a: list<@invalid>, b: list<@invalid>) -> list<@invalid> {
674+
let result = a;
675+
list::iter(b) {|elt|
676+
let found = false;
677+
list::iter(a) {|e| if e == elt { found = true; } }
678+
if !found { result = list::cons(elt, @result); }
691679
}
692-
ret dest;
680+
result
693681
}
694682

695683
fn filter_invalid(src: list<@invalid>, bs: [binding]) -> list<@invalid> {

src/comp/middle/resolve.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1378,13 +1378,13 @@ fn lookup_glob_in_mod(e: env, info: @indexed_mod, sp: span, id: ident,
13781378
// absence takes the place of todo()
13791379
if !info.glob_imported_names.contains_key(id) {
13801380
info.glob_imported_names.insert(id, glob_resolving(sp));
1381-
let val = lookup_in_globs(e, info.glob_imports, sp, id,
1382-
// kludge
1383-
(if wanted_ns == ns_val(ns_a_enum)
1384-
{ ns_val(ns_a_enum) }
1385-
else { ns_val(ns_any_value) }), dr);
1386-
let typ = lookup_in_globs(e, info.glob_imports, sp, id, ns_type, dr);
1387-
let md = lookup_in_globs(e, info.glob_imports, sp, id, ns_module, dr);
1381+
// kludge
1382+
let val_ns = if wanted_ns == ns_val(ns_a_enum) { ns_val(ns_a_enum) }
1383+
else { ns_val(ns_any_value) };
1384+
let globs = info.glob_imports;
1385+
let val = lookup_in_globs(e, globs, sp, id, val_ns, dr);
1386+
let typ = lookup_in_globs(e, globs, sp, id, ns_type, dr);
1387+
let md = lookup_in_globs(e, globs, sp, id, ns_module, dr);
13881388
info.glob_imported_names.insert(id, glob_resolved(val, typ, md));
13891389
}
13901390
alt info.glob_imported_names.get(id) {

src/test/compile-fail/cross-crate-glob-collision.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// error-pattern:'member' is glob-imported from multiple different modules
1+
// error-pattern: is glob-imported from multiple different modules
22
// issue #482
33

44
use std;

0 commit comments

Comments
 (0)