about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/at_vec.rs18
-rw-r--r--src/libcore/vec.rs49
-rw-r--r--src/libstd/arena.rs115
-rw-r--r--src/libsyntax/parse/parser.rs1
-rw-r--r--src/rustc/middle/typeck/check.rs4
-rw-r--r--src/test/compile-fail/borrowck-lend-args.rs4
-rw-r--r--src/test/compile-fail/deprecated-mode-fn-arg.rs2
-rw-r--r--src/test/compile-fail/issue-511.rs6
-rw-r--r--src/test/compile-fail/liveness-dead.rs4
-rw-r--r--src/test/compile-fail/liveness-move-from-args.rs4
-rw-r--r--src/test/compile-fail/liveness-unused.rs2
-rw-r--r--src/test/compile-fail/mutable-arguments.rs12
-rw-r--r--src/test/run-pass/intrinsic-move-val.rs6
13 files changed, 204 insertions, 23 deletions
diff --git a/src/libcore/at_vec.rs b/src/libcore/at_vec.rs
index 5e1111c20d3..8c023a7cb4c 100644
--- a/src/libcore/at_vec.rs
+++ b/src/libcore/at_vec.rs
@@ -21,7 +21,11 @@ extern mod rustrt {
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
+    #[cfg(stage0)]
     fn move_val_init<T>(&dst: T, -src: T);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn move_val_init<T>(dst: &mut T, -src: T);
 }
 
 /// Returns the number of elements the vector can hold without reallocating
@@ -176,7 +180,9 @@ pub mod raw {
             push_slow(v, move initval);
         }
     }
+
     // This doesn't bother to make sure we have space.
