diff options
| author | Graydon Hoare <[email protected]> | 2010-12-01 17:08:46 -0800 |
|---|---|---|
| committer | Graydon Hoare <[email protected]> | 2010-12-01 17:09:02 -0800 |
| commit | 98a63bd1f9fda47fc34b16d9f0782022e1022277 (patch) | |
| tree | 25796c068e3219553a6b7e984d512523ddd754cf /src | |
| parent | rustc: Annotate variants with their types. This may be useful for trans! (diff) | |
| download | rust-98a63bd1f9fda47fc34b16d9f0782022e1022277.tar.xz rust-98a63bd1f9fda47fc34b16d9f0782022e1022277.zip | |
Add code to fail on non-exhaustive alt matching. Fix all cases this picked up in rustc.
Diffstat (limited to 'src')
| -rw-r--r-- | src/boot/me/trans.ml | 9 | ||||
| -rw-r--r-- | src/comp/front/parser.rs | 7 | ||||
| -rw-r--r-- | src/comp/middle/fold.rs | 20 | ||||
| -rw-r--r-- | src/comp/middle/resolve.rs | 1 | ||||
| -rw-r--r-- | src/comp/middle/trans.rs | 39 | ||||
| -rw-r--r-- | src/comp/middle/typeck.rs | 27 |
6 files changed, 89 insertions, 14 deletions
diff --git a/src/boot/me/trans.ml b/src/boot/me/trans.ml index 58cccb99..34f4d81d 100644 --- a/src/boot/me/trans.ml +++ b/src/boot/me/trans.ml @@ -4895,7 +4895,14 @@ let trans_visitor last_jump in let last_jumps = Array.map trans_arm at.Ast.alt_tag_arms in - Array.iter patch last_jumps + if not (arr_exists + (fun _ arm -> (fst arm.node) = Ast.PAT_wild) + at.Ast.alt_tag_arms) + then + trans_cond_fail "non-exhaustive match failure" + (Array.to_list last_jumps) + else + Array.iter patch last_jumps (* If we're about to drop a channel, synthesize an upcall_flush_chan. * TODO: This should rather appear in a chan dtor when chans become diff --git a/src/comp/front/parser.rs b/src/comp/front/parser.rs index ede8c637..f8d3bf07 100644 --- a/src/comp/front/parser.rs +++ b/src/comp/front/parser.rs @@ -388,6 +388,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { es.node, ast.ann_none); hi = es.span; } + case (_) { /* fall through */ } } } @@ -401,6 +402,7 @@ impure fn parse_bottom_expr(parser p) -> @ast.expr { ret @spanned(lo, hi, ast.expr_lit(lit, ast.ann_none)); } + case (_) { /* fall through */ } } auto e = parse_expr(p); hi = p.get_span(); @@ -590,6 +592,7 @@ impure fn parse_binops(parser p, more = true; } } + case (_) { /* fall through */ } } } } @@ -711,6 +714,7 @@ impure fn parse_assign_expr(parser p) -> @ast.expr { ret @spanned(lo, rhs.span, ast.expr_assign(lhs, rhs, ast.ann_none)); } + case (_) { /* fall through */ } } ret lhs; } @@ -733,6 +737,7 @@ impure fn parse_if_expr(parser p) -> @ast.expr { els = some(eblk); hi = eblk.span; } + case (_) { /* fall through */ } } ret @spanned(lo, hi, ast.expr_if(cond, thn, els, ast.ann_none)); } @@ -1039,6 +1044,7 @@ fn index_block(vec[@ast.stmt] stmts, option.t[@ast.expr] expr) -> ast.block_ { } } } + case (_) { /* fall through */ } } } ret rec(stmts=stmts, expr=expr, index=index); @@ -1211,7 +1217,6 @@ impure fn parse_mod_items(parser p, token.token term) -> ast._mod { case (ast.item_tag(?id, ?variants, _, _)) { index.insert(id, ast.mie_item(u)); - let uint variant_idx = 0u; for (ast.variant v in variants) { index.insert(v.name, ast.mie_tag_variant(u, variant_idx)); diff --git a/src/comp/middle/fold.rs b/src/comp/middle/fold.rs index 48cb1e01..203b8fda 100644 --- a/src/comp/middle/fold.rs +++ b/src/comp/middle/fold.rs @@ -87,6 +87,10 @@ type ast_fold[ENV] = @ast.lit, ann a) -> @expr) fold_expr_lit, (fn(&ENV e, &span sp, + @ast.expr e, @ast.ty ty, + ann a) -> @expr) fold_expr_cast, + + (fn(&ENV e, &span sp, @expr cond, &block thn, &option.t[block] els, ann a) -> @expr) fold_expr_if, @@ -296,11 +300,13 @@ fn fold_decl[ENV](&ENV env, ast_fold[ENV] fld, @decl d) -> @decl { case (some[@ast.ty](?t)) { ty_ = some[@ast.ty](fold_ty(env, fld, t)); } + case (_) { /* fall through */ } } alt (local.init) { case (some[@ast.expr](?e)) { init_ = some[@ast.expr](fold_expr(env, fld, e)); } + case (_) { /* fall through */ } } let @ast.local local_ = @rec(ty=ty_, init=init_ with *local); ret fld.fold_decl_local(env_, d.span, local_); @@ -405,6 +411,12 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr { ret fld.fold_expr_lit(env_, e.span, lit, t); } + case (ast.expr_cast(?e, ?t, ?at)) { + auto ee = fold_expr(env_, fld, e); + auto tt = fold_ty(env, fld, t); + ret fld.fold_expr_cast(env_, e.span, ee, tt, at); + } + case (ast.expr_if(?cnd, ?thn, ?els, ?t)) { auto ccnd = fold_expr(env_, fld, cnd); auto tthn = fold_block(env_, fld, thn); @@ -413,6 +425,7 @@ fn fold_expr[ENV](&ENV env, ast_fold[ENV] fld, &@expr e) -> @expr { case (some[block](?b)) { eels = some(fold_block(env_, fld, b)); } + case (_) { /* fall through */ } } ret fld.fold_expr_if(env_, e.span, ccnd, tthn, eels, t); } @@ -492,6 +505,7 @@ fn fold_stmt[ENV](&ENV env, ast_fold[ENV] fld, &@stmt s) -> @stmt { case (some[@expr](?e)) { oee = some(fold_expr(env_, fld, e)); } + case (_) { /* fall through */ } } ret fld.fold_stmt_ret(env_, s.span, oee); } @@ -737,6 +751,11 @@ fn identity_fold_expr_lit[ENV](&ENV env, &span sp, @ast.lit lit, ret @respan(sp, ast.expr_lit(lit, a)); } +fn identity_fold_expr_cast[ENV](&ENV env, &span sp, @ast.expr e, + @ast.ty t, ann a) -> @expr { + ret @respan(sp, ast.expr_cast(e, t, a)); +} + fn identity_fold_expr_if[ENV](&ENV env, &span sp, @expr cond, &block thn, &option.t[block] els, ann a) -> @expr { @@ -956,6 +975,7 @@ fn new_identity_fold[ENV]() -> ast_fold[ENV] { fold_expr_binary = bind identity_fold_expr_binary[ENV](_,_,_,_,_,_), fold_expr_unary = bind identity_fold_expr_unary[ENV](_,_,_,_,_), fold_expr_lit = bind identity_fold_expr_lit[ENV](_,_,_,_), + fold_expr_cast = bind identity_fold_expr_cast[ENV](_,_,_,_,_), fold_expr_if = bind identity_fold_expr_if[ENV](_,_,_,_,_,_), fold_expr_while = bind identity_fold_expr_while[ENV](_,_,_,_,_), fold_expr_do_while diff --git a/src/comp/middle/resolve.rs b/src/comp/middle/resolve.rs index 2655a6c5..498596d6 100644 --- a/src/comp/middle/resolve.rs +++ b/src/comp/middle/resolve.rs @@ -113,6 +113,7 @@ fn lookup_name(&env e, ast.ident i) -> option.t[def] { case (some[uint](?ix)) { ret found_decl_stmt(b.node.stmts.(ix)); } + case (_) { /* fall through */ } } } } diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index bc580166..89055578 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -295,6 +295,7 @@ fn type_of_inner(@crate_ctxt cx, @typeck.ty t) -> TypeRef { case (ast.alias) { t = T_ptr(t); } + case (_) { /* fall through */ } } atys += t; } @@ -506,6 +507,17 @@ fn iter_structural_ty(@block_ctxt cx, i += 1; } } + case (typeck.ty_rec(?fields)) { + let int i = 0; + for (typeck.field fld in fields) { + auto llfld = r.bcx.build.GEP(v, vec(C_int(0), C_int(i))); + r = f(r.bcx, llfld, fld.ty); + i += 1; + } + } + case (_) { + cx.fcx.ccx.sess.unimpl("type in iter_structural_ty"); + } // FIXME: handle records and tags when we support them. } ret r; @@ -560,6 +572,7 @@ fn iter_sequence(@block_ctxt cx, auto et = typeck.plain_ty(typeck.ty_machine(common.ty_u8)); ret iter_sequence_body(cx, v, et, f, false); } + case (_) { fail; } } cx.fcx.ccx.sess.bug("bad type in trans.iter_sequence"); fail; @@ -765,6 +778,7 @@ fn target_type(@crate_ctxt cx, @typeck.ty t) -> @typeck.ty { auto tm = typeck.ty_machine(cx.sess.get_targ_cfg().uint_type); ret @rec(struct=tm with *t); } + case (_) { /* fall through */ } } ret t; } @@ -813,8 +827,10 @@ impure fn trans_unary(@block_ctxt cx, ast.unop op, C_int(abi.box_rc_field_refcnt))); ret res(sub.bcx, cx.build.Store(C_int(1), rc)); } + case (_) { + cx.fcx.ccx.sess.unimpl("expr variant in trans_unary"); + } } - cx.fcx.ccx.sess.unimpl("expr variant in trans_unary"); fail; } @@ -859,6 +875,8 @@ impure fn trans_binary(@block_ctxt cx, ast.binop op, ret join_results(cx, T_bool(), vec(lhs_true_res, rhs_res)); } + + case (_) { /* fall through */ } } // Remaining cases are eager: @@ -958,8 +976,11 @@ impure fn trans_binary(@block_ctxt cx, ast.binop op, sub.val = cx.build.ICmp(lib.llvm.LLVMIntSGT, lhs.val, sub.val); ret sub; } + + case (_) { + cx.fcx.ccx.sess.unimpl("operator in trans_binary"); + } } - cx.fcx.ccx.sess.unimpl("expr variant in trans_binary"); fail; } @@ -994,6 +1015,8 @@ fn join_results(@block_ctxt parent_cx, // onward. ret live.(0); } + + case (_) { /* fall through */ } } // We have >1 incoming edges. Make a join block and br+phi them into it. @@ -1020,6 +1043,7 @@ impure fn trans_if(@block_ctxt cx, @ast.expr cond, case (some[ast.block](?eblk)) { else_res = trans_block(else_cx, eblk); } + case (_) { /* fall through */ } } cond_res.bcx.build.CondBr(cond_res.val, @@ -1119,8 +1143,8 @@ fn trans_field(@block_ctxt cx, &ast.span sp, @ast.expr base, auto v = r.bcx.build.GEP(r.val, vec(C_int(0), C_int(ix as int))); ret tup(res(r.bcx, v), lv._1); } + case (_) { cx.fcx.ccx.sess.unimpl("field variant in trans_field"); } } - cx.fcx.ccx.sess.unimpl("field variant in trans_field"); fail; } @@ -1132,8 +1156,8 @@ fn trans_lval(@block_ctxt cx, @ast.expr e) -> tup(result, bool) { case (ast.expr_field(?base, ?ident, ?ann)) { ret trans_field(cx, e.span, base, ident, ann); } + case (_) { cx.fcx.ccx.sess.unimpl("expr variant in trans_lval"); } } - cx.fcx.ccx.sess.unimpl("expr variant in trans_lval"); fail; } @@ -1366,6 +1390,7 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { case (some[@ast.expr](?x)) { r = trans_expr(cx, x); } + case (_) { /* fall through */ } } // Run all cleanups and back out. @@ -1388,6 +1413,7 @@ impure fn trans_ret(@block_ctxt cx, &option.t[@ast.expr] e) -> result { r.val = r.bcx.build.Ret(r.val); ret r; } + case (_) { /* fall through */ } } // FIXME: until LLVM has a unit type, we are moving around @@ -1426,6 +1452,7 @@ impure fn trans_stmt(@block_ctxt cx, &ast.stmt s) -> result { copy_ty(sub.bcx, true, llptr, sub.val, typeck.expr_ty(e)); } + case (_) { /* fall through */ } } } } @@ -1496,8 +1523,10 @@ iter block_locals(&ast.block b) -> @ast.local { case (ast.decl_local(?local)) { put local; } + case (_) { /* fall through */ } } } + case (_) { /* fall through */ } } } } @@ -1626,6 +1655,7 @@ impure fn trans_item(@crate_ctxt cx, &ast.item item) { auto sub_cx = @rec(path=cx.path + "." + name with *cx); trans_mod(sub_cx, m); } + case (_) { /* fall through */ } } } @@ -1650,6 +1680,7 @@ fn collect_item(&@crate_ctxt cx, @ast.item i) -> @crate_ctxt { case (ast.item_mod(?name, ?m, ?mid)) { cx.items.insert(mid, i); } + case (_) { /* fall through */ } } ret cx; } diff --git a/src/comp/middle/typeck.rs b/src/comp/middle/typeck.rs index 80bafb29..79f57be2 100644 --- a/src/comp/middle/typeck.rs +++ b/src/comp/middle/typeck.rs @@ -537,13 +537,15 @@ fn mode_is_alias(ast.mode m) -> bool { case (ast.val) { ret false; } case (ast.alias) { ret true; } } + fail; } fn type_is_nil(@ty t) -> bool { alt (t.struct) { case (ty_nil) { ret true; } + case (_) { ret false; } } - ret false; + fail; } fn type_is_structural(@ty t) -> bool { @@ -551,24 +553,27 @@ fn type_is_structural(@ty t) -> bool { // FIXME: cover tag when we support it. case (ty_tup(_)) { ret true; } case (ty_rec(_)) { ret true; } + case (_) { ret false; } } - ret false; + fail; } fn type_is_binding(@ty t) -> bool { alt (t.struct) { // FIXME: cover obj when we support it. case (ty_fn(_,_)) { ret true; } + case (_) { ret false; } } - ret false; + fail; } fn type_is_boxed(@ty t) -> bool { alt (t.struct) { case (ty_str) { ret true; } case (ty_vec(_)) { ret true; } + case (_) { ret false; } } - ret false; + fail; } fn type_is_scalar(@ty t) -> bool { @@ -578,8 +583,9 @@ fn type_is_scalar(@ty t) -> bool { case (ty_uint) { ret true; } case (ty_machine(_)) { ret true; } case (ty_char) { ret true; } + case (_) { ret false; } } - ret false; + fail; } fn type_is_fp(@ty t) -> bool { @@ -588,10 +594,12 @@ fn type_is_fp(@ty t) -> bool { alt (tm) { case (common.ty_f32) { ret true; } case (common.ty_f64) { ret true; } + case (_) { ret false; } } } + case (_) { ret false; } } - ret false; + fail; } fn type_is_signed(@ty t) -> bool { @@ -603,10 +611,12 @@ fn type_is_signed(@ty t) -> bool { case (common.ty_i16) { ret true; } case (common.ty_i32) { ret true; } case (common.ty_i64) { ret true; } + case (_) { ret false; } } } + case (_) { ret false; } } - ret false; + fail; } fn plain_ty(&sty st) -> @ty { @@ -662,7 +672,6 @@ fn expr_ty(@ast.expr expr) -> @ty { case (ast.expr_index(_, _, ?ann)) { ret ann_to_type(ann); } case (ast.expr_name(_, _, ?ann)) { ret ann_to_type(ann); } } - fail; } @@ -1198,6 +1207,7 @@ fn check_expr(&fn_ctxt fcx, @ast.expr expr) -> @ast.expr { case (ast.ne) { t = plain_ty(ty_bool); } case (ast.ge) { t = plain_ty(ty_bool); } case (ast.gt) { t = plain_ty(ty_bool); } + case (_) { /* fall through */ } } ret @fold.respan[ast.expr_](expr.span, ast.expr_binary(binop, lhs_1, rhs_1, @@ -1506,6 +1516,7 @@ fn check_stmt(&fn_ctxt fcx, &@ast.stmt stmt) auto expr_1 = demand_expr(fcx, lty, expr_0); init = some[@ast.expr](expr_1); } + case (_) { /* fall through */ } } auto local_1 = @rec(init = init with *local); |