about summary refs log tree commit diff
path: root/src/libcore
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2012-09-12 10:38:17 -0700
committerNiko Matsakis <niko@alum.mit.edu>2012-09-12 13:29:31 -0700
commit5d540de76993eb6dac9893138e45d0324c23e631 (patch)
tree067007dea6fa0428c80b913a10730ab3323a40f0 /src/libcore
parent8fbe4b58412b2818d4ef3d92259bdf5f88f61606 (diff)
fixup mutability of vec::each, make iter_bytes pure
also, change DVec() to work with imm vectors rather than mut ones
Diffstat (limited to 'src/libcore')
-rw-r--r--src/libcore/dvec.rs46
-rw-r--r--src/libcore/hash.rs4
-rw-r--r--src/libcore/io.rs2
-rw-r--r--src/libcore/ptr.rs50
-rw-r--r--src/libcore/str.rs8
-rw-r--r--src/libcore/to_bytes.rs75
-rw-r--r--src/libcore/unsafe.rs12
-rw-r--r--src/libcore/vec.rs141
8 files changed, 224 insertions, 114 deletions
diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs
index ed8a814bba8..d59d3828206 100644
--- a/src/libcore/dvec.rs
+++ b/src/libcore/dvec.rs
@@ -50,7 +50,7 @@ export unwrap;
  * type could only produce 47 million pushes/second.
  */
 type DVec_<A> = {
-    mut data: ~[mut A]
+    mut data: ~[A]
 };
 
 enum DVec<A> {
@@ -59,21 +59,21 @@ enum DVec<A> {
 
 /// Creates a new, empty dvec
 fn DVec<A>() -> DVec<A> {
-    DVec_({mut data: ~[mut]})
+    DVec_({mut data: ~[]})
 }
 
 /// Creates a new dvec with a single element
 fn from_elem<A>(+e: A) -> DVec<A> {
-    DVec_({mut data: ~[mut move e]})
+    DVec_({mut data: ~[move e]})
 }
 
 /// Creates a new dvec with the contents of a vector
-fn from_vec<A>(+v: ~[mut A]) -> DVec<A> {
+fn from_vec<A>(+v: ~[A]) -> DVec<A> {
     DVec_({mut data: move v})
 }
 
 /// Consumes the vector and returns its contents
-fn unwrap<A>(+d: DVec<A>) -> ~[mut A] {
+fn unwrap<A>(+d: DVec<A>) -> ~[A] {
     let DVec_({data: v}) <- d;
     move v
 }
@@ -89,7 +89,7 @@ priv impl<A> DVec<A> {
     }
 
     #[inline(always)]
-    fn check_out<B>(f: fn(-~[mut A]) -> B) -> B {
+    fn check_out<B>(f: fn(-~[A]) -> B) -> B {
         unsafe {
             let mut data = unsafe::reinterpret_cast(&null::<()>());
             data <-> self.data;
@@ -100,9 +100,9 @@ priv impl<A> DVec<A> {
     }
 
     #[inline(always)]
-    fn give_back(-data: ~[mut A]) {
+    fn give_back(+data: ~[A]) {
         unsafe {
-            self.data <- data;
+            self.data = move data;
         }
     }
 }
@@ -122,10 +122,22 @@ impl<A> DVec<A> {
      * and return a new vector to replace it with.
      */
     #[inline(always)]
-    fn swap(f: fn(-~[mut A]) -> ~[mut A]) {
+    fn swap(f: fn(-~[A]) -> ~[A]) {
         self.check_out(|v| self.give_back(f(move v)))
     }
 
+    /**
+     * Swaps out the current vector and hands it off to a user-provided
+     * function `f`.  The function should transform it however is desired
+     * and return a new vector to replace it with.
+     */
+    #[inline(always)]
+    fn swap_mut(f: fn(-~[mut A]) -> ~[mut A]) {
+        do self.swap |v| {
+            vec::from_mut(f(vec::to_mut(move v)))
+        }
+    }
+
     /// Returns the number of elements currently in the dvec
     pure fn len() -> uint {
         unchecked {
@@ -138,7 +150,7 @@ impl<A> DVec<A> {
     }
 
     /// Overwrite the current contents
-    fn set(+w: ~[mut A]) {
+    fn set(+w: ~[A]) {
         self.check_not_borrowed();
         self.data <- w;
     }
@@ -161,7 +173,7 @@ impl<A> DVec<A> {
             let data_ptr: *() = unsafe::reinterpret_cast(&data);
             if data_ptr.is_null() { fail ~"Recursive use of dvec"; }
             log(error, ~"a");
-            self.data <- ~[mut move t];
+            self.data <- ~[move t];
             vec::push_all_move(self.data, move data);
             log(error, ~"b");
         }
@@ -176,9 +188,9 @@ impl<A> DVec<A> {
     /// Remove and return the first element
     fn shift() -> A {
         do self.check_out |v| {
-            let mut v = vec::from_mut(move v);
+            let mut v = move v;
             let result = vec::shift(v);
-            self.give_back(vec::to_mut(move v));
+            self.give_back(move v);
             move result
         }
     }
@@ -186,6 +198,7 @@ impl<A> DVec<A> {
     /// Reverse the elements in the list, in place
     fn reverse() {
         do self.check_out |v| {
+            let mut v = move v;
             vec::reverse(v);
             self.give_back(move v);
         }
@@ -203,6 +216,7 @@ impl<A> DVec<A> {
     /// Gives access to the vector as a slice with mutable contents
     fn borrow_mut<R>(op: fn(x: &[mut A]) -> R) -> R {
         do self.check_out |v| {
+            let mut v = move v;
             let result = op(v);
             self.give_back(move v);
             move result
@@ -268,7 +282,7 @@ impl<A: Copy> DVec<A> {
     pure fn get() -> ~[A] {
         unchecked {
             do self.check_out |v| {
-                let w = vec::from_mut(copy v);
+                let w = copy v;
                 self.give_back(move v);
                 move w
             }
@@ -295,9 +309,9 @@ impl<A: Copy> DVec<A> {
      */
     fn grow_set_elt(idx: uint, initval: A, val: A) {
         do self.swap |v| {
-            let mut v <- v;
+            let mut v = vec::to_mut(move v);
             vec::grow_set(v, idx, initval, val);
-            move v
+            move vec::from_mut(v)
         }
     }
 
diff --git a/src/libcore/hash.rs b/src/libcore/hash.rs
index 9fdfd7b102e..13fef207fac 100644
--- a/src/libcore/hash.rs
+++ b/src/libcore/hash.rs
@@ -130,7 +130,7 @@ pure fn hash_keyed_5<A: IterBytes,
     }
 }
 
-pure fn hash_bytes_keyed(val: &[const u8], k0: u64, k1: u64) -> u64 {
+pure fn hash_bytes_keyed(val: &[u8], k0: u64, k1: u64) -> u64 {
     val.hash_keyed(k0, k1)
 }
 pure fn hash_str_keyed(val: &str, k0: u64, k1: u64) -> u64 {
@@ -152,7 +152,7 @@ pure fn hash_uint_keyed(val: uint, k0: u64, k1: u64) -> u64 {
     val.hash_keyed(k0, k1)
 }
 
-pure fn hash_bytes(val: &[const u8]) -> u64 { hash_bytes_keyed(val, 0, 0) }
+pure fn hash_bytes(val: &[u8]) -> u64 { hash_bytes_keyed(val, 0, 0) }
 pure fn hash_str(val: &str) -> u64 { hash_str_keyed(val, 0, 0) }
 pure fn hash_u64(val: u64) -> u64 { hash_u64_keyed(val, 0, 0) }
 pure fn hash_u32(val: u32) -> u64 { hash_u32_keyed(val, 0, 0) }
diff --git a/src/libcore/io.rs b/src/libcore/io.rs
index 200d448e6b1..9d4176ea40b 100644
--- a/src/libcore/io.rs
+++ b/src/libcore/io.rs
@@ -214,7 +214,7 @@ fn convert_whence(whence: SeekStyle) -> i32 {
 
 impl *libc::FILE: Reader {
     fn read(buf: &[mut u8], len: uint) -> uint {
-        do vec::as_buf(buf) |buf_p, buf_len| {
+        do vec::as_mut_buf(buf) |buf_p, buf_len| {
             assert buf_len <= len;
 
             let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index be3ab40dfcd..79ec6fea668 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -2,6 +2,7 @@
 
 export addr_of;
 export to_unsafe_ptr;
+export to_const_unsafe_ptr;
 export to_mut_unsafe_ptr;
 export mut_addr_of;
 export offset;
@@ -26,11 +27,16 @@ use libc::{c_void, size_t};
 #[abi = "cdecl"]
 extern mod libc_ {
     #[rust_stack]
-    fn memcpy(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
+    fn memcpy(dest: *mut c_void, src: *const c_void,
+              n: libc::size_t) -> *c_void;
+
     #[rust_stack]
-    fn memmove(dest: *c_void, src: *c_void, n: libc::size_t) -> *c_void;
+    fn memmove(dest: *mut c_void, src: *const c_void,
+               n: libc::size_t) -> *c_void;
+
     #[rust_stack]
-    fn memset(dest: *c_void, c: libc::c_int, len: libc::size_t) -> *c_void;
+    fn memset(dest: *mut c_void, c: libc::c_int,
+              len: libc::size_t) -> *c_void;
 }
 
 #[abi = "rust-intrinsic"]
@@ -105,9 +111,9 @@ pure fn is_not_null<T>(ptr: *const T) -> bool { !is_null(ptr) }
  * and destination may not overlap.
  */
 #[inline(always)]
-unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
+unsafe fn memcpy<T>(dst: *mut T, src: *const T, count: uint) {
     let n = count * sys::size_of::<T>();
-    libc_::memcpy(dst as *c_void, src as *c_void, n as size_t);
+    libc_::memcpy(dst as *mut c_void, src as *c_void, n as size_t);
 }
 
 /**
@@ -117,15 +123,15 @@ unsafe fn memcpy<T>(dst: *T, src: *T, count: uint) {
  * and destination may overlap.
  */
 #[inline(always)]
-unsafe fn memmove<T>(dst: *T, src: *T, count: uint)  {
+unsafe fn memmove<T>(dst: *mut T, src: *const T, count: uint)  {
     let n = count * sys::size_of::<T>();
-    libc_::memmove(dst as *c_void, src as *c_void, n as size_t);
+    libc_::memmove(dst as *mut c_void, src as *c_void, n as size_t);
 }
 
 #[inline(always)]
 unsafe fn memset<T>(dst: *mut T, c: int, count: uint)  {
     let n = count * sys::size_of::<T>();
-    libc_::memset(dst as *c_void, c as libc::c_int, n as size_t);
+    libc_::memset(dst as *mut c_void, c as libc::c_int, n as size_t);
 }
 
 
@@ -135,8 +141,18 @@ unsafe fn memset<T>(dst: *mut T, c: int, count: uint)  {
   reinterpret_cast.
 */
 #[inline(always)]
-fn to_unsafe_ptr<T>(thing: &T) -> *T unsafe {
-    unsafe::reinterpret_cast(&thing)
+fn to_unsafe_ptr<T>(thing: &T) -> *T {
+    unsafe { unsafe::reinterpret_cast(&thing) }
+}
+
+/**
+  Transform a const region pointer - &const T - to a const unsafe pointer -
+  *const T. This is safe, but is implemented with an unsafe block due to
+  reinterpret_cast.
+*/
+#[inline(always)]
+fn to_const_unsafe_ptr<T>(thing: &const T) -> *const T {
+    unsafe { unsafe::reinterpret_cast(&thing) }
 }
 
 /**
@@ -145,8 +161,8 @@ fn to_unsafe_ptr<T>(thing: &T) -> *T unsafe {
   reinterpret_cast.
 */
 #[inline(always)]
-fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T unsafe {
-    unsafe::reinterpret_cast(&thing)
+fn to_mut_unsafe_ptr<T>(thing: &mut T) -> *mut T {
+    unsafe { unsafe::reinterpret_cast(&thing) }
 }
 
 /**
@@ -246,16 +262,16 @@ fn test() {
         assert (p.fst == 50);
         assert (p.snd == 60);
 
-        let v0 = ~[32000u16, 32001u16, 32002u16];
-        let v1 = ~[0u16, 0u16, 0u16];
+        let mut v0 = ~[32000u16, 32001u16, 32002u16];
+        let mut v1 = ~[0u16, 0u16, 0u16];
 
-        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 1u),
+        ptr::memcpy(ptr::mut_offset(vec::unsafe::to_mut_ptr(v1), 1u),
                     ptr::offset(vec::unsafe::to_ptr(v0), 1u), 1u);
         assert (v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16);
-        ptr::memcpy(vec::unsafe::to_ptr(v1),
+        ptr::memcpy(vec::unsafe::to_mut_ptr(v1),
                     ptr::offset(vec::unsafe::to_ptr(v0), 2u), 1u);
         assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 0u16);
-        ptr::memcpy(ptr::offset(vec::unsafe::to_ptr(v1), 2u),
+        ptr::memcpy(ptr::mut_offset(vec::unsafe::to_mut_ptr(v1), 2u),
                     vec::unsafe::to_ptr(v0), 1u);
         assert (v1[0] == 32002u16 && v1[1] == 32001u16 && v1[2] == 32000u16);
     }
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index 3a2aa0b0f0d..88858e2b1ab 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -250,6 +250,7 @@ fn push_str_no_overallocate(&lhs: ~str, rhs: &str) {
         do as_buf(lhs) |lbuf, _llen| {
             do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
+                let dst = ::unsafe::transmute_mut_unsafe(dst);
                 ptr::memcpy(dst, rbuf, rlen);
             }
         }
@@ -266,6 +267,7 @@ fn push_str(&lhs: ~str, rhs: &str) {
         do as_buf(lhs) |lbuf, _llen| {
             do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
+                let dst = ::unsafe::transmute_mut_unsafe(dst);
                 ptr::memcpy(dst, rbuf, rlen);
             }
         }
@@ -1990,7 +1992,10 @@ mod unsafe {
     unsafe fn from_buf_len(buf: *const u8, len: uint) -> ~str {
         let mut v: ~[mut u8] = ~[mut];
         vec::reserve(v, len + 1u);
-        vec::as_buf(v, |b, _len| ptr::memcpy(b, buf as *u8, len));
+        vec::as_buf(v, |vbuf, _len| {
+            let vbuf = ::unsafe::transmute_mut_unsafe(vbuf);
+            ptr::memcpy(vbuf, buf as *u8, len)
+        });
         vec::unsafe::set_len(v, len);
         vec::push(v, 0u8);
 
@@ -2045,6 +2050,7 @@ mod unsafe {
             vec::reserve(v, end - begin + 1u);
             unsafe {
                 do vec::as_buf(v) |vbuf, _vlen| {
+                    let vbuf = ::unsafe::transmute_mut_unsafe(vbuf);
                     let src = ptr::offset(sbuf, begin);
                     ptr::memcpy(vbuf, src, end - begin);
                 }
diff --git a/src/libcore/to_bytes.rs b/src/libcore/to_bytes.rs
index f619085bd4b..337aa5980d7 100644
--- a/src/libcore/to_bytes.rs
+++ b/src/libcore/to_bytes.rs
@@ -7,12 +7,12 @@ use io::Writer;
 type Cb = fn(buf: &[const u8]) -> bool;
 
 trait IterBytes {
-    fn iter_bytes(lsb0: bool, f: Cb);
+    pure fn iter_bytes(lsb0: bool, f: Cb);
 }
 
 impl u8: IterBytes {
     #[inline(always)]
-    fn iter_bytes(_lsb0: bool, f: Cb) {
+    pure fn iter_bytes(_lsb0: bool, f: Cb) {
         f([
             self
         ]);
@@ -21,7 +21,7 @@ impl u8: IterBytes {
 
 impl u16: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         if lsb0 {
             f([
                 self as u8,
@@ -38,7 +38,7 @@ impl u16: IterBytes {
 
 impl u32: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         if lsb0 {
             f([
                 self as u8,
@@ -59,7 +59,7 @@ impl u32: IterBytes {
 
 impl u64: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         if lsb0 {
             f([
                 self as u8,
@@ -88,36 +88,43 @@ impl u64: IterBytes {
 
 impl i8: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as u8).iter_bytes(lsb0, f)
     }
 }
 
 impl i16: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as u16).iter_bytes(lsb0, f)
     }
 }
 
 impl i32: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as u32).iter_bytes(lsb0, f)
     }
 }
 
 impl i64: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as u64).iter_bytes(lsb0, f)
     }
 }
 
+impl char: IterBytes {
+    #[inline(always)]
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
+        (self as u32).iter_bytes(lsb0, f)
+    }
+}
+
 #[cfg(target_word_size = "32")]
 impl uint: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as u32).iter_bytes(lsb0, f)
     }
 }
@@ -125,21 +132,21 @@ impl uint: IterBytes {
 #[cfg(target_word_size = "64")]
 impl uint: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as u64).iter_bytes(lsb0, f)
     }
 }
 
 impl int: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as uint).iter_bytes(lsb0, f)
     }
 }
 
-impl<A: IterBytes> &[const A]: IterBytes {
+impl<A: IterBytes> &[A]: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         for self.each |elt| {
             do elt.iter_bytes(lsb0) |bytes| {
                 f(bytes)
@@ -149,26 +156,26 @@ impl<A: IterBytes> &[const A]: IterBytes {
 }
 
 // Move this to vec, probably.
-fn borrow<A>(a: &x/[const A]) -> &x/[const A] {
+pure fn borrow<A>(a: &x/[A]) -> &x/[A] {
     a
 }
 
-impl<A: IterBytes> ~[const A]: IterBytes {
+impl<A: IterBytes> ~[A]: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         borrow(self).iter_bytes(lsb0, f)
     }
 }
 
 
-impl<A: IterBytes> @[const A]: IterBytes {
+impl<A: IterBytes> @[A]: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         borrow(self).iter_bytes(lsb0, f)
     }
 }
 
-fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
+pure fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
                                             lsb0: bool, z: Cb) {
     let mut flag = true;
     a.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
@@ -176,7 +183,7 @@ fn iter_bytes_2<A: IterBytes, B: IterBytes>(a: &A, b: &B,
     b.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
 }
 
-fn iter_bytes_3<A: IterBytes,
+pure fn iter_bytes_3<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes>(a: &A, b: &B, c: &C,
                               lsb0: bool, z: Cb) {
@@ -188,7 +195,7 @@ fn iter_bytes_3<A: IterBytes,
     c.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
 }
 
-fn iter_bytes_4<A: IterBytes,
+pure fn iter_bytes_4<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
                 D: IterBytes>(a: &A, b: &B, c: &C,
@@ -204,7 +211,7 @@ fn iter_bytes_4<A: IterBytes,
     d.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
 }
 
-fn iter_bytes_5<A: IterBytes,
+pure fn iter_bytes_5<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
                 D: IterBytes,
@@ -223,7 +230,7 @@ fn iter_bytes_5<A: IterBytes,
     e.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
 }
 
-fn iter_bytes_6<A: IterBytes,
+pure fn iter_bytes_6<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
                 D: IterBytes,
@@ -245,7 +252,7 @@ fn iter_bytes_6<A: IterBytes,
     f.iter_bytes(lsb0, |bytes| {flag = z(bytes); flag});
 }
 
-fn iter_bytes_7<A: IterBytes,
+pure fn iter_bytes_7<A: IterBytes,
                 B: IterBytes,
                 C: IterBytes,
                 D: IterBytes,
@@ -273,7 +280,7 @@ fn iter_bytes_7<A: IterBytes,
 
 impl &str: IterBytes {
     #[inline(always)]
-    fn iter_bytes(_lsb0: bool, f: Cb) {
+    pure fn iter_bytes(_lsb0: bool, f: Cb) {
         do str::byte_slice(self) |bytes| {
             f(bytes);
         }
@@ -282,7 +289,7 @@ impl &str: IterBytes {
 
 impl ~str: IterBytes {
     #[inline(always)]
-    fn iter_bytes(_lsb0: bool, f: Cb) {
+    pure fn iter_bytes(_lsb0: bool, f: Cb) {
         do str::byte_slice(self) |bytes| {
             f(bytes);
         }
@@ -291,7 +298,7 @@ impl ~str: IterBytes {
 
 impl @str: IterBytes {
     #[inline(always)]
-    fn iter_bytes(_lsb0: bool, f: Cb) {
+    pure fn iter_bytes(_lsb0: bool, f: Cb) {
         do str::byte_slice(self) |bytes| {
             f(bytes);
         }
@@ -300,7 +307,7 @@ impl @str: IterBytes {
 
 impl<A: IterBytes> Option<A>: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         match self {
           Some(a) => iter_bytes_2(&0u8, &a, lsb0, f),
           None => 1u8.iter_bytes(lsb0, f)
@@ -310,30 +317,30 @@ impl<A: IterBytes> Option<A>: IterBytes {
 
 impl<A: IterBytes> &A: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (*self).iter_bytes(lsb0, f);
     }
 }
 
 impl<A: IterBytes> @A: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (*self).iter_bytes(lsb0, f);
     }
 }
 
 impl<A: IterBytes> ~A: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (*self).iter_bytes(lsb0, f);
     }
 }
 
 // NB: raw-pointer IterBytes does _not_ dereference
 // to the target; it just gives you the pointer-bytes.
-impl<A> *A: IterBytes {
+impl<A> *const A: IterBytes {
     #[inline(always)]
-    fn iter_bytes(lsb0: bool, f: Cb) {
+    pure fn iter_bytes(lsb0: bool, f: Cb) {
         (self as uint).iter_bytes(lsb0, f);
     }
 }
diff --git a/src/libcore/unsafe.rs b/src/libcore/unsafe.rs
index eb3fd3974cd..8875fc1d0ea 100644
--- a/src/libcore/unsafe.rs
+++ b/src/libcore/unsafe.rs
@@ -2,6 +2,7 @@
 
 export reinterpret_cast, forget, bump_box_refcount, transmute;
 export transmute_mut, transmute_immut, transmute_region, transmute_mut_region;
+export transmute_mut_unsafe, transmute_immut_unsafe;
 
 export SharedMutableState, shared_mutable_state, clone_shared_mutable_state;
 export get_shared_mutable_state, get_shared_immutable_state;
@@ -68,6 +69,12 @@ unsafe fn transmute_immut<T>(+ptr: &a/mut T) -> &a/T { transmute(move ptr) }
 /// Coerce a borrowed pointer to have an arbitrary associated region.
 unsafe fn transmute_region<T>(+ptr: &a/T) -> &b/T { transmute(move ptr) }
 
+/// Coerce an immutable reference to be mutable.
+unsafe fn transmute_mut_unsafe<T>(+ptr: *const T) -> *mut T { transmute(ptr) }
+
+/// Coerce an immutable reference to be mutable.
+unsafe fn transmute_immut_unsafe<T>(+ptr: *const T) -> *T { transmute(ptr) }
+
 /// Coerce a borrowed mutable pointer to have an arbitrary associated region.
 unsafe fn transmute_mut_region<T>(+ptr: &a/mut T) -> &b/mut T {
     transmute(move ptr)
@@ -78,6 +85,11 @@ unsafe fn copy_lifetime<S,T>(_ptr: &a/S, ptr: &T) -> &a/T {
     transmute_region(ptr)
 }
 
+/// Transforms lifetime of the second pointer to match the first.
+unsafe fn copy_lifetime_to_unsafe<S,T>(_ptr: &a/S, +ptr: *T) -> &a/T {
+    transmute(ptr)
+}
+
 
 /****************************************************************************
  * Shared state & exclusive ARC
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index 38340c2b8d1..62cc5ce6f60 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -77,7 +77,7 @@ export swap;
 export reverse;
 export reversed;
 export iter, iter_between, each, eachi, reach, reachi;
-export each_mut, each_const;
+export each_ref, each_mut_ref, each_const_ref;
 export iter2;
 export iteri;
 export riter;
@@ -336,7 +336,8 @@ pure fn view<T>(v: &[T], start: uint, end: uint) -> &[T] {
     do as_buf(v) |p, _len| {
         unsafe {
             ::unsafe::reinterpret_cast(
-                &(ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
+                &(ptr::offset(p, start),
+                  (end - start) * sys::size_of::<T>()))
         }
     }
 }
@@ -345,10 +346,11 @@ pure fn view<T>(v: &[T], start: uint, end: uint) -> &[T] {
 pure fn mut_view<T>(v: &[mut T], start: uint, end: uint) -> &[mut T] {
     assert (start <= end);
     assert (end <= len(v));
-    do as_buf(v) |p, _len| {
+    do as_mut_buf(v) |p, _len| {
         unsafe {
             ::unsafe::reinterpret_cast(
-                &(ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
+                &(ptr::mut_offset(p, start),
+                  (end - start) * sys::size_of::<T>()))
         }
     }
 }
@@ -357,10 +359,11 @@ pure fn mut_view<T>(v: &[mut T], start: uint, end: uint) -> &[mut T] {
 pure fn const_view<T>(v: &[const T], start: uint, end: uint) -> &[const T] {
     assert (start <= end);
     assert (end <= len(v));
-    do as_buf(v) |p, _len| {
+    do as_const_buf(v) |p, _len| {
         unsafe {
             ::unsafe::reinterpret_cast(
-                &(ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
+                &(ptr::const_offset(p, start),
+                  (end - start) * sys::size_of::<T>()))
         }
     }
 }
@@ -1141,7 +1144,7 @@ fn swap<T>(v: &[mut T], a: uint, b: uint) {
 }
 
 /// Reverse the order of elements in a vector, in place
-fn reverse<T>(v: ~[mut T]) {
+fn reverse<T>(v: &[mut T]) {
     let mut i: uint = 0u;
     let ln = len::<T>(v);
     while i < ln / 2u { v[i] <-> v[ln - i - 1u]; i += 1u; }
@@ -1203,7 +1206,12 @@ pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
  * Return true to continue, false to break.
  */
 #[inline(always)]
-pure fn each<T>(v: &[const T], f: fn(T) -> bool) {
+pure fn each<T>(v: &[T], f: fn(T) -> bool) {
+    //             ^^^^
+    // NB---this CANNOT be &[const T]!  The reason
+    // is that you are passing it to `f()` using
+    // an immutable.
+
     do vec::as_buf(v) |p, n| {
         let mut n = n;
         let mut p = p;
@@ -1217,21 +1225,52 @@ pure fn each<T>(v: &[const T], f: fn(T) -> bool) {
     }
 }
 
+/**
+ * Iterates over a vector, with option to break
+ *
+ * Return true to continue, false to break.
+ */
+#[inline(always)]
+pure fn each_ref<T>(v: &r/[T], f: fn(v: &r/T) -> bool) {
+    // this is not the most efficient impl, as it repeats the bound checks,
+    // but it's good enough
+    let mut i = 0;
+    let n = v.len();
+    while i < n {
+        if !f(&v[i]) {
+            return;
+        }
+        i += 1;
+    }
+}
+
 /// 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;
+fn each_mut_ref<T>(v: &[mut T], f: fn(elem: &mut T) -> bool) {
+    let mut i = 0;
+    let n = v.len();
+    while i < n {
+        if !f(&mut v[i]) {
+            return;
+        }
+        i += 1;
+    }
+}
+
+/// 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_const_ref<T>(v: &[const T], f: fn(elem: &const T) -> bool) {
+    let mut i = 0;
+    let n = v.len();
+    while i < n {
+        if !f(&const v[i]) {
+            return;
         }
+        i += 1;
     }
 }
 
@@ -1241,7 +1280,7 @@ pure fn each_mut<T>(v: &[mut T], f: fn(elem: &mut T) -> bool) {
  * Return true to continue, false to break.
  */
 #[inline(always)]
-pure fn eachi<T>(v: &[const T], f: fn(uint, T) -> bool) {
+pure fn eachi<T>(v: &[T], f: fn(uint, T) -> bool) {
     do vec::as_buf(v) |p, n| {
         let mut i = 0u;
         let mut p = p;
@@ -1392,10 +1431,18 @@ pure fn windowed<TT: Copy>(nn: uint, xx: &[TT]) -> ~[~[TT]] {
  * foreign interop.
  */
 #[inline(always)]
-pure fn as_buf<T,U>(s: &[const T],
+pure fn as_buf<T,U>(s: &[T], /* NB---this CANNOT be const, see below */
                     f: fn(*T, uint) -> U) -> U {
+
+    // NB---People keep changing the type of s to `&[const T]`.  This is
+    // unsound.  The reason is that we are going to create immutable pointers
+    // into `s` and pass them to `f()`, but in fact they are potentially
+    // pointing at *mutable memory*.  Use `as_const_buf` or `as_mut_buf`
+    // instead!
+
     unsafe {
-        let v : *(*T,uint) = ::unsafe::reinterpret_cast(&ptr::addr_of(s));
+        let v : *(*T,uint) =
+            ::unsafe::reinterpret_cast(&ptr::addr_of(s));
         let (buf,len) = *v;
         f(buf, len / sys::size_of::<T>())
     }
@@ -1405,11 +1452,12 @@ pure fn as_buf<T,U>(s: &[const T],
 #[inline(always)]
 pure fn as_const_buf<T,U>(s: &[const T],
                           f: fn(*const T, uint) -> U) -> U {
-    do as_buf(s) |p, len| {
-        unsafe {
-            let pp : *const T = ::unsafe::reinterpret_cast(&p);
-            f(pp, len)
-        }
+
+    unsafe {
+        let v : *(*const T,uint) =
+            ::unsafe::reinterpret_cast(&ptr::addr_of(s));
+        let (buf,len) = *v;
+        f(buf, len / sys::size_of::<T>())
     }
 }
 
@@ -1417,11 +1465,12 @@ pure fn as_const_buf<T,U>(s: &[const T],
 #[inline(always)]
 pure fn as_mut_buf<T,U>(s: &[mut T],
                         f: fn(*mut T, uint) -> U) -> U {
-    do as_buf(s) |p, len| {
-        unsafe {
-            let pp : *mut T = ::unsafe::reinterpret_cast(&p);
-            f(pp, len)
-        }
+
+    unsafe {
+        let v : *(*mut T,uint) =
+            ::unsafe::reinterpret_cast(&ptr::addr_of(s));
+        let (buf,len) = *v;
+        f(buf, len / sys::size_of::<T>())
     }
 }
 
@@ -1765,7 +1814,7 @@ mod unsafe {
         let mut dst = ~[];
         reserve(dst, elts);
         set_len(dst, elts);
-        as_buf(dst, |p_dst, _len_dst| ptr::memcpy(p_dst, ptr, elts));
+        as_mut_buf(dst, |p_dst, _len_dst| ptr::memcpy(p_dst, ptr, elts));
         move dst
     }
 
@@ -1792,18 +1841,24 @@ mod unsafe {
      * would also make any pointers to it invalid.
      */
     #[inline(always)]
-    unsafe fn to_ptr<T>(v: ~[const T]) -> *T {
-        let repr: **VecRepr = ::unsafe::reinterpret_cast(&addr_of(v));
+    unsafe fn to_ptr<T>(v: &[T]) -> *T {
+        let repr: **SliceRepr = ::unsafe::reinterpret_cast(&addr_of(v));
         return ::unsafe::reinterpret_cast(&addr_of((**repr).data));
     }
 
-
+    /** see `to_ptr()` */
     #[inline(always)]
-    unsafe fn to_ptr_slice<T>(v: &[const T]) -> *T {
+    unsafe fn to_const_ptr<T>(v: &[const T]) -> *const T {
         let repr: **SliceRepr = ::unsafe::reinterpret_cast(&addr_of(v));
         return ::unsafe::reinterpret_cast(&addr_of((**repr).data));
     }
 
+    /** see `to_ptr()` */
+    #[inline(always)]
+    unsafe fn to_mut_ptr<T>(v: &[mut T]) -> *mut T {
+        let repr: **SliceRepr = ::unsafe::reinterpret_cast(&addr_of(v));
+        return ::unsafe::reinterpret_cast(&addr_of((**repr).data));
+    }
 
     /**
      * Form a slice from a pointer and length (as a number of units,
@@ -1822,7 +1877,7 @@ mod unsafe {
      */
     #[inline(always)]
     unsafe fn get<T: Copy>(v: &[const T], i: uint) -> T {
-        as_buf(v, |p, _len| *ptr::offset(p, i))
+        as_const_buf(v, |p, _len| *ptr::const_offset(p, i))
     }
 
     /**
@@ -1846,8 +1901,8 @@ mod unsafe {
       * may overlap.
       */
     unsafe fn memcpy<T>(dst: &[mut T], src: &[const T], count: uint) {
-        do as_buf(dst) |p_dst, _len_dst| {
-            do as_buf(src) |p_src, _len_src| {
+        do as_mut_buf(dst) |p_dst, _len_dst| {
+            do as_const_buf(src) |p_src, _len_src| {
                 ptr::memcpy(p_dst, p_src, count)
             }
         }
@@ -1860,8 +1915,8 @@ mod unsafe {
       * may overlap.
       */
     unsafe fn memmove<T>(dst: &[mut T], src: &[const T], count: uint) {
-        do as_buf(dst) |p_dst, _len_dst| {
-            do as_buf(src) |p_src, _len_src| {
+        do as_mut_buf(dst) |p_dst, _len_dst| {
+            do as_const_buf(src) |p_src, _len_src| {
                 ptr::memmove(p_dst, p_src, count)
             }
         }
@@ -1952,12 +2007,12 @@ mod u8 {
 // This cannot be used with iter-trait.rs because of the region pointer
 // required in the slice.
 
-impl<A> &[const A]: iter::BaseIter<A> {
+impl<A> &[A]: iter::BaseIter<A> {
     pure fn each(blk: fn(A) -> bool) { each(self, blk) }
     pure fn size_hint() -> Option<uint> { Some(len(self)) }
 }
 
-impl<A> &[const A]: iter::ExtendedIter<A> {
+impl<A> &[A]: iter::ExtendedIter<A> {
     pure fn eachi(blk: fn(uint, A) -> bool) { iter::eachi(self, blk) }
     pure fn all(blk: fn(A) -> bool) -> bool { iter::all(self, blk) }
     pure fn any(blk: fn(A) -> bool) -> bool { iter::any(self, blk) }