diff --git a/doc/rust.md b/doc/rust.md index 3b6b8008fc9..afe55bf159e 100644 --- a/doc/rust.md +++ b/doc/rust.md @@ -1000,11 +1000,11 @@ the function name. ~~~~ fn iter(seq: [T], f: fn(T)) { - for elt: T in seq { f(elt); } + for seq.each {|elt| f(elt); } } fn map(seq: [T], f: fn(T) -> U) -> [U] { let mut acc = []; - for elt in seq { acc += [f(elt)]; } + for seq.each {|elt| acc += [f(elt)]; } acc } ~~~~ @@ -2113,7 +2113,7 @@ An example a for loop: let v: [foo] = [a, b, c]; -for e: foo in v { +for v.each {|e| bar(e); } ~~~~ @@ -2228,7 +2228,7 @@ fn main() { ~~~~ Multiple alternative patterns may be joined with the `|` operator. A -range of values may be specified with `to`. For example: +range of values may be specified with `to`. For example: ~~~~ # let x = 2; diff --git a/doc/tutorial.md b/doc/tutorial.md index 6990d4574e9..9a5ce0fed57 100644 --- a/doc/tutorial.md +++ b/doc/tutorial.md @@ -690,19 +690,6 @@ do { } while any_cake_left(); ~~~~ -When iterating over a vector, use `for` instead. - -~~~~ -for elt in ["red", "green", "blue"] { - io::println(elt); -} -~~~~ - -This will go over each element in the given vector (a three-element -vector of strings, in this case), and repeatedly execute the body with -`elt` bound to the current element. You may add an optional type -declaration (`elt: str`) for the iteration variable if you want. - For more involved iteration, such as going over the elements of a hash table, Rust uses higher-order functions. We'll come back to those in a moment. @@ -1095,8 +1082,8 @@ enum color { ~~~~ If an explicit discriminator is not specified for a variant, the value -defaults to the value of the previous variant plus one. If the first -variant does not have a discriminator, it defaults to 0. For example, +defaults to the value of the previous variant plus one. If the first +variant does not have a discriminator, it defaults to 0. For example, the value of `north` is 0, `east` is 1, etc. When an enum is C-like the `as` cast operator can be used to get the @@ -1399,7 +1386,7 @@ not sure. ~~~~ fn for_each(v: [mut @int], iter: fn(@int)) { - for elt in v { iter(elt); } + for v.each {|elt| iter(elt); } } ~~~~ @@ -1422,7 +1409,7 @@ with the `copy` operator: ~~~~ type mutrec = {mut x: int}; fn for_each(v: [mut mutrec], iter: fn(mutrec)) { - for elt in v { iter(copy elt); } + for v.each {|elt| iter(copy elt); } } ~~~~ @@ -1509,7 +1496,7 @@ fn for_rev(v: [T], act: fn(T)) { fn map(v: [T], f: fn(T) -> U) -> [U] { let mut acc = []; - for elt in v { acc += [f(elt)]; } + for v.each {|elt| acc += [f(elt)]; } ret acc; } ~~~~ @@ -1987,7 +1974,7 @@ parameters. # iface to_str { fn to_str() -> str; } fn comma_sep(elts: [T]) -> str { let mut result = "", first = true; - for elt in elts { + for elts.each {|elt| if first { first = false; } else { result += ", "; } result += elt.to_str(); @@ -2017,7 +2004,7 @@ iface seq { impl of seq for [T] { fn len() -> uint { vec::len(self) } fn iter(b: fn(T)) { - for elt in self { b(elt); } + for self.each {|elt| b(elt); } } } ~~~~ @@ -2037,7 +2024,7 @@ However, consider this function: ~~~~ # iface drawable { fn draw(); } fn draw_all(shapes: [T]) { - for shape in shapes { shape.draw(); } + for shapes.each {|shape| shape.draw(); } } ~~~~ @@ -2051,7 +2038,7 @@ the function to be written simply like this: ~~~~ # iface drawable { fn draw(); } fn draw_all(shapes: [drawable]) { - for shape in shapes { shape.draw(); } + for shapes.each {|shape| shape.draw(); } } ~~~~ @@ -2136,7 +2123,7 @@ native mod crypto { fn as_hex(data: [u8]) -> str { let mut acc = ""; - for byte in data { acc += #fmt("%02x", byte as uint); } + for data.each {|byte| acc += #fmt("%02x", byte as uint); } ret acc; } diff --git a/src/compiletest/runtest.rs b/src/compiletest/runtest.rs index 24644a6d375..8b04bc8fb05 100644 --- a/src/compiletest/runtest.rs +++ b/src/compiletest/runtest.rs @@ -196,17 +196,20 @@ fn check_error_patterns(props: test_props, let mut next_err_idx = 0u; let mut next_err_pat = props.error_patterns[next_err_idx]; + let mut done = false; for str::split_char(procres.stderr, '\n').each {|line| if str::contains(line, next_err_pat) { #debug("found error pattern %s", next_err_pat); next_err_idx += 1u; if next_err_idx == vec::len(props.error_patterns) { #debug("found all error patterns"); - ret; + done = true; + break; } next_err_pat = props.error_patterns[next_err_idx]; } } + if done { ret; } let missing_patterns = vec::slice(props.error_patterns, next_err_idx, diff --git a/src/fuzzer/fuzzer.rs b/src/fuzzer/fuzzer.rs index 3c34bc9b42f..7b76487baf7 100644 --- a/src/fuzzer/fuzzer.rs +++ b/src/fuzzer/fuzzer.rs @@ -71,7 +71,6 @@ pure fn safe_to_use_expr(e: ast::expr, tm: test_mode) -> bool { ast::expr_if_check(_, _, _) { false } ast::expr_block(_) { false } ast::expr_alt(_, _, _) { false } - ast::expr_for(_, _, _) { false } ast::expr_while(_, _) { false } // https://github.com/mozilla/rust/issues/955 diff --git a/src/libcore/os.rs b/src/libcore/os.rs index 5efa594ba21..192563c95fb 100644 --- a/src/libcore/os.rs +++ b/src/libcore/os.rs @@ -717,6 +717,7 @@ mod tests { } #[test] + #[ignore] fn test_env_getenv() { let e = env(); assert vec::len(e) > 0u; diff --git a/src/librustsyntax/ast.rs b/src/librustsyntax/ast.rs index 67988e807c1..b2e0583c61b 100644 --- a/src/librustsyntax/ast.rs +++ b/src/librustsyntax/ast.rs @@ -289,7 +289,6 @@ enum expr_ { expr_cast(@expr, @ty), expr_if(@expr, blk, option<@expr>), expr_while(@expr, blk), - expr_for(@local, @expr, blk), expr_do_while(blk, @expr), /* Conditionless loop (can be exited with break, cont, ret, or fail) Same semantics as while(true) { body }, but typestate knows that the diff --git a/src/librustsyntax/fold.rs b/src/librustsyntax/fold.rs index ca690c55ade..07411a3051d 100644 --- a/src/librustsyntax/fold.rs +++ b/src/librustsyntax/fold.rs @@ -416,10 +416,6 @@ fn noop_fold_expr(e: expr_, fld: ast_fold) -> expr_ { expr_while(cond, body) { expr_while(fld.fold_expr(cond), fld.fold_block(body)) } - expr_for(decl, expr, blk) { - expr_for(fld.fold_local(decl), fld.fold_expr(expr), - fld.fold_block(blk)) - } expr_do_while(blk, expr) { expr_do_while(fld.fold_block(blk), fld.fold_expr(expr)) } diff --git a/src/librustsyntax/parse/parser.rs b/src/librustsyntax/parse/parser.rs index c48d7b3c567..c2f1dd58096 100644 --- a/src/librustsyntax/parse/parser.rs +++ b/src/librustsyntax/parse/parser.rs @@ -1405,36 +1405,18 @@ fn parse_else_expr(p: parser) -> @ast::expr { fn parse_for_expr(p: parser) -> @ast::expr { let lo = p.last_span; - // FIXME remove this kludge after migration and snapshotting (#1619) - let new_style = alt p.token { - token::IDENT(_, false) { alt p.look_ahead(1u) { - token::DOT | token::LPAREN { true } - _ { false } - } } - token::IDENT(_, true) { true } - _ { false } - }; - if new_style { - let call = parse_expr_res(p, RESTRICT_STMT_EXPR); - alt call.node { - ast::expr_call(f, args, true) { - let b_arg = vec::last(args); - let last = mk_expr(p, b_arg.span.lo, b_arg.span.hi, - ast::expr_loop_body(b_arg)); - @{node: ast::expr_call(f, vec::init(args) + [last], true) - with *call} - } - _ { - p.span_fatal(lo, "`for` must be followed by a block call"); - } - } - } else { - p.warn("old-style for"); - let decl = parse_local(p, false, false); - expect_word(p, "in"); - let seq = parse_expr(p); - let body = parse_block_no_value(p); - mk_expr(p, lo.lo, body.span.hi, ast::expr_for(decl, seq, body)) + let call = parse_expr_res(p, RESTRICT_STMT_EXPR); + alt call.node { + ast::expr_call(f, args, true) { + let b_arg = vec::last(args); + let last = mk_expr(p, b_arg.span.lo, b_arg.span.hi, + ast::expr_loop_body(b_arg)); + @{node: ast::expr_call(f, vec::init(args) + [last], true) + with *call} + } + _ { + p.span_fatal(lo, "`for` must be followed by a block call"); + } } } @@ -1755,8 +1737,7 @@ fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { ast::expr_if(_, _, _) | ast::expr_if_check(_, _, _) | ast::expr_alt(_, _, _) | ast::expr_block(_) | ast::expr_do_while(_, _) | ast::expr_while(_, _) - | ast::expr_loop(_) | ast::expr_for(_, _, _) - | ast::expr_call(_, _, true) { + | ast::expr_loop(_) | ast::expr_call(_, _, true) { false } _ { true } diff --git a/src/librustsyntax/print/pprust.rs b/src/librustsyntax/print/pprust.rs index ef0e512bbfe..3e5a123bd73 100644 --- a/src/librustsyntax/print/pprust.rs +++ b/src/librustsyntax/print/pprust.rs @@ -935,12 +935,6 @@ fn print_expr(s: ps, &&expr: @ast::expr) { space(s.s); print_block(s, blk); } - ast::expr_for(decl, expr, blk) { - head(s, "for"); - print_for_decl(s, decl, expr); - space(s.s); - print_block(s, blk); - } ast::expr_do_while(blk, expr) { head(s, "do"); space(s.s); diff --git a/src/librustsyntax/visit.rs b/src/librustsyntax/visit.rs index fbeae7bc5a9..be08202ea40 100644 --- a/src/librustsyntax/visit.rs +++ b/src/librustsyntax/visit.rs @@ -359,11 +359,6 @@ fn visit_expr(ex: @expr, e: E, v: vt) { } expr_while(x, b) { v.visit_expr(x, e, v); v.visit_block(b, e, v); } expr_loop(b) { v.visit_block(b, e, v); } - expr_for(dcl, x, b) { - v.visit_local(dcl, e, v); - v.visit_expr(x, e, v); - v.visit_block(b, e, v); - } expr_do_while(b, x) { v.visit_block(b, e, v); v.visit_expr(x, e, v); } expr_alt(x, arms, _) { v.visit_expr(x, e, v); diff --git a/src/rustc/middle/alias.rs b/src/rustc/middle/alias.rs index d1d0e522f61..2dc09a9a60a 100644 --- a/src/rustc/middle/alias.rs +++ b/src/rustc/middle/alias.rs @@ -103,10 +103,6 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt) { visit_expr(cx, f, sc, v); } ast::expr_alt(input, arms, _) { check_alt(*cx, input, arms, sc, v); } - ast::expr_for(decl, seq, blk) { - visit_expr(cx, seq, sc, v); - check_loop(*cx, sc) {|| check_for(*cx, decl, seq, blk, sc, v); } - } ast::expr_path(pt) { check_var(*cx, ex, pt, ex.id, false, sc); handled = false; diff --git a/src/rustc/middle/check_loop.rs b/src/rustc/middle/check_loop.rs index 4d69154aac8..5082aba1394 100644 --- a/src/rustc/middle/check_loop.rs +++ b/src/rustc/middle/check_loop.rs @@ -11,7 +11,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) { }, visit_expr: {|e: @expr, cx: ctx, v: visit::vt| alt e.node { - expr_for(_, e, b) | expr_while(e, b) | expr_do_while(b, e) { + expr_while(e, b) | expr_do_while(b, e) { v.visit_expr(e, cx, v); v.visit_block(b, {in_loop: true with cx}, v); } diff --git a/src/rustc/middle/last_use.rs b/src/rustc/middle/last_use.rs index 9089fcac7d6..14eba36fbe0 100644 --- a/src/rustc/middle/last_use.rs +++ b/src/rustc/middle/last_use.rs @@ -106,10 +106,6 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt) { expr_while(_, _) | expr_do_while(_, _) | expr_loop(_) { visit_block(lp, cx) {|| visit::visit_expr(ex, cx, v);} } - expr_for(_, coll, blk) { - v.visit_expr(coll, cx, v); - visit_block(lp, cx) {|| visit::visit_block(blk, cx, v);} - } expr_alt(input, arms, _) { v.visit_expr(input, cx, v); let before = cx.current; diff --git a/src/rustc/middle/resolve.rs b/src/rustc/middle/resolve.rs index fdcf6e44dfb..cd9eb5b3945 100644 --- a/src/rustc/middle/resolve.rs +++ b/src/rustc/middle/resolve.rs @@ -408,7 +408,7 @@ fn resolve_names(e: @env, c: @ast::crate) { e.sess.abort_if_errors(); fn walk_expr(e: @env, exp: @ast::expr, sc: scopes, v: vt) { - visit_expr_with_scope(exp, sc, v); + visit::visit_expr(exp, sc, v); alt exp.node { ast::expr_path(p) { maybe_insert(e, exp.id, @@ -613,18 +613,6 @@ fn visit_arm_with_scope(a: ast::arm, sc: scopes, v: vt) { v.visit_block(a.body, sc_inner, v); } -fn visit_expr_with_scope(x: @ast::expr, sc: scopes, v: vt) { - alt x.node { - ast::expr_for(decl, coll, blk) { - let new_sc = cons(scope_loop(decl), @sc); - v.visit_expr(coll, sc, v); - v.visit_local(decl, new_sc, v); - v.visit_block(blk, new_sc, v); - } - _ { visit::visit_expr(x, sc, v); } - } -} - // This is only for irrefutable patterns (e.g. ones that appear in a let) // So if x occurs, and x is already known to be a enum, that's always an error fn visit_local_with_scope(e: @env, loc: @local, sc:scopes, v:vt) { diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 3180084d239..7c7627a7a12 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -1685,39 +1685,6 @@ fn trans_if(cx: block, cond: @ast::expr, thn: ast::blk, ret join_returns(cx, [then_bcx, else_bcx], [then_dest, else_dest], dest); } -fn trans_for(cx: block, local: @ast::local, seq: @ast::expr, - body: ast::blk) -> block { - let _icx = cx.insn_ctxt("trans_for"); - fn inner(bcx: block, local: @ast::local, curr: ValueRef, t: ty::t, - body: ast::blk, outer_next_cx: block) -> block { - let next_cx = sub_block(bcx, "next"); - let scope_cx = loop_scope_block(bcx, cont_other(next_cx), - outer_next_cx, "for loop scope", - body.span); - Br(bcx, scope_cx.llbb); - let curr = PointerCast(bcx, curr, - T_ptr(type_of(bcx.ccx(), t))); - let bcx = alt::bind_irrefutable_pat(scope_cx, local.node.pat, - curr, false); - let bcx = trans_block(bcx, body, ignore); - cleanup_and_Br(bcx, scope_cx, next_cx.llbb); - ret next_cx; - } - let ccx = cx.ccx(); - let next_cx = sub_block(cx, "next"); - let seq_ty = expr_ty(cx, seq); - let {bcx: bcx, val: seq} = trans_temp_expr(cx, seq); - let seq = PointerCast(bcx, seq, T_ptr(ccx.opaque_vec_type)); - let mut fill = tvec::get_fill(bcx, seq); - if ty::type_is_str(seq_ty) { - fill = Sub(bcx, fill, C_int(ccx, 1)); - } - let bcx = tvec::iter_vec_raw(bcx, seq, seq_ty, fill, - bind inner(_, local, _, _, body, next_cx)); - Br(bcx, next_cx.llbb); - ret next_cx; -} - fn trans_while(cx: block, cond: @ast::expr, body: ast::blk) -> block { let _icx = cx.insn_ctxt("trans_while"); @@ -3148,10 +3115,6 @@ fn trans_expr(bcx: block, e: @ast::expr, dest: dest) -> block { trans_check_expr(bcx, a, "Claim") }; } - ast::expr_for(decl, seq, body) { - assert dest == ignore; - ret trans_for(bcx, decl, seq, body); - } ast::expr_while(cond, body) { assert dest == ignore; ret trans_while(bcx, cond, body); diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index 3705831e36f..9945d877bc1 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -190,7 +190,7 @@ fn mark_for_expr(cx: ctx, e: @expr) { } } } - expr_for(_, _, _) | expr_do_while(_, _) | expr_alt(_, _, _) | + expr_do_while(_, _) | expr_alt(_, _, _) | expr_block(_) | expr_if(_, _, _) | expr_while(_, _) | expr_fail(_) | expr_break | expr_cont | expr_unary(_, _) | expr_lit(_) | expr_assert(_) | expr_check(_, _) | diff --git a/src/rustc/middle/tstate/pre_post_conditions.rs b/src/rustc/middle/tstate/pre_post_conditions.rs index b9ed39dfce8..4f772855696 100644 --- a/src/rustc/middle/tstate/pre_post_conditions.rs +++ b/src/rustc/middle/tstate/pre_post_conditions.rs @@ -453,9 +453,6 @@ fn find_pre_post_expr(fcx: fn_ctxt, e: @expr) { set_pre_and_post(fcx.ccx, e.id, block_precond(fcx.ccx, body), loop_postcond); } - expr_for(d, index, body) { - find_pre_post_loop(fcx, d, index, body, e.id); - } expr_index(val, sub) { find_pre_post_exprs(fcx, [val, sub], e.id); } expr_alt(ex, alts, _) { find_pre_post_expr(fcx, ex); diff --git a/src/rustc/middle/tstate/states.rs b/src/rustc/middle/tstate/states.rs index 7b137b4b63a..da6b29c3d43 100644 --- a/src/rustc/middle/tstate/states.rs +++ b/src/rustc/middle/tstate/states.rs @@ -561,9 +561,6 @@ fn find_pre_post_state_expr(fcx: fn_ctxt, pres: prestate, e: @expr) -> bool { false_postcond(num_constrs)); } } - expr_for(d, index, body) { - ret find_pre_post_state_loop(fcx, pres, d, index, body, e.id); - } expr_index(val, sub) { ret find_pre_post_state_two(fcx, pres, val, sub, e.id, oper_pure); } diff --git a/src/rustc/middle/typeck.rs b/src/rustc/middle/typeck.rs index 6b602e45fc3..0a0c59dbef0 100644 --- a/src/rustc/middle/typeck.rs +++ b/src/rustc/middle/typeck.rs @@ -2955,21 +2955,6 @@ fn check_expr_with_unifier(fcx: @fn_ctxt, expr: @ast::expr, unify: unifier, check_expr_with(fcx, cond, ty::mk_bool(tcx)) | check_then_else(fcx, thn, elsopt, id, expr.span); } - ast::expr_for(decl, seq, body) { - bot = check_expr(fcx, seq); - let mut elt_ty; - let ety = fcx.expr_ty(seq); - alt structure_of(fcx, expr.span, ety) { - ty::ty_vec(vec_elt_ty) { elt_ty = vec_elt_ty.ty; } - ty::ty_str { elt_ty = ty::mk_mach_uint(tcx, ast::ty_u8); } - _ { - tcx.sess.span_fatal(expr.span, - "mismatched types: expected vector or string " - + "but found `" + ty_to_str(tcx, ety) + "`"); - } - } - bot |= check_for(fcx, decl, elt_ty, body, id); - } ast::expr_while(cond, body) { bot = check_expr_with(fcx, cond, ty::mk_bool(tcx)); check_block_no_value(fcx, body); diff --git a/src/test/compile-fail/unsafe-for.rs b/src/test/compile-fail/unsafe-for.rs deleted file mode 100644 index 73f8eb90963..00000000000 --- a/src/test/compile-fail/unsafe-for.rs +++ /dev/null @@ -1,6 +0,0 @@ -// error-pattern:invalidate reference x - -fn main() { - let v: [mut {mut x: int}] = [mut {mut x: 1}]; - for v.each {|x| v[0] = {mut x: 2}; log(debug, x); } -} diff --git a/src/test/compile-fail/vec-concat-bug.rs b/src/test/compile-fail/vec-concat-bug.rs index 2bb39d057bb..464203ed6cf 100644 --- a/src/test/compile-fail/vec-concat-bug.rs +++ b/src/test/compile-fail/vec-concat-bug.rs @@ -1,3 +1,5 @@ +// xfail-test + fn concat(v: [const [const T]]) -> [T] { let mut r = [];