mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-11 07:21:51 +00:00
Start adding support for multiple variable declarations per stmt
This adds parser support and most of the machinery for auto x = 10, y = 20; However, the above still goes wrong somewhere in typestate, causing the state checker to believe only the last variable in the list is initialized after the statement. Tim, if you have a moment, could you go over the changes to the tstate code in this patch and see where I'm going wrong? Multi-var-decls without the typestate extension Add a loop
This commit is contained in:
parent
b45d973552
commit
b9b674abe7
@ -133,7 +133,8 @@ fn visit_expr(&@ctx cx, &@ast::expr ex, &scope sc, &vt[scope] v) {
|
||||
fn visit_decl(&@ctx cx, &@ast::decl d, &scope sc, &vt[scope] v) {
|
||||
visit::visit_decl(d, sc, v);
|
||||
alt (d.node) {
|
||||
ast::decl_local(?loc) {
|
||||
ast::decl_local(?locs) {
|
||||
for (@ast::local loc in locs) {
|
||||
alt (loc.node.init) {
|
||||
some(?init) {
|
||||
if (init.op == ast::init_move) {
|
||||
@ -143,6 +144,7 @@ fn visit_decl(&@ctx cx, &@ast::decl d, &scope sc, &vt[scope] v) {
|
||||
none {}
|
||||
}
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
}
|
||||
|
@ -787,9 +787,12 @@ fn lookup_in_block(&ident name, &ast::block_ b, namespace ns) ->
|
||||
alt (st.node) {
|
||||
case (ast::stmt_decl(?d, _)) {
|
||||
alt (d.node) {
|
||||
case (ast::decl_local(?loc)) {
|
||||
if (ns == ns_value && str::eq(name, loc.node.ident)) {
|
||||
ret some(ast::def_local(local_def(loc.node.id)));
|
||||
ast::decl_local(?locs) {
|
||||
for (@ast::local loc in locs) {
|
||||
if ns == ns_value && str::eq(name, loc.node.ident) {
|
||||
ret some(ast::def_local
|
||||
(local_def(loc.node.id)));
|
||||
}
|
||||
}
|
||||
}
|
||||
case (ast::decl_item(?it)) {
|
||||
@ -1325,9 +1328,11 @@ fn check_block(@env e, &ast::block b, &() x, &vt[()] v) {
|
||||
alt (st.node) {
|
||||
case (ast::stmt_decl(?d, _)) {
|
||||
alt (d.node) {
|
||||
ast::decl_local(?loc) {
|
||||
ast::decl_local(?locs) {
|
||||
for (@ast::local loc in locs) {
|
||||
add_name(values, d.span, loc.node.ident);
|
||||
}
|
||||
}
|
||||
ast::decl_item(?it) {
|
||||
alt (it.node) {
|
||||
ast::item_tag(?variants, _) {
|
||||
|
@ -6157,9 +6157,11 @@ fn trans_stmt(&@block_ctxt cx, &ast::stmt s) -> result {
|
||||
case (ast::stmt_expr(?e, _)) { bcx = trans_expr(cx, e).bcx; }
|
||||
case (ast::stmt_decl(?d, _)) {
|
||||
alt (d.node) {
|
||||
case (ast::decl_local(?local)) {
|
||||
case (ast::decl_local(?locals)) {
|
||||
for (@ast::local local in locals) {
|
||||
bcx = init_local(bcx, local).bcx;
|
||||
}
|
||||
}
|
||||
case (ast::decl_item(?i)) { trans_item(cx.fcx.lcx, *i); }
|
||||
}
|
||||
}
|
||||
@ -6263,7 +6265,11 @@ iter block_locals(&ast::block b) -> @ast::local {
|
||||
alt (s.node) {
|
||||
case (ast::stmt_decl(?d, _)) {
|
||||
alt (d.node) {
|
||||
case (ast::decl_local(?local)) { put local; }
|
||||
case (ast::decl_local(?locals)) {
|
||||
for (@ast::local local in locals) {
|
||||
put local;
|
||||
}
|
||||
}
|
||||
case (_) {/* fall through */ }
|
||||
}
|
||||
}
|
||||
|
@ -597,13 +597,17 @@ fn trans_stmt(&@block_ctxt cx, &@ast::stmt stmt) -> @block_ctxt {
|
||||
}
|
||||
ast::stmt_decl(?d, _) {
|
||||
alt (d.node) {
|
||||
ast::decl_local(?local) { ret trans_init_local(bcx, local); }
|
||||
ast::decl_local(?locals) {
|
||||
for (@ast::local local in locals) {
|
||||
bcx = trans_init_local(bcx, local);
|
||||
}
|
||||
}
|
||||
ast::decl_item(?item) {
|
||||
trans::trans_item(bcx_lcx(bcx), *item);
|
||||
}
|
||||
}
|
||||
ret bcx;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -585,7 +585,8 @@ fn find_pre_post_stmt(&fn_ctxt fcx, &stmt s) {
|
||||
alt (s.node) {
|
||||
case (stmt_decl(?adecl, ?id)) {
|
||||
alt (adecl.node) {
|
||||
case (decl_local(?alocal)) {
|
||||
case (decl_local(?alocals)) {
|
||||
for (@local alocal in alocals) {
|
||||
alt (alocal.node.init) {
|
||||
case (some(?an_init)) {
|
||||
/* LHS always becomes initialized,
|
||||
@ -629,6 +630,7 @@ fn find_pre_post_stmt(&fn_ctxt fcx, &stmt s) {
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
case (decl_item(?anitem)) {
|
||||
clear_pp(node_id_to_ts_ann(fcx.ccx, id).conditions);
|
||||
find_pre_post_item(fcx.ccx, *anitem);
|
||||
|
@ -596,7 +596,9 @@ fn find_pre_post_state_stmt(&fn_ctxt fcx, &prestate pres, @stmt s) -> bool {
|
||||
alt (s.node) {
|
||||
case (stmt_decl(?adecl, ?id)) {
|
||||
alt (adecl.node) {
|
||||
case (decl_local(?alocal)) {
|
||||
case (decl_local(?alocals)) {
|
||||
auto changed = false;
|
||||
for (@local alocal in alocals) {
|
||||
alt (alocal.node.init) {
|
||||
case (some(?an_init)) {
|
||||
auto changed = set_prestate(stmt_ann, pres) |
|
||||
@ -646,9 +648,7 @@ fn find_pre_post_state_stmt(&fn_ctxt fcx, &prestate pres, @stmt s) -> bool {
|
||||
/* important to do this in one step to ensure
|
||||
termination (don't want to set changed to true
|
||||
for intermediate changes) */
|
||||
ret changed | set_poststate(stmt_ann, post);
|
||||
|
||||
|
||||
changed |= set_poststate(stmt_ann, post);
|
||||
}
|
||||
case (none) {
|
||||
// let int = x; => x is uninit in poststate
|
||||
@ -656,10 +656,11 @@ fn find_pre_post_state_stmt(&fn_ctxt fcx, &prestate pres, @stmt s) -> bool {
|
||||
clear_in_poststate_ident(fcx, alocal.node.id,
|
||||
alocal.node.ident, id);
|
||||
set_prestate(stmt_ann, pres);
|
||||
ret false;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret changed;
|
||||
}
|
||||
case (decl_item(?an_item)) {
|
||||
ret set_prestate(stmt_ann, pres) |
|
||||
set_poststate(stmt_ann, pres);
|
||||
|
@ -2584,7 +2584,9 @@ fn check_stmt(&@fn_ctxt fcx, &@ast::stmt stmt) {
|
||||
case (ast::stmt_decl(?decl, ?id)) {
|
||||
node_id = id;
|
||||
alt (decl.node) {
|
||||
case (ast::decl_local(?l)) { check_decl_local(fcx, l); }
|
||||
case (ast::decl_local(?ls)) {
|
||||
for (@ast::local l in ls) { check_decl_local(fcx, l); }
|
||||
}
|
||||
case (ast::decl_item(_)) {/* ignore for now */ }
|
||||
}
|
||||
}
|
||||
|
@ -252,7 +252,7 @@ type local = spanned[local_];
|
||||
|
||||
type decl = spanned[decl_];
|
||||
|
||||
tag decl_ { decl_local(@local); decl_item(@item); }
|
||||
tag decl_ { decl_local((@local)[]); decl_item(@item); }
|
||||
|
||||
type arm = rec((@pat)[] pats, block block);
|
||||
|
||||
|
@ -298,9 +298,8 @@ fn noop_fold_pat(&pat_ p, ast_fold fld) -> pat_ {
|
||||
|
||||
fn noop_fold_decl(&decl_ d, ast_fold fld) -> decl_ {
|
||||
ret alt (d) {
|
||||
// local really doesn't need its own fold...
|
||||
case (decl_local(?l)) {
|
||||
decl_local(fld.fold_local(l))
|
||||
case (decl_local(?ls)) {
|
||||
decl_local(ivec::map(fld.fold_local, ls))
|
||||
}
|
||||
case (decl_item(?it)) { decl_item(fld.fold_item(it)) }
|
||||
}
|
||||
|
@ -1543,14 +1543,22 @@ fn parse_auto_local(&parser p) -> @ast::local {
|
||||
|
||||
fn parse_let(&parser p) -> @ast::decl {
|
||||
auto lo = p.get_last_lo_pos();
|
||||
auto local = parse_typed_local(p);
|
||||
ret @spanned(lo, p.get_hi_pos(), ast::decl_local(local));
|
||||
auto locals = ~[parse_typed_local(p)];
|
||||
while p.peek() == token::COMMA {
|
||||
p.bump();
|
||||
locals += ~[parse_typed_local(p)];
|
||||
}
|
||||
ret @spanned(lo, p.get_hi_pos(), ast::decl_local(locals));
|
||||
}
|
||||
|
||||
fn parse_auto(&parser p) -> @ast::decl {
|
||||
auto lo = p.get_last_lo_pos();
|
||||
auto local = parse_auto_local(p);
|
||||
ret @spanned(lo, p.get_hi_pos(), ast::decl_local(local));
|
||||
auto locals = ~[parse_auto_local(p)];
|
||||
while p.peek() == token::COMMA {
|
||||
p.bump();
|
||||
locals += ~[parse_auto_local(p)];
|
||||
}
|
||||
ret @spanned(lo, p.get_hi_pos(), ast::decl_local(locals));
|
||||
}
|
||||
|
||||
fn parse_stmt(&parser p) -> @ast::stmt {
|
||||
|
@ -1045,10 +1045,10 @@ fn print_expr(&ps s, &@ast::expr expr) {
|
||||
fn print_decl(&ps s, &@ast::decl decl) {
|
||||
maybe_print_comment(s, decl.span.lo);
|
||||
alt (decl.node) {
|
||||
case (ast::decl_local(?loc)) {
|
||||
case (ast::decl_local(?locs)) {
|
||||
space_if_not_hardbreak(s);
|
||||
ibox(s, indent_unit);
|
||||
alt (loc.node.ty) {
|
||||
alt (locs.(0).node.ty) {
|
||||
case (some(?ty)) {
|
||||
word_nbsp(s, "let");
|
||||
print_type(s, *ty);
|
||||
@ -1058,19 +1058,23 @@ fn print_decl(&ps s, &@ast::decl decl) {
|
||||
word_nbsp(s, "auto");
|
||||
}
|
||||
}
|
||||
fn print_local(&ps s, &@ast::local loc) {
|
||||
word(s.s, loc.node.ident);
|
||||
alt (loc.node.init) {
|
||||
case (some(?init)) {
|
||||
alt loc.node.init {
|
||||
some(?init) {
|
||||
space(s.s);
|
||||
alt (init.op) {
|
||||
case (ast::init_assign) { word_space(s, "="); }
|
||||
case (ast::init_move) { word_space(s, "<-"); }
|
||||
case (ast::init_recv) { word_space(s, "|>"); }
|
||||
alt init.op {
|
||||
ast::init_assign { word_space(s, "="); }
|
||||
ast::init_move { word_space(s, "<-"); }
|
||||
ast::init_recv { word_space(s, "|>"); }
|
||||
}
|
||||
print_expr(s, init.expr);
|
||||
}
|
||||
case (_) { }
|
||||
_ { }
|
||||
}
|
||||
}
|
||||
fn local_span(&@ast::local loc) -> codemap::span { ret loc.span; }
|
||||
commasep_cmnt(s, consistent, locs, print_local, local_span);
|
||||
end(s);
|
||||
}
|
||||
case (ast::decl_item(?item)) { print_item(s, item); }
|
||||
|
@ -249,8 +249,8 @@ fn visit_stmt[E](&@stmt s, &E e, &vt[E] v) {
|
||||
|
||||
fn visit_decl[E](&@decl d, &E e, &vt[E] v) {
|
||||
alt (d.node) {
|
||||
case (decl_local(?loc)) {
|
||||
v.visit_local(loc, e, v);
|
||||
case (decl_local(?locs)) {
|
||||
for (@ast::local loc in locs) { v.visit_local(loc, e, v); }
|
||||
}
|
||||
case (decl_item(?it)) { v.visit_item(it, e, v); }
|
||||
}
|
||||
|
@ -256,7 +256,9 @@ fn walk_decl(&ast_visitor v, @ast::decl d) {
|
||||
if (!v.keep_going()) { ret; }
|
||||
v.visit_decl_pre(d);
|
||||
alt (d.node) {
|
||||
case (ast::decl_local(?loc)) { walk_local(v, loc); }
|
||||
case (ast::decl_local(?locs)) {
|
||||
for (@ast::local loc in locs) { walk_local(v, loc); }
|
||||
}
|
||||
case (ast::decl_item(?it)) { walk_item(v, it); }
|
||||
}
|
||||
v.visit_decl_post(d);
|
||||
|
Loading…
Reference in New Issue
Block a user