about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/task.rs10
-rw-r--r--src/libcore/vec.rs19
-rw-r--r--src/libstd/sha1.rs3
-rw-r--r--src/libsyntax/ext/simplext.rs9
-rw-r--r--src/libsyntax/parse/common.rs15
-rw-r--r--src/rustc/middle/borrowck/check_loans.rs15
-rw-r--r--src/rustc/middle/resolve3.rs2
-rw-r--r--src/rustc/middle/trans/type_use.rs9
-rw-r--r--src/test/compile-fail/borrowck-imm-ref-to-mut-rec-field-issue-3162-c.rs8
9 files changed, 51 insertions, 39 deletions
diff --git a/src/libcore/task.rs b/src/libcore/task.rs
index 16b4e681051..863efc79d4a 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 15db86f937d..c6be27c4b77 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<T>(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<T>(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 508bdaa86f0..22219c77f6c 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 7c37312a433..586a428c1d7 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<matchable>, idx_path: @mut ~[uint]) ->
+pure fn follow(m: arb_depth<matchable>, idx_path: &[uint]) ->
    arb_depth<matchable> {
     let mut res: arb_depth<matchable> = 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<arb_depth<matchable>>,
     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 afb9c91fc8d..e68a8120992 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 885d8a65046..6db7297618b 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 68d2b145829..da6b0b5087b 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 004de82e064..ce84269bb67 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 00000000000..7ac3cfca07e
--- /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
+    }
+}