about summary refs log tree commit diff
diff options
context:
space:
mode:
authorGraydon Hoare <graydon@mozilla.com>2012-07-24 12:35:34 -0700
committerGraydon Hoare <graydon@mozilla.com>2012-07-24 12:35:52 -0700
commita63e0e47f0d4fa6b79365c645d6c284de234e2d0 (patch)
treee897ee8d81a8524fc75e82871b7aee7ab748e144
parentae094a7adc8e0f166ea2b137c2940afdb9396bcd (diff)
downloadrust-a63e0e47f0d4fa6b79365c645d6c284de234e2d0.tar.gz
rust-a63e0e47f0d4fa6b79365c645d6c284de234e2d0.zip
Update some str functions to slices, merge as_buf and unpack_slice.
-rw-r--r--src/libcore/comm.rs7
-rw-r--r--src/libcore/int-template.rs2
-rw-r--r--src/libcore/io.rs6
-rw-r--r--src/libcore/option.rs4
-rw-r--r--src/libcore/os.rs8
-rw-r--r--src/libcore/ptr.rs3
-rw-r--r--src/libcore/run.rs4
-rw-r--r--src/libcore/str.rs147
-rw-r--r--src/libcore/uint-template.rs4
-rw-r--r--src/libcore/vec.rs86
-rw-r--r--src/libstd/net_ip.rs2
-rw-r--r--src/libstd/par.rs2
-rw-r--r--src/libstd/uv_ll.rs10
-rw-r--r--src/rustc/middle/trans/foreign.rs2
-rw-r--r--src/test/run-fail/bug-2470-bounds-check-overflow.rs2
15 files changed, 135 insertions, 154 deletions
diff --git a/src/libcore/comm.rs b/src/libcore/comm.rs
index 7e1ef280ea6..a4bd25e5b9d 100644
--- a/src/libcore/comm.rs
+++ b/src/libcore/comm.rs
@@ -221,14 +221,13 @@ fn peek_(p: *rust_port) -> bool {
 fn select2<A: send, B: send>(p_a: port<A>, p_b: port<B>)
     -> either<A, B> {
     let ports = ~[(**p_a).po, (**p_b).po];
-    let n_ports = 2 as libc::size_t;
     let yield = 0u, yieldp = ptr::addr_of(yield);
 
     let mut resport: *rust_port;
     resport = rusti::init::<*rust_port>();
-    do vec::as_buf(ports) |ports| {
-        rustrt::rust_port_select(ptr::addr_of(resport), ports, n_ports,
-                                 yieldp);
+    do vec::as_buf(ports) |ports, n_ports| {
+        rustrt::rust_port_select(ptr::addr_of(resport), ports,
+                                 n_ports as size_t, yieldp);
     }
 
     if yield != 0u {
diff --git a/src/libcore/int-template.rs b/src/libcore/int-template.rs
index 9986b22669d..02ce125e35c 100644
--- a/src/libcore/int-template.rs
+++ b/src/libcore/int-template.rs
@@ -94,7 +94,7 @@ fn from_str(s: ~str) -> option<T> { parse_buf(str::bytes(s), 10u) }
 /// Convert to a string in a given base
 fn to_str(n: T, radix: uint) -> ~str {
     do to_str_bytes(n, radix) |slice| {
-        do vec::unpack_slice(slice) |p, len| {
+        do vec::as_buf(slice) |p, len| {
             unsafe { str::unsafe::from_buf_len(p, len) }
         }
     }
diff --git a/src/libcore/io.rs b/src/libcore/io.rs
index 4da7044e48b..25d1b5e6680 100644
--- a/src/libcore/io.rs
+++ b/src/libcore/io.rs
@@ -205,7 +205,7 @@ fn convert_whence(whence: seek_style) -> i32 {
 
 impl of reader for *libc::FILE {
     fn read(buf: &[mut u8], len: uint) -> uint {
-        do vec::unpack_slice(buf) |buf_p, buf_len| {
+        do vec::as_buf(buf) |buf_p, buf_len| {
             assert buf_len <= len;
 
             let count = libc::fread(buf_p as *mut c_void, 1u as size_t,
@@ -348,7 +348,7 @@ impl <T: writer, C> of writer for {base: T, cleanup: C} {
 
 impl of writer for *libc::FILE {
     fn write(v: &[const u8]) {
-        do vec::unpack_const_slice(v) |vbuf, len| {
+        do vec::as_const_buf(v) |vbuf, len| {
             let nout = libc::fwrite(vbuf as *c_void, len as size_t,
                                     1u as size_t, self);
             if nout < 1 as size_t {
@@ -377,7 +377,7 @@ fn FILE_writer(f: *libc::FILE, cleanup: bool) -> writer {
 impl of writer for fd_t {
     fn write(v: &[const u8]) {
         let mut count = 0u;
-        do vec::unpack_const_slice(v) |vbuf, len| {
+        do vec::as_const_buf(v) |vbuf, len| {
             while count < len {
                 let vb = ptr::const_offset(vbuf, count) as *c_void;
                 let nout = libc::write(self, vb, len as size_t);
diff --git a/src/libcore/option.rs b/src/libcore/option.rs
index 0ad0cb6045b..6cfb18dc644 100644
--- a/src/libcore/option.rs
+++ b/src/libcore/option.rs
@@ -175,10 +175,10 @@ fn test_unwrap_ptr() {
 #[test]
 fn test_unwrap_str() {
     let x = ~"test";
-    let addr_x = str::as_buf(x, |buf| ptr::addr_of(buf));
+    let addr_x = str::as_buf(x, |buf, _len| ptr::addr_of(buf));
     let opt = some(x);
     let y = unwrap(opt);
-    let addr_y = str::as_buf(y, |buf| ptr::addr_of(buf));
+    let addr_y = str::as_buf(y, |buf, _len| ptr::addr_of(buf));
     assert addr_x == addr_y;
 }
 
diff --git a/src/libcore/os.rs b/src/libcore/os.rs
index bb22c2137dc..d068841bc53 100644
--- a/src/libcore/os.rs
+++ b/src/libcore/os.rs
@@ -71,8 +71,8 @@ fn as_c_charp<T>(s: ~str, f: fn(*c_char) -> T) -> T {
 fn fill_charp_buf(f: fn(*mut c_char, size_t) -> bool)
     -> option<~str> {
     let buf = vec::to_mut(vec::from_elem(tmpbuf_sz, 0u8 as c_char));
-    do vec::as_mut_buf(buf) |b| {
-        if f(b, tmpbuf_sz as size_t) unsafe {
+    do vec::as_mut_buf(buf) |b, sz| {
+        if f(b, sz as size_t) unsafe {
             some(str::unsafe::from_buf(b as *u8))
         } else {
             none
@@ -667,7 +667,7 @@ fn copy_file(from: path, to: path) -> bool {
         let mut done = false;
         let mut ok = true;
         while !done {
-            do vec::as_mut_buf(buf) |b| {
+            do vec::as_mut_buf(buf) |b, _sz| {
               let nread = libc::fread(b as *mut c_void, 1u as size_t,
                                       bufsize as size_t,
                                       istream);
@@ -970,7 +970,7 @@ mod tests {
       assert (ostream as uint != 0u);
       let s = ~"hello";
       let mut buf = vec::to_mut(str::bytes(s) + ~[0 as u8]);
-      do vec::as_mut_buf(buf) |b| {
+      do vec::as_mut_buf(buf) |b, _len| {
           assert (libc::fwrite(b as *c_void, 1u as size_t,
                                (str::len(s) + 1u) as size_t, ostream)
                   == buf.len() as size_t)};
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index ba98fb3c119..e1d21b826a5 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -192,8 +192,9 @@ fn test_buf_len() {
         do str::as_c_str(s1) |p1| {
             do str::as_c_str(s2) |p2| {
                 let v = ~[p0, p1, p2, null()];
-                do vec::as_buf(v) |vp| {
+                do vec::as_buf(v) |vp, len| {
                     assert unsafe { buf_len(vp) } == 3u;
+                    assert len == 4u;
                 }
             }
         }
diff --git a/src/libcore/run.rs b/src/libcore/run.rs
index 1229d0724de..9f3da067253 100644
--- a/src/libcore/run.rs
+++ b/src/libcore/run.rs
@@ -88,7 +88,7 @@ fn with_argv<T>(prog: ~str, args: ~[~str],
         vec::push_all(argptrs, str::as_c_str(*t, |b| ~[b]));
     }
     vec::push(argptrs, ptr::null());
-    vec::as_buf(argptrs, cb)
+    vec::as_buf(argptrs, |buf, _len| cb(buf))
 }
 
 #[cfg(unix)]
@@ -108,7 +108,7 @@ fn with_envp<T>(env: option<~[(~str,~str)]>,
             vec::push_all(ptrs, str::as_c_str(*t, |b| ~[b]));
         }
         vec::push(ptrs, ptr::null());
-        vec::as_buf(ptrs, |p|
+        vec::as_buf(ptrs, |p, _len|
             unsafe { cb(::unsafe::reinterpret_cast(p)) }
         )
       }
diff --git a/src/libcore/str.rs b/src/libcore/str.rs
index e9a6f4f1694..0cf0b4fbbf9 100644
--- a/src/libcore/str.rs
+++ b/src/libcore/str.rs
@@ -23,7 +23,6 @@ export
    as_bytes,
    as_buf,
    as_c_str,
-   unpack_slice,
 
    // Adding things to and removing things from a string
    push_str_no_overallocate,
@@ -127,11 +126,16 @@ Section: Creating a string
  *
  * Fails if invalid UTF-8
  */
-pure fn from_bytes(+vv: ~[u8]) -> ~str {
+pure fn from_bytes(vv: &[const u8]) -> ~str {
     assert is_utf8(vv);
     ret unsafe { unsafe::from_bytes(vv) };
 }
 
+/// Copy a slice into a new unique str
+pure fn from_slice(s: &str) -> ~str {
+    unsafe { unsafe::slice_bytes(s, 0, len(s)) }
+}
+
 /**
  * Convert a byte to a UTF-8 string
  *
@@ -159,7 +163,7 @@ fn push_char(&s: ~str, ch: char) {
         let new_len = len + nb;
         reserve_at_least(s, new_len);
         let off = len;
-        do as_buf(s) |buf| {
+        do as_buf(s) |buf, _len| {
             let buf: *mut u8 = ::unsafe::reinterpret_cast(buf);
             if nb == 1u {
                 *ptr::mut_offset(buf, off) =
@@ -245,8 +249,8 @@ fn push_str_no_overallocate(&lhs: ~str, rhs: &str) {
         let llen = lhs.len();
         let rlen = rhs.len();
         reserve(lhs, llen + rlen);
-        do as_buf(lhs) |lbuf| {
-            do unpack_slice(rhs) |rbuf, _rlen| {
+        do as_buf(lhs) |lbuf, _llen| {
+            do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
                 ptr::memcpy(dst, rbuf, rlen);
             }
@@ -261,8 +265,8 @@ fn push_str(&lhs: ~str, rhs: &str) {
         let llen = lhs.len();
         let rlen = rhs.len();
         reserve_at_least(lhs, llen + rlen);
-        do as_buf(lhs) |lbuf| {
-            do unpack_slice(rhs) |rbuf, _rlen| {
+        do as_buf(lhs) |lbuf, _llen| {
+            do as_buf(rhs) |rbuf, _rlen| {
                 let dst = ptr::offset(lbuf, llen);
                 ptr::memcpy(dst, rbuf, rlen);
             }
@@ -290,7 +294,7 @@ pure fn concat(v: &[~str]) -> ~str {
 }
 
 /// Concatenate a vector of strings, placing a given separator between each
-pure fn connect(v: &[~str], sep: ~str) -> ~str {
+pure fn connect(v: &[~str], sep: &str) -> ~str {
     let mut s = ~"", first = true;
     for vec::each(v) |ss| {
         if first { first = false; } else { unchecked { push_str(s, sep); } }
@@ -335,30 +339,28 @@ fn shift_char(&s: ~str) -> char {
 fn unshift_char(&s: ~str, ch: char) { s = from_char(ch) + s; }
 
 /// Returns a string with leading whitespace removed
-pure fn trim_left(+s: ~str) -> ~str {
+pure fn trim_left(s: &str) -> ~str {
     alt find(s, |c| !char::is_whitespace(c)) {
       none { ~"" }
       some(first) {
-        if first == 0u { s }
-        else unsafe { unsafe::slice_bytes(s, first, len(s)) }
+        unsafe { unsafe::slice_bytes(s, first, len(s)) }
       }
     }
 }
 
 /// Returns a string with trailing whitespace removed
-pure fn trim_right(+s: ~str) -> ~str {
+pure fn trim_right(s: &str) -> ~str {
     alt rfind(s, |c| !char::is_whitespace(c)) {
       none { ~"" }
       some(last) {
         let {next, _} = char_range_at(s, last);
-        if next == len(s) { s }
-        else unsafe { unsafe::slice_bytes(s, 0u, next) }
+        unsafe { unsafe::slice_bytes(s, 0u, next) }
       }
     }
 }
 
 /// Returns a string with leading and trailing whitespace removed
-pure fn trim(+s: ~str) -> ~str { trim_left(trim_right(s)) }
+pure fn trim(s: &str) -> ~str { trim_left(trim_right(s)) }
 
 /*
 Section: Transforming strings
@@ -369,9 +371,9 @@ Section: Transforming strings
  *
  * The result vector is not null-terminated.
  */
-pure fn bytes(s: ~str) -> ~[u8] {
+pure fn bytes(s: &str) -> ~[u8] {
     unsafe {
-        let mut s_copy = s;
+        let mut s_copy = from_slice(s);
         let mut v: ~[u8] = ::unsafe::transmute(s_copy);
         vec::unsafe::set_len(v, len(s));
         ret v;
@@ -381,7 +383,7 @@ pure fn bytes(s: ~str) -> ~[u8] {
 /// Work with the string as a byte slice, not including trailing null.
 #[inline(always)]
 pure fn byte_slice<T>(s: &str, f: fn(v: &[u8]) -> T) -> T {
-    do unpack_slice(s) |p,n| {
+    do as_buf(s) |p,n| {
         unsafe { vec::unsafe::form_slice(p, n-1u, f) }
     }
 }
@@ -622,7 +624,7 @@ pure fn to_upper(s: &str) -> ~str {
  *
  * The original string with all occurances of `from` replaced with `to`
  */
-pure fn replace(s: ~str, from: ~str, to: ~str) -> ~str {
+pure fn replace(s: &str, from: &str, to: &str) -> ~str {
     let mut result = ~"", first = true;
     do iter_between_matches(s, from) |start, end| {
         if first { first = false; } else { unchecked {push_str(result, to); }}
@@ -1277,7 +1279,7 @@ fn is_alphanumeric(s: &str) -> bool {
 
 /// Returns the string length/size in bytes not counting the null terminator
 pure fn len(s: &str) -> uint {
-    do unpack_slice(s) |_p, n| { n - 1u }
+    do as_buf(s) |_p, n| { n - 1u }
 }
 
 /// Returns the number of characters that a string holds
@@ -1288,7 +1290,7 @@ Section: Misc
 */
 
 /// Determines if a vector of bytes contains valid UTF-8
-pure fn is_utf8(v: &[u8]) -> bool {
+pure fn is_utf8(v: &[const u8]) -> bool {
     let mut i = 0u;
     let total = vec::len::<u8>(v);
     while i < total {
@@ -1637,42 +1639,43 @@ pure fn as_bytes<T>(s: ~str, f: fn(~[u8]) -> T) -> T {
 }
 
 /**
- * Work with the byte buffer of a string.
- *
- * Allows for unsafe manipulation of strings, which is useful for foreign
- * interop.
- */
-pure fn as_buf<T>(s: ~str, f: fn(*u8) -> T) -> T {
-    as_bytes(s, |v| unsafe { vec::as_buf(v, f) })
-}
-
-/**
  * Work with the byte buffer of a string as a null-terminated C string.
  *
  * Allows for unsafe manipulation of strings, which is useful for foreign
- * interop, without copying the original string.
+ * interop. This is similar to `str::as_buf`, but guarantees null-termination.
+ * If the given slice is not already null-terminated, this function will
+ * allocate a temporary, copy the slice, null terminate it, and pass
+ * that instead.
  *
  * # Example
  *
  * ~~~
- * let s = str::as_buf("PATH", { |path_buf| libc::getenv(path_buf) });
+ * let s = str::as_c_str("PATH", { |path| libc::getenv(path) });
  * ~~~
  */
-pure fn as_c_str<T>(s: ~str, f: fn(*libc::c_char) -> T) -> T {
-    as_buf(s, |buf| f(buf as *libc::c_char))
+pure fn as_c_str<T>(s: &str, f: fn(*libc::c_char) -> T) -> T {
+    do as_buf(s) |buf, len| {
+        // NB: len includes the trailing null.
+        assert len > 0;
+        if unsafe { *(ptr::offset(buf,len-1)) != 0 } {
+            as_c_str(from_slice(s), f)
+        } else {
+            f(buf as *libc::c_char)
+        }
+    }
 }
 
 
 /**
  * Work with the byte buffer and length of a slice.
  *
- * The unpacked length is one byte longer than the 'official' indexable
+ * The given length is one byte longer than the 'official' indexable
  * length of the string. This is to permit probing the byte past the
  * indexable area for a null byte, as is the case in slices pointing
  * to full strings, or suffixes of them.
  */
 #[inline(always)]
-pure fn unpack_slice<T>(s: &str, f: fn(*u8, uint) -> T) -> T {
+pure fn as_buf<T>(s: &str, f: fn(*u8, uint) -> T) -> T {
     unsafe {
         let v : *(*u8,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
         let (buf,len) = *v;
@@ -1783,10 +1786,10 @@ mod unsafe {
     }
 
     /// Create a Rust string from a *u8 buffer of the given length
-    unsafe fn from_buf_len(buf: *u8, len: uint) -> ~str {
-        let mut v: ~[u8] = ~[];
+    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| ptr::memcpy(b, buf, len));
+        vec::as_buf(v, |b, _len| ptr::memcpy(b, buf as *u8, len));
         vec::unsafe::set_len(v, len);
         vec::push(v, 0u8);
 
@@ -1804,25 +1807,15 @@ mod unsafe {
         from_buf_len(::unsafe::reinterpret_cast(c_str), len)
     }
 
-   /**
-    * Converts a vector of bytes to a string.
-    *
-    * Does not verify that the vector contains valid UTF-8.
-    */
-   unsafe fn from_bytes(+v: ~[const u8]) -> ~str {
-       unsafe {
-           let mut vcopy = ::unsafe::transmute(v);
-           vec::push(vcopy, 0u8);
-           ::unsafe::transmute(vcopy)
-       }
-   }
+    /// Converts a vector of bytes to a string.
+    unsafe fn from_bytes(v: &[const u8]) -> ~str {
+        do vec::as_const_buf(v) |buf, len| {
+            from_buf_len(buf, len)
+        }
+    }
 
-   /**
-    * Converts a byte to a string.
-    *
-    * Does not verify that the byte is valid UTF-8.
-    */
-   unsafe fn from_byte(u: u8) -> ~str { unsafe::from_bytes(~[u]) }
+    /// Converts a byte to a string.
+    unsafe fn from_byte(u: u8) -> ~str { unsafe::from_bytes([u]) }
 
    /**
     * Takes a bytewise (not UTF-8) slice from a string.
@@ -1835,14 +1828,14 @@ mod unsafe {
     * If end is greater than the length of the string.
     */
    unsafe fn slice_bytes(s: &str, begin: uint, end: uint) -> ~str {
-       do unpack_slice(s) |sbuf, n| {
+       do as_buf(s) |sbuf, n| {
            assert (begin <= end);
            assert (end <= n);
 
            let mut v = ~[];
            vec::reserve(v, end - begin + 1u);
            unsafe {
-               do vec::as_buf(v) |vbuf| {
+               do vec::as_buf(v) |vbuf, _vlen| {
                    let src = ptr::offset(sbuf, begin);
                    ptr::memcpy(vbuf, src, end - begin);
                }
@@ -2683,7 +2676,7 @@ mod tests {
     #[test]
     fn test_as_buf() {
         let a = ~"Abcdefg";
-        let b = as_buf(a, |buf| {
+        let b = as_buf(a, |buf, _l| {
             assert unsafe { *buf } == 65u8;
             100
         });
@@ -2693,7 +2686,7 @@ mod tests {
     #[test]
     fn test_as_buf_small() {
         let a = ~"A";
-        let b = as_buf(a, |buf| {
+        let b = as_buf(a, |buf, _l| {
             assert unsafe { *buf } == 65u8;
             100
         });
@@ -2704,13 +2697,27 @@ mod tests {
     fn test_as_buf2() {
         unsafe {
             let s = ~"hello";
-            let sb = as_buf(s, |b| b);
+            let sb = as_buf(s, |b, _l| b);
             let s_cstr = unsafe::from_buf(sb);
             assert (eq(s_cstr, s));
         }
     }
 
     #[test]
+    fn test_as_buf_3() {
+        let a = ~"hello";
+        do as_buf(a) |buf, len| {
+            unsafe {
+                assert a[0] == 'h' as u8;
+                assert *buf == 'h' as u8;
+                assert len == 6u;
+                assert *ptr::offset(buf,4u) == 'o' as u8;
+                assert *ptr::offset(buf,5u) == 0u8;
+            }
+        }
+    }
+
+    #[test]
     fn vec_str_conversions() {
         let s1: ~str = ~"All mimsy were the borogoves";
 
@@ -2953,20 +2960,6 @@ mod tests {
     }
 
     #[test]
-    fn test_unpack_slice() {
-        let a = ~"hello";
-        do unpack_slice(a) |buf, len| {
-            unsafe {
-                assert a[0] == 'h' as u8;
-                assert *buf == 'h' as u8;
-                assert len == 6u;
-                assert *ptr::offset(buf,4u) == 'o' as u8;
-                assert *ptr::offset(buf,5u) == 0u8;
-            }
-        }
-    }
-
-    #[test]
     fn test_escape_unicode() {
         assert escape_unicode(~"abc") == ~"\\x61\\x62\\x63";
         assert escape_unicode(~"a c") == ~"\\x61\\x20\\x63";
diff --git a/src/libcore/uint-template.rs b/src/libcore/uint-template.rs
index e3b4f08ddaa..d3c042fb05d 100644
--- a/src/libcore/uint-template.rs
+++ b/src/libcore/uint-template.rs
@@ -161,7 +161,7 @@ fn from_str_radix(buf: ~str, radix: u64) -> option<u64> {
  */
 fn to_str(num: T, radix: uint) -> ~str {
     do to_str_bytes(false, num, radix) |slice| {
-        do vec::unpack_slice(slice) |p, len| {
+        do vec::as_buf(slice) |p, len| {
             unsafe { str::unsafe::from_buf_len(p, len) }
         }
     }
@@ -206,7 +206,7 @@ fn to_str_bytes<U>(neg: bool, num: T, radix: uint,
     // in-bounds, no extra cost.
 
     unsafe {
-        do vec::unpack_slice(buf) |p, len| {
+        do vec::as_buf(buf) |p, len| {
             let mp = p as *mut u8;
             let mut i = len;
             let mut n = num;
diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs
index a5d535e62f2..2950b791f98 100644
--- a/src/libcore/vec.rs
+++ b/src/libcore/vec.rs
@@ -81,8 +81,7 @@ export permute;
 export windowed;
 export as_buf;
 export as_mut_buf;
-export unpack_slice;
-export unpack_const_slice;
+export as_const_buf;
 export unsafe;
 export u8;
 export extensions;
@@ -113,12 +112,12 @@ type init_op<T> = fn(uint) -> T;
 
 /// Returns true if a vector contains no elements
 pure fn is_empty<T>(v: &[const T]) -> bool {
-    unpack_const_slice(v, |_p, len| len == 0u)
+    as_const_buf(v, |_p, len| len == 0u)
 }
 
 /// Returns true if a vector contains some elements
 pure fn is_not_empty<T>(v: &[const T]) -> bool {
-    unpack_const_slice(v, |_p, len| len > 0u)
+    as_const_buf(v, |_p, len| len > 0u)
 }
 
 /// Returns true if two vectors have the same length
@@ -177,7 +176,7 @@ pure fn capacity<T>(&&v: ~[const T]) -> uint {
 /// Returns the length of a vector
 #[inline(always)]
 pure fn len<T>(&&v: &[const T]) -> uint {
-    unpack_const_slice(v, |_p, len| len)
+    as_const_buf(v, |_p, len| len)
 }
 
 /**
@@ -317,7 +316,7 @@ pure fn slice<T: copy>(v: &[const T], start: uint, end: uint) -> ~[T] {
 pure fn view<T>(v: &[T], start: uint, end: uint) -> &[T] {
     assert (start <= end);
     assert (end <= len(v));
-    do unpack_slice(v) |p, _len| {
+    do as_buf(v) |p, _len| {
         unsafe {
             ::unsafe::reinterpret_cast(
                 (ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
@@ -329,7 +328,7 @@ 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 unpack_slice(v) |p, _len| {
+    do as_buf(v) |p, _len| {
         unsafe {
             ::unsafe::reinterpret_cast(
                 (ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
@@ -341,7 +340,7 @@ 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 unpack_slice(v) |p, _len| {
+    do as_buf(v) |p, _len| {
         unsafe {
             ::unsafe::reinterpret_cast(
                 (ptr::offset(p, start), (end - start) * sys::size_of::<T>()))
@@ -481,7 +480,7 @@ fn unshift<T>(&v: ~[T], +x: T) {
 }
 
 fn consume<T>(+v: ~[T], f: fn(uint, +T)) unsafe {
-    do unpack_slice(v) |p, ln| {
+    do as_buf(v) |p, ln| {
         for uint::range(0, ln) |i| {
             let x <- *ptr::offset(p, i);
             f(i, x);
@@ -529,13 +528,13 @@ fn push_slow<T>(&v: ~[const T], +initval: T) {
 // Unchecked vector indexing
 #[inline(always)]
 unsafe fn ref<T: copy>(v: &[const T], i: uint) -> T {
-    unpack_slice(v, |p, _len| *ptr::offset(p, i))
+    as_buf(v, |p, _len| *ptr::offset(p, i))
 }
 
 #[inline(always)]
 unsafe fn ref_set<T: copy>(v: &[mut T], i: uint, +val: T) {
     let mut box = some(val);
-    do unpack_mut_slice(v) |p, _len| {
+    do as_mut_buf(v) |p, _len| {
         let mut box2 = none;
         box2 <-> box;
         rusti::move_val_init(*ptr::mut_offset(p, i), option::unwrap(box2));
@@ -555,7 +554,7 @@ fn push_all<T: copy>(&v: ~[const T], rhs: &[const T]) {
 fn push_all_move<T>(&v: ~[const T], -rhs: ~[const T]) {
     reserve(v, v.len() + rhs.len());
     unsafe {
-        do unpack_slice(rhs) |p, len| {
+        do as_buf(rhs) |p, len| {
             for uint::range(0, len) |i| {
                 let x <- *ptr::offset(p, i);
                 push(v, x);
@@ -1056,7 +1055,7 @@ element's value.
 */
 #[inline(always)]
 pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
-    do unpack_slice(v) |base_ptr, len| {
+    do as_buf(v) |base_ptr, len| {
         assert start <= end;
         assert end <= len;
         unsafe {
@@ -1078,7 +1077,7 @@ pure fn iter_between<T>(v: &[T], start: uint, end: uint, f: fn(T)) {
  */
 #[inline(always)]
 pure fn each<T>(v: &[T], f: fn(T) -> bool) {
-    do vec::unpack_slice(v) |p, n| {
+    do vec::as_buf(v) |p, n| {
         let mut n = n;
         let mut p = p;
         while n > 0u {
@@ -1098,7 +1097,7 @@ pure fn each<T>(v: &[T], f: fn(T) -> bool) {
  */
 #[inline(always)]
 pure fn eachi<T>(v: &[T], f: fn(uint, T) -> bool) {
-    do vec::unpack_slice(v) |p, n| {
+    do vec::as_buf(v) |p, n| {
         let mut i = 0u;
         let mut p = p;
         while i < n {
@@ -1118,7 +1117,7 @@ pure fn eachi<T>(v: &[T], f: fn(uint, T) -> bool) {
  */
 #[inline(always)]
 pure fn reach<T>(v: &[T], blk: fn(T) -> bool) {
-    do vec::unpack_slice(v) |p, n| {
+    do vec::as_buf(v) |p, n| {
         let mut i = 1;
         while i <= n {
             unsafe {
@@ -1136,7 +1135,7 @@ pure fn reach<T>(v: &[T], blk: fn(T) -> bool) {
  */
 #[inline(always)]
 pure fn reachi<T>(v: &[T], blk: fn(uint, T) -> bool) {
-    do vec::unpack_slice(v) |p, n| {
+    do vec::as_buf(v) |p, n| {
         let mut i = 1;
         while i <= n {
             unsafe {
@@ -1247,18 +1246,9 @@ pure fn windowed<TT: copy>(nn: uint, xx: &[TT]) -> ~[~[TT]] {
  * Allows for unsafe manipulation of vector contents, which is useful for
  * foreign interop.
  */
-fn as_buf<E,T>(v: &[E], f: fn(*E) -> T) -> T {
-    unpack_slice(v, |buf, _len| f(buf))
-}
-
-fn as_mut_buf<E,T>(v: &[mut E], f: fn(*mut E) -> T) -> T {
-    unpack_mut_slice(v, |buf, _len| f(buf))
-}
-
-/// Work with the buffer and length of a slice.
 #[inline(always)]
-pure fn unpack_slice<T,U>(s: &[const T],
-                          f: fn(*T, uint) -> U) -> U {
+pure fn as_buf<T,U>(s: &[const T],
+                    f: fn(*T, uint) -> U) -> U {
     unsafe {
         let v : *(*T,uint) = ::unsafe::reinterpret_cast(ptr::addr_of(s));
         let (buf,len) = *v;
@@ -1266,27 +1256,27 @@ pure fn unpack_slice<T,U>(s: &[const T],
     }
 }
 
-/// Work with the buffer and length of a slice.
+/// Similar to `as_buf` but passing a `*const T`
 #[inline(always)]
-pure fn unpack_const_slice<T,U>(s: &[const T],
-                                f: fn(*const T, uint) -> U) -> U {
-    unsafe {
-        let v : *(*const T,uint) =
-            ::unsafe::reinterpret_cast(ptr::addr_of(s));
-        let (buf,len) = *v;
-        f(buf, len / sys::size_of::<T>())
+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)
+        }
     }
 }
 
-/// Work with the buffer and length of a slice.
+/// Similar to `as_buf` but passing a `*mut T`
 #[inline(always)]
-pure fn unpack_mut_slice<T,U>(s: &[mut T],
-                              f: fn(*mut T, uint) -> U) -> U {
-    unsafe {
-        let v : *(*const T,uint) =
-            ::unsafe::reinterpret_cast(ptr::addr_of(s));
-        let (buf,len) = *v;
-        f(buf, len / sys::size_of::<T>())
+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)
+        }
     }
 }
 
@@ -1605,8 +1595,8 @@ mod unsafe {
       * may overlap.
       */
     unsafe fn memcpy<T>(dst: &[mut T], src: &[const T], count: uint) {
-        do unpack_slice(dst) |p_dst, _len_dst| {
-            do unpack_slice(src) |p_src, _len_src| {
+        do as_buf(dst) |p_dst, _len_dst| {
+            do as_buf(src) |p_src, _len_src| {
                 ptr::memcpy(p_dst, p_src, count)
             }
         }
@@ -1619,8 +1609,8 @@ mod unsafe {
       * may overlap.
       */
     unsafe fn memmove<T>(dst: &[mut T], src: &[const T], count: uint) {
-        do unpack_slice(dst) |p_dst, _len_dst| {
-            do unpack_slice(src) |p_src, _len_src| {
+        do as_buf(dst) |p_dst, _len_dst| {
+            do as_buf(src) |p_src, _len_src| {
                 ptr::memmove(p_dst, p_src, count)
             }
         }
diff --git a/src/libstd/net_ip.rs b/src/libstd/net_ip.rs
index f79a95d8ab5..6fb4b3c1b33 100644
--- a/src/libstd/net_ip.rs
+++ b/src/libstd/net_ip.rs
@@ -91,7 +91,7 @@ enum ip_get_addr_err {
 fn get_addr(++node: ~str, iotask: iotask)
         -> result::result<~[ip_addr], ip_get_addr_err> unsafe {
     do comm::listen |output_ch| {
-        do str::unpack_slice(node) |node_ptr, len| {
+        do str::as_buf(node) |node_ptr, len| {
             log(debug, #fmt("slice len %?", len));
             let handle = create_uv_getaddrinfo_t();
             let handle_ptr = ptr::addr_of(handle);
diff --git a/src/libstd/par.rs b/src/libstd/par.rs
index ce78bc945db..3c05a0b5574 100644
--- a/src/libstd/par.rs
+++ b/src/libstd/par.rs
@@ -46,7 +46,7 @@ fn map_slices<A: copy send, B: copy send>(
         while base < len {
             let end = uint::min(len, base + items_per_task);
             // FIXME: why is the ::<A, ()> annotation required here? (#2617)
-            do vec::unpack_slice::<A, ()>(xs) |p, _len| {
+            do vec::as_buf::<A, ()>(xs) |p, _len| {
                 let f = f();
                 let f = do future_spawn() |copy base| {
                     unsafe {
diff --git a/src/libstd/uv_ll.rs b/src/libstd/uv_ll.rs
index 56365514da9..cb1f5321f78 100644
--- a/src/libstd/uv_ll.rs
+++ b/src/libstd/uv_ll.rs
@@ -821,10 +821,9 @@ unsafe fn ip4_name(src: &sockaddr_in) -> ~str {
     // ipv4 addr max size: 15 + 1 trailing null byte
     let dst: ~[u8] = ~[0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
                      0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8];
-    let size = 16 as libc::size_t;
-    do vec::as_buf(dst) |dst_buf| {
+    do vec::as_buf(dst) |dst_buf, size| {
         rustrt::rust_uv_ip4_name(src as *sockaddr_in,
-                                              dst_buf, size);
+                                 dst_buf, size as libc::size_t);
         // seems that checking the result of uv_ip4_name
         // doesn't work too well..
         // you're stuck looking at the value of dst_buf
@@ -842,13 +841,12 @@ unsafe fn ip6_name(src: &sockaddr_in6) -> ~str {
                        0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
                        0u8,0u8,0u8,0u8,0u8,0u8,0u8,0u8,
                        0u8,0u8,0u8,0u8,0u8,0u8];
-    let size = 46 as libc::size_t;
-    do vec::as_buf(dst) |dst_buf| {
+    do vec::as_buf(dst) |dst_buf, size| {
         let src_unsafe_ptr = src as *sockaddr_in6;
         log(debug, #fmt("val of src *sockaddr_in6: %? sockaddr_in6: %?",
                         src_unsafe_ptr, src));
         let result = rustrt::rust_uv_ip6_name(src_unsafe_ptr,
-                                              dst_buf, size);
+                                              dst_buf, size as libc::size_t);
         alt result {
           0i32 {
             str::unsafe::from_buf(dst_buf)
diff --git a/src/rustc/middle/trans/foreign.rs b/src/rustc/middle/trans/foreign.rs
index 21ffefc5456..855f9134dd7 100644
--- a/src/rustc/middle/trans/foreign.rs
+++ b/src/rustc/middle/trans/foreign.rs
@@ -66,7 +66,7 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] {
     fn struct_tys(ty: TypeRef) -> ~[TypeRef] {
         let n = llvm::LLVMCountStructElementTypes(ty);
         let elts = vec::from_elem(n as uint, ptr::null());
-        do vec::as_buf(elts) |buf| {
+        do vec::as_buf(elts) |buf, _len| {
             llvm::LLVMGetStructElementTypes(ty, buf);
         }
         ret elts;
diff --git a/src/test/run-fail/bug-2470-bounds-check-overflow.rs b/src/test/run-fail/bug-2470-bounds-check-overflow.rs
index 3fcc768c4d9..abf1bc5d6c8 100644
--- a/src/test/run-fail/bug-2470-bounds-check-overflow.rs
+++ b/src/test/run-fail/bug-2470-bounds-check-overflow.rs
@@ -9,7 +9,7 @@ fn main() {
     // huge).
 
     let x = ~[1u,2u,3u];
-    do vec::unpack_slice(x) |p, _len| {
+    do vec::as_buf(x) |p, _len| {
         let base = p as uint;                     // base = 0x1230 say
         let idx = base / sys::size_of::<uint>();  // idx  = 0x0246 say
         #error("ov1 base = 0x%x", base);