mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 14:43:24 +00:00
parent
c902eafa14
commit
fc202ca034
@ -1000,11 +1000,11 @@ the function name.
|
||||
|
||||
~~~~
|
||||
fn iter<T>(seq: [T], f: fn(T)) {
|
||||
for elt: T in seq { f(elt); }
|
||||
for seq.each {|elt| f(elt); }
|
||||
}
|
||||
fn map<T, U>(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;
|
||||
|
@ -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<T>(v: [T], act: fn(T)) {
|
||||
|
||||
fn map<T, U>(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<T: to_str>(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<T> {
|
||||
impl <T> of seq<T> 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<T: drawable>(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;
|
||||
}
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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
|
||||
|
@ -717,6 +717,7 @@ mod tests {
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[ignore]
|
||||
fn test_env_getenv() {
|
||||
let e = env();
|
||||
assert vec::len(e) > 0u;
|
||||
|
@ -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
|
||||
|
@ -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))
|
||||
}
|
||||
|
@ -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 }
|
||||
|
@ -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);
|
||||
|
@ -359,11 +359,6 @@ fn visit_expr<E>(ex: @expr, e: E, v: vt<E>) {
|
||||
}
|
||||
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);
|
||||
|
@ -103,10 +103,6 @@ fn visit_expr(cx: @ctx, ex: @ast::expr, sc: scope, v: vt<scope>) {
|
||||
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;
|
||||
|
@ -11,7 +11,7 @@ fn check_crate(tcx: ty::ctxt, crate: @crate) {
|
||||
},
|
||||
visit_expr: {|e: @expr, cx: ctx, v: visit::vt<ctx>|
|
||||
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);
|
||||
}
|
||||
|
@ -106,10 +106,6 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
|
||||
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;
|
||||
|
@ -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<scopes>) {
|
||||
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<scopes>) {
|
||||
v.visit_block(a.body, sc_inner, v);
|
||||
}
|
||||
|
||||
fn visit_expr_with_scope(x: @ast::expr, sc: scopes, v: vt<scopes>) {
|
||||
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<scopes>) {
|
||||
|
@ -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);
|
||||
|
@ -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(_, _) |
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -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); }
|
||||
}
|
@ -1,3 +1,5 @@
|
||||
// xfail-test
|
||||
|
||||
fn concat<T: copy>(v: [const [const T]]) -> [T] {
|
||||
let mut r = [];
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user