Skip to content

Commit 6627890

Browse files
committed
Support 'alt check' syntax
It is only a way to flag an alt as intentionally non-exhaustive right now. Issue #1679
1 parent 9f95ccb commit 6627890

File tree

14 files changed

+29
-29
lines changed

14 files changed

+29
-29
lines changed

src/comp/metadata/astencode.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -293,7 +293,7 @@ impl ast_output for ast_ctxt {
293293
}
294294
}
295295

296-
ast::expr_alt(cond, arms) {
296+
ast::expr_alt(cond, arms, _) {
297297
self.tag(at_expr_node_alt) {||
298298
self.blk(blk);
299299
self.expr(cond);

src/comp/middle/alias.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
110110
check_call(*cx, sc, f, args);
111111
handled = false;
112112
}
113-
ast::expr_alt(input, arms) { check_alt(*cx, input, arms, sc, v); }
113+
ast::expr_alt(input, arms, _) { check_alt(*cx, input, arms, sc, v); }
114114
ast::expr_for(decl, seq, blk) {
115115
v.visit_expr(seq, sc, v);
116116
check_loop(*cx, sc) {|| check_for(*cx, decl, seq, blk, sc, v); }

src/comp/middle/check_alt.rs

Lines changed: 10 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -21,19 +21,21 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
2121
fn check_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) {
2222
visit::visit_expr(ex, s, v);
2323
alt ex.node {
24-
expr_alt(scrut, arms) {
25-
check_arms(tcx, ex.span, scrut,
26-
pat_util::normalize_arms(tcx, arms));
24+
expr_alt(scrut, arms, mode) {
25+
let arms = pat_util::normalize_arms(tcx, arms);
26+
check_arms(tcx, arms);
27+
/* Check for exhaustiveness */
28+
if mode == alt_exhaustive {
29+
let arms = vec::concat(vec::filter_map(arms, unguarded_pat));
30+
check_exhaustive(tcx, ex.span, expr_ty(tcx, scrut), arms);
2731
}
28-
_ { }
32+
}
33+
_ { }
2934
}
3035
}
3136

32-
fn check_arms(tcx: ty::ctxt, sp:span, scrut: @expr, arms: [arm]) {
37+
fn check_arms(tcx: ty::ctxt, arms: [arm]) {
3338
let i = 0;
34-
let scrut_ty = expr_ty(tcx, scrut);
35-
/* (Could both checks be done in a single pass?) */
36-
3739
/* Check for unreachable patterns */
3840
for arm: arm in arms {
3941
for arm_pat: @pat in arm.pats {
@@ -55,11 +57,6 @@ fn check_arms(tcx: ty::ctxt, sp:span, scrut: @expr, arms: [arm]) {
5557
}
5658
i += 1;
5759
}
58-
59-
/* Check for exhaustiveness */
60-
61-
check_exhaustive(tcx, sp, scrut_ty,
62-
vec::concat(vec::filter_map(arms, unguarded_pat)));
6360
}
6461

6562
// Precondition: patterns have been normalized

src/comp/middle/last_use.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
8888
v.visit_expr(coll, cx, v);
8989
visit_block(loop, cx) {|| visit::visit_block(blk, cx, v);}
9090
}
91-
expr_alt(input, arms) {
91+
expr_alt(input, arms, _) {
9292
v.visit_expr(input, cx, v);
9393
let before = cx.current, sets = [];
9494
for arm in arms {

src/comp/middle/trans/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3257,7 +3257,7 @@ fn trans_expr(bcx: @block_ctxt, e: @ast::expr, dest: dest) -> @block_ctxt {
32573257
ast::expr_if(cond, thn, els) | ast::expr_if_check(cond, thn, els) {
32583258
ret trans_if(bcx, cond, thn, els, dest);
32593259
}
3260-
ast::expr_alt(expr, arms) {
3260+
ast::expr_alt(expr, arms, _) {
32613261
ret alt::trans_alt(bcx, expr, arms, dest);
32623262
}
32633263
ast::expr_block(blk) {

src/comp/middle/tstate/pre_post_conditions.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -447,7 +447,7 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) {
447447
find_pre_post_loop(fcx, d, index, body, e.id);
448448
}
449449
expr_index(val, sub) { find_pre_post_exprs(fcx, [val, sub], e.id); }
450-
expr_alt(ex, alts) {
450+
expr_alt(ex, alts, _) {
451451
find_pre_post_expr(fcx, ex);
452452
fn do_an_alt(fcx: fn_ctxt, an_alt: arm) -> pre_and_post {
453453
alt an_alt.guard {

src/comp/middle/tstate/states.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -552,7 +552,7 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool {
552552
expr_index(val, sub) {
553553
ret find_pre_post_state_two(fcx, pres, val, sub, e.id, oper_pure);
554554
}
555-
expr_alt(val, alts) {
555+
expr_alt(val, alts, _) {
556556
let changed =
557557
set_prestate_ann(fcx.ccx, e.id, pres) |
558558
find_pre_post_state_expr(fcx, pres, val);

src/comp/middle/typeck.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2231,7 +2231,7 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier,
22312231
check_block_no_value(fcx, body);
22322232
write_ty(tcx, id, block_ty(tcx, body));
22332233
}
2234-
ast::expr_alt(expr, arms) {
2234+
ast::expr_alt(expr, arms, _) {
22352235
bot = check_expr(fcx, expr);
22362236

22372237
// Typecheck the patterns first, so that we get types for all the

src/comp/syntax/ast.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,8 @@ enum expr_check_mode { claimed_expr, checked_expr, }
215215

216216
type expr = {id: node_id, node: expr_, span: span};
217217

218+
enum alt_mode { alt_check, alt_exhaustive, }
219+
218220
enum expr_ {
219221
expr_vec([@expr], mutability),
220222
expr_rec([field], option<@expr>),
@@ -229,7 +231,7 @@ enum expr_ {
229231
expr_while(@expr, blk),
230232
expr_for(@local, @expr, blk),
231233
expr_do_while(blk, @expr),
232-
expr_alt(@expr, [arm]),
234+
expr_alt(@expr, [arm], alt_mode),
233235
expr_fn(proto, fn_decl, blk, @capture_clause),
234236
expr_fn_block(fn_decl, blk),
235237
expr_block(blk),

src/comp/syntax/fold.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -383,8 +383,8 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ {
383383
expr_do_while(blk, expr) {
384384
expr_do_while(fld.fold_block(blk), fld.fold_expr(expr))
385385
}
386-
expr_alt(expr, arms) {
387-
expr_alt(fld.fold_expr(expr), vec::map(arms, fld.fold_arm))
386+
expr_alt(expr, arms, mode) {
387+
expr_alt(fld.fold_expr(expr), vec::map(arms, fld.fold_arm), mode)
388388
}
389389
expr_fn(proto, decl, body, captures) {
390390
expr_fn(proto, fold_fn_decl(decl, fld),

src/comp/syntax/parse/parser.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1372,6 +1372,8 @@ fn parse_do_while_expr(p: parser) -> @ast::expr {
13721372

13731373
fn parse_alt_expr(p: parser) -> @ast::expr {
13741374
let lo = p.last_span.lo;
1375+
let mode = if eat_word(p, "check") { ast::alt_check }
1376+
else { ast::alt_exhaustive };
13751377
let discriminant = parse_expr(p);
13761378
expect(p, token::LBRACE);
13771379
let arms: [ast::arm] = [];
@@ -1384,7 +1386,7 @@ fn parse_alt_expr(p: parser) -> @ast::expr {
13841386
}
13851387
let hi = p.span.hi;
13861388
p.bump();
1387-
ret mk_expr(p, lo, hi, ast::expr_alt(discriminant, arms));
1389+
ret mk_expr(p, lo, hi, ast::expr_alt(discriminant, arms, mode));
13881390
}
13891391

13901392
fn parse_expr(p: parser) -> @ast::expr {
@@ -1653,7 +1655,7 @@ fn expr_is_complete(p: parser, e: pexpr) -> bool {
16531655
fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool {
16541656
alt e.node {
16551657
ast::expr_if(_, _, _) | ast::expr_if_check(_, _, _)
1656-
| ast::expr_alt(_, _) | ast::expr_block(_)
1658+
| ast::expr_alt(_, _, _) | ast::expr_block(_)
16571659
| ast::expr_do_while(_, _) | ast::expr_while(_, _)
16581660
| ast::expr_for(_, _, _)
16591661
| ast::expr_call(_, _, true) {

src/comp/syntax/print/pprust.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -901,10 +901,11 @@ fn print_expr(s: ps, &&expr: @ast::expr) {
901901
word_space(s, "while");
902902
print_expr(s, expr);
903903
}
904-
ast::expr_alt(expr, arms) {
904+
ast::expr_alt(expr, arms, mode) {
905905
cbox(s, alt_indent_unit);
906906
ibox(s, 4u);
907907
word_nbsp(s, "alt");
908+
if mode == ast::alt_check { word_nbsp(s, "check"); }
908909
print_maybe_parens_discrim(s, expr);
909910
space(s.s);
910911
bopen(s);

src/comp/syntax/visit.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
339339
v.visit_block(b, e, v);
340340
}
341341
expr_do_while(b, x) { v.visit_block(b, e, v); v.visit_expr(x, e, v); }
342-
expr_alt(x, arms) {
342+
expr_alt(x, arms, _) {
343343
v.visit_expr(x, e, v);
344344
for a: arm in arms { v.visit_arm(a, e, v); }
345345
}

src/test/run-pass/bind-methods.rs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
// xfail-test
2-
31
iface foo {
42
fn foo() -> int;
53
fn bar(p: int) -> int;

0 commit comments

Comments
 (0)