diff --git a/src/libextra/dlist.rs b/src/libextra/dlist.rs index 9eacddd90028b..35600df4f9dd0 100644 --- a/src/libextra/dlist.rs +++ b/src/libextra/dlist.rs @@ -173,11 +173,11 @@ impl Deque for DList { let tail_own = match tail.prev.resolve() { None => { self.list_tail = Rawlink::none(); - self.list_head.swap_unwrap() + self.list_head.take_unwrap() }, Some(tail_prev) => { self.list_tail = tail.prev; - tail_prev.next.swap_unwrap() + tail_prev.next.take_unwrap() } }; Some(tail_own.value) @@ -465,7 +465,7 @@ impl<'self, A> ListInsertion for MutDListIterator<'self, A> { Some(prev) => prev, }; let mut ins_node = ~Node{value: elt, next: None, prev: Rawlink::none()}; - let node_own = prev_node.next.swap_unwrap(); + let node_own = prev_node.next.take_unwrap(); ins_node.next = link_with_prev(node_own, Rawlink::some(ins_node)); prev_node.next = link_with_prev(ins_node, Rawlink::some(prev_node)); self.list.length += 1; diff --git a/src/libextra/net/ip.rs b/src/libextra/net/ip.rs index 6876b3510b6ca..11e3106e4b5a9 100644 --- a/src/libextra/net/ip.rs +++ b/src/libextra/net/ip.rs @@ -116,7 +116,7 @@ pub fn get_addr(node: &str, iotask: &iotask) let (output_po, output_ch) = stream(); let mut output_ch = Some(SharedChan::new(output_ch)); do str::as_buf(node) |node_ptr, len| { - let output_ch = output_ch.swap_unwrap(); + let output_ch = output_ch.take_unwrap(); debug!("slice len %?", len); let handle = create_uv_getaddrinfo_t(); let handle_ptr: *uv_getaddrinfo_t = &handle; diff --git a/src/libextra/smallintmap.rs b/src/libextra/smallintmap.rs index 27e9f8cd60f33..200e824209450 100644 --- a/src/libextra/smallintmap.rs +++ b/src/libextra/smallintmap.rs @@ -161,8 +161,8 @@ impl SmallIntMap { /// Visit all key-value pairs in reverse order pub fn each_reverse<'a>(&'a self, it: &fn(uint, &'a V) -> bool) -> bool { for uint::range_rev(self.v.len(), 0) |i| { - match self.v[i - 1] { - Some(ref elt) => if !it(i - 1, elt) { return false; }, + match self.v[i] { + Some(ref elt) => if !it(i, elt) { return false; }, None => () } } diff --git a/src/libextra/sync.rs b/src/libextra/sync.rs index b9d25451a8a95..632f5d7827d4c 100644 --- a/src/libextra/sync.rs +++ b/src/libextra/sync.rs @@ -260,7 +260,7 @@ impl<'self> Condvar<'self> { signal_waitqueue(&state.waiters); } // Enqueue ourself to be woken up by a signaller. - let SignalEnd = SignalEnd.swap_unwrap(); + let SignalEnd = SignalEnd.take_unwrap(); state.blocked[condvar_id].tail.send(SignalEnd); } else { out_of_bounds = Some(state.blocked.len()); @@ -281,7 +281,7 @@ impl<'self> Condvar<'self> { // Unconditionally "block". (Might not actually block if a // signaller already sent -- I mean 'unconditionally' in contrast // with acquire().) - let _ = comm::recv_one(WaitEnd.swap_unwrap()); + let _ = comm::recv_one(WaitEnd.take_unwrap()); } // This is needed for a failing condition variable to reacquire the @@ -353,7 +353,7 @@ impl<'self> Condvar<'self> { } } do check_cvar_bounds(out_of_bounds, condvar_id, "cond.signal_on()") { - let queue = queue.swap_unwrap(); + let queue = queue.take_unwrap(); broadcast_waitqueue(&queue) } } @@ -1436,7 +1436,7 @@ mod tests { do x.write_downgrade |xwrite| { let mut xopt = Some(xwrite); do y.write_downgrade |_ywrite| { - y.downgrade(xopt.swap_unwrap()); + y.downgrade(xopt.take_unwrap()); error!("oops, y.downgrade(x) should have failed!"); } } diff --git a/src/libextra/treemap.rs b/src/libextra/treemap.rs index f1fe7acb00f83..bd13c8619be1d 100644 --- a/src/libextra/treemap.rs +++ b/src/libextra/treemap.rs @@ -552,7 +552,7 @@ fn mutate_values<'r, K: TotalOrd, V>(node: &'r mut Option<~TreeNode>, // Remove left horizontal link by rotating right fn skew(node: &mut ~TreeNode) { if node.left.map_default(false, |x| x.level == node.level) { - let mut save = node.left.swap_unwrap(); + let mut save = node.left.take_unwrap(); swap(&mut node.left, &mut save.right); // save.right now None swap(node, &mut save); node.right = Some(save); @@ -564,7 +564,7 @@ fn skew(node: &mut ~TreeNode) { fn split(node: &mut ~TreeNode) { if node.right.map_default(false, |x| x.right.map_default(false, |y| y.level == node.level)) { - let mut save = node.right.swap_unwrap(); + let mut save = node.right.take_unwrap(); swap(&mut node.right, &mut save.left); // save.left now None save.level += 1; swap(node, &mut save); @@ -643,7 +643,7 @@ fn remove(node: &mut Option<~TreeNode>, Equal => { if save.left.is_some() { if save.right.is_some() { - let mut left = save.left.swap_unwrap(); + let mut left = save.left.take_unwrap(); if left.right.is_some() { heir_swap(save, &mut left.right); } else { @@ -653,13 +653,13 @@ fn remove(node: &mut Option<~TreeNode>, save.left = Some(left); (remove(&mut save.left, key), true) } else { - let new = save.left.swap_unwrap(); + let new = save.left.take_unwrap(); let ~TreeNode{value, _} = replace(save, new); - *save = save.left.swap_unwrap(); + *save = save.left.take_unwrap(); (Some(value), true) } } else if save.right.is_some() { - let new = save.right.swap_unwrap(); + let new = save.right.take_unwrap(); let ~TreeNode{value, _} = replace(save, new); (Some(value), true) } else { diff --git a/src/librustc/driver/driver.rs b/src/librustc/driver/driver.rs index d41c1167c70ce..15ce8c4c7e286 100644 --- a/src/librustc/driver/driver.rs +++ b/src/librustc/driver/driver.rs @@ -422,7 +422,7 @@ pub fn pretty_print_input(sess: Session, cfg: ast::crate_cfg, input: &input, pprust::node_block(s, ref blk) => { pp::space(s.s); pprust::synth_comment( - s, ~"block " + int::to_str(blk.node.id)); + s, ~"block " + int::to_str(blk.id)); } pprust::node_expr(s, expr) => { pp::space(s.s); diff --git a/src/librustc/front/config.rs b/src/librustc/front/config.rs index 0d4d96b3b2b3e..9a468788f7a42 100644 --- a/src/librustc/front/config.rs +++ b/src/librustc/front/config.rs @@ -33,7 +33,7 @@ pub fn strip_items(crate: &ast::crate, in_cfg: in_cfg_pred) let precursor = @fold::AstFoldFns { fold_mod: |a,b| fold_mod(ctxt, a, b), - fold_block: fold::wrap(|a,b| fold_block(ctxt, a, b) ), + fold_block: |a,b| fold_block(ctxt, a, b), fold_foreign_mod: |a,b| fold_foreign_mod(ctxt, a, b), fold_item_underscore: |a,b| { // Bad copy. @@ -133,21 +133,22 @@ fn filter_stmt(cx: @Context, stmt: @ast::stmt) -> fn fold_block( cx: @Context, - b: &ast::blk_, + b: &ast::blk, fld: @fold::ast_fold -) -> ast::blk_ { +) -> ast::blk { let resulting_stmts = do b.stmts.iter().filter_map |a| { filter_stmt(cx, *a).chain(|stmt| fld.fold_stmt(stmt)) }.collect(); let filtered_view_items = do b.view_items.iter().filter_map |a| { filter_view_item(cx, a).map(|&x| fld.fold_view_item(x)) }.collect(); - ast::blk_ { + ast::blk { view_items: filtered_view_items, stmts: resulting_stmts, expr: b.expr.map(|x| fld.fold_expr(*x)), id: b.id, rules: b.rules, + span: b.span, } } diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 2e0090f7dda04..7684f465a4c33 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -289,7 +289,7 @@ fn encode_ast(ebml_w: &mut writer::Encoder, item: ast::inlined_item) { // nested items, as otherwise it would get confused when translating // inlined items. fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item { - fn drop_nested_items(blk: &ast::blk_, fld: @fold::ast_fold) -> ast::blk_ { + fn drop_nested_items(blk: &ast::blk, fld: @fold::ast_fold) -> ast::blk { let stmts_sans_items = do blk.stmts.iter().filter_map |stmt| { match stmt.node { ast::stmt_expr(_, _) | ast::stmt_semi(_, _) | @@ -300,19 +300,20 @@ fn simplify_ast(ii: &ast::inlined_item) -> ast::inlined_item { ast::stmt_mac(*) => fail!("unexpanded macro in astencode") } }.collect(); - let blk_sans_items = ast::blk_ { + let blk_sans_items = ast::blk { view_items: ~[], // I don't know if we need the view_items here, // but it doesn't break tests! stmts: stmts_sans_items, expr: blk.expr, id: blk.id, - rules: blk.rules + rules: blk.rules, + span: blk.span, }; fold::noop_fold_block(&blk_sans_items, fld) } let fld = fold::make_fold(@fold::AstFoldFns { - fold_block: fold::wrap(drop_nested_items), + fold_block: drop_nested_items, .. *fold::default_ast_fold() }); diff --git a/src/librustc/middle/borrowck/check_loans.rs b/src/librustc/middle/borrowck/check_loans.rs index a455bdc436cad..f10a2a258fe9b 100644 --- a/src/librustc/middle/borrowck/check_loans.rs +++ b/src/librustc/middle/borrowck/check_loans.rs @@ -44,7 +44,7 @@ pub fn check_loans(bccx: @BorrowckCtxt, move_data: move_data::FlowedMoveData, all_loans: &[Loan], body: &ast::blk) { - debug!("check_loans(body id=%?)", body.node.id); + debug!("check_loans(body id=%?)", body.id); let clcx = @mut CheckLoanCtxt { bccx: bccx, @@ -751,5 +751,5 @@ fn check_loans_in_block<'a>(blk: &ast::blk, visit::vt<@mut CheckLoanCtxt<'a>>)) { visit::visit_block(blk, (this, vt)); - this.check_for_conflicting_loans(blk.node.id); + this.check_for_conflicting_loans(blk.id); } diff --git a/src/librustc/middle/borrowck/gather_loans/mod.rs b/src/librustc/middle/borrowck/gather_loans/mod.rs index 23451e0f36ea0..ce18785ca3969 100644 --- a/src/librustc/middle/borrowck/gather_loans/mod.rs +++ b/src/librustc/middle/borrowck/gather_loans/mod.rs @@ -80,8 +80,8 @@ pub fn gather_loans(bccx: @BorrowckCtxt, bccx: bccx, id_range: id_range::max(), all_loans: @mut ~[], - item_ub: body.node.id, - repeating_ids: ~[body.node.id], + item_ub: body.id, + repeating_ids: ~[body.id], move_data: @mut MoveData::new() }; glcx.gather_fn_arg_patterns(decl, body); @@ -123,9 +123,9 @@ fn gather_loans_in_fn(fk: &visit::fn_kind, // Visit closures as part of the containing item. &visit::fk_anon(*) | &visit::fk_fn_block(*) => { - this.push_repeating_id(body.node.id); + this.push_repeating_id(body.id); visit::visit_fn(fk, decl, body, sp, id, (this, v)); - this.pop_repeating_id(body.node.id); + this.pop_repeating_id(body.id); this.gather_fn_arg_patterns(decl, body); } } @@ -134,7 +134,7 @@ fn gather_loans_in_fn(fk: &visit::fn_kind, fn gather_loans_in_block(blk: &ast::blk, (this, vt): (@mut GatherLoanCtxt, visit::vt<@mut GatherLoanCtxt>)) { - this.id_range.add(blk.node.id); + this.id_range.add(blk.id); visit::visit_block(blk, (this, vt)); } @@ -240,7 +240,7 @@ fn gather_loans_in_expr(ex: @ast::expr, let cmt = this.bccx.cat_expr(ex_v); for arms.iter().advance |arm| { for arm.pats.iter().advance |pat| { - this.gather_pat(cmt, *pat, Some((arm.body.node.id, ex.id))); + this.gather_pat(cmt, *pat, Some((arm.body.id, ex.id))); } } visit::visit_expr(ex, (this, vt)); @@ -268,16 +268,16 @@ fn gather_loans_in_expr(ex: @ast::expr, this.pop_repeating_id(cond.id); // during body, can only root for the body - this.push_repeating_id(body.node.id); + this.push_repeating_id(body.id); (vt.visit_block)(body, (this, vt)); - this.pop_repeating_id(body.node.id); + this.pop_repeating_id(body.id); } // see explanation attached to the `root_ub` field: ast::expr_loop(ref body, _) => { - this.push_repeating_id(body.node.id); + this.push_repeating_id(body.id); visit::visit_expr(ex, (this, vt)); - this.pop_repeating_id(body.node.id); + this.pop_repeating_id(body.id); } ast::expr_fn_block(*) => { @@ -623,7 +623,7 @@ impl GatherLoanCtxt { let arg_cmt = mc_ctxt.cat_rvalue( arg.id, arg.pat.span, - body.node.id, // Arguments live only as long as the fn body. + body.id, // Arguments live only as long as the fn body. arg_ty); self.gather_pat(arg_cmt, arg.pat, None); diff --git a/src/librustc/middle/cfg/construct.rs b/src/librustc/middle/cfg/construct.rs index 9ecb4dcaf5e9f..19debc9c12354 100644 --- a/src/librustc/middle/cfg/construct.rs +++ b/src/librustc/middle/cfg/construct.rs @@ -53,13 +53,13 @@ pub fn construct(tcx: ty::ctxt, impl CFGBuilder { fn block(&mut self, blk: &ast::blk, pred: CFGIndex) -> CFGIndex { let mut stmts_exit = pred; - for blk.node.stmts.iter().advance |&stmt| { + for blk.stmts.iter().advance |&stmt| { stmts_exit = self.stmt(stmt, stmts_exit); } - let expr_exit = self.opt_expr(blk.node.expr, stmts_exit); + let expr_exit = self.opt_expr(blk.expr, stmts_exit); - self.add_node(blk.node.id, [expr_exit]) + self.add_node(blk.id, [expr_exit]) } fn stmt(&mut self, stmt: @ast::stmt, pred: CFGIndex) -> CFGIndex { diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index af39dea6d79e1..2cf99e07dc9f1 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -165,10 +165,58 @@ pub fn classify(e: &expr, pub fn lookup_const(tcx: ty::ctxt, e: &expr) -> Option<@expr> { match tcx.def_map.find(&e.id) { Some(&ast::def_static(def_id, false)) => lookup_const_by_id(tcx, def_id), + Some(&ast::def_variant(enum_def, variant_def)) => lookup_variant_by_id(tcx, + enum_def, + variant_def), _ => None } } +pub fn lookup_variant_by_id(tcx: ty::ctxt, + enum_def: ast::def_id, + variant_def: ast::def_id) + -> Option<@expr> { + fn variant_expr(variants: &[ast::variant], id: ast::node_id) -> Option<@expr> { + for variants.iter().advance |variant| { + if variant.node.id == id { + return variant.node.disr_expr; + } + } + None + } + + if ast_util::is_local(enum_def) { + match tcx.items.find(&enum_def.node) { + None => None, + Some(&ast_map::node_item(it, _)) => match it.node { + item_enum(ast::enum_def { variants: ref variants }, _) => { + variant_expr(*variants, variant_def.node) + } + _ => None + }, + Some(_) => None + } + } else { + let maps = astencode::Maps { + root_map: @mut HashMap::new(), + method_map: @mut HashMap::new(), + vtable_map: @mut HashMap::new(), + write_guard_map: @mut HashSet::new(), + capture_map: @mut HashMap::new() + }; + match csearch::maybe_get_item_ast(tcx, enum_def, + |a, b, c, d| astencode::decode_inlined_item(a, b, maps, /*bar*/ copy c, d)) { + csearch::found(ast::ii_item(item)) => match item.node { + item_enum(ast::enum_def { variants: ref variants }, _) => { + variant_expr(*variants, variant_def.node) + } + _ => None + }, + _ => None + } + } +} + pub fn lookup_const_by_id(tcx: ty::ctxt, def_id: ast::def_id) -> Option<@expr> { @@ -237,13 +285,13 @@ pub enum const_val { } pub fn eval_const_expr(tcx: middle::ty::ctxt, e: &expr) -> const_val { - match eval_const_expr_partial(tcx, e) { + match eval_const_expr_partial(&tcx, e) { Ok(r) => r, Err(s) => tcx.sess.span_fatal(e.span, s) } } -pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) +pub fn eval_const_expr_partial(tcx: &T, e: &expr) -> Result { use middle::ty; fn fromb(b: bool) -> Result { Ok(const_int(b as i64)) } @@ -360,7 +408,7 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) } } expr_cast(base, _) => { - let ety = ty::expr_ty(tcx, e); + let ety = tcx.expr_ty(e); let base = eval_const_expr_partial(tcx, base); match /*bad*/copy base { Err(_) => base, @@ -390,8 +438,8 @@ pub fn eval_const_expr_partial(tcx: middle::ty::ctxt, e: &expr) } } expr_path(_) => { - match lookup_const(tcx, e) { - Some(actual_e) => eval_const_expr_partial(tcx, actual_e), + match lookup_const(tcx.ty_ctxt(), e) { + Some(actual_e) => eval_const_expr_partial(&tcx.ty_ctxt(), actual_e), None => Err(~"Non-constant path in constant expr") } } diff --git a/src/librustc/middle/dataflow.rs b/src/librustc/middle/dataflow.rs index ec375eaba0e86..8c464928b5825 100644 --- a/src/librustc/middle/dataflow.rs +++ b/src/librustc/middle/dataflow.rs @@ -330,7 +330,7 @@ impl DataFlowContext { let pre: @fn(pprust::ann_node) = |node| { let (ps, id) = match node { pprust::node_expr(ps, expr) => (ps, expr.id), - pprust::node_block(ps, blk) => (ps, blk.node.id), + pprust::node_block(ps, blk) => (ps, blk.id), pprust::node_item(ps, _) => (ps, 0), pprust::node_pat(ps, pat) => (ps, pat.id) }; @@ -383,18 +383,18 @@ impl<'self, O:DataFlowOperator> PropagationContext<'self, O> { blk: &ast::blk, in_out: &mut [uint], loop_scopes: &mut ~[LoopScope]) { - debug!("DataFlowContext::walk_block(blk.node.id=%?, in_out=%s)", - blk.node.id, bits_to_str(reslice(in_out))); + debug!("DataFlowContext::walk_block(blk.id=%?, in_out=%s)", + blk.id, bits_to_str(reslice(in_out))); - self.merge_with_entry_set(blk.node.id, in_out); + self.merge_with_entry_set(blk.id, in_out); - for blk.node.stmts.iter().advance |&stmt| { + for blk.stmts.iter().advance |&stmt| { self.walk_stmt(stmt, in_out, loop_scopes); } - self.walk_opt_expr(blk.node.expr, in_out, loop_scopes); + self.walk_opt_expr(blk.expr, in_out, loop_scopes); - self.dfcx.apply_gen_kill(blk.node.id, in_out); + self.dfcx.apply_gen_kill(blk.id, in_out); } fn walk_stmt(&mut self, diff --git a/src/librustc/middle/effect.rs b/src/librustc/middle/effect.rs index 654cc25c15e8c..5970054620558 100644 --- a/src/librustc/middle/effect.rs +++ b/src/librustc/middle/effect.rs @@ -99,9 +99,9 @@ pub fn check_crate(tcx: ty::ctxt, visit_block: |block, (_, visitor)| { let old_unsafe_context = context.unsafe_context; - if block.node.rules == unsafe_blk && + if block.rules == unsafe_blk && context.unsafe_context == SafeContext { - context.unsafe_context = UnsafeBlock(block.node.id) + context.unsafe_context = UnsafeBlock(block.id) } visit::visit_block(block, ((), visitor)); diff --git a/src/librustc/middle/kind.rs b/src/librustc/middle/kind.rs index a9454d1b23096..ae2a27ed6ed7b 100644 --- a/src/librustc/middle/kind.rs +++ b/src/librustc/middle/kind.rs @@ -309,7 +309,7 @@ pub fn check_expr(e: @expr, (cx, v): (Context, visit::vt)) { "explicit copy requires a copyable argument"); } expr_repeat(element, count_expr, _) => { - let count = ty::eval_repeat_count(cx.tcx, count_expr); + let count = ty::eval_repeat_count(&cx.tcx, count_expr); if count > 1 { let element_ty = ty::expr_ty(cx.tcx, element); check_copy(cx, element_ty, element.span, diff --git a/src/librustc/middle/lint.rs b/src/librustc/middle/lint.rs index b679da714a174..128755364b0ba 100644 --- a/src/librustc/middle/lint.rs +++ b/src/librustc/middle/lint.rs @@ -916,8 +916,8 @@ fn lint_unused_unsafe() -> visit::vt<@mut Context> { visit::mk_vt(@visit::Visitor { visit_expr: |e, (cx, vt): (@mut Context, visit::vt<@mut Context>)| { match e.node { - ast::expr_block(ref blk) if blk.node.rules == ast::unsafe_blk => { - if !cx.tcx.used_unsafe.contains(&blk.node.id) { + ast::expr_block(ref blk) if blk.rules == ast::unsafe_blk => { + if !cx.tcx.used_unsafe.contains(&blk.id) { cx.span_lint(unused_unsafe, blk.span, "unnecessary `unsafe` block"); } diff --git a/src/librustc/middle/liveness.rs b/src/librustc/middle/liveness.rs index 83f8b161b7522..a62a14ed48180 100644 --- a/src/librustc/middle/liveness.rs +++ b/src/librustc/middle/liveness.rs @@ -886,7 +886,7 @@ impl Liveness { self.tcx.sess.intr())); let entry_ln: LiveNode = - self.with_loop_nodes(body.node.id, self.s.exit_ln, self.s.exit_ln, + self.with_loop_nodes(body.id, self.s.exit_ln, self.s.exit_ln, || { self.propagate_through_fn_block(decl, body) }); // hack to skip the loop unless debug! is enabled: @@ -895,7 +895,7 @@ impl Liveness { for uint::range(0u, self.ir.num_live_nodes) |ln_idx| { debug!("%s", self.ln_str(LiveNode(ln_idx))); } - body.node.id + body.id }, entry_ln.to_str()); @@ -907,7 +907,7 @@ impl Liveness { // the fallthrough exit is only for those cases where we do not // explicitly return: self.init_from_succ(self.s.fallthrough_ln, self.s.exit_ln); - if blk.node.expr.is_none() { + if blk.expr.is_none() { self.acc(self.s.fallthrough_ln, self.s.no_ret_var, ACC_READ) } @@ -916,8 +916,8 @@ impl Liveness { pub fn propagate_through_block(&self, blk: &blk, succ: LiveNode) -> LiveNode { - let succ = self.propagate_through_opt_expr(blk.node.expr, succ); - do blk.node.stmts.rev_iter().fold(succ) |succ, stmt| { + let succ = self.propagate_through_opt_expr(blk.expr, succ); + do blk.stmts.rev_iter().fold(succ) |succ, stmt| { self.propagate_through_stmt(*stmt, succ) } } @@ -1009,7 +1009,7 @@ impl Liveness { The next-node for a break is the successor of the entire loop. The next-node for a continue is the top of this loop. */ - self.with_loop_nodes(blk.node.id, succ, + self.with_loop_nodes(blk.id, succ, self.live_node(expr.id, expr.span), || { // the construction of a closure itself is not important, diff --git a/src/librustc/middle/moves.rs b/src/librustc/middle/moves.rs index 07bdee07c0feb..d569f852612ec 100644 --- a/src/librustc/middle/moves.rs +++ b/src/librustc/middle/moves.rs @@ -285,13 +285,13 @@ impl VisitContext { * meaning either copied or moved depending on its type. */ - debug!("consume_block(blk.id=%?)", blk.node.id); + debug!("consume_block(blk.id=%?)", blk.id); - for blk.node.stmts.iter().advance |stmt| { + for blk.stmts.iter().advance |stmt| { (visitor.visit_stmt)(*stmt, (*self, visitor)); } - for blk.node.expr.iter().advance |tail_expr| { + for blk.expr.iter().advance |tail_expr| { self.consume_expr(*tail_expr, visitor); } } diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs index 8a2b134191534..0a13cf4ed1856 100644 --- a/src/librustc/middle/privacy.rs +++ b/src/librustc/middle/privacy.rs @@ -384,7 +384,7 @@ pub fn check_crate<'mm>(tcx: ty::ctxt, visit_block: |block, (method_map, visitor)| { // Gather up all the privileged items. let mut n_added = 0; - for block.node.stmts.iter().advance |stmt| { + for block.stmts.iter().advance |stmt| { match stmt.node { stmt_decl(decl, _) => { match decl.node { diff --git a/src/librustc/middle/region.rs b/src/librustc/middle/region.rs index e1c43121ec82b..4ede700d7a65d 100644 --- a/src/librustc/middle/region.rs +++ b/src/librustc/middle/region.rs @@ -324,11 +324,11 @@ fn parent_to_expr(cx: Context, child_id: ast::node_id, sp: span) { fn resolve_block(blk: &ast::blk, (cx, visitor): (Context, visit::vt)) { // Record the parent of this block. - parent_to_expr(cx, blk.node.id, blk.span); + parent_to_expr(cx, blk.id, blk.span); // Descend. - let new_cx = Context {var_parent: Some(blk.node.id), - parent: Some(blk.node.id), + let new_cx = Context {var_parent: Some(blk.id), + parent: Some(blk.id), ..cx}; visit::visit_block(blk, (new_cx, visitor)); } @@ -420,20 +420,20 @@ fn resolve_fn(fk: &visit::fn_kind, visit::vt)) { debug!("region::resolve_fn(id=%?, \ span=%?, \ - body.node.id=%?, \ + body.id=%?, \ cx.parent=%?)", id, cx.sess.codemap.span_to_str(sp), - body.node.id, + body.id, cx.parent); // The arguments and `self` are parented to the body of the fn. - let decl_cx = Context {parent: Some(body.node.id), - var_parent: Some(body.node.id), + let decl_cx = Context {parent: Some(body.id), + var_parent: Some(body.id), ..cx}; match *fk { visit::fk_method(_, _, method) => { - cx.region_maps.record_parent(method.self_id, body.node.id); + cx.region_maps.record_parent(method.self_id, body.id); } _ => {} } diff --git a/src/librustc/middle/resolve.rs b/src/librustc/middle/resolve.rs index 619bfbdb54784..fbb89ffe69088 100644 --- a/src/librustc/middle/resolve.rs +++ b/src/librustc/middle/resolve.rs @@ -1069,12 +1069,12 @@ impl Resolver { pub fn block_needs_anonymous_module(@mut self, block: &blk) -> bool { // If the block has view items, we need an anonymous module. - if block.node.view_items.len() > 0 { + if block.view_items.len() > 0 { return true; } // Check each statement. - for block.node.stmts.iter().advance |statement| { + for block.stmts.iter().advance |statement| { match statement.node { stmt_decl(declaration, _) => { match declaration.node { @@ -1566,7 +1566,7 @@ impl Resolver { vt)) { let new_parent; if self.block_needs_anonymous_module(block) { - let block_id = block.node.id; + let block_id = block.id; debug!("(building reduced graph for block) creating a new \ anonymous module for block %d", @@ -4096,7 +4096,7 @@ impl Resolver { // Move down in the graph, if there's an anonymous module rooted here. let orig_module = self.current_module; - match self.current_module.anonymous_children.find(&block.node.id) { + match self.current_module.anonymous_children.find(&block.id) { None => { /* Nothing to do. */ } Some(&anonymous_module) => { debug!("(resolving block) found anonymous module, moving \ @@ -4989,7 +4989,7 @@ impl Resolver { } expr_fn_block(ref fn_decl, ref block) => { - self.resolve_function(FunctionRibKind(expr.id, block.node.id), + self.resolve_function(FunctionRibKind(expr.id, block.id), Some(fn_decl), NoTypeParameters, block, diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index fc635954237c8..bd0f0baedf9e8 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -1430,7 +1430,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, } pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { - for b.node.stmts.iter().advance |s| { + for b.stmts.iter().advance |s| { match s.node { ast::stmt_decl(d, _) => { match d.node { @@ -1858,7 +1858,7 @@ pub fn trans_closure(ccx: @mut CrateContext, let bcx_top = top_scope_block(fcx, body.info()); let mut bcx = bcx_top; let lltop = bcx.llbb; - let block_ty = node_id_type(bcx, body.node.id); + let block_ty = node_id_type(bcx, body.id); let arg_tys = ty::ty_fn_args(node_id_type(bcx, id)); bcx = copy_args_to_allocas(fcx, bcx, decl.inputs, raw_llargs, arg_tys); @@ -1869,7 +1869,7 @@ pub fn trans_closure(ccx: @mut CrateContext, // translation calls that don't have a return value (trans_crate, // trans_mod, trans_item, et cetera) and those that do // (trans_block, trans_expr, et cetera). - if body.node.expr.is_none() || ty::type_is_bot(block_ty) || + if body.expr.is_none() || ty::type_is_bot(block_ty) || ty::type_is_nil(block_ty) { bcx = controlflow::trans_block(bcx, body, expr::Ignore); @@ -2132,7 +2132,7 @@ pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { item.id, item.attrs); } else { - for body.node.stmts.iter().advance |stmt| { + for body.stmts.iter().advance |stmt| { match stmt.node { ast::stmt_decl(@codemap::spanned { node: ast::decl_item(i), _ }, _) => { diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 196807baabbe6..a5a607ba1a5e4 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -481,7 +481,7 @@ impl get_node_info for ast::expr { impl get_node_info for ast::blk { fn info(&self) -> Option { - Some(NodeInfo {id: self.node.id, + Some(NodeInfo {id: self.id, callee_id: None, span: self.span}) } diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 36f1f5cdbefc8..c573b926f44ae 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -35,11 +35,11 @@ use syntax::codemap::span; pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block { let _icx = push_ctxt("trans_block"); let mut bcx = bcx; - for b.node.stmts.iter().advance |s| { + for b.stmts.iter().advance |s| { debuginfo::update_source_pos(bcx, b.span); bcx = trans_stmt(bcx, *s); } - match b.node.expr { + match b.expr { Some(e) => { debuginfo::update_source_pos(bcx, e.span); bcx = expr::trans_into(bcx, e, dest); @@ -58,7 +58,7 @@ pub fn trans_if(bcx: block, dest: expr::Dest) -> block { debug!("trans_if(bcx=%s, cond=%s, thn=%?, dest=%s)", - bcx.to_str(), bcx.expr_to_str(cond), thn.node.id, + bcx.to_str(), bcx.expr_to_str(cond), thn.id, dest.to_str(bcx.ccx())); let _indenter = indenter(); diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 8fff23c649848..561c9a3399a04 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -417,7 +417,7 @@ pub fn write_content(bcx: block, return expr::trans_into(bcx, element, Ignore); } SaveIn(lldest) => { - let count = ty::eval_repeat_count(bcx.tcx(), count_expr); + let count = ty::eval_repeat_count(&bcx.tcx(), count_expr); if count == 0 { return bcx; } @@ -509,7 +509,7 @@ pub fn elements_required(bcx: block, content_expr: &ast::expr) -> uint { }, ast::expr_vec(ref es, _) => es.len(), ast::expr_repeat(_, count_expr, _) => { - ty::eval_repeat_count(bcx.tcx(), count_expr) + ty::eval_repeat_count(&bcx.tcx(), count_expr) } _ => bcx.tcx().sess.span_bug(content_expr.span, "Unexpected evec content") diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index eda8f8530710d..bc11953c073e7 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -414,7 +414,7 @@ pub fn handle_body(cx: &Context, body: &blk) { }, visit_block: |b, (cx, v)| { visit::visit_block(b, (cx, v)); - for b.node.expr.iter().advance |e| { + for b.expr.iter().advance |e| { node_type_needs(cx, use_repr, e.id); } }, diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8e23f5431bcee..47cf19cc61a8a 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -2840,7 +2840,7 @@ pub fn tys_in_fn_sig(sig: &FnSig) -> ~[t] { // Type accessors for AST nodes pub fn block_ty(cx: ctxt, b: &ast::blk) -> t { - return node_id_to_type(cx, b.node.id); + return node_id_to_type(cx, b.id); } @@ -4230,42 +4230,57 @@ pub fn normalize_ty(cx: ctxt, t: t) -> t { return t_norm; } +pub trait ExprTyProvider { + pub fn expr_ty(&self, ex: &ast::expr) -> t; + pub fn ty_ctxt(&self) -> ctxt; +} + +impl ExprTyProvider for ctxt { + pub fn expr_ty(&self, ex: &ast::expr) -> t { + expr_ty(*self, ex) + } + + pub fn ty_ctxt(&self) -> ctxt { + *self + } +} + // Returns the repeat count for a repeating vector expression. -pub fn eval_repeat_count(tcx: ctxt, count_expr: &ast::expr) -> uint { +pub fn eval_repeat_count(tcx: &T, count_expr: &ast::expr) -> uint { match const_eval::eval_const_expr_partial(tcx, count_expr) { Ok(ref const_val) => match *const_val { const_eval::const_int(count) => if count < 0 { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found negative integer"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found negative integer"); return 0; } else { return count as uint }, const_eval::const_uint(count) => return count as uint, const_eval::const_float(count) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found float"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found float"); return count as uint; } const_eval::const_str(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found string"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found string"); return 0; } const_eval::const_bool(_) => { - tcx.sess.span_err(count_expr.span, - "expected positive integer for \ - repeat count but found boolean"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected positive integer for \ + repeat count but found boolean"); return 0; } }, Err(*) => { - tcx.sess.span_err(count_expr.span, - "expected constant integer for repeat count \ - but found variable"); + tcx.ty_ctxt().sess.span_err(count_expr.span, + "expected constant integer for repeat count \ + but found variable"); return 0; } } diff --git a/src/librustc/middle/typeck/astconv.rs b/src/librustc/middle/typeck/astconv.rs index d8185022e416d..1186f8cecabc5 100644 --- a/src/librustc/middle/typeck/astconv.rs +++ b/src/librustc/middle/typeck/astconv.rs @@ -479,7 +479,7 @@ pub fn ast_ty_to_ty( } } ast::ty_fixed_length_vec(ref a_mt, e) => { - match const_eval::eval_const_expr_partial(tcx, e) { + match const_eval::eval_const_expr_partial(&tcx, e) { Ok(ref r) => { match *r { const_eval::const_int(i) => diff --git a/src/librustc/middle/typeck/check/_match.rs b/src/librustc/middle/typeck/check/_match.rs index ac7a9db99e9ac..5f0a32bb02e64 100644 --- a/src/librustc/middle/typeck/check/_match.rs +++ b/src/librustc/middle/typeck/check/_match.rs @@ -72,14 +72,14 @@ pub fn check_match(fcx: @mut FnCtxt, None => () } check_block(fcx, &arm.body); - let bty = fcx.node_ty(arm.body.node.id); + let bty = fcx.node_ty(arm.body.id); saw_err = saw_err || ty::type_is_error(bty); if guard_err { - fcx.write_error(arm.body.node.id); + fcx.write_error(arm.body.id); saw_err = true; } else if guard_bot { - fcx.write_bot(arm.body.node.id); + fcx.write_bot(arm.body.id); } result_ty = diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 4caf0b62a546d..562efb767ecec 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -83,7 +83,7 @@ use middle::pat_util; use middle::lint::unreachable_code; use middle::ty::{FnSig, VariantInfo_}; use middle::ty::{ty_param_bounds_and_ty, ty_param_substs_and_ty}; -use middle::ty::{substs, param_ty}; +use middle::ty::{substs, param_ty, ExprTyProvider}; use middle::ty; use middle::typeck::astconv::AstConv; use middle::typeck::astconv::{ast_region_to_region, ast_ty_to_ty}; @@ -200,8 +200,8 @@ impl PurityState { ast::unsafe_fn if self.from_fn => *self, purity => { - let (purity, def) = match blk.node.rules { - ast::unsafe_blk => (ast::unsafe_fn, blk.node.id), + let (purity, def) = match blk.rules { + ast::unsafe_blk => (ast::unsafe_fn, blk.id), ast::default_blk => (purity, self.def), }; PurityState{ def: def, @@ -290,6 +290,16 @@ pub fn blank_fn_ctxt(ccx: @mut CrateCtxt, } } +impl ExprTyProvider for FnCtxt { + pub fn expr_ty(&self, ex: &ast::expr) -> ty::t { + self.expr_ty(ex) + } + + pub fn ty_ctxt(&self) -> ty::ctxt { + self.ccx.tcx + } +} + pub fn check_item_types(ccx: @mut CrateCtxt, crate: &ast::crate) { let visit = visit::mk_simple_visitor(@visit::SimpleVisitor { visit_item: |a| check_item(ccx, a), @@ -355,7 +365,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, let (isr, opt_self_ty, fn_sig) = replace_bound_regions_in_fn_sig( tcx, inherited_isr, opt_self_ty, fn_sig, - |br| ty::re_free(ty::FreeRegion {scope_id: body.node.id, + |br| ty::re_free(ty::FreeRegion {scope_id: body.id, bound_region: br})); let opt_self_info = opt_self_info.map( @@ -389,7 +399,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, ret_ty: ret_ty, indirect_ret_ty: indirect_ret_ty, ps: PurityState::function(purity, id), - region_lb: body.node.id, + region_lb: body.id, in_scope_regions: isr, fn_kind: fn_kind, inh: inherited, @@ -402,7 +412,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, // We unify the tail expr's type with the // function result type, if there is a tail expr. - match body.node.expr { + match body.expr { Some(tail_expr) => { let tail_expr_ty = fcx.expr_ty(tail_expr); // Special case: we print a special error if there appears @@ -505,7 +515,7 @@ pub fn check_fn(ccx: @mut CrateCtxt, // non-obvious: the `blk` variable maps to region lb, so // we have to keep this up-to-date. This // is... unfortunate. It'd be nice to not need this. - do fcx.with_region_lb(b.node.id) { + do fcx.with_region_lb(b.id) { visit::visit_block(b, (e, v)); } }; @@ -797,7 +807,7 @@ impl FnCtxt { pat.repr(self.tcx()) } - pub fn expr_ty(&self, ex: @ast::expr) -> ty::t { + pub fn expr_ty(&self, ex: &ast::expr) -> ty::t { match self.inh.node_types.find(&ex.id) { Some(&t) => t, None => { @@ -1446,7 +1456,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, let branches_ty = match opt_else_expr { Some(else_expr) => { check_block_with_expected(fcx, then_blk, expected); - let then_ty = fcx.node_ty(then_blk.node.id); + let then_ty = fcx.node_ty(then_blk.id); check_expr_with_opt_hint(fcx, else_expr, expected); let else_ty = fcx.expr_ty(else_expr); infer::common_supertype(fcx.infcx(), @@ -2250,8 +2260,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } } ast::expr_repeat(element, count_expr, mutbl) => { - let _ = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint()); + let _ = ty::eval_repeat_count(fcx, count_expr); let tt = ast_expr_vstore_to_vstore(fcx, ev, vst); let mutability = match vst { ast::expr_vstore_mut_box | ast::expr_vstore_mut_slice => { @@ -2523,7 +2533,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, check_expr_has_type(fcx, cond, ty::mk_bool()); check_block_no_value(fcx, body); let cond_ty = fcx.expr_ty(cond); - let body_ty = fcx.node_ty(body.node.id); + let body_ty = fcx.node_ty(body.id); if ty::type_is_error(cond_ty) || ty::type_is_error(body_ty) { fcx.write_error(id); } @@ -2588,7 +2598,7 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, } ast::expr_block(ref b) => { check_block_with_expected(fcx, b, expected); - fcx.write_ty(id, fcx.node_ty(b.node.id)); + fcx.write_ty(id, fcx.node_ty(b.id)); } ast::expr_call(f, ref args, sugar) => { check_call(fcx, expr.id, expr, f, *args, sugar); @@ -2730,8 +2740,8 @@ pub fn check_expr_with_unifier(fcx: @mut FnCtxt, fcx.write_ty(id, typ); } ast::expr_repeat(element, count_expr, mutbl) => { - let count = ty::eval_repeat_count(tcx, count_expr); check_expr_with_hint(fcx, count_expr, ty::mk_uint()); + let count = ty::eval_repeat_count(fcx, count_expr); let t: ty::t = fcx.infcx().next_ty_var(); check_expr_has_type(fcx, element, t); let element_ty = fcx.expr_ty(element); @@ -2949,12 +2959,12 @@ pub fn check_stmt(fcx: @mut FnCtxt, stmt: @ast::stmt) { pub fn check_block_no_value(fcx: @mut FnCtxt, blk: &ast::blk) { check_block_with_expected(fcx, blk, Some(ty::mk_nil())); - let blkty = fcx.node_ty(blk.node.id); + let blkty = fcx.node_ty(blk.id); if ty::type_is_error(blkty) { - fcx.write_error(blk.node.id); + fcx.write_error(blk.id); } else if ty::type_is_bot(blkty) { - fcx.write_bot(blk.node.id); + fcx.write_bot(blk.id); } else { let nilty = ty::mk_nil(); @@ -2972,12 +2982,12 @@ pub fn check_block_with_expected(fcx: @mut FnCtxt, let purity_state = fcx.ps.recurse(blk); let prev = replace(&mut fcx.ps, purity_state); - do fcx.with_region_lb(blk.node.id) { + do fcx.with_region_lb(blk.id) { let mut warned = false; let mut last_was_bot = false; let mut any_bot = false; let mut any_err = false; - for blk.node.stmts.iter().advance |s| { + for blk.stmts.iter().advance |s| { check_stmt(fcx, *s); let s_id = ast_util::stmt_id(*s); let s_ty = fcx.node_ty(s_id); @@ -2999,15 +3009,15 @@ pub fn check_block_with_expected(fcx: @mut FnCtxt, any_bot = any_bot || ty::type_is_bot(s_ty); any_err = any_err || ty::type_is_error(s_ty); } - match blk.node.expr { + match blk.expr { None => if any_err { - fcx.write_error(blk.node.id); + fcx.write_error(blk.id); } else if any_bot { - fcx.write_bot(blk.node.id); + fcx.write_bot(blk.id); } else { - fcx.write_nil(blk.node.id); + fcx.write_nil(blk.id); }, Some(e) => { if any_bot && !warned { @@ -3015,12 +3025,12 @@ pub fn check_block_with_expected(fcx: @mut FnCtxt, } check_expr_with_opt_hint(fcx, e, expected); let ety = fcx.expr_ty(e); - fcx.write_ty(blk.node.id, ety); + fcx.write_ty(blk.id, ety); if any_err { - fcx.write_error(blk.node.id); + fcx.write_error(blk.id); } else if any_bot { - fcx.write_bot(blk.node.id); + fcx.write_bot(blk.id); } } }; @@ -3126,7 +3136,7 @@ pub fn check_enum_variants(ccx: @mut CrateCtxt, // that the expression is in an form that eval_const_expr can // handle, so we may still get an internal compiler error - match const_eval::eval_const_expr_partial(ccx.tcx, e) { + match const_eval::eval_const_expr_partial(&ccx.tcx, e) { Ok(const_eval::const_int(val)) => { *disr_val = val as int; } diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 6e3f0a208430a..e46cc31a79a47 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -155,7 +155,7 @@ pub fn regionck_expr(fcx: @mut FnCtxt, e: @ast::expr) { pub fn regionck_fn(fcx: @mut FnCtxt, blk: &ast::blk) { let rcx = @mut Rcx { fcx: fcx, errors_reported: 0, - repeating_scope: blk.node.id }; + repeating_scope: blk.id }; if fcx.err_count_since_creation() == 0 { // regionck assumes typeck succeeded let v = regionck_visitor(); @@ -188,7 +188,7 @@ fn visit_item(_item: @ast::item, (_rcx, _v): (@mut Rcx, rvt)) { } fn visit_block(b: &ast::blk, (rcx, v): (@mut Rcx, rvt)) { - rcx.fcx.tcx().region_maps.record_cleanup_scope(b.node.id); + rcx.fcx.tcx().region_maps.record_cleanup_scope(b.id); visit::visit_block(b, (rcx, v)); } @@ -287,11 +287,11 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { } } ast::expr_loop(ref body, _) => { - tcx.region_maps.record_cleanup_scope(body.node.id); + tcx.region_maps.record_cleanup_scope(body.id); } ast::expr_while(cond, ref body) => { tcx.region_maps.record_cleanup_scope(cond.id); - tcx.region_maps.record_cleanup_scope(body.node.id); + tcx.region_maps.record_cleanup_scope(body.id); } _ => {} } @@ -434,7 +434,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { } ast::expr_loop(ref body, _) => { - let repeating_scope = rcx.set_repeating_scope(body.node.id); + let repeating_scope = rcx.set_repeating_scope(body.id); visit::visit_expr(expr, (rcx, v)); rcx.set_repeating_scope(repeating_scope); } @@ -443,7 +443,7 @@ fn visit_expr(expr: @ast::expr, (rcx, v): (@mut Rcx, rvt)) { let repeating_scope = rcx.set_repeating_scope(cond.id); (v.visit_expr)(cond, (rcx, v)); - rcx.set_repeating_scope(body.node.id); + rcx.set_repeating_scope(body.id); (v.visit_block)(body, (rcx, v)); rcx.set_repeating_scope(repeating_scope); @@ -486,7 +486,7 @@ fn check_expr_fn_block(rcx: @mut Rcx, _ => () } - let repeating_scope = rcx.set_repeating_scope(body.node.id); + let repeating_scope = rcx.set_repeating_scope(body.id); visit::visit_expr(expr, (rcx, v)); rcx.set_repeating_scope(repeating_scope); } diff --git a/src/librustc/middle/typeck/check/writeback.rs b/src/librustc/middle/typeck/check/writeback.rs index d59c8e5e894fb..0ffadba7f2247 100644 --- a/src/librustc/middle/typeck/check/writeback.rs +++ b/src/librustc/middle/typeck/check/writeback.rs @@ -276,7 +276,7 @@ fn visit_block(b: &ast::blk, (wbcx, v): (@mut WbCtxt, wb_vt)) { return; } - resolve_type_vars_for_node(wbcx, b.span, b.node.id); + resolve_type_vars_for_node(wbcx, b.span, b.id); visit::visit_block(b, (wbcx, v)); } diff --git a/src/librustc/middle/typeck/collect.rs b/src/librustc/middle/typeck/collect.rs index ec384543deac1..68a6c675f8830 100644 --- a/src/librustc/middle/typeck/collect.rs +++ b/src/librustc/middle/typeck/collect.rs @@ -745,7 +745,7 @@ pub fn convert_methods(ccx: &CrateCtxt, write_ty_to_tcx(tcx, m.id, fty); tcx.methods.insert(mty.def_id, mty); ConvertedMethod {mty: mty, id: m.id, - span: m.span, body_id: m.body.node.id} + span: m.span, body_id: m.body.id} }).collect(); fn ty_of_method(ccx: &CrateCtxt, diff --git a/src/librusti/program.rs b/src/librusti/program.rs index 9031a001eca60..f8cbd70c0b1b5 100644 --- a/src/librusti/program.rs +++ b/src/librusti/program.rs @@ -346,7 +346,7 @@ impl Program { // helper functions to perform ast iteration fn each_user_local(blk: &ast::blk, f: &fn(@ast::local)) { do find_user_block(blk) |blk| { - for blk.node.stmts.iter().advance |stmt| { + for blk.stmts.iter().advance |stmt| { match stmt.node { ast::stmt_decl(d, _) => { match d.node { @@ -361,7 +361,7 @@ impl Program { } fn find_user_block(blk: &ast::blk, f: &fn(&ast::blk)) { - for blk.node.stmts.iter().advance |stmt| { + for blk.stmts.iter().advance |stmt| { match stmt.node { ast::stmt_semi(e, _) => { match e.node { diff --git a/src/librusti/rusti.rs b/src/librusti/rusti.rs index 0d21dda3edd61..ab6ae0385fba2 100644 --- a/src/librusti/rusti.rs +++ b/src/librusti/rusti.rs @@ -149,7 +149,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str], do find_main(crate, sess) |blk| { // Fish out all the view items, be sure to record 'extern mod' items // differently beause they must appear before all 'use' statements - for blk.node.view_items.iter().advance |vi| { + for blk.view_items.iter().advance |vi| { let s = do with_pp(intr) |pp, _| { pprust::print_view_item(pp, vi); }; @@ -163,7 +163,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str], // Iterate through all of the block's statements, inserting them into // the correct portions of the program - for blk.node.stmts.iter().advance |stmt| { + for blk.stmts.iter().advance |stmt| { let s = do with_pp(intr) |pp, _| { pprust::print_stmt(pp, *stmt); }; match stmt.node { ast::stmt_decl(d, _) => { @@ -203,7 +203,7 @@ fn run(mut program: ~Program, binary: ~str, lib_search_paths: ~[~str], } } } - result = do blk.node.expr.map_consume |e| { + result = do blk.expr.map_consume |e| { do with_pp(intr) |pp, _| { pprust::print_expr(pp, e); } }; } diff --git a/src/libstd/num/int_macros.rs b/src/libstd/num/int_macros.rs index 75e0bbcb71b04..cef32b5c7e445 100644 --- a/src/libstd/num/int_macros.rs +++ b/src/libstd/num/int_macros.rs @@ -29,28 +29,38 @@ pub static bytes : uint = ($bits / 8); pub static min_value: $T = (-1 as $T) << (bits - 1); pub static max_value: $T = min_value - 1 as $T; +enum Range { Closed, HalfOpen } + +#[inline] /// -/// Iterate over the range [`lo`..`hi`) +/// Iterate through a range with a given step value. /// -/// # Arguments +/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed; +/// otherwise `term` denotes the half-open interval `[stop-step,stop)`. +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_j == start + step*j`, and `x_n` lies in the interval `term`. /// -/// * `lo` - lower bound, inclusive -/// * `hi` - higher bound, exclusive -/// -/// # Examples -/// ~~~ -/// let mut sum = 0; -/// for int::range(1, 5) |i| { -/// sum += i; -/// } -/// assert!(sum == 10); -/// ~~~ +/// If no such nonnegative integer `n` exists, then the iteration range +/// is empty. /// -#[inline] -pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { +fn range_step_core(start: $T, stop: $T, step: $T, r: Range, it: &fn($T) -> bool) -> bool { let mut i = start; if step == 0 { fail!(~"range_step called with step == 0"); + } else if step == (1 as $T) { // elide bounds check to tighten loop + while i < stop { + if !it(i) { return false; } + // no need for overflow check; + // cannot have i + 1 > max_value because i < stop <= max_value + i += (1 as $T); + } + } else if step == (-1 as $T) { // elide bounds check to tighten loop + while i > stop { + if !it(i) { return false; } + // no need for underflow check; + // cannot have i - 1 < min_value because i > stop >= min_value + i -= (1 as $T); + } } else if step > 0 { // ascending while i < stop { if !it(i) { return false; } @@ -66,9 +76,55 @@ pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { i += step; } } - return true; + match r { + HalfOpen => return true, + Closed => return (i != stop || it(i)) + } +} + +#[inline] +/// +/// Iterate through the range [`start`..`stop`) with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// * `x_i == start + step*i`, and +/// * `n` is the greatest nonnegative integer such that `x_n < stop` +/// +/// (If no such `n` exists, then the iteration range is empty.) +/// +/// # Arguments +/// +/// * `start` - lower bound, inclusive +/// * `stop` - higher bound, exclusive +/// +/// # Examples +/// ~~~ +/// let mut sum = 0; +/// for int::range(1, 5) |i| { +/// sum += i; +/// } +/// assert!(sum == 10); +/// ~~~ +/// +pub fn range_step(start: $T, stop: $T, step: $T, it: &fn($T) -> bool) -> bool { + range_step_core(start, stop, step, HalfOpen, it) +} + +#[inline] +/// +/// Iterate through a range with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_i == start + step*i` and `x_n <= last < step + x_n`. +/// +/// (If no such nonnegative integer `n` exists, then the iteration +/// range is empty.) +/// +pub fn range_step_inclusive(start: $T, last: $T, step: $T, it: &fn($T) -> bool) -> bool { + range_step_core(start, last, step, Closed, it) } + #[inline] /// Iterate over the range [`lo`..`hi`) pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { @@ -76,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { } #[inline] -/// Iterate over the range [`hi`..`lo`) +/// Iterate over the range (`hi`..`lo`] pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { - range_step(hi, lo, -1 as $T, it) + if hi == min_value { return true; } + range_step_inclusive(hi-1, lo, -1 as $T, it) } impl Num for $T {} @@ -841,7 +898,7 @@ mod tests { for range(0,3) |i| { l.push(i); } - for range_rev(13,10) |i| { + for range_rev(14,11) |i| { l.push(i); } for range_step(20,26,2) |i| { diff --git a/src/libstd/num/uint_macros.rs b/src/libstd/num/uint_macros.rs index de1b997b14b52..54c1327fa9303 100644 --- a/src/libstd/num/uint_macros.rs +++ b/src/libstd/num/uint_macros.rs @@ -30,32 +30,46 @@ pub static bytes : uint = ($bits / 8); pub static min_value: $T = 0 as $T; pub static max_value: $T = 0 as $T - 1 as $T; +enum Range { Closed, HalfOpen } + #[inline] -/** - * Iterate through a range with a given step value. - * - * # Examples - * ~~~ {.rust} - * let nums = [1,2,3,4,5,6,7]; - * - * for uint::range_step(0, nums.len() - 1, 2) |i| { - * println(fmt!("%d & %d", nums[i], nums[i+1])); - * } - * ~~~ - */ -pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { +/// +/// Iterate through a range with a given step value. +/// +/// Let `term` denote the closed interval `[stop-step,stop]` if `r` is Closed; +/// otherwise `term` denotes the half-open interval `[stop-step,stop)`. +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_j == start + step*j`, and `x_n` lies in the interval `term`. +/// +/// If no such nonnegative integer `n` exists, then the iteration range +/// is empty. +/// +fn range_step_core(start: $T, stop: $T, step: $T_SIGNED, r: Range, it: &fn($T) -> bool) -> bool { let mut i = start; if step == 0 { fail!("range_step called with step == 0"); - } - if step >= 0 { + } else if step == (1 as $T_SIGNED) { // elide bounds check to tighten loop + while i < stop { + if !it(i) { return false; } + // no need for overflow check; + // cannot have i + 1 > max_value because i < stop <= max_value + i += (1 as $T); + } + } else if step == (-1 as $T_SIGNED) { // elide bounds check to tighten loop + while i > stop { + if !it(i) { return false; } + // no need for underflow check; + // cannot have i - 1 < min_value because i > stop >= min_value + i -= (1 as $T); + } + } else if step > 0 { // ascending while i < stop { if !it(i) { return false; } // avoiding overflow. break if i + step > max_value if i > max_value - (step as $T) { return true; } i += step as $T; } - } else { + } else { // descending while i > stop { if !it(i) { return false; } // avoiding underflow. break if i + step < min_value @@ -63,7 +77,52 @@ pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> i -= -step as $T; } } - return true; + match r { + HalfOpen => return true, + Closed => return (i != stop || it(i)) + } +} + +#[inline] +/// +/// Iterate through the range [`start`..`stop`) with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// - `x_i == start + step*i`, and +/// - `n` is the greatest nonnegative integer such that `x_n < stop` +/// +/// (If no such `n` exists, then the iteration range is empty.) +/// +/// # Arguments +/// +/// * `start` - lower bound, inclusive +/// * `stop` - higher bound, exclusive +/// +/// # Examples +/// ~~~ {.rust} +/// let nums = [1,2,3,4,5,6,7]; +/// +/// for uint::range_step(0, nums.len() - 1, 2) |i| { +/// println(fmt!("%d & %d", nums[i], nums[i+1])); +/// } +/// ~~~ +/// +pub fn range_step(start: $T, stop: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { + range_step_core(start, stop, step, HalfOpen, it) +} + +#[inline] +/// +/// Iterate through a range with a given step value. +/// +/// Iterates through the range `[x_0, x_1, ..., x_n]` where +/// `x_i == start + step*i` and `x_n <= last < step + x_n`. +/// +/// (If no such nonnegative integer `n` exists, then the iteration +/// range is empty.) +/// +pub fn range_step_inclusive(start: $T, last: $T, step: $T_SIGNED, it: &fn($T) -> bool) -> bool { + range_step_core(start, last, step, Closed, it) } #[inline] @@ -73,9 +132,10 @@ pub fn range(lo: $T, hi: $T, it: &fn($T) -> bool) -> bool { } #[inline] -/// Iterate over the range [`hi`..`lo`) +/// Iterate over the range (`hi`..`lo`] pub fn range_rev(hi: $T, lo: $T, it: &fn($T) -> bool) -> bool { - range_step(hi, lo, -1 as $T_SIGNED, it) + if hi == min_value { return true; } + range_step_inclusive(hi-1, lo, -1 as $T_SIGNED, it) } impl Num for $T {} @@ -603,7 +663,7 @@ mod tests { for range(0,3) |i| { l.push(i); } - for range_rev(13,10) |i| { + for range_rev(14,11) |i| { l.push(i); } for range_step(20,26,2) |i| { diff --git a/src/libstd/option.rs b/src/libstd/option.rs index 222952a6dc143..b0811674a7bfa 100644 --- a/src/libstd/option.rs +++ b/src/libstd/option.rs @@ -203,14 +203,14 @@ impl Option { /// Apply a function to the contained value or do nothing pub fn mutate(&mut self, f: &fn(T) -> T) { if self.is_some() { - *self = Some(f(self.swap_unwrap())); + *self = Some(f(self.take_unwrap())); } } /// Apply a function to the contained value or set it to a default pub fn mutate_default(&mut self, def: T, f: &fn(T) -> T) { if self.is_some() { - *self = Some(f(self.swap_unwrap())); + *self = Some(f(self.take_unwrap())); } else { *self = Some(def); } @@ -293,8 +293,8 @@ impl Option { * Fails if the value equals `None`. */ #[inline] - pub fn swap_unwrap(&mut self) -> T { - if self.is_none() { fail!("option::swap_unwrap none") } + pub fn take_unwrap(&mut self) -> T { + if self.is_none() { fail!("option::take_unwrap none") } util::replace(self, None).unwrap() } @@ -460,7 +460,7 @@ fn test_option_dance() { let mut y = Some(5); let mut y2 = 0; for x.iter().advance |_x| { - y2 = y.swap_unwrap(); + y2 = y.take_unwrap(); } assert_eq!(y2, 5); assert!(y.is_none()); @@ -468,8 +468,8 @@ fn test_option_dance() { #[test] #[should_fail] #[ignore(cfg(windows))] fn test_option_too_much_dance() { let mut y = Some(util::NonCopyable); - let _y2 = y.swap_unwrap(); - let _y3 = y.swap_unwrap(); + let _y2 = y.take_unwrap(); + let _y3 = y.take_unwrap(); } #[test] diff --git a/src/libstd/rt/sched.rs b/src/libstd/rt/sched.rs index 6e9aef7773051..4e4145ddc161f 100644 --- a/src/libstd/rt/sched.rs +++ b/src/libstd/rt/sched.rs @@ -328,7 +328,7 @@ impl Scheduler { /// Given an input Coroutine sends it back to its home scheduler. fn send_task_home(task: ~Task) { let mut task = task; - let mut home = task.home.swap_unwrap(); + let mut home = task.home.take_unwrap(); match home { Sched(ref mut home_handle) => { home_handle.send(PinnedTask(task)); @@ -418,7 +418,7 @@ impl Scheduler { do self.deschedule_running_task_and_then |sched, dead_task| { let mut dead_task = dead_task; - let coroutine = dead_task.coroutine.swap_unwrap(); + let coroutine = dead_task.coroutine.take_unwrap(); coroutine.recycle(&mut sched.stack_pool); } @@ -506,7 +506,7 @@ impl Scheduler { this.metrics.context_switches_task_to_sched += 1; unsafe { - let blocked_task = this.current_task.swap_unwrap(); + let blocked_task = this.current_task.take_unwrap(); let f_fake_region = transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f); let f_opaque = ClosureConverter::from_fn(f_fake_region); @@ -538,7 +538,7 @@ impl Scheduler { rtdebug!("switching tasks"); this.metrics.context_switches_task_to_task += 1; - let old_running_task = this.current_task.swap_unwrap(); + let old_running_task = this.current_task.take_unwrap(); let f_fake_region = unsafe { transmute::<&fn(&mut Scheduler, ~Task), &fn(&mut Scheduler, ~Task)>(f) @@ -576,7 +576,7 @@ impl Scheduler { assert!(self.cleanup_job.is_some()); - let cleanup_job = self.cleanup_job.swap_unwrap(); + let cleanup_job = self.cleanup_job.take_unwrap(); match cleanup_job { DoNothing => { } GiveTask(task, f) => (f.to_fn())(self, task) diff --git a/src/libstd/rt/task.rs b/src/libstd/rt/task.rs index 17d0d59660f1b..449438b920551 100644 --- a/src/libstd/rt/task.rs +++ b/src/libstd/rt/task.rs @@ -127,7 +127,7 @@ impl Task { // Wait for children. Possibly report the exit status. let local_success = !self.unwinder.unwinding; - let join_latch = self.join_latch.swap_unwrap(); + let join_latch = self.join_latch.take_unwrap(); match self.on_exit { Some(ref on_exit) => { let success = join_latch.wait(local_success); diff --git a/src/libstd/rt/tube.rs b/src/libstd/rt/tube.rs index 013eb438c3657..f61eee8859b1a 100644 --- a/src/libstd/rt/tube.rs +++ b/src/libstd/rt/tube.rs @@ -53,7 +53,7 @@ impl Tube { if (*state).blocked_task.is_some() { // There's a waiting task. Wake it up rtdebug!("waking blocked tube"); - let task = (*state).blocked_task.swap_unwrap(); + let task = (*state).blocked_task.take_unwrap(); let sched = Local::take::(); sched.resume_task_immediately(task); } diff --git a/src/libstd/rt/uv/async.rs b/src/libstd/rt/uv/async.rs index f3d1024024ff8..81428509e33e5 100644 --- a/src/libstd/rt/uv/async.rs +++ b/src/libstd/rt/uv/async.rs @@ -62,7 +62,7 @@ impl AsyncWatcher { let mut watcher: AsyncWatcher = NativeHandle::from_native_handle(handle); { let data = watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } watcher.drop_watcher_data(); unsafe { uvll::free_handle(handle as *c_void); } diff --git a/src/libstd/rt/uv/idle.rs b/src/libstd/rt/uv/idle.rs index a3630c9b9bf8d..28b101f686d4c 100644 --- a/src/libstd/rt/uv/idle.rs +++ b/src/libstd/rt/uv/idle.rs @@ -73,7 +73,7 @@ impl IdleWatcher { let mut idle_watcher: IdleWatcher = NativeHandle::from_native_handle(handle); { let data = idle_watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } idle_watcher.drop_watcher_data(); uvll::idle_delete(handle); diff --git a/src/libstd/rt/uv/net.rs b/src/libstd/rt/uv/net.rs index 6d096f9885a7d..09c748ec04782 100644 --- a/src/libstd/rt/uv/net.rs +++ b/src/libstd/rt/uv/net.rs @@ -209,7 +209,7 @@ impl StreamWatcher { let write_request: WriteRequest = NativeHandle::from_native_handle(req); let mut stream_watcher = write_request.stream(); write_request.delete(); - let cb = stream_watcher.get_watcher_data().write_cb.swap_unwrap(); + let cb = stream_watcher.get_watcher_data().write_cb.take_unwrap(); let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); cb(stream_watcher, status); } @@ -233,7 +233,7 @@ impl StreamWatcher { extern fn close_cb(handle: *uvll::uv_stream_t) { let mut stream_watcher: StreamWatcher = NativeHandle::from_native_handle(handle); - stream_watcher.get_watcher_data().close_cb.swap_unwrap()(); + stream_watcher.get_watcher_data().close_cb.take_unwrap()(); stream_watcher.drop_watcher_data(); unsafe { free_handle(handle as *c_void) } } @@ -301,7 +301,7 @@ impl TcpWatcher { let connect_request: ConnectRequest = NativeHandle::from_native_handle(req); let mut stream_watcher = connect_request.stream(); connect_request.delete(); - let cb = stream_watcher.get_watcher_data().connect_cb.swap_unwrap(); + let cb = stream_watcher.get_watcher_data().connect_cb.take_unwrap(); let status = status_to_maybe_uv_error(stream_watcher.native_handle(), status); cb(stream_watcher, status); } @@ -438,7 +438,7 @@ impl UdpWatcher { let send_request: UdpSendRequest = NativeHandle::from_native_handle(req); let mut udp_watcher = send_request.handle(); send_request.delete(); - let cb = udp_watcher.get_watcher_data().udp_send_cb.swap_unwrap(); + let cb = udp_watcher.get_watcher_data().udp_send_cb.take_unwrap(); let status = status_to_maybe_uv_error(udp_watcher.native_handle(), status); cb(udp_watcher, status); } @@ -456,7 +456,7 @@ impl UdpWatcher { extern fn close_cb(handle: *uvll::uv_udp_t) { let mut udp_watcher: UdpWatcher = NativeHandle::from_native_handle(handle); - udp_watcher.get_watcher_data().close_cb.swap_unwrap()(); + udp_watcher.get_watcher_data().close_cb.take_unwrap()(); udp_watcher.drop_watcher_data(); unsafe { free_handle(handle as *c_void) } } diff --git a/src/libstd/rt/uv/timer.rs b/src/libstd/rt/uv/timer.rs index 14465eb7dfd3a..bc5399327a032 100644 --- a/src/libstd/rt/uv/timer.rs +++ b/src/libstd/rt/uv/timer.rs @@ -70,7 +70,7 @@ impl TimerWatcher { let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle); { let data = watcher.get_watcher_data(); - data.close_cb.swap_unwrap()(); + data.close_cb.take_unwrap()(); } watcher.drop_watcher_data(); unsafe { diff --git a/src/libstd/run.rs b/src/libstd/run.rs index 17dc604a17858..883870db1e673 100644 --- a/src/libstd/run.rs +++ b/src/libstd/run.rs @@ -669,7 +669,7 @@ fn spawn_process_os(prog: &str, args: &[~str], fail!("failure in dup3(err_fd, 2): %s", os::last_os_error()); } // close all other fds - for int::range_rev(getdtablesize() as int - 1, 2) |fd| { + for int::range_rev(getdtablesize() as int, 3) |fd| { close(fd as c_int); } diff --git a/src/libstd/task/spawn.rs b/src/libstd/task/spawn.rs index 206d19e175fe9..bf09a533ebe12 100644 --- a/src/libstd/task/spawn.rs +++ b/src/libstd/task/spawn.rs @@ -302,7 +302,7 @@ fn each_ancestor(list: &mut AncestorList, fn with_parent_tg(parent_group: &mut Option, blk: &fn(TaskGroupInner) -> U) -> U { // If this trips, more likely the problem is 'blk' failed inside. - let tmp_arc = parent_group.swap_unwrap(); + let tmp_arc = parent_group.take_unwrap(); let result = do access_group(&tmp_arc) |tg_opt| { blk(tg_opt) }; *parent_group = Some(tmp_arc); result @@ -609,7 +609,7 @@ fn spawn_raw_newsched(mut opts: TaskOpts, f: ~fn()) { }; if opts.notify_chan.is_some() { - let notify_chan = opts.notify_chan.swap_unwrap(); + let notify_chan = opts.notify_chan.take_unwrap(); let notify_chan = Cell::new(notify_chan); let on_exit: ~fn(bool) = |success| { notify_chan.take().send( @@ -647,7 +647,7 @@ fn spawn_raw_oldsched(mut opts: TaskOpts, f: ~fn()) { let notify_chan = if opts.notify_chan.is_none() { None } else { - Some(opts.notify_chan.swap_unwrap()) + Some(opts.notify_chan.take_unwrap()) }; let child_wrapper = make_child_wrapper(new_task, child_tg, diff --git a/src/libstd/trie.rs b/src/libstd/trie.rs index 3882ab0de6333..396fdaf2e6a55 100644 --- a/src/libstd/trie.rs +++ b/src/libstd/trie.rs @@ -287,7 +287,7 @@ impl TrieNode { fn each_reverse<'a>(&'a self, f: &fn(&uint, &'a T) -> bool) -> bool { for uint::range_rev(self.children.len(), 0) |idx| { - match self.children[idx - 1] { + match self.children[idx] { Internal(ref x) => if !x.each_reverse(|i,t| f(i,t)) { return false }, External(k, ref v) => if !f(&k, v) { return false }, Nothing => () @@ -488,7 +488,7 @@ mod test_map { m.insert(x, x / 2); } - let mut n = uint::max_value - 9999; + let mut n = uint::max_value - 10000; for m.each |k, v| { if n == uint::max_value - 5000 { break } assert!(n < uint::max_value - 5000); @@ -525,7 +525,7 @@ mod test_map { m.insert(x, x / 2); } - let mut n = uint::max_value; + let mut n = uint::max_value - 1; for m.each_reverse |k, v| { if n == uint::max_value - 5000 { break } assert!(n > uint::max_value - 5000); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b6275ed186c82..6cf38d5ae1df2 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -215,15 +215,16 @@ pub enum meta_item_ { meta_name_value(@str, lit), } -pub type blk = spanned; +//pub type blk = spanned; #[deriving(Eq, Encodable, Decodable,IterBytes)] -pub struct blk_ { +pub struct blk { view_items: ~[view_item], stmts: ~[@stmt], expr: Option<@expr>, id: node_id, rules: blk_check_mode, + span: span, } #[deriving(Eq, Encodable, Decodable,IterBytes)] diff --git a/src/libsyntax/ast_map.rs b/src/libsyntax/ast_map.rs index e7eedcaa62e55..354471fc2a1e7 100644 --- a/src/libsyntax/ast_map.rs +++ b/src/libsyntax/ast_map.rs @@ -190,7 +190,7 @@ pub fn map_fn( } pub fn map_block(b: &blk, (cx,v): (@mut Ctx, visit::vt<@mut Ctx>)) { - cx.map.insert(b.node.id, node_block(/* FIXME (#2543) */ copy *b)); + cx.map.insert(b.id, node_block(/* FIXME (#2543) */ copy *b)); visit::visit_block(b, (cx, v)); } diff --git a/src/libsyntax/ast_util.rs b/src/libsyntax/ast_util.rs index a1d209d19ac56..00e667d7b88ce 100644 --- a/src/libsyntax/ast_util.rs +++ b/src/libsyntax/ast_util.rs @@ -11,7 +11,7 @@ use ast::*; use ast; use ast_util; -use codemap::{span, spanned}; +use codemap::{span, dummy_sp}; use opt_vec; use parse::token; use visit; @@ -194,21 +194,23 @@ pub fn is_call_expr(e: @expr) -> bool { } pub fn block_from_expr(e: @expr) -> blk { - let blk_ = default_block(~[], option::Some::<@expr>(e), e.id); - return spanned {node: blk_, span: e.span}; + let mut blk = default_block(~[], option::Some::<@expr>(e), e.id); + blk.span = e.span; + return blk; } pub fn default_block( stmts1: ~[@stmt], expr1: Option<@expr>, id1: node_id -) -> blk_ { - ast::blk_ { +) -> blk { + ast::blk { view_items: ~[], stmts: stmts1, expr: expr1, id: id1, rules: default_blk, + span: dummy_sp(), } } @@ -437,7 +439,7 @@ pub fn id_visitor(vfn: @fn(node_id, T)) -> visit::vt { visit::visit_local(l, (t, vt)); }, visit_block: |b, (t, vt)| { - vfn(b.node.id, copy t); + vfn(b.id, copy t); visit::visit_block(b, (t, vt)); }, visit_stmt: |s, (t, vt)| { diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 73220ec288170..83fce24bef8b7 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -400,14 +400,14 @@ impl AstBuilder for @ExtCtxt { view_items: ~[ast::view_item], stmts: ~[@ast::stmt], expr: Option<@ast::expr>) -> ast::blk { - respan(span, - ast::blk_ { - view_items: view_items, - stmts: stmts, - expr: expr, - id: self.next_id(), - rules: ast::default_blk, - }) + ast::blk { + view_items: view_items, + stmts: stmts, + expr: expr, + id: self.next_id(), + rules: ast::default_blk, + span: span, + } } fn expr(&self, span: span, node: ast::expr_) -> @ast::expr { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index c421da067951c..3f7579c769129 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use ast::{blk_, crate, expr_, expr_mac, mac_invoc_tt}; +use ast::{blk, crate, expr_, expr_mac, mac_invoc_tt}; use ast::{item_mac, stmt_, stmt_mac, stmt_expr, stmt_semi}; use ast::{illegal_ctxt}; use ast; @@ -394,13 +394,12 @@ pub fn new_name_finder() -> @Visitor<@mut ~[ast::ident]> { pub fn expand_block(extsbox: @mut SyntaxEnv, _cx: @ExtCtxt, - blk: &blk_, - sp: span, + blk: &blk, fld: @ast_fold, - orig: @fn(&blk_, span, @ast_fold) -> (blk_, span)) - -> (blk_, span) { + orig: @fn(&blk, @ast_fold) -> blk) + -> blk { // see note below about treatment of exts table - with_exts_frame!(extsbox,false,orig(blk,sp,fld)) + with_exts_frame!(extsbox,false,orig(blk,fld)) } @@ -736,8 +735,8 @@ pub fn expand_crate(parse_sess: @mut parse::ParseSess, expand_item(extsbox, cx, item, recur, afp.fold_item), fold_stmt: |stmt,span,recur| expand_stmt(extsbox, cx, stmt, span, recur, afp.fold_stmt), - fold_block: |blk,span,recur| - expand_block(extsbox, cx, blk, span, recur, afp.fold_block), + fold_block: |blk,recur| + expand_block(extsbox, cx, blk, recur, afp.fold_block), new_span: |a| new_span(cx, a), .. *afp}; let f = make_fold(f_pre); diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs index c36b717ea0055..059637ca73613 100644 --- a/src/libsyntax/fold.rs +++ b/src/libsyntax/fold.rs @@ -51,7 +51,7 @@ pub struct AstFoldFns { fold_struct_field: @fn(@struct_field, @ast_fold) -> @struct_field, fold_item_underscore: @fn(&item_, @ast_fold) -> item_, fold_method: @fn(@method, @ast_fold) -> @method, - fold_block: @fn(&blk_, span, @ast_fold) -> (blk_, span), + fold_block: @fn(&blk, @ast_fold) -> blk, fold_stmt: @fn(&stmt_, span, @ast_fold) -> (Option, span), fold_arm: @fn(&arm, @ast_fold) -> arm, fold_pat: @fn(&pat_, span, @ast_fold) -> (pat_, span), @@ -372,7 +372,7 @@ fn noop_fold_method(m: @method, fld: @ast_fold) -> @method { } -pub fn noop_fold_block(b: &blk_, fld: @ast_fold) -> blk_ { +pub fn noop_fold_block(b: &blk, fld: @ast_fold) -> blk { let view_items = b.view_items.map(|x| fld.fold_view_item(x)); let mut stmts = ~[]; for b.stmts.iter().advance |stmt| { @@ -381,12 +381,13 @@ pub fn noop_fold_block(b: &blk_, fld: @ast_fold) -> blk_ { Some(stmt) => stmts.push(stmt) } } - ast::blk_ { + ast::blk { view_items: view_items, stmts: stmts, expr: b.expr.map(|x| fld.fold_expr(*x)), id: fld.new_id(b.id), rules: b.rules, + span: b.span, } } @@ -794,7 +795,7 @@ pub fn default_ast_fold() -> ast_fold_fns { fold_struct_field: noop_fold_struct_field, fold_item_underscore: noop_fold_item_underscore, fold_method: noop_fold_method, - fold_block: wrap(noop_fold_block), + fold_block: noop_fold_block, fold_stmt: |x, s, fld| (noop_fold_stmt(x, fld), s), fold_arm: noop_fold_arm, fold_pat: wrap(noop_fold_pat), @@ -851,8 +852,7 @@ impl ast_fold for AstFoldFns { (self.fold_method)(x, self as @ast_fold) } fn fold_block(@self, x: &blk) -> blk { - let (n, s) = (self.fold_block)(&x.node, x.span, self as @ast_fold); - spanned { node: n, span: (self.new_span)(s) } + (self.fold_block)(x, self as @ast_fold) } fn fold_stmt(@self, x: &stmt) -> Option<@stmt> { let (n_opt, s) = (self.fold_stmt)(&x.node, x.span, self as @ast_fold); diff --git a/src/libsyntax/parse/classify.rs b/src/libsyntax/parse/classify.rs index 62b36b12f2669..44497f7200337 100644 --- a/src/libsyntax/parse/classify.rs +++ b/src/libsyntax/parse/classify.rs @@ -13,7 +13,6 @@ */ use ast; -use codemap; // does this expression require a semicolon to be treated // as a statement? The negation of this: 'can this expression @@ -40,8 +39,7 @@ pub fn expr_requires_semi_to_be_stmt(e: @ast::expr) -> bool { pub fn expr_is_simple_block(e: @ast::expr) -> bool { match e.node { ast::expr_block( - codemap::spanned { - node: ast::blk_ { rules: ast::default_blk, _ }, _ } + ast::blk { rules: ast::default_blk, _ } ) => true, _ => false } diff --git a/src/libsyntax/parse/mod.rs b/src/libsyntax/parse/mod.rs index 75d1f35bf38a5..40f1964bc9cd0 100644 --- a/src/libsyntax/parse/mod.rs +++ b/src/libsyntax/parse/mod.rs @@ -557,27 +557,26 @@ mod test { lifetimes: opt_vec::Empty, ty_params: opt_vec::Empty, }, - spanned{ + ast::blk { + view_items: ~[], + stmts: ~[@spanned{ + node: ast::stmt_semi(@ast::expr{ + id: 6, + node: ast::expr_path( + ast::Path{ + span:sp(17,18), + global:false, + idents:~[str_to_ident("b")], + rp:None, + types: ~[]}), + span: sp(17,18)}, + 7), // fixme + span: sp(17,18)}], + expr: None, + id: 8, // fixme + rules: ast::default_blk, // no idea span: sp(15,21), - node: ast::blk_{ - view_items: ~[], - stmts: ~[@spanned{ - node: ast::stmt_semi(@ast::expr{ - id: 6, - node: ast::expr_path( - ast::Path{ - span:sp(17,18), - global:false, - idents:~[str_to_ident("b")], - rp:None, - types: ~[]}), - span: sp(17,18)}, - 7), // fixme - span: sp(17,18)}], - expr: None, - id: 8, // fixme - rules: ast::default_blk // no idea - }}), + }), vis: ast::inherited, span: sp(0,21)})); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 05dda16214a8f..9e9071d6b8cb3 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2245,15 +2245,15 @@ impl Parser { let lo = self.last_span.lo; let decl = parse_decl(); let body = parse_body(); - let fakeblock = ast::blk_ { + let fakeblock = ast::blk { view_items: ~[], stmts: ~[], expr: Some(body), id: self.get_id(), rules: default_blk, + span: body.span, }; - let fakeblock = spanned(body.span.lo, body.span.hi, - fakeblock); + return self.mk_expr(lo, body.span.hi, expr_fn_block(decl, fakeblock)); } @@ -2402,14 +2402,12 @@ impl Parser { self.eat(&token::COMMA); } - let blk = codemap::spanned { - node: ast::blk_ { - view_items: ~[], - stmts: ~[], - expr: Some(expr), - id: self.get_id(), - rules: default_blk, - }, + let blk = ast::blk { + view_items: ~[], + stmts: ~[], + expr: Some(expr), + id: self.get_id(), + rules: default_blk, span: expr.span, }; @@ -3120,14 +3118,14 @@ impl Parser { let hi = self.span.hi; self.bump(); - let bloc = ast::blk_ { + ast::blk { view_items: view_items, stmts: stmts, expr: expr, id: self.get_id(), rules: s, - }; - spanned(lo, hi, bloc) + span: mk_sp(lo, hi), + } } fn parse_optional_purity(&self) -> ast::purity { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index c37108536154d..67d5f4aa845ca 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -932,7 +932,7 @@ pub fn print_possibly_embedded_block_(s: @ps, indented: uint, attrs: &[ast::attribute], close_box: bool) { - match blk.node.rules { + match blk.rules { ast::unsafe_blk => word_space(s, "unsafe"), ast::default_blk => () } @@ -946,11 +946,11 @@ pub fn print_possibly_embedded_block_(s: @ps, print_inner_attributes(s, attrs); - for blk.node.view_items.iter().advance |vi| { print_view_item(s, vi); } - for blk.node.stmts.iter().advance |st| { + for blk.view_items.iter().advance |vi| { print_view_item(s, vi); } + for blk.stmts.iter().advance |st| { print_stmt(s, *st); } - match blk.node.expr { + match blk.expr { Some(expr) => { space_if_not_bol(s); print_expr(s, expr); @@ -1255,12 +1255,12 @@ pub fn print_expr(s: @ps, expr: &ast::expr) { // Extract the expression from the extra block the parser adds // in the case of foo => expr - if arm.body.node.view_items.is_empty() && - arm.body.node.stmts.is_empty() && - arm.body.node.rules == ast::default_blk && - arm.body.node.expr.is_some() + if arm.body.view_items.is_empty() && + arm.body.stmts.is_empty() && + arm.body.rules == ast::default_blk && + arm.body.expr.is_some() { - match arm.body.node.expr { + match arm.body.expr { Some(expr) => { match expr.node { ast::expr_block(ref blk) => { @@ -1297,16 +1297,16 @@ pub fn print_expr(s: @ps, expr: &ast::expr) { print_fn_block_args(s, decl); space(s.s); // } - assert!(body.node.stmts.is_empty()); - assert!(body.node.expr.is_some()); + assert!(body.stmts.is_empty()); + assert!(body.expr.is_some()); // we extract the block, so as not to create another set of boxes - match body.node.expr.get().node { + match body.expr.get().node { ast::expr_block(ref blk) => { print_block_unclosed(s, blk); } _ => { // this is a bare expression - print_expr(s, body.node.expr.get()); + print_expr(s, body.expr.get()); end(s); // need to close a box } } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index b2d9d49f0ee77..09daa2e648af7 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -413,13 +413,13 @@ pub fn visit_struct_field(sf: &struct_field, (e, v): (E, vt)) { } pub fn visit_block(b: &blk, (e, v): (E, vt)) { - for b.node.view_items.iter().advance |vi| { + for b.view_items.iter().advance |vi| { (v.visit_view_item)(vi, (copy e, v)); } - for b.node.stmts.iter().advance |s| { + for b.stmts.iter().advance |s| { (v.visit_stmt)(*s, (copy e, v)); } - visit_expr_opt(b.node.expr, (e, v)); + visit_expr_opt(b.expr, (e, v)); } pub fn visit_stmt(s: &stmt, (e, v): (E, vt)) { diff --git a/src/test/bench/msgsend-ring-mutex-arcs.rs b/src/test/bench/msgsend-ring-mutex-arcs.rs index 2bd53f81b0581..0bf492ae55f0c 100644 --- a/src/test/bench/msgsend-ring-mutex-arcs.rs +++ b/src/test/bench/msgsend-ring-mutex-arcs.rs @@ -60,8 +60,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); - let mut num_chan2 = num_chan.swap_unwrap(); - let mut num_port2 = num_port.swap_unwrap(); + let mut num_chan2 = num_chan.take_unwrap(); + let mut num_port2 = num_port.take_unwrap(); send(&num_chan2, i * j); num_chan = Some(num_chan2); let _n = recv(&num_port2); diff --git a/src/test/bench/msgsend-ring-rw-arcs.rs b/src/test/bench/msgsend-ring-rw-arcs.rs index b5b5b685d87c4..a5f96b35999e2 100644 --- a/src/test/bench/msgsend-ring-rw-arcs.rs +++ b/src/test/bench/msgsend-ring-rw-arcs.rs @@ -56,8 +56,8 @@ fn thread_ring(i: uint, count: uint, num_chan: pipe, num_port: pipe) { // Send/Receive lots of messages. for uint::range(0u, count) |j| { //error!("task %?, iter %?", i, j); - let mut num_chan2 = num_chan.swap_unwrap(); - let mut num_port2 = num_port.swap_unwrap(); + let mut num_chan2 = num_chan.take_unwrap(); + let mut num_port2 = num_port.take_unwrap(); send(&num_chan2, i * j); num_chan = Some(num_chan2); let _n = recv(&num_port2); diff --git a/src/test/run-pass/enum-vec-initializer.rs b/src/test/run-pass/enum-vec-initializer.rs new file mode 100644 index 0000000000000..ae590ad7d1f71 --- /dev/null +++ b/src/test/run-pass/enum-vec-initializer.rs @@ -0,0 +1,24 @@ +// Copyright 2012 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum Flopsy { + Bunny = 2 +} + +static BAR:uint = Bunny as uint; +static BAR2:uint = BAR; + +fn main() { + let v = [0, .. Bunny as uint]; + let v = [0, .. BAR]; + let v = [0, .. BAR2]; + static BAR3:uint = BAR2; + let v = [0, .. BAR3]; +} \ No newline at end of file diff --git a/src/test/run-pass/num-range-rev.rs b/src/test/run-pass/num-range-rev.rs new file mode 100644 index 0000000000000..7262339e431d9 --- /dev/null +++ b/src/test/run-pass/num-range-rev.rs @@ -0,0 +1,114 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::int; +use std::uint; + +fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { + uint::range(lo, hi, it) +} + +fn int_range(lo: int, hi: int, it: &fn(int) -> bool) -> bool { + int::range(lo, hi, it) +} + +fn uint_range_rev(hi: uint, lo: uint, it: &fn(uint) -> bool) -> bool { + uint::range_rev(hi, lo, it) +} + +fn int_range_rev(hi: int, lo: int, it: &fn(int) -> bool) -> bool { + int::range_rev(hi, lo, it) +} + +fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool { + int::range_step(a, b, step, it) +} + +fn uint_range_step(a: uint, b: uint, step: int, it: &fn(uint) -> bool) -> bool { + uint::range_step(a, b, step, it) +} + + +pub fn main() { + // int and uint have same result for + // Sum{100 > i >= 2} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99 + let mut sum = 0u; + for uint_range_rev(100, 2) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + let mut sum = 0i; + for int_range_rev(100, 2) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + + // elements are visited in correct order + let primes = [2,3,5,7,11]; + let mut prod = 1i; + for uint_range_rev(5, 0) |i| { + println(fmt!("uint 4 downto 0: %u", i)); + prod *= int::pow(primes[i], i); + } + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1); + let mut prod = 1i; + for int_range_rev(5, 0) |i| { + println(fmt!("int 4 downto 0: %d", i)); + prod *= int::pow(primes[i], i as uint); + } + assert_eq!(prod, 11*11*11*11*7*7*7*5*5*3*1); + + + // range and range_rev are symmetric. + let mut sum_up = 0u; + for uint_range(10, 30) |i| { + sum_up += i; + } + let mut sum_down = 0u; + for uint_range_rev(30, 10) |i| { + sum_down += i; + } + assert_eq!(sum_up, sum_down); + + let mut sum_up = 0; + for int_range(-20, 10) |i| { + sum_up += i; + } + let mut sum_down = 0; + for int_range_rev(10, -20) |i| { + sum_down += i; + } + assert_eq!(sum_up, sum_down); + + + // empty ranges + for int_range_rev(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + for uint_range_rev(0, 1) |_| { + fail!("range should be empty when start-1 underflows"); + } + + // range iterations do not wrap/underflow + let mut uflo_loop_visited = ~[]; + for int_range_step(int::min_value+15, int::min_value, -4) |x| { + uflo_loop_visited.push(x - int::min_value); + } + assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]); + + let mut uflo_loop_visited = ~[]; + for uint_range_step(uint::min_value+15, uint::min_value, -4) |x| { + uflo_loop_visited.push(x - uint::min_value); + } + assert_eq!(uflo_loop_visited, ~[15, 11, 7, 3]); +} diff --git a/src/test/run-pass/num-range.rs b/src/test/run-pass/num-range.rs new file mode 100644 index 0000000000000..7c1f905a049b6 --- /dev/null +++ b/src/test/run-pass/num-range.rs @@ -0,0 +1,119 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use std::int; +use std::uint; + +fn uint_range(lo: uint, hi: uint, it: &fn(uint) -> bool) -> bool { + uint::range(lo, hi, it) +} + +fn int_range(lo: int, hi: int, it: &fn(int) -> bool) -> bool { + int::range(lo, hi, it) +} + +fn int_range_step(a: int, b: int, step: int, it: &fn(int) -> bool) -> bool { + int::range_step(a, b, step, it) +} + +fn uint_range_step(a: uint, b: uint, s: int, it: &fn(uint) -> bool) -> bool { + uint::range_step(a, b, s, it) +} + +pub fn main() { + println(fmt!("num-range start")); + // int and uint have same result for + // Sum{2 <= i < 100} == (Sum{1 <= i <= 99} - 1) == n*(n+1)/2 - 1 for n=99 + let mut sum = 0u; + for uint_range(2, 100) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + let mut sum = 0i; + for int_range(2, 100) |i| { + sum += i; + } + assert_eq!(sum, 4949); + + + // elements are visited in correct order + let primes = [2,3,5,7]; + let mut prod = 1i; + for uint_range(0, 4) |i| { + prod *= int::pow(primes[i], i); + } + assert_eq!(prod, 1*3*5*5*7*7*7); + let mut prod = 1i; + for int_range(0, 4) |i| { + prod *= int::pow(primes[i], i as uint); + } + assert_eq!(prod, 1*3*5*5*7*7*7); + + + // empty ranges + for int_range(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + for uint_range(10, 10) |_| { + fail!("range should be empty when start == stop"); + } + + + // range iterations do not wrap/overflow + let mut oflo_loop_visited = ~[]; + for uint_range_step(uint::max_value-15, uint::max_value, 4) |x| { + oflo_loop_visited.push(uint::max_value - x); + } + assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]); + + let mut oflo_loop_visited = ~[]; + for int_range_step(int::max_value-15, int::max_value, 4) |x| { + oflo_loop_visited.push(int::max_value - x); + } + assert_eq!(oflo_loop_visited, ~[15, 11, 7, 3]); + + + // range_step never passes nor visits the stop element + for int_range_step(0, 21, 3) |x| { + assert!(x < 21); + } + + // range_step_inclusive will never pass stop element, and may skip it. + let mut saw21 = false; + for uint::range_step_inclusive(0, 21, 4) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(!saw21); + let mut saw21 = false; + for int::range_step_inclusive(0, 21, 4) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(!saw21); + + // range_step_inclusive will never pass stop element, but may visit it. + let mut saw21 = false; + for uint::range_step_inclusive(0, 21, 3) |x| { + assert!(x <= 21); + println(fmt!("saw: %u", x)); + if x == 21 { saw21 = true; } + } + assert!(saw21); + let mut saw21 = false; + for int::range_step_inclusive(0, 21, 3) |x| { + assert!(x <= 21); + if x == 21 { saw21 = true; } + } + assert!(saw21); + +}