diff --git a/src/comp/front/ast.rs b/src/comp/front/ast.rs index 7106515083e..11db3eedc31 100644 --- a/src/comp/front/ast.rs +++ b/src/comp/front/ast.rs @@ -33,6 +33,7 @@ tag def { def_variant(def_id /* tag */, def_id /* variant */); def_ty(def_id); def_ty_arg(def_id); + def_binding(def_id); } type crate = spanned[crate_]; @@ -124,7 +125,7 @@ tag decl_ { 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 field = rec(mutability mut, ident ident, @expr expr); diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index f8db2f71b14..decb28e1f47 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -817,8 +817,9 @@ impure fn parse_alt_expr(parser p) -> @ast.expr { expect(p, token.LPAREN); auto pat = parse_pat(p); expect(p, token.RPAREN); + auto index = index_arm(pat); 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 (?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); } +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] { alt (stmt.node) { case (ast.stmt_expr(?e)) { ret some[@ast.expr](e); } diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 54e098384c5..521b433e756 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -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); auto ppat = fold_pat(env_, fld, a.pat); 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 { diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 491d9e4a4c2..08175e7893e 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -18,6 +18,7 @@ tag scope { scope_crate(@ast.crate); scope_item(@ast.item); scope_block(ast.block); + scope_arm(ast.arm); } 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 (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]; } @@ -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); } +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 { 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(_,_,_,_), update_env_for_crate = bind update_env_for_crate(_,_), 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 ); auto e = rec(scopes = nil[scope],