diff --git a/src/libcore/task.rs b/src/libcore/task.rs index 16b4e6810518a..863efc79d4a30 100644 --- a/src/libcore/task.rs +++ b/src/libcore/task.rs @@ -851,12 +851,10 @@ fn each_ancestor(list: &mut AncestorList, do with_parent_tg(&mut nobe.parent_group) |tg_opt| { // Decide whether this group is dead. Note that the // group being *dead* is disjoint from it *failing*. - match *tg_opt { - some(ref tg) => { - nobe_is_dead = taskgroup_is_dead(tg); - }, - none => { } - } + nobe_is_dead = match *tg_opt { + some(ref tg) => taskgroup_is_dead(tg), + none => nobe_is_dead + }; // Call iterator block. (If the group is dead, it's // safe to skip it. This will leave our *rust_task // hanging around in the group even after it's freed, diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 15db86f937df9..c6be27c4b77a0 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -75,6 +75,7 @@ export swap; export reverse; export reversed; export iter, iter_between, each, eachi, reach, reachi; +export each_mut, each_const; export iter2; export iteri; export riter; @@ -1174,6 +1175,24 @@ pure fn each(v: &[T], f: fn(T) -> bool) { } } +/// Like `each()`, but for the case where you have +/// a vector with mutable contents and you would like +/// to mutate the contents as you iterate. +#[inline(always)] +pure fn each_mut(v: &[mut T], f: fn(elem: &mut T) -> bool) { + do vec::as_mut_buf(v) |p, n| { + let mut n = n; + let mut p = p; + while n > 0u { + unsafe { + if !f(&mut *p) { break; } + p = ptr::mut_offset(p, 1u); + } + n -= 1u; + } + } +} + /** * Iterates over a vector's elements and indices * diff --git a/src/libstd/sha1.rs b/src/libstd/sha1.rs index 508bdaa86f0da..22219c77f6cc1 100644 --- a/src/libstd/sha1.rs +++ b/src/libstd/sha1.rs @@ -158,7 +158,8 @@ fn sha1() -> sha1 { fn mk_result(st: sha1state) -> ~[u8] { if !st.computed { pad_msg(st); st.computed = true; } let mut rs: ~[u8] = ~[]; - for vec::each(st.h) |hpart| { + for vec::each_mut(st.h) |ptr_hpart| { + let hpart = *ptr_hpart; let a = (hpart >> 24u32 & 0xFFu32) as u8; let b = (hpart >> 16u32 & 0xFFu32) as u8; let c = (hpart >> 8u32 & 0xFFu32) as u8; diff --git a/src/libsyntax/ext/simplext.rs b/src/libsyntax/ext/simplext.rs index 7c37312a4333a..586a428c1d70a 100644 --- a/src/libsyntax/ext/simplext.rs +++ b/src/libsyntax/ext/simplext.rs @@ -205,10 +205,10 @@ fn transcribe(cx: ext_ctxt, b: bindings, body: @expr) -> @expr { /* helper: descend into a matcher */ -fn follow(m: arb_depth, idx_path: @mut ~[uint]) -> +pure fn follow(m: arb_depth, idx_path: &[uint]) -> arb_depth { let mut res: arb_depth = m; - for vec::each(*idx_path) |idx| { + for vec::each(idx_path) |idx| { res = match res { leaf(_) => return res,/* end of the line */ seq(new_ms, _) => new_ms[idx] @@ -222,7 +222,7 @@ fn follow_for_trans(cx: ext_ctxt, mmaybe: option>, match mmaybe { none => return none, some(m) => { - return match follow(m, idx_path) { + return match follow(m, *idx_path) { seq(_, sp) => { cx.span_fatal(sp, ~"syntax matched under ... but not " + @@ -274,7 +274,8 @@ fn transcribe_exprs(cx: ext_ctxt, b: bindings, idx_path: @mut ~[uint], /* we need to walk over all the free vars in lockstep, except for the leaves, which are just duplicated */ do free_vars(b, repeat_me) |fv| { - let cur_pos = follow(b.get(fv), idx_path); + let fv_depth = b.get(fv); + let cur_pos = follow(fv_depth, *idx_path); match cur_pos { leaf(_) => (), seq(ms, _) => { diff --git a/src/libsyntax/parse/common.rs b/src/libsyntax/parse/common.rs index afb9c91fc8d84..e68a81209927d 100644 --- a/src/libsyntax/parse/common.rs +++ b/src/libsyntax/parse/common.rs @@ -146,19 +146,12 @@ impl parser: parser_common { fn eat_keyword(word: ~str) -> bool { self.require_keyword(word); - - let mut bump = false; - let val = match self.token { - token::IDENT(sid, false) => { - if word == *self.id_to_str(sid) { - bump = true; - true - } else { false } - } + let is_kw = match self.token { + token::IDENT(sid, false) => (word == *self.id_to_str(sid)), _ => false }; - if bump { self.bump() } - val + if is_kw { self.bump() } + is_kw } fn expect_keyword(word: ~str) { diff --git a/src/rustc/middle/borrowck/check_loans.rs b/src/rustc/middle/borrowck/check_loans.rs index 885d8a65046e1..6db7297618b58 100644 --- a/src/rustc/middle/borrowck/check_loans.rs +++ b/src/rustc/middle/borrowck/check_loans.rs @@ -326,19 +326,8 @@ impl check_loan_ctxt { // even to data owned by the current stack frame. This is // because that aliasable data might have been located on // the current stack frame, we don't know. - match cmt.lp { - some(@lp_local(*)) | some(@lp_arg(*)) => { - // it's ok to mutate a local variable, as it is either - // lent our or not. The problem arises when you have - // some subcomponent that might have been lent out - // through an alias on the condition that you ensure - // purity. - } - none | some(@lp_comp(*)) | some(@lp_deref(*)) => { - self.report_purity_error( - pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt))); - } - } + self.report_purity_error( + pc, ex.span, at.ing_form(self.bccx.cmt_to_str(cmt))); } some(pc_pure_fn) => { if cmt.lp.is_none() { diff --git a/src/rustc/middle/resolve3.rs b/src/rustc/middle/resolve3.rs index 68d2b1458291d..da6b0b5087bbe 100644 --- a/src/rustc/middle/resolve3.rs +++ b/src/rustc/middle/resolve3.rs @@ -2065,7 +2065,7 @@ struct Resolver { str_of(name))); return Failed; } - ModuleDef(module_) => { + ModuleDef(copy module_) => { search_module = module_; } } diff --git a/src/rustc/middle/trans/type_use.rs b/src/rustc/middle/trans/type_use.rs index 004de82e064d7..ce84269bb67ac 100644 --- a/src/rustc/middle/trans/type_use.rs +++ b/src/rustc/middle/trans/type_use.rs @@ -116,10 +116,13 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint) } fn type_needs(cx: ctx, use: uint, ty: ty::t) { - let mut done = true; // Optimization -- don't descend type if all params already have this use - for vec::each(cx.uses) |u| { if u & use != use { done = false } } - if !done { type_needs_inner(cx, use, ty, @nil); } + for vec::each_mut(cx.uses) |u| { + if *u & use != use { + type_needs_inner(cx, use, ty, @nil); + return; + } + } } fn type_needs_inner(cx: ctx, use: uint, ty: ty::t, diff --git a/src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs b/src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs new file mode 100644 index 0000000000000..7ac3cfca07e92 --- /dev/null +++ b/src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs @@ -0,0 +1,8 @@ +fn main() { + let mut _a = 3; + let _b = &mut _a; + { + let _c = &*_b; //~ ERROR illegal borrow unless pure + _a = 4; //~ NOTE impure due to assigning to mutable local variable + } +}