+    #[cfg(stage0)]
     #[inline(always)] // really pretty please
     pub unsafe fn push_fast<T>(v: &mut @[const T], initval: T) {
         let repr: **VecRepr = ::cast::reinterpret_cast(&v);
@@ -186,6 +192,18 @@ pub mod raw {
         let p = ptr::offset(p, fill) as *mut T;
         rusti::move_val_init(*p, move initval);
     }
+    // This doesn't bother to make sure we have space.
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    #[inline(always)] // really pretty please
+    pub unsafe fn push_fast<T>(v: &mut @[const T], initval: T) {
+        let repr: **VecRepr = ::cast::reinterpret_cast(&v);
+        let fill = (**repr).unboxed.fill;
+        (**repr).unboxed.fill += sys::size_of::<T>();
+        let p = addr_of(&((**repr).unboxed.data));
+        let p = ptr::offset(p, fill) as *mut T;
+        rusti::move_val_init(&mut(*p), move initval);
+    }
 
     pub unsafe fn push_slow<T>(v: &mut @[const T], initval: T) {
         reserve_at_least(v, v.len() + 1u);
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index a157071c955..ce1193aa730 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -18,9 +18,14 @@ extern mod rustrt {
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
+    #[cfg(stage0)]
     fn move_val_init<T>(&dst: T, -src: T);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn move_val_init<T>(dst: &mut T, -src: T);
 }
 
+
 /// Returns true if a vector contains no elements
 pub pure fn is_empty<T>(v: &[const T]) -> bool {
     as_const_buf(v, |_p, len| len == 0u)
@@ -98,6 +103,7 @@ pub pure fn len<T>(v: &[const T]) -> uint {
  * Creates an immutable vector of size `n_elts` and initializes the elements
  * to the value returned by the function `op`.
  */
+#[cfg(stage0)]
 pub pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> ~[T] {
     unsafe {
         let mut v = with_capacity(n_elts);
@@ -112,6 +118,22 @@ pub pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> ~[T] {
         return move v;
     }
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+pub pure fn from_fn<T>(n_elts: uint, op: iter::InitOp<T>) -> ~[T] {
+    unsafe {
+        let mut v = with_capacity(n_elts);
+        do as_mut_buf(v) |p, _len| {
+            let mut i: uint = 0u;
+            while i < n_elts {
+                rusti::move_val_init(&mut(*ptr::mut_offset(p, i)), op(i));
+                i += 1u;
+            }
+        }
+        raw::set_len(&mut v, n_elts);
+        return move v;
+    }
+}
 
 /**
  * Creates and initializes an immutable vector.
@@ -481,6 +503,7 @@ pub fn push<T>(v: &mut ~[T], initval: T) {
     }
 }
 
+#[cfg(stage0)]
 // This doesn't bother to make sure we have space.
 #[inline(always)] // really pretty please
 unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
@@ -491,6 +514,18 @@ unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
     let p = ptr::offset(p, fill) as *mut T;
     rusti::move_val_init(*p, move initval);
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+// This doesn't bother to make sure we have space.
+#[inline(always)] // really pretty please
+unsafe fn push_fast<T>(v: &mut ~[T], initval: T) {
+    let repr: **raw::VecRepr = ::cast::transmute(v);
+    let fill = (**repr).unboxed.fill;
+    (**repr).unboxed.fill += sys::size_of::<T>();
+    let p = addr_of(&((**repr).unboxed.data));
+    let p = ptr::offset(p, fill) as *mut T;
+    rusti::move_val_init(&mut(*p), move initval);
+}
 
 #[inline(never)]
 fn push_slow<T>(v: &mut ~[T], initval: T) {
@@ -1758,6 +1793,18 @@ pub mod raw {
         as_const_buf(v, |p, _len| *ptr::const_offset(p, i))
     }
 
+    #[cfg(stage0)]
+    #[inline(always)]
+    pub unsafe fn init_elem<T>(v: &[mut T], i: uint, val: T) {
+        let mut box = Some(move val);
+        do as_mut_buf(v) |p, _len| {
+            let mut box2 = None;
+            box2 <-> box;
+            rusti::move_val_init(*ptr::mut_offset(p, i),
+                                 option::unwrap(move box2));
+        }
+    }
+    #[cfg(stage1)]
     /**
      * Unchecked vector index assignment.  Does not drop the
      * old value and hence is only suitable when the vector
@@ -1769,7 +1816,7 @@ pub mod raw {
         do as_mut_buf(v) |p, _len| {
             let mut box2 = None;
             box2 <-> box;
-            rusti::move_val_init(*ptr::mut_offset(p, i),
+            rusti::move_val_init(&mut(*ptr::mut_offset(p, i)),
                                  option::unwrap(move box2));
         }
     }
diff --git a/src/libstd/arena.rs b/src/libstd/arena.rs
index 4d2b910fa85..69478b3e731 100644
--- a/src/libstd/arena.rs
+++ b/src/libstd/arena.rs
@@ -31,9 +31,14 @@ use libc::size_t;
 
 #[abi = "rust-intrinsic"]
 extern mod rusti {
+    #[cfg(stage0)]
     fn move_val_init<T>(&dst: T, -src: T);
+    #[cfg(stage1)]
+    #[cfg(stage2)]
+    fn move_val_init<T>(dst: &mut T, -src: T);
     fn needs_drop<T>() -> bool;
 }
+
 extern mod rustrt {
     #[rust_stack]
     fn rust_call_tydesc_glue(root: *u8, tydesc: *TypeDesc, field: size_t);
@@ -127,6 +132,8 @@ unsafe fn un_bitpack_tydesc_ptr(p: uint) -> (*TypeDesc, bool) {
     (reinterpret_cast(&(p & !1)), p & 1 == 1)
 }
 
+// tjc: Can get rid of the duplication post-snapshot
+#[cfg(stage0)]
 // The duplication between the POD and non-POD functions is annoying.
 impl &Arena {
     // Functions for the POD part of the arena
@@ -234,6 +241,114 @@ impl &Arena {
         } else { self.alloc_nonpod(op) }
     }
 }
+#[cfg(stage1)]
+#[cfg(stage2)]
+impl &Arena {
+    // Functions for the POD part of the arena
+    fn alloc_pod_grow(n_bytes: uint, align: uint) -> *u8 {
+        // Allocate a new chunk.
+        let chunk_size = at_vec::capacity(self.pod_head.data);
+        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
+        self.chunks = @Cons(copy self.pod_head, self.chunks);
+        self.pod_head =
+            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), true);
+
+        return self.alloc_pod_inner(n_bytes, align);
+    }
+
+    #[inline(always)]
+    fn alloc_pod_inner(n_bytes: uint, align: uint) -> *u8 {
+        let head = &mut self.pod_head;
+
+        let start = round_up_to(head.fill, align);
+        let end = start + n_bytes;
+        if end > at_vec::capacity(head.data) {
+            return self.alloc_pod_grow(n_bytes, align);
+        }
+        head.fill = end;
+
+        //debug!("idx = %u, size = %u, align = %u, fill = %u",
+        //       start, n_bytes, align, head.fill);
+
+        unsafe {
+            ptr::offset(vec::raw::to_ptr(head.data), start)
+        }
+    }
+
+    #[inline(always)]
+    fn alloc_pod<T>(op: fn() -> T) -> &self/T {
+        unsafe {
+            let tydesc = sys::get_type_desc::<T>();
+            let ptr = self.alloc_pod_inner((*tydesc).size, (*tydesc).align);
+            let ptr: *mut T = reinterpret_cast(&ptr);
+            rusti::move_val_init(&mut (*ptr), op());
+            return reinterpret_cast(&ptr);
+        }
+    }
+
+    // Functions for the non-POD part of the arena
+    fn alloc_nonpod_grow(n_bytes: uint, align: uint) -> (*u8, *u8) {
+        // Allocate a new chunk.
+        let chunk_size = at_vec::capacity(self.head.data);
+        let new_min_chunk_size = uint::max(n_bytes, chunk_size);
+        self.chunks = @Cons(copy self.head, self.chunks);
+        self.head =
+            chunk(uint::next_power_of_two(new_min_chunk_size + 1u), false);
+
+        return self.alloc_nonpod_inner(n_bytes, align);
+    }
+
+    #[inline(always)]
+    fn alloc_nonpod_inner(n_bytes: uint, align: uint) -> (*u8, *u8) {
+        let head = &mut self.head;
+
+        let tydesc_start = head.fill;
+        let after_tydesc = head.fill + sys::size_of::<*TypeDesc>();
+        let start = round_up_to(after_tydesc, align);
+        let end = start + n_bytes;
+        if end > at_vec::capacity(head.data) {
+            return self.alloc_nonpod_grow(n_bytes, align);
+        }
+        head.fill = round_up_to(end, sys::pref_align_of::<*TypeDesc>());
+
+        //debug!("idx = %u, size = %u, align = %u, fill = %u",
+        //       start, n_bytes, align, head.fill);
+
+        unsafe {
+            let buf = vec::raw::to_ptr(head.data);
+            return (ptr::offset(buf, tydesc_start), ptr::offset(buf, start));
+        }
+    }
+
+    #[inline(always)]
+    fn alloc_nonpod<T>(op: fn() -> T) -> &self/T {
+        unsafe {
+            let tydesc = sys::get_type_desc::<T>();
+            let (ty_ptr, ptr) =
+                self.alloc_nonpod_inner((*tydesc).size, (*tydesc).align);
+            let ty_ptr: *mut uint = reinterpret_cast(&ty_ptr);
+            let ptr: *mut T = reinterpret_cast(&ptr);
+            // Write in our tydesc along with a bit indicating that it
+            // has *not* been initialized yet.
+            *ty_ptr = reinterpret_cast(&tydesc);
+            // Actually initialize it
+            rusti::move_val_init(&mut(*ptr), op());
+            // Now that we are done, update the tydesc to indicate that
+            // the object is there.
+            *ty_ptr = bitpack_tydesc_ptr(tydesc, true);
+
+            return reinterpret_cast(&ptr);
+        }
+    }
+
+    // The external interface
+    #[inline(always)]
+    fn alloc<T>(op: fn() -> T) -> &self/T {
+        if !rusti::needs_drop::<T>() {
+            self.alloc_pod(op)
+        } else { self.alloc_nonpod(op) }
+    }
+}
 
 #[test]
 fn test_arena_destructors() {
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 8860d1b5cea..1a87d7fed69 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -570,6 +570,7 @@ impl parser {
 
     fn parse_arg_mode() -> mode {
         if self.eat(token::BINOP(token::AND)) {
+            self.warn(~"Obsolete syntax has no effect");
             expl(by_mutbl_ref)
         } else if self.eat(token::BINOP(token::MINUS)) {
             expl(by_move)
diff --git a/src/rustc/middle/typeck/check.rs b/src/rustc/middle/typeck/check.rs
index 368b69cafab..7cc2c8b0ad7 100644
--- a/src/rustc/middle/typeck/check.rs
+++ b/src/rustc/middle/typeck/check.rs
@@ -2601,7 +2601,9 @@ fn check_intrinsic_type(ccx: @crate_ctxt, it: @ast::foreign_item) {
       ~"addr_of" => (1u, ~[arg(ast::by_ref, param(ccx, 0u))],
                       ty::mk_imm_ptr(tcx, param(ccx, 0u))),
       ~"move_val" | ~"move_val_init" => {
-        (1u, ~[arg(ast::by_mutbl_ref, param(ccx, 0u)),
+          (1u, ~[arg(ast::by_copy,
+                     ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)),
+                                     param(ccx, 0u))),
                arg(ast::by_move, param(ccx, 0u))],
          ty::mk_nil(tcx))
       }
diff --git a/src/test/compile-fail/borrowck-lend-args.rs b/src/test/compile-fail/borrowck-lend-args.rs
index 3cb7009ee27..79f52b93612 100644
--- a/src/test/compile-fail/borrowck-lend-args.rs
+++ b/src/test/compile-fail/borrowck-lend-args.rs
@@ -4,8 +4,8 @@ fn borrow_from_arg_imm_ref(&&v: ~int) {
     borrow(v);
 }
 
-fn borrow_from_arg_mut_ref(&v: ~int) {
-    borrow(v); //~ ERROR illegal borrow unless pure
+fn borrow_from_arg_mut_ref(v: &mut ~int) {
+    borrow(*v); //~ ERROR illegal borrow unless pure
     //~^ NOTE impure due to access to impure function
 }
 
diff --git a/src/test/compile-fail/deprecated-mode-fn-arg.rs b/src/test/compile-fail/deprecated-mode-fn-arg.rs
index 5afffb59dfc..2c20e604f50 100644
--- a/src/test/compile-fail/deprecated-mode-fn-arg.rs
+++ b/src/test/compile-fail/deprecated-mode-fn-arg.rs
@@ -1,9 +1,11 @@
 #[forbid(deprecated_mode)];
 
 fn foo(_f: fn(&i: int)) { //~ ERROR explicit mode
+    //~^ WARNING Obsolete syntax has no effect
 }
 
 type Bar = fn(&i: int); //~ ERROR explicit mode
+    //~^ WARNING Obsolete syntax has no effect
 
 fn main() {
 }
\ No newline at end of file
diff --git a/src/test/compile-fail/issue-511.rs b/src/test/compile-fail/issue-511.rs
index a3498dd1968..02a3082dc10 100644
--- a/src/test/compile-fail/issue-511.rs
+++ b/src/test/compile-fail/issue-511.rs
@@ -1,11 +1,11 @@
 extern mod std;
 use cmp::Eq;
 
-fn f<T:Eq>(&o: Option<T>) {
-    assert o == option::None;
+fn f<T:Eq>(o: &mut Option<T>) {
+    assert *o == option::None;
 }
 
 fn main() {
-    f::<int>(option::None);
+    f::<int>(&mut option::None);
     //~^ ERROR illegal borrow: creating mutable alias to static item
 }
diff --git a/src/test/compile-fail/liveness-dead.rs b/src/test/compile-fail/liveness-dead.rs
index a115d7c4e34..834457940be 100644
--- a/src/test/compile-fail/liveness-dead.rs
+++ b/src/test/compile-fail/liveness-dead.rs
@@ -1,5 +1,5 @@
-fn f1(&x: int) {
-    x = 1; // no error
+fn f1(x: &mut int) {
+    *x = 1; // no error
 }
 
 fn f2() {
diff --git a/src/test/compile-fail/liveness-move-from-args.rs b/src/test/compile-fail/liveness-move-from-args.rs
index 27e7e51b405..27e9d3b60dc 100644
--- a/src/test/compile-fail/liveness-move-from-args.rs
+++ b/src/test/compile-fail/liveness-move-from-args.rs
@@ -4,10 +4,6 @@ fn from_by_value_arg(++x: int) {
     take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
 }
 
-fn from_by_mut_ref_arg(&x: int) {
-    take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
-}
-
 fn from_by_ref_arg(&&x: int) {
     take(x);  //~ ERROR illegal move from argument `x`, which is not copy or move mode
 }
diff --git a/src/test/compile-fail/liveness-unused.rs b/src/test/compile-fail/liveness-unused.rs
index 7db02897112..8b2fef7cd35 100644
--- a/src/test/compile-fail/liveness-unused.rs
+++ b/src/test/compile-fail/liveness-unused.rs
@@ -2,7 +2,7 @@ fn f1(x: int) {
     //~^ WARNING unused variable: `x`
 }
 
-fn f1b(&x: int) {
+fn f1b(x: &mut int) {
     //~^ WARNING unused variable: `x`
 }
 
diff --git a/src/test/compile-fail/mutable-arguments.rs b/src/test/compile-fail/mutable-arguments.rs
index 4fcb73e8516..d84c9401e25 100644
--- a/src/test/compile-fail/mutable-arguments.rs
+++ b/src/test/compile-fail/mutable-arguments.rs
@@ -1,28 +1,28 @@
 // Note: it would be nice to give fewer warnings in these cases.
 
-fn mutate_by_mut_ref(&x: uint) {
-    x = 0u;
+fn mutate_by_mut_ref(x: &mut uint) {
+    *x = 0;
 }
 
 fn mutate_by_ref(&&x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
 }
 
 fn mutate_by_val(++x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
 }
 
 fn mutate_by_copy(+x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
     //~^ WARNING value assigned to `x` is never read
 }
 
 fn mutate_by_move(-x: uint) {
     //~^ WARNING unused variable: `x`
-    x = 0u; //~ ERROR assigning to argument
+    x = 0; //~ ERROR assigning to argument
     //~^ WARNING value assigned to `x` is never read
 }
 
diff --git a/src/test/run-pass/intrinsic-move-val.rs b/src/test/run-pass/intrinsic-move-val.rs
index b7f2115f45d..683321aac3d 100644
--- a/src/test/run-pass/intrinsic-move-val.rs
+++ b/src/test/run-pass/intrinsic-move-val.rs
@@ -1,13 +1,13 @@
 #[abi = "rust-intrinsic"]
 extern mod rusti {
     #[legacy_exports];
-    fn move_val_init<T>(&dst: T, -src: T);
-    fn move_val<T>(&dst: T, -src: T);
+    fn move_val_init<T>(dst: &mut T, -src: T);
+    fn move_val<T>(dst: &mut T, -src: T);
 }
 
 fn main() {
     let mut x = @1;
     let mut y = @2;
-    rusti::move_val(y, x);
+    rusti::move_val(&mut y, x);
     assert *y == 1;
 }
\ No newline at end of file