From 67cc89f38d2e75cb0dcd6303fbe4bb4f659277a7 Mon Sep 17 00:00:00 2001 From: Marijn Haverbeke Date: Wed, 15 Feb 2012 09:40:42 +0100 Subject: [PATCH] Rewrite exhaustiveness checker Issue #352 Closes #1720 The old checker would happily accept things like 'alt x { @some(a) { a } }'. It now properly descends into patterns, checks exhaustiveness of booleans, and complains when number/string patterns aren't exhaustive. --- src/comp/metadata/decoder.rs | 8 +- src/comp/metadata/tydecode.rs | 10 +- src/comp/middle/check_alt.rs | 191 +++++++++++------- src/comp/middle/lint.rs | 2 +- src/comp/syntax/print/pprust.rs | 2 +- src/compiletest/procsrv.rs | 2 +- src/libcore/bool.rs | 3 +- src/libcore/str.rs | 4 +- src/libstd/four.rs | 6 +- src/libstd/serialization.rs | 2 +- src/libstd/treemap.rs | 8 +- src/libstd/tri.rs | 4 +- src/test/compile-fail/missing-return2.rs | 2 +- .../non-exhaustive-match-nested.rs | 2 +- src/test/compile-fail/non-exhaustive-match.rs | 16 +- src/test/pretty/block-disambig.rs | 10 +- src/test/pretty/unary-op-disambig.rs | 4 +- src/test/run-fail/unwind-alt.rs | 2 +- src/test/run-pass/alt-bot-2.rs | 2 +- src/test/run-pass/alt-pattern-lit.rs | 2 +- src/test/run-pass/alt-range.rs | 2 +- src/test/run-pass/alt-str.rs | 6 +- .../run-pass/binary-minus-without-space.rs | 2 +- src/test/run-pass/expr-alt-box.rs | 7 +- src/test/run-pass/expr-alt-generic-box1.rs | 2 +- src/test/run-pass/expr-alt-generic-box2.rs | 2 +- src/test/run-pass/expr-alt-generic-unique1.rs | 2 +- src/test/run-pass/expr-alt-generic-unique2.rs | 2 +- src/test/run-pass/expr-alt-generic.rs | 2 +- src/test/run-pass/expr-alt-struct.rs | 2 +- src/test/run-pass/expr-alt-unique.rs | 5 +- src/test/run-pass/unreachable-code.rs | 2 +- 32 files changed, 193 insertions(+), 125 deletions(-) diff --git a/src/comp/metadata/decoder.rs b/src/comp/metadata/decoder.rs index 2a089ad14ad..867497f37fd 100644 --- a/src/comp/metadata/decoder.rs +++ b/src/comp/metadata/decoder.rs @@ -218,7 +218,7 @@ fn lookup_def(cnum: ast::crate_num, data: @[u8], did_: ast::def_id) -> let fam_ch = item_family(item); let did = {crate: cnum, node: did_.node}; // We treat references to enums as references to types. - alt fam_ch { + alt check fam_ch { 'c' { ast::def_const(did) } 'u' { ast::def_fn(did, ast::unsafe_fn) } 'f' { ast::def_fn(did, ast::impure_fn) } @@ -336,7 +336,7 @@ fn get_iface_methods(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) _ { tcx.sess.bug("get_iface_methods: id has non-function type"); } }; result += [{ident: name, tps: bounds, fty: fty, - purity: alt item_family(mth) { + purity: alt check item_family(mth) { 'u' { ast::unsafe_fn } 'f' { ast::impure_fn } 'p' { ast::pure_fn } @@ -346,7 +346,7 @@ fn get_iface_methods(cdata: cmd, id: ast::node_id, tcx: ty::ctxt) } fn family_has_type_params(fam_ch: char) -> bool { - alt fam_ch { + alt check fam_ch { 'c' | 'T' | 'm' | 'n' { false } 'f' | 'u' | 'p' | 'F' | 'U' | 'P' | 'y' | 't' | 'v' | 'i' | 'I' { true } } @@ -370,7 +370,7 @@ fn describe_def(items: ebml::doc, id: ast::def_id) -> str { } fn item_family_to_str(fam: char) -> str { - alt fam { + alt check fam { 'c' { ret "const"; } 'f' { ret "fn"; } 'u' { ret "unsafe fn"; } diff --git a/src/comp/metadata/tydecode.rs b/src/comp/metadata/tydecode.rs index be7afbe0437..c7d434b3c1c 100644 --- a/src/comp/metadata/tydecode.rs +++ b/src/comp/metadata/tydecode.rs @@ -177,7 +177,7 @@ fn parse_proto(c: char) -> ast::proto { } fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { - alt next(st) { + alt check next(st) { 'n' { ret ty::mk_nil(st.tcx); } 'z' { ret ty::mk_bot(st.tcx); } 'b' { ret ty::mk_bool(st.tcx); } @@ -185,7 +185,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { 'u' { ret ty::mk_uint(st.tcx); } 'l' { ret ty::mk_float(st.tcx); } 'M' { - alt next(st) { + alt check next(st) { 'b' { ret ty::mk_mach_uint(st.tcx, ast::ty_u8); } 'w' { ret ty::mk_mach_uint(st.tcx, ast::ty_u16); } 'l' { ret ty::mk_mach_uint(st.tcx, ast::ty_u32); } @@ -269,7 +269,7 @@ fn parse_ty(st: @pstate, conv: conv_did) -> ty::t { 'Y' { ret ty::mk_type(st.tcx); } 'y' { ret ty::mk_send_type(st.tcx); } 'C' { - let ck = alt next(st) { + let ck = alt check next(st) { '&' { ty::ck_block } '@' { ty::ck_box } '~' { ty::ck_uniq } @@ -355,7 +355,7 @@ fn parse_ty_fn(st: @pstate, conv: conv_did) -> ty::fn_ty { assert (next(st) == '['); let inputs: [ty::arg] = []; while peek(st) != ']' { - let mode = alt peek(st) { + let mode = alt check peek(st) { '&' { ast::by_mut_ref } '-' { ast::by_move } '+' { ast::by_copy } @@ -405,7 +405,7 @@ fn parse_bounds_data(data: @[u8], start: uint, fn parse_bounds(st: @pstate, conv: conv_did) -> @[ty::param_bound] { let bounds = []; while true { - bounds += [alt next(st) { + bounds += [alt check next(st) { 'S' { ty::bound_send } 'C' { ty::bound_copy } 'I' { ty::bound_iface(parse_ty(st, conv)) } diff --git a/src/comp/middle/check_alt.rs b/src/comp/middle/check_alt.rs index 5e377e33226..e1bf34ce5e4 100644 --- a/src/comp/middle/check_alt.rs +++ b/src/comp/middle/check_alt.rs @@ -27,7 +27,7 @@ fn check_expr(tcx: ty::ctxt, ex: @expr, &&s: (), v: visit::vt<()>) { /* Check for exhaustiveness */ if mode == alt_exhaustive { let arms = vec::concat(vec::filter_map(arms, unguarded_pat)); - check_exhaustive(tcx, ex.span, expr_ty(tcx, scrut), arms); + check_exhaustive(tcx, ex.span, arms); } } _ { } @@ -59,89 +59,136 @@ fn check_arms(tcx: ty::ctxt, arms: [arm]) { } } +fn raw_pat(p: @pat) -> @pat { + alt p.node { + pat_ident(_, some(s)) { raw_pat(s) } + _ { p } + } +} + // Precondition: patterns have been normalized // (not checked statically yet) -fn check_exhaustive(tcx: ty::ctxt, sp:span, scrut_ty:ty::t, pats:[@pat]) { - let represented : [def_id] = []; - /* Determine the type of the scrutinee */ - /* If it's not an enum, exit (bailing out on checking non-enum alts - for now) */ - /* Otherwise, get the list of variants and make sure each one is - represented. Then recurse on the columns. */ +fn check_exhaustive(tcx: ty::ctxt, sp: span, pats: [@pat]) { + if pats.len() == 0u { + tcx.sess.span_err(sp, "non-exhaustive patterns"); + ret; + } + // If there a non-refutable pattern in the set, we're okay. + for pat in pats { if !is_refutable(tcx, pat) { ret; } } - let ty_def_id = alt ty::get(scrut_ty).struct { - ty_enum(id, _) { id } - _ { ret; } }; - - let variants = *enum_variants(tcx, ty_def_id); - for pat in pats { - if !is_refutable(tcx, pat) { - /* automatically makes this alt complete */ ret; + alt ty::get(ty::node_id_to_type(tcx, pats[0].id)).struct { + ty::ty_enum(id, _) { + check_exhaustive_enum(tcx, id, sp, pats); + } + ty::ty_box(_) { + check_exhaustive(tcx, sp, vec::filter_map(pats, {|p| + alt raw_pat(p).node { pat_box(sub) { some(sub) } _ { none } } + })); + } + ty::ty_uniq(_) { + check_exhaustive(tcx, sp, vec::filter_map(pats, {|p| + alt raw_pat(p).node { pat_uniq(sub) { some(sub) } _ { none } } + })); + } + ty::ty_tup(ts) { + let cols = vec::init_elt_mut(ts.len(), []); + for p in pats { + alt raw_pat(p).node { + pat_tup(sub) { + vec::iteri(sub) {|i, sp| cols[i] += [sp];} + } + _ {} + } } - alt pat.node { - // want the def_id for the constructor - pat_enum(id,_) { - alt tcx.def_map.find(pat.id) { - some(def_variant(_, variant_def_id)) { - represented += [variant_def_id]; + vec::iter(cols) {|col| check_exhaustive(tcx, sp, col); } + } + ty::ty_rec(fs) { + let cols = vec::init_elt(fs.len(), {mutable wild: false, + mutable pats: []}); + for p in pats { + alt raw_pat(p).node { + pat_rec(sub, _) { + vec::iteri(fs) {|i, field| + alt vec::find(sub, {|pf| pf.ident == field.ident }) { + some(pf) { cols[i].pats += [pf.pat]; } + none { cols[i].wild = true; } } - _ { tcx.sess.span_bug(pat.span, "check_exhaustive: - pat_tag not bound to a variant"); } } + } + _ {} } - _ { tcx.sess.span_bug(pat.span, "check_exhaustive: ill-typed \ - pattern"); // we know this has enum type, - } // so anything else should be impossible - } - } - fn not_represented(v: [def_id], &&vinfo: variant_info) -> bool { - !vec::contains(v, vinfo.id) - } - // Could be more efficient (bitvectors?) - alt vec::find(variants, bind not_represented(represented,_)) { - some(bad) { - // complain - // TODO: give examples of cases that aren't covered - tcx.sess.note("Patterns not covered include:"); - tcx.sess.note(bad.name); - tcx.sess.span_err(sp, "Non-exhaustive pattern"); } - _ {} + vec::iter(cols) {|col| + if !col.wild { check_exhaustive(tcx, sp, copy col.pats); } + } + } + ty::ty_bool { + let saw_true = false, saw_false = false; + for p in pats { + alt raw_pat(p).node { + pat_lit(@{node: expr_lit(@{node: lit_bool(b), _}), _}) { + if b { saw_true = true; } + else { saw_false = true; } + } + _ {} + } + } + if !saw_true { tcx.sess.span_err( + sp, "non-exhaustive bool patterns: true not covered"); } + if !saw_false { tcx.sess.span_err( + sp, "non-exhaustive bool patterns: false not covered"); } + } + ty::ty_nil { + let seen = vec::any(pats, {|p| + alt raw_pat(p).node { + pat_lit(@{node: expr_lit(@{node: lit_nil, _}), _}) { true } + _ { false } + } + }); + if !seen { tcx.sess.span_err(sp, "non-exhaustive patterns"); } + } + // Literal patterns are always considered non-exhaustive + _ { + tcx.sess.span_err(sp, "non-exhaustive literal patterns"); + } } - // Otherwise, check subpatterns - // inefficient - for variant in variants { - // rows consists of the argument list for each pat that's an enum - let rows : [[@pat]] = []; - for pat in pats { +} + +fn check_exhaustive_enum(tcx: ty::ctxt, enum_id: def_id, sp: span, + pats: [@pat]) { + let variants = enum_variants(tcx, enum_id); + let columns_by_variant = vec::map(*variants, {|v| + {mutable seen: false, + cols: vec::init_elt_mut(v.args.len(), [])} + }); + + for pat in pats { + let pat = raw_pat(pat); + alt tcx.def_map.get(pat.id) { + def_variant(_, id) { + let variant_idx = + option::get(vec::position(*variants, {|v| v.id == id})); + columns_by_variant[variant_idx].seen = true; alt pat.node { - pat_enum(id, args) { - alt tcx.def_map.find(pat.id) { - some(def_variant(_,variant_id)) - if variant_id == variant.id { rows += [args]; } - _ { } - } - } - _ {} - } - } - if check vec::is_not_empty(rows) { - let i = 0u; - for it in rows[0] { - let column = [it]; - // Annoying -- see comment in - // tstate::states::find_pre_post_state_loop - check vec::is_not_empty(rows); - for row in vec::tail(rows) { - column += [row[i]]; + pat_enum(_, args) { + vec::iteri(args) {|i, p| + columns_by_variant[variant_idx].cols[i] += [p]; } - check_exhaustive(tcx, sp, pat_ty(tcx, it), column); - i += 1u; - } + } + _ {} + } + } + _ {} + } + } + + vec::iteri(columns_by_variant) {|i, cv| + if !cv.seen { + tcx.sess.span_err(sp, "non-exhaustive patterns: variant `" + + variants[i].name + "` not covered"); + } else { + vec::iter(cv.cols) {|col| check_exhaustive(tcx, sp, col); } } - // This shouldn't actually happen, since there were no - // irrefutable patterns if we got here. - else { cont; } } } diff --git a/src/comp/middle/lint.rs b/src/comp/middle/lint.rs index ff1b97b9587..f46a50ea4a1 100644 --- a/src/comp/middle/lint.rs +++ b/src/comp/middle/lint.rs @@ -40,7 +40,7 @@ fn time(do_it: bool, what: str, thunk: fn()) { fn merge_opts(attrs: [ast::attribute], cmd_opts: [(option, bool)]) -> [(option, bool)] { fn str_to_option(name: str) -> (option, bool) { - ret alt name { + ret alt check name { "ctypes" { (ctypes, true) } "no_ctypes" { (ctypes, false) } } diff --git a/src/comp/syntax/print/pprust.rs b/src/comp/syntax/print/pprust.rs index 9cd9cd0503a..23cea66e8db 100644 --- a/src/comp/syntax/print/pprust.rs +++ b/src/comp/syntax/print/pprust.rs @@ -1023,7 +1023,7 @@ fn print_expr(s: ps, &&expr: @ast::expr) { } ast::expr_be(result) { word_nbsp(s, "be"); print_expr(s, result); } ast::expr_log(lvl, lexp, expr) { - alt lvl { + alt check lvl { 1 { word_nbsp(s, "log"); print_expr(s, expr); } 0 { word_nbsp(s, "log_err"); print_expr(s, expr); } 2 { diff --git a/src/compiletest/procsrv.rs b/src/compiletest/procsrv.rs index 9304e359321..b856b092e7a 100644 --- a/src/compiletest/procsrv.rs +++ b/src/compiletest/procsrv.rs @@ -68,7 +68,7 @@ fn run(lib_path: str, prog: str, args: [str], let count = 2; while count > 0 { let stream = comm::recv(p); - alt stream { + alt check stream { (1, s) { outs = s; } diff --git a/src/libcore/bool.rs b/src/libcore/bool.rs index d027e3825e1..cc4efe54dfc 100644 --- a/src/libcore/bool.rs +++ b/src/libcore/bool.rs @@ -60,9 +60,10 @@ pure fn is_false(v: t) -> bool { !v } brief = "Parse logic value from `s`" )] pure fn from_str(s: str) -> t { - alt s { + alt check s { "true" { true } "false" { false } + _ { fail "'" + s + "' is not a valid boolean string"; } } } diff --git a/src/libcore/str.rs b/src/libcore/str.rs index d71828c79e8..f79594a3023 100644 --- a/src/libcore/str.rs +++ b/src/libcore/str.rs @@ -2140,7 +2140,7 @@ mod tests { fn test_chars_iter() { let i = 0; chars_iter("x\u03c0y") {|ch| - alt i { + alt check i { 0 { assert ch == 'x'; } 1 { assert ch == '\u03c0'; } 2 { assert ch == 'y'; } @@ -2156,7 +2156,7 @@ mod tests { let i = 0; bytes_iter("xyz") {|bb| - alt i { + alt check i { 0 { assert bb == 'x' as u8; } 1 { assert bb == 'y' as u8; } 2 { assert bb == 'z' as u8; } diff --git a/src/libstd/four.rs b/src/libstd/four.rs index ad44f225f25..e1804be2b91 100644 --- a/src/libstd/four.rs +++ b/src/libstd/four.rs @@ -166,7 +166,7 @@ Function: from_str Parse logic value from `s` */ pure fn from_str(s: str) -> t { - alt s { + alt check s { "none" { none } "false" { four::false } "true" { four::true } @@ -181,7 +181,7 @@ Convert `v` into a string */ pure fn to_str(v: t) -> str { // FIXME replace with consts as soon as that works - alt v { + alt check v { 0u8 { "none" } 1u8 { "true" } 2u8 { "false" } @@ -265,7 +265,7 @@ mod tests { } fn to_tup(v: four::t) -> (bool, bool) { - alt v { + alt check v { 0u8 { (false, false) } 1u8 { (false, true) } 2u8 { (true, false) } diff --git a/src/libstd/serialization.rs b/src/libstd/serialization.rs index 1b91b34fe11..1cc8cb529d8 100644 --- a/src/libstd/serialization.rs +++ b/src/libstd/serialization.rs @@ -241,7 +241,7 @@ fn test_option_int() { fn deserialize_0(s: S) -> option { s.read_enum("option") {|| s.read_enum_variant {|i| - alt i { + alt check i { 0u { none } 1u { let v0 = s.read_enum_variant_arg(0u) {|| diff --git a/src/libstd/treemap.rs b/src/libstd/treemap.rs index bcea14df377..1647ea8f977 100644 --- a/src/libstd/treemap.rs +++ b/src/libstd/treemap.rs @@ -52,8 +52,12 @@ fn insert(m: treemap, k: K, v: V) { // We have to name left and right individually, because // otherwise the alias checker complains. if k < kk { - alt m { @node(_, _, left, _) { insert(left, k, v); } } - } else { alt m { @node(_, _, _, right) { insert(right, k, v); } } } + alt check m { @node(_, _, left, _) { insert(left, k, v); } } + } else { + alt check m { + @node(_, _, _, right) { insert(right, k, v); } + } + } } } } diff --git a/src/libstd/tri.rs b/src/libstd/tri.rs index 7cc749429ce..5835dbf8c42 100644 --- a/src/libstd/tri.rs +++ b/src/libstd/tri.rs @@ -137,7 +137,7 @@ Function: from_str Parse logic value from `s` */ pure fn from_str(s: str) -> t { - alt s { + alt check s { "unknown" { unknown } "true" { tri::true } "false" { tri::false } @@ -151,7 +151,7 @@ Convert `v` into a string */ pure fn to_str(v: t) -> str { // FIXME replace with consts as soon as that works - alt v { + alt check v { 0u8 { "unknown" } 1u8 { "true" } 2u8 { "false" } diff --git a/src/test/compile-fail/missing-return2.rs b/src/test/compile-fail/missing-return2.rs index 26a9febd3c7..54d8de63014 100644 --- a/src/test/compile-fail/missing-return2.rs +++ b/src/test/compile-fail/missing-return2.rs @@ -3,7 +3,7 @@ fn f() -> int { // Make sure typestate doesn't interpret this alt expression // as the function result - alt true { true { } }; + alt check true { true { } }; } fn main() { } diff --git a/src/test/compile-fail/non-exhaustive-match-nested.rs b/src/test/compile-fail/non-exhaustive-match-nested.rs index b3b854f53e5..a4efbb5684c 100644 --- a/src/test/compile-fail/non-exhaustive-match-nested.rs +++ b/src/test/compile-fail/non-exhaustive-match-nested.rs @@ -1,5 +1,5 @@ // -*- rust -*- -// error-pattern: Non-exhaustive pattern +// error-pattern: non-exhaustive patterns enum t { a(u), b } enum u { c, d } diff --git a/src/test/compile-fail/non-exhaustive-match.rs b/src/test/compile-fail/non-exhaustive-match.rs index 7beb7f1b17d..b2fec6c0c5d 100644 --- a/src/test/compile-fail/non-exhaustive-match.rs +++ b/src/test/compile-fail/non-exhaustive-match.rs @@ -1,5 +1,15 @@ -// -*- rust -*- -// error-pattern: Non-exhaustive pattern enum t { a, b, } -fn main() { let x = a; alt x { b { } } } +fn main() { + let x = a; + alt x { b { } } //! ERROR non-exhaustive patterns + alt true { //! ERROR non-exhaustive bool patterns + true {} + } + alt @some(10) { //! ERROR non-exhaustive patterns + @none {} + } + alt (2, 3, 4) { //! ERROR non-exhaustive literal patterns + (_, _, 4) {} + } +} diff --git a/src/test/pretty/block-disambig.rs b/src/test/pretty/block-disambig.rs index d1a7a9b85ac..64752505952 100644 --- a/src/test/pretty/block-disambig.rs +++ b/src/test/pretty/block-disambig.rs @@ -8,7 +8,7 @@ fn test2() -> int { let val = @0; { } *val } fn test3() { let regs = @{mutable eax: 0}; - alt true { true { } } + alt check true { true { } } (*regs).eax = 1; } @@ -20,13 +20,13 @@ fn test6() -> bool { { } (true || false) && true } fn test7() -> uint { let regs = @0; - alt true { true { } } + alt check true { true { } } (*regs < 2) as uint } fn test8() -> int { let val = @0; - alt true { + alt check true { true { } } if *val < 1 { @@ -36,11 +36,11 @@ fn test8() -> int { } } -fn test9() { let regs = @mutable 0; alt true { true { } } *regs += 1; } +fn test9() { let regs = @mutable 0; alt check true { true { } } *regs += 1; } fn test10() -> int { let regs = @mutable [0]; - alt true { true { } } + alt check true { true { } } (*regs)[0] } diff --git a/src/test/pretty/unary-op-disambig.rs b/src/test/pretty/unary-op-disambig.rs index 88406813b42..e9fd2c2dc2c 100644 --- a/src/test/pretty/unary-op-disambig.rs +++ b/src/test/pretty/unary-op-disambig.rs @@ -10,8 +10,8 @@ fn if_semi() -> int { if true { f() } else { f() }; -1 } fn if_nosemi() -> int { (if true { 0 } else { 0 }) - 1 } -fn alt_semi() -> int { alt true { true { f() } }; -1 } +fn alt_semi() -> int { alt check true { true { f() } }; -1 } -fn alt_no_semi() -> int { (alt true { true { 0 } }) - 1 } +fn alt_no_semi() -> int { (alt check true { true { 0 } }) - 1 } fn stmt() { { f() }; -1; } diff --git a/src/test/run-fail/unwind-alt.rs b/src/test/run-fail/unwind-alt.rs index 741a7eb4975..1cd512cfc41 100644 --- a/src/test/run-fail/unwind-alt.rs +++ b/src/test/run-fail/unwind-alt.rs @@ -4,7 +4,7 @@ fn test_box() { @0; } fn test_str() { - let res = alt false { true { "happy" } }; + let res = alt check false { true { "happy" } }; assert res == "happy"; } fn main() { diff --git a/src/test/run-pass/alt-bot-2.rs b/src/test/run-pass/alt-bot-2.rs index 3183b580fc6..e3fd606c2d8 100644 --- a/src/test/run-pass/alt-bot-2.rs +++ b/src/test/run-pass/alt-bot-2.rs @@ -1,3 +1,3 @@ // n.b. This was only ever failing with optimization disabled. -fn a() -> int { alt ret 1 { 2 { 3 } } } +fn a() -> int { alt check ret 1 { 2 { 3 } } } fn main() { a(); } diff --git a/src/test/run-pass/alt-pattern-lit.rs b/src/test/run-pass/alt-pattern-lit.rs index afc72c80afa..d266a63418f 100644 --- a/src/test/run-pass/alt-pattern-lit.rs +++ b/src/test/run-pass/alt-pattern-lit.rs @@ -1,7 +1,7 @@ fn altlit(f: int) -> int { - alt f { + alt check f { 10 { #debug("case 10"); ret 20; } 11 { #debug("case 11"); ret 22; } } diff --git a/src/test/run-pass/alt-range.rs b/src/test/run-pass/alt-range.rs index 1cd29cb3517..e85a82a2fd4 100644 --- a/src/test/run-pass/alt-range.rs +++ b/src/test/run-pass/alt-range.rs @@ -7,7 +7,7 @@ fn main() { 6u to 7u { fail "shouldn't match range"; } _ {} } - alt 5u { + alt check 5u { 1u { fail "should match non-first range"; } 2u to 6u {} } diff --git a/src/test/run-pass/alt-str.rs b/src/test/run-pass/alt-str.rs index 6b7a3e6c279..c0a096cc2c9 100644 --- a/src/test/run-pass/alt-str.rs +++ b/src/test/run-pass/alt-str.rs @@ -1,7 +1,7 @@ // Issue #53 fn main() { - alt "test" { "not-test" { fail; } "test" { } _ { fail; } } + alt check "test" { "not-test" { fail; } "test" { } _ { fail; } } enum t { tag1(str), tag2, } @@ -13,9 +13,9 @@ fn main() { _ { fail; } } - let x = alt "a" { "a" { 1 } "b" { 2 } }; + let x = alt check "a" { "a" { 1 } "b" { 2 } }; assert (x == 1); - alt "a" { "a" { } "b" { } } + alt check "a" { "a" { } "b" { } } } diff --git a/src/test/run-pass/binary-minus-without-space.rs b/src/test/run-pass/binary-minus-without-space.rs index cb31faacc3c..79627d5501d 100644 --- a/src/test/run-pass/binary-minus-without-space.rs +++ b/src/test/run-pass/binary-minus-without-space.rs @@ -1,6 +1,6 @@ // Check that issue #954 stays fixed fn main() { - alt -1 { -1 {} } + alt check -1 { -1 {} } assert 1-1 == 0; } diff --git a/src/test/run-pass/expr-alt-box.rs b/src/test/run-pass/expr-alt-box.rs index 84c9e424f46..93a65d62977 100644 --- a/src/test/run-pass/expr-alt-box.rs +++ b/src/test/run-pass/expr-alt-box.rs @@ -4,10 +4,13 @@ // -*- rust -*- // Tests for alt as expressions resulting in boxed types -fn test_box() { let res = alt true { true { @100 } }; assert (*res == 100); } +fn test_box() { + let res = alt check true { true { @100 } }; + assert (*res == 100); +} fn test_str() { - let res = alt true { true { "happy" } }; + let res = alt check true { true { "happy" } }; assert (res == "happy"); } diff --git a/src/test/run-pass/expr-alt-generic-box1.rs b/src/test/run-pass/expr-alt-generic-box1.rs index 98f3b86aec9..bdaa676954b 100644 --- a/src/test/run-pass/expr-alt-generic-box1.rs +++ b/src/test/run-pass/expr-alt-generic-box1.rs @@ -5,7 +5,7 @@ type compare = fn@(@T, @T) -> bool; fn test_generic(expected: @T, eq: compare) { - let actual: @T = alt true { true { expected } }; + let actual: @T = alt check true { true { expected } }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-alt-generic-box2.rs b/src/test/run-pass/expr-alt-generic-box2.rs index b4a40c51361..de1143464c8 100644 --- a/src/test/run-pass/expr-alt-generic-box2.rs +++ b/src/test/run-pass/expr-alt-generic-box2.rs @@ -5,7 +5,7 @@ type compare = fn@(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = alt true { true { expected } }; + let actual: T = alt check true { true { expected } }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-alt-generic-unique1.rs b/src/test/run-pass/expr-alt-generic-unique1.rs index 2b8b9f53946..55e33263776 100644 --- a/src/test/run-pass/expr-alt-generic-unique1.rs +++ b/src/test/run-pass/expr-alt-generic-unique1.rs @@ -4,7 +4,7 @@ type compare = fn@(~T, ~T) -> bool; fn test_generic(expected: ~T, eq: compare) { - let actual: ~T = alt true { true { expected } }; + let actual: ~T = alt check true { true { expected } }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-alt-generic-unique2.rs b/src/test/run-pass/expr-alt-generic-unique2.rs index 0a0dd1dd8d5..9dc580ed3b0 100644 --- a/src/test/run-pass/expr-alt-generic-unique2.rs +++ b/src/test/run-pass/expr-alt-generic-unique2.rs @@ -5,7 +5,7 @@ type compare = fn@(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = alt true { true { expected } }; + let actual: T = alt check true { true { expected } }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-alt-generic.rs b/src/test/run-pass/expr-alt-generic.rs index 13da160c73c..84324a00db7 100644 --- a/src/test/run-pass/expr-alt-generic.rs +++ b/src/test/run-pass/expr-alt-generic.rs @@ -5,7 +5,7 @@ type compare = fn@(T, T) -> bool; fn test_generic(expected: T, eq: compare) { - let actual: T = alt true { true { expected } }; + let actual: T = alt check true { true { expected } }; assert (eq(expected, actual)); } diff --git a/src/test/run-pass/expr-alt-struct.rs b/src/test/run-pass/expr-alt-struct.rs index def9b607afe..52ec91884f6 100644 --- a/src/test/run-pass/expr-alt-struct.rs +++ b/src/test/run-pass/expr-alt-struct.rs @@ -5,7 +5,7 @@ // Tests for alt as expressions resulting in structural types fn test_rec() { - let rs = alt true { true { {i: 100} } }; + let rs = alt check true { true { {i: 100} } }; assert (rs == {i: 100}); } diff --git a/src/test/run-pass/expr-alt-unique.rs b/src/test/run-pass/expr-alt-unique.rs index f83dae4e9fa..e3a55892955 100644 --- a/src/test/run-pass/expr-alt-unique.rs +++ b/src/test/run-pass/expr-alt-unique.rs @@ -4,6 +4,9 @@ // -*- rust -*- // Tests for alt as expressions resulting in boxed types -fn test_box() { let res = alt true { true { ~100 } }; assert (*res == 100); } +fn test_box() { + let res = alt check true { true { ~100 } }; + assert (*res == 100); +} fn main() { test_box(); } diff --git a/src/test/run-pass/unreachable-code.rs b/src/test/run-pass/unreachable-code.rs index 2570e598b08..d5f896d36d3 100644 --- a/src/test/run-pass/unreachable-code.rs +++ b/src/test/run-pass/unreachable-code.rs @@ -30,7 +30,7 @@ fn log_cont() { do { log(error, cont); } while false } fn ret_ret() -> int { ret (ret 2) + 3; } fn ret_guard() { - alt 2 { + alt check 2 { x if (ret) { x; } } }