aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorPatrick Walton <[email protected]>2010-12-13 16:39:35 -0800
committerPatrick Walton <[email protected]>2010-12-13 16:39:35 -0800
commit0ef65780ca1c23ddb4d0cfb294704e51c4f418f7 (patch)
tree56b155b84c02d6c7fe0a5c2d353195099047d283 /src
parentrustc: Hack to get rid of passing i1 types for unit around in most cases, sug... (diff)
downloadrust-0ef65780ca1c23ddb4d0cfb294704e51c4f418f7.tar.xz
rust-0ef65780ca1c23ddb4d0cfb294704e51c4f418f7.zip
rustc: Check patterns before arm blocks in alt expressions; this will be needed for binding type resolution
Diffstat (limited to 'src')
-rw-r--r--src/comp/middle/typeck.rs40
1 files changed, 31 insertions, 9 deletions
diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs
index 346e40ab..85ee74da 100644
--- a/src/comp/middle/typeck.rs
+++ b/src/comp/middle/typeck.rs
@@ -1581,6 +1581,10 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
check (fcx.ccx.item_types.contains_key(variant_id));
t = fcx.ccx.item_types.get(variant_id);
}
+ case (ast.def_binding(?id)) {
+ check (fcx.locals.contains_key(id));
+ t = fcx.locals.get(id);
+ }
case (_) {
// FIXME: handle other names.
fcx.ccx.sess.unimpl("definition variant for: "
@@ -1674,30 +1678,48 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr {
case (ast.expr_alt(?expr, ?arms, _)) {
auto expr_0 = check_expr(fcx, expr);
+
+ // Typecheck the patterns first, so that we get types for all the
+ // bindings.
auto pattern_ty = expr_ty(expr_0);
- auto result_ty = next_ty_var(fcx);
- let vec[ast.arm] arms_0 = vec();
+ let vec[@ast.pat] pats_0 = vec();
for (ast.arm arm in arms) {
auto pat_0 = check_pat(fcx, arm.pat);
pattern_ty = demand(fcx, pat_0.span, pattern_ty,
pat_ty(pat_0));
+ pats_0 += vec(pat_0);
+ }
+
+ let vec[@ast.pat] pats_1 = vec();
+ for (@ast.pat pat_0 in pats_0) {
+ pats_1 += vec(demand_pat(fcx, pattern_ty, pat_0));
+ }
+
+ // Now typecheck the blocks.
+ auto result_ty = next_ty_var(fcx);
+
+ let vec[ast.block] blocks_0 = vec();
+ for (ast.arm arm in arms) {
auto block_0 = check_block(fcx, arm.block);
result_ty = demand(fcx, block_0.span, result_ty,
block_ty(block_0));
- arms_0 += vec(rec(pat=pat_0, block=block_0, index=arm.index));
+ blocks_0 += vec(block_0);
}
- auto expr_1 = demand_expr(fcx, pattern_ty, expr);
-
let vec[ast.arm] arms_1 = vec();
- for (ast.arm arm_0 in arms_0) {
- auto pat_1 = demand_pat(fcx, pattern_ty, arm_0.pat);
- auto block_1 = demand_block(fcx, result_ty, arm_0.block);
- auto arm_1 = rec(pat=pat_1, block=block_1, index=arm_0.index);
+ auto i = 0u;
+ for (ast.block block_0 in blocks_0) {
+ auto block_1 = demand_block(fcx, result_ty, block_0);
+ auto pat_1 = pats_1.(i);
+ auto arm = arms.(i);
+ auto arm_1 = rec(pat=pat_1, block=block_1, index=arm.index);
arms_1 += vec(arm_1);
+ i += 1u;
}
+ auto expr_1 = demand_expr(fcx, pattern_ty, expr_0);
+
auto ann = ast.ann_type(result_ty);
ret @fold.respan[ast.expr_](expr.span,
ast.expr_alt(expr_1, arms_1, ann));