rustc: Resolve pattern bindings
This commit is contained in:
parent
0509b1b9d7
commit
de118d79b6
4 changed files with 40 additions and 4 deletions
|
@ -33,6 +33,7 @@ tag def {
|
||||||
def_variant(def_id /* tag */, def_id /* variant */);
|
def_variant(def_id /* tag */, def_id /* variant */);
|
||||||
def_ty(def_id);
|
def_ty(def_id);
|
||||||
def_ty_arg(def_id);
|
def_ty_arg(def_id);
|
||||||
|
def_binding(def_id);
|
||||||
}
|
}
|
||||||
|
|
||||||
type crate = spanned[crate_];
|
type crate = spanned[crate_];
|
||||||
|
@ -124,7 +125,7 @@ tag decl_ {
|
||||||
decl_item(@item);
|
decl_item(@item);
|
||||||
}
|
}
|
||||||
|
|
||||||
type arm = rec(@pat pat, block block);
|
type arm = rec(@pat pat, block block, hashmap[ident,def_id] index);
|
||||||
|
|
||||||
type elt = rec(mutability mut, @expr expr);
|
type elt = rec(mutability mut, @expr expr);
|
||||||
type field = rec(mutability mut, ident ident, @expr expr);
|
type field = rec(mutability mut, ident ident, @expr expr);
|
||||||
|
|
|
@ -817,8 +817,9 @@ impure fn parse_alt_expr(parser p) -> @ast.expr {
|
||||||
expect(p, token.LPAREN);
|
expect(p, token.LPAREN);
|
||||||
auto pat = parse_pat(p);
|
auto pat = parse_pat(p);
|
||||||
expect(p, token.RPAREN);
|
expect(p, token.RPAREN);
|
||||||
|
auto index = index_arm(pat);
|
||||||
auto block = parse_block(p);
|
auto block = parse_block(p);
|
||||||
arms += vec(rec(pat=pat, block=block));
|
arms += vec(rec(pat=pat, block=block, index=index));
|
||||||
}
|
}
|
||||||
case (token.RBRACE) { /* empty */ }
|
case (token.RBRACE) { /* empty */ }
|
||||||
case (?tok) {
|
case (?tok) {
|
||||||
|
@ -1082,6 +1083,24 @@ fn index_block(vec[@ast.stmt] stmts, option.t[@ast.expr] expr) -> ast.block_ {
|
||||||
ret rec(stmts=stmts, expr=expr, index=index);
|
ret rec(stmts=stmts, expr=expr, index=index);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn index_arm(@ast.pat pat) -> hashmap[ast.ident,ast.def_id] {
|
||||||
|
fn do_index_arm(&hashmap[ast.ident,ast.def_id] index, @ast.pat pat) {
|
||||||
|
alt (pat.node) {
|
||||||
|
case (ast.pat_bind(?i, ?def_id, _)) { index.insert(i, def_id); }
|
||||||
|
case (ast.pat_wild(_)) { /* empty */ }
|
||||||
|
case (ast.pat_tag(_, ?pats, _)) {
|
||||||
|
for (@ast.pat p in pats) {
|
||||||
|
do_index_arm(index, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto index = new_str_hash[ast.def_id]();
|
||||||
|
do_index_arm(index, pat);
|
||||||
|
ret index;
|
||||||
|
}
|
||||||
|
|
||||||
fn stmt_to_expr(@ast.stmt stmt) -> option.t[@ast.expr] {
|
fn stmt_to_expr(@ast.stmt stmt) -> option.t[@ast.expr] {
|
||||||
alt (stmt.node) {
|
alt (stmt.node) {
|
||||||
case (ast.stmt_expr(?e)) { ret some[@ast.expr](e); }
|
case (ast.stmt_expr(?e)) { ret some[@ast.expr](e); }
|
||||||
|
|
|
@ -574,7 +574,7 @@ fn fold_arm[ENV](&ENV env, ast_fold[ENV] fld, &arm a) -> arm {
|
||||||
let ENV env_ = fld.update_env_for_arm(env, a);
|
let ENV env_ = fld.update_env_for_arm(env, a);
|
||||||
auto ppat = fold_pat(env_, fld, a.pat);
|
auto ppat = fold_pat(env_, fld, a.pat);
|
||||||
auto bblock = fold_block(env_, fld, a.block);
|
auto bblock = fold_block(env_, fld, a.block);
|
||||||
ret rec(pat=ppat, block=bblock);
|
ret rec(pat=ppat, block=bblock, index=a.index);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn fold_arg[ENV](&ENV env, ast_fold[ENV] fld, &arg a) -> arg {
|
fn fold_arg[ENV](&ENV env, ast_fold[ENV] fld, &arg a) -> arg {
|
||||||
|
|
|
@ -18,6 +18,7 @@ tag scope {
|
||||||
scope_crate(@ast.crate);
|
scope_crate(@ast.crate);
|
||||||
scope_item(@ast.item);
|
scope_item(@ast.item);
|
||||||
scope_block(ast.block);
|
scope_block(ast.block);
|
||||||
|
scope_arm(ast.arm);
|
||||||
}
|
}
|
||||||
|
|
||||||
type env = rec(list[scope] scopes,
|
type env = rec(list[scope] scopes,
|
||||||
|
@ -120,6 +121,15 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] {
|
||||||
case (_) { /* fall through */ }
|
case (_) { /* fall through */ }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
case (scope_arm(?a)) {
|
||||||
|
alt (a.index.find(i)) {
|
||||||
|
case (some[ast.def_id](?did)) {
|
||||||
|
ret some[def](ast.def_binding(did));
|
||||||
|
}
|
||||||
|
case (_) { /* fall through */ }
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ret none[def];
|
ret none[def];
|
||||||
}
|
}
|
||||||
|
@ -189,6 +199,11 @@ fn update_env_for_block(&env e, &ast.block b) -> env {
|
||||||
ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
|
ret rec(scopes = cons[scope](scope_block(b), @e.scopes) with e);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn update_env_for_arm(&env e, &ast.arm p) -> env {
|
||||||
|
log "update_env_for_arm";
|
||||||
|
ret rec(scopes = cons[scope](scope_arm(p), @e.scopes) with e);
|
||||||
|
}
|
||||||
|
|
||||||
fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
|
fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
|
||||||
|
|
||||||
let fold.ast_fold[env] fld = fold.new_identity_fold[env]();
|
let fold.ast_fold[env] fld = fold.new_identity_fold[env]();
|
||||||
|
@ -197,7 +212,8 @@ fn resolve_crate(session.session sess, @ast.crate crate) -> @ast.crate {
|
||||||
fold_ty_path = bind fold_ty_path(_,_,_,_),
|
fold_ty_path = bind fold_ty_path(_,_,_,_),
|
||||||
update_env_for_crate = bind update_env_for_crate(_,_),
|
update_env_for_crate = bind update_env_for_crate(_,_),
|
||||||
update_env_for_item = bind update_env_for_item(_,_),
|
update_env_for_item = bind update_env_for_item(_,_),
|
||||||
update_env_for_block = bind update_env_for_block(_,_)
|
update_env_for_block = bind update_env_for_block(_,_),
|
||||||
|
update_env_for_arm = bind update_env_for_arm(_,_)
|
||||||
with *fld );
|
with *fld );
|
||||||
|
|
||||||
auto e = rec(scopes = nil[scope],
|
auto e = rec(scopes = nil[scope],
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue