about summary refs log tree commit diff
path: root/src/libstd/ptr.rs
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-05-07 11:06:45 -0700
committerbors <bors@rust-lang.org>2014-05-07 11:06:45 -0700
commit87115fd001440652291c509a77bda74fa511dab0 (patch)
tree06de178943c0e48728df22b090dcdc1b9ba9a9d2 /src/libstd/ptr.rs
parent445988b47811679144d0fa9b3a2ccf2348752850 (diff)
parent07caa224501817c93be3f5c57a013ed5db6c04e1 (diff)
downloadrust-87115fd001440652291c509a77bda74fa511dab0.tar.gz
rust-87115fd001440652291c509a77bda74fa511dab0.zip
auto merge of #13901 : alexcrichton/rust/facade, r=brson
This is the second step in implementing #13851. This PR cannot currently land until a snapshot exists with #13892, but I imagine that this review will take longer.

This PR refactors a large amount of functionality outside of the standard library into a new library, libcore. This new library has 0 dependencies (in theory). In practice, this library currently depends on these symbols being available:

* `rust_begin_unwind` and `rust_fail_bounds_check` - These are the two entry points of failure in libcore. The symbols are provided by libstd currently. In the future (see the bullets on #13851) this will be officially supported with nice error mesages. Additionally, there will only be one failure entry point once `std::fmt` migrates to libcore.
* `memcpy` - This is often generated by LLVM. This is also quite trivial to implement for any platform, so I'm not too worried about this.
* `memcmp` - This is required for comparing strings. This function is quite common *everywhere*, so I don't feel to bad about relying on a consumer of libcore to define it.
* `malloc` and `free` - This is quite unfortunate, and is a temporary stopgap until we deal with the `~` situation. More details can be found in the module `core::should_not_exist`
* `fmod` and `fmodf` - These exist because the `Rem` trait is defined in libcore, so the `Rem` implementation for floats must also be defined in libcore. I imagine that any platform using floating-point modulus will have these symbols anyway, and otherwise they will be optimized out.
* `fdim` and `fdimf` - Like `fmod`, these are from the `Signed` trait being defined in libcore. I don't expect this to be much of a problem

These dependencies all "Just Work" for now because libcore only exists as an rlib, not as a dylib.

The commits themselves are organized to show that the overall diff of this extraction is not all that large. Most modules were able to be moved with very few modifications. The primary module left out of this iteration is `std::fmt`. I plan on migrating the `fmt` module to libcore, but I chose to not do so at this time because it had implications on the `Writer` trait that I wanted to deal with in isolation. There are a few breaking changes in these commits, but they are fairly minor, and are all labeled with `[breaking-change]`.

The nastiest parts of this movement come up with `~[T]` and `~str` being language-defined types today. I believe that much of this nastiness will get better over time as we migrate towards `Vec<T>` and `Str` (or whatever the types will be named). There will likely always be some extension traits, but the situation won't be as bad as it is today.

Known deficiencies:

* rustdoc will get worse in terms of readability. This is the next issue I will tackle as part of #13851. If others think that the rustdoc change should happen first, I can also table this to fix rustdoc first.
* The compiler reveals that all these types are reexports via error messages like `core::option::Option`. This is filed as #13065, and I believe that issue would have a higher priority now. I do not currently plan on fixing that as part of #13851. If others believe that this issue should be fixed, I can also place it on the roadmap for #13851.

I recommend viewing these changes on a commit-by-commit basis. The overall change is likely too overwhelming to take in.
Diffstat (limited to 'src/libstd/ptr.rs')
-rw-r--r--src/libstd/ptr.rs772
1 files changed, 0 insertions, 772 deletions
diff --git a/src/libstd/ptr.rs b/src/libstd/ptr.rs
deleted file mode 100644
index dac727c2aa4..00000000000
--- a/src/libstd/ptr.rs
+++ /dev/null
@@ -1,772 +0,0 @@
-// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
-// file at the top-level directory of this distribution and at
-// http://rust-lang.org/COPYRIGHT.
-//
-// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
-// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
-// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
-// option. This file may not be copied, modified, or distributed
-// except according to those terms.
-
-//! Conveniences for working with unsafe pointers, the `*T`, and `*mut T` types.
-//!
-//! Working with unsafe pointers in Rust is fairly uncommon,
-//! and often limited to some narrow use cases: holding
-//! an unsafe pointer when safe pointers are unsuitable;
-//! checking for null; and converting back to safe pointers.
-//! As a result, there is not yet an abundance of library code
-//! for working with unsafe pointers, and in particular,
-//! since pointer math is fairly uncommon in Rust, it is not
-//! all that convenient.
-//!
-//! Use the [`null` function](fn.null.html) to create null pointers,
-//! the [`is_null`](trait.RawPtr.html#tymethod.is_null)
-//! and [`is_not_null`](trait.RawPtr.html#method.is_not_null)
-//! methods of the [`RawPtr` trait](trait.RawPtr.html) to check for null.
-//! The `RawPtr` trait is imported by the prelude, so `is_null` etc.
-//! work everywhere.
-//!
-//! # Common ways to create unsafe pointers
-//!
-//! ## 1. Coerce a reference (`&T`) or mutable reference (`&mut T`).
-//!
-//! ```
-//! let my_num: int = 10;
-//! let my_num_ptr: *int = &my_num;
-//! let mut my_speed: int = 88;
-//! let my_speed_ptr: *mut int = &mut my_speed;
-//! ```
-//!
-//! This does not take ownership of the original allocation
-//! and requires no resource management later,
-//! but you must not use the pointer after its lifetime.
-//!
-//! ## 2. Transmute an owned box (`Box<T>`).
-//!
-//! The `transmute` function takes, by value, whatever it's given
-//! and returns it as whatever type is requested, as long as the
-//! types are the same size. Because `Box<T>` and `*T` have the same
-//! representation they can be trivially,
-//! though unsafely, transformed from one type to the other.
-//!
-//! ```
-//! use std::cast;
-//!
-//! unsafe {
-//!     let my_num: Box<int> = box 10;
-//!     let my_num: *int = cast::transmute(my_num);
-//!     let my_speed: Box<int> = box 88;
-//!     let my_speed: *mut int = cast::transmute(my_speed);
-//!
-//!     // By taking ownership of the original `Box<T>` though
-//!     // we are obligated to transmute it back later to be destroyed.
-//!     drop(cast::transmute::<_, Box<int>>(my_speed));
-//!     drop(cast::transmute::<_, Box<int>>(my_num));
-//! }
-//! ```
-//!
-//! Note that here the call to `drop` is for clarity - it indicates
-//! that we are done with the given value and it should be destroyed.
-//!
-//! ## 3. Get it from C.
-//!
-//! ```
-//! extern crate libc;
-//!
-//! use std::mem;
-//!
-//! fn main() {
-//!     unsafe {
-//!         let my_num: *mut int = libc::malloc(mem::size_of::<int>() as libc::size_t) as *mut int;
-//!         if my_num.is_null() {
-//!             fail!("failed to allocate memory");
-//!         }
-//!         libc::free(my_num as *mut libc::c_void);
-//!     }
-//! }
-//! ```
-//!
-//! Usually you wouldn't literally use `malloc` and `free` from Rust,
-//! but C APIs hand out a lot of pointers generally, so are a common source
-//! of unsafe pointers in Rust.
-
-use cast;
-use clone::Clone;
-#[cfg(not(test))]
-use cmp::Equiv;
-use iter::{range, Iterator};
-use mem;
-use option::{Option, Some, None};
-use intrinsics;
-
-#[cfg(not(test))] use cmp::{Eq, TotalEq, Ord};
-
-/// Return the offset of the first null pointer in `buf`.
-#[inline]
-pub unsafe fn buf_len<T>(buf: **T) -> uint {
-    position(buf, |i| *i == null())
-}
-
-impl<T> Clone for *T {
-    #[inline]
-    fn clone(&self) -> *T {
-        *self
-    }
-}
-
-impl<T> Clone for *mut T {
-    #[inline]
-    fn clone(&self) -> *mut T {
-        *self
-    }
-}
-
-/// Return the first offset `i` such that `f(buf[i]) == true`.
-#[inline]
-pub unsafe fn position<T>(buf: *T, f: |&T| -> bool) -> uint {
-    let mut i = 0;
-    loop {
-        if f(&(*buf.offset(i as int))) { return i; }
-        else { i += 1; }
-    }
-}
-
-/// Create a null pointer.
-///
-/// # Example
-///
-/// ```
-/// use std::ptr;
-///
-/// let p: *int = ptr::null();
-/// assert!(p.is_null());
-/// ```
-#[inline]
-pub fn null<T>() -> *T { 0 as *T }
-
-/// Create an unsafe mutable null pointer.
-///
-/// # Example
-///
-/// ```
-/// use std::ptr;
-///
-/// let p: *mut int = ptr::mut_null();
-/// assert!(p.is_null());
-/// ```
-#[inline]
-pub fn mut_null<T>() -> *mut T { 0 as *mut T }
-
-/// Copies data from one location to another.
-///
-/// Copies `count` elements (not bytes) from `src` to `dst`. The source
-/// and destination may overlap.
-///
-/// `copy_memory` is semantically equivalent to C's `memmove`.
-///
-/// # Example
-///
-/// Efficiently create a Rust vector from an unsafe buffer:
-///
-/// ```
-/// use std::ptr;
-///
-/// unsafe fn from_buf_raw<T>(ptr: *T, elts: uint) -> Vec<T> {
-///     let mut dst = Vec::with_capacity(elts);
-///     dst.set_len(elts);
-///     ptr::copy_memory(dst.as_mut_ptr(), ptr, elts);
-///     dst
-/// }
-/// ```
-///
-#[inline]
-pub unsafe fn copy_memory<T>(dst: *mut T, src: *T, count: uint) {
-    intrinsics::copy_memory(dst, src, count)
-}
-
-/// Copies data from one location to another.
-///
-/// Copies `count` elements (not bytes) from `src` to `dst`. The source
-/// and destination may *not* overlap.
-///
-/// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`.
-///
-/// # Example
-///
-/// A safe swap function:
-///
-/// ```
-/// use std::cast;
-/// use std::mem;
-/// use std::ptr;
-///
-/// fn swap<T>(x: &mut T, y: &mut T) {
-///     unsafe {
-///         // Give ourselves some scratch space to work with
-///         let mut t: T = mem::uninit();
-///
-///         // Perform the swap, `&mut` pointers never alias
-///         ptr::copy_nonoverlapping_memory(&mut t, &*x, 1);
-///         ptr::copy_nonoverlapping_memory(x, &*y, 1);
-///         ptr::copy_nonoverlapping_memory(y, &t, 1);
-///
-///         // y and t now point to the same thing, but we need to completely forget `tmp`
-///         // because it's no longer relevant.
-///         cast::forget(t);
-///     }
-/// }
-/// ```
-///
-/// # Safety Note
-///
-/// If the source and destination overlap then the behavior of this
-/// function is undefined.
-#[inline]
-pub unsafe fn copy_nonoverlapping_memory<T>(dst: *mut T,
-                                            src: *T,
-                                            count: uint) {
-    intrinsics::copy_nonoverlapping_memory(dst, src, count)
-}
-
-/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
-/// bytes of memory starting at `dst` to `c`.
-#[inline]
-pub unsafe fn set_memory<T>(dst: *mut T, c: u8, count: uint) {
-    intrinsics::set_memory(dst, c, count)
-}
-
-/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`
-#[inline]
-pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) {
-    set_memory(dst, 0, count);
-}
-
-/// Swap the values at two mutable locations of the same type, without
-/// deinitialising either. They may overlap.
-#[inline]
-pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
-    // Give ourselves some scratch space to work with
-    let mut tmp: T = mem::uninit();
-    let t: *mut T = &mut tmp;
-
-    // Perform the swap
-    copy_nonoverlapping_memory(t, &*x, 1);
-    copy_memory(x, &*y, 1); // `x` and `y` may overlap
-    copy_nonoverlapping_memory(y, &*t, 1);
-
-    // y and t now point to the same thing, but we need to completely forget `tmp`
-    // because it's no longer relevant.
-    cast::forget(tmp);
-}
-
-/// Replace the value at a mutable location with a new one, returning the old
-/// value, without deinitialising either.
-#[inline]
-pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
-    mem::swap(cast::transmute(dest), &mut src); // cannot overlap
-    src
-}
-
-/// Reads the value from `*src` and returns it.
-#[inline(always)]
-pub unsafe fn read<T>(src: *T) -> T {
-    let mut tmp: T = mem::uninit();
-    copy_nonoverlapping_memory(&mut tmp, src, 1);
-    tmp
-}
-
-/// Reads the value from `*src` and nulls it out.
-/// This currently prevents destructors from executing.
-#[inline(always)]
-pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
-    // Copy the data out from `dest`:
-    let tmp = read(&*dest);
-
-    // Now zero out `dest`:
-    zero_memory(dest, 1);
-
-    tmp
-}
-
-/// Given a **T (pointer to an array of pointers),
-/// iterate through each *T, up to the provided `len`,
-/// passing to the provided callback function
-pub unsafe fn array_each_with_len<T>(arr: **T, len: uint, cb: |*T|) {
-    if arr.is_null() {
-        fail!("ptr::array_each_with_len failure: arr input is null pointer");
-    }
-    //let start_ptr = *arr;
-    for e in range(0, len) {
-        let n = arr.offset(e as int);
-        cb(*n);
-    }
-}
-
-/// Given a null-pointer-terminated **T (pointer to
-/// an array of pointers), iterate through each *T,
-/// passing to the provided callback function
-///
-/// # Safety Note
-///
-/// This will only work with a null-terminated
-/// pointer array.
-pub unsafe fn array_each<T>(arr: **T, cb: |*T|) {
-    if arr.is_null()  {
-        fail!("ptr::array_each_with_len failure: arr input is null pointer");
-    }
-    let len = buf_len(arr);
-    array_each_with_len(arr, len, cb);
-}
-
-/// Extension methods for raw pointers.
-pub trait RawPtr<T> {
-    /// Returns the null pointer.
-    fn null() -> Self;
-    /// Returns true if the pointer is equal to the null pointer.
-    fn is_null(&self) -> bool;
-    /// Returns true if the pointer is not equal to the null pointer.
-    fn is_not_null(&self) -> bool { !self.is_null() }
-    /// Returns the value of this pointer (ie, the address it points to)
-    fn to_uint(&self) -> uint;
-    /// Returns `None` if the pointer is null, or else returns the value wrapped
-    /// in `Some`.
-    ///
-    /// # Safety Notes
-    ///
-    /// While this method is useful for null-safety, it is important to note
-    /// that this is still an unsafe operation because the returned value could
-    /// be pointing to invalid memory.
-    unsafe fn to_option(&self) -> Option<&T>;
-    /// Calculates the offset from a pointer. The offset *must* be in-bounds of
-    /// the object, or one-byte-past-the-end.  `count` is in units of T; e.g. a
-    /// `count` of 3 represents a pointer offset of `3 * sizeof::<T>()` bytes.
-    unsafe fn offset(self, count: int) -> Self;
-}
-
-impl<T> RawPtr<T> for *T {
-    #[inline]
-    fn null() -> *T { null() }
-
-    #[inline]
-    fn is_null(&self) -> bool { *self == RawPtr::null() }
-
-    #[inline]
-    fn to_uint(&self) -> uint { *self as uint }
-
-    #[inline]
-    unsafe fn offset(self, count: int) -> *T { intrinsics::offset(self, count) }
-
-    #[inline]
-    unsafe fn to_option(&self) -> Option<&T> {
-        if self.is_null() {
-            None
-        } else {
-            Some(cast::transmute(*self))
-        }
-    }
-}
-
-impl<T> RawPtr<T> for *mut T {
-    #[inline]
-    fn null() -> *mut T { mut_null() }
-
-    #[inline]
-    fn is_null(&self) -> bool { *self == RawPtr::null() }
-
-    #[inline]
-    fn to_uint(&self) -> uint { *self as uint }
-
-    #[inline]
-    unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *T, count) as *mut T }
-
-    #[inline]
-    unsafe fn to_option(&self) -> Option<&T> {
-        if self.is_null() {
-            None
-        } else {
-            Some(cast::transmute(*self))
-        }
-    }
-}
-
-// Equality for pointers
-#[cfg(not(test))]
-impl<T> Eq for *T {
-    #[inline]
-    fn eq(&self, other: &*T) -> bool {
-        *self == *other
-    }
-    #[inline]
-    fn ne(&self, other: &*T) -> bool { !self.eq(other) }
-}
-
-#[cfg(not(test))]
-impl<T> TotalEq for *T {}
-
-#[cfg(not(test))]
-impl<T> Eq for *mut T {
-    #[inline]
-    fn eq(&self, other: &*mut T) -> bool {
-        *self == *other
-    }
-    #[inline]
-    fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
-}
-
-#[cfg(not(test))]
-impl<T> TotalEq for *mut T {}
-
-// Equivalence for pointers
-#[cfg(not(test))]
-impl<T> Equiv<*mut T> for *T {
-    fn equiv(&self, other: &*mut T) -> bool {
-        self.to_uint() == other.to_uint()
-    }
-}
-
-#[cfg(not(test))]
-impl<T> Equiv<*T> for *mut T {
-    fn equiv(&self, other: &*T) -> bool {
-        self.to_uint() == other.to_uint()
-    }
-}
-
-// Equality for extern "C" fn pointers
-#[cfg(not(test))]
-mod externfnpointers {
-    use cast;
-    use cmp::Eq;
-
-    impl<_R> Eq for extern "C" fn() -> _R {
-        #[inline]
-        fn eq(&self, other: &extern "C" fn() -> _R) -> bool {
-            let self_: *() = unsafe { cast::transmute(*self) };
-            let other_: *() = unsafe { cast::transmute(*other) };
-            self_ == other_
-        }
-        #[inline]
-        fn ne(&self, other: &extern "C" fn() -> _R) -> bool {
-            !self.eq(other)
-        }
-    }
-    macro_rules! fnptreq(
-        ($($p:ident),*) => {
-            impl<_R,$($p),*> Eq for extern "C" fn($($p),*) -> _R {
-                #[inline]
-                fn eq(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
-                    let self_: *() = unsafe { cast::transmute(*self) };
-                    let other_: *() = unsafe { cast::transmute(*other) };
-                    self_ == other_
-                }
-                #[inline]
-                fn ne(&self, other: &extern "C" fn($($p),*) -> _R) -> bool {
-                    !self.eq(other)
-                }
-            }
-        }
-    )
-    fnptreq!(A)
-    fnptreq!(A,B)
-    fnptreq!(A,B,C)
-    fnptreq!(A,B,C,D)
-    fnptreq!(A,B,C,D,E)
-}
-
-// Comparison for pointers
-#[cfg(not(test))]
-impl<T> Ord for *T {
-    #[inline]
-    fn lt(&self, other: &*T) -> bool {
-        *self < *other
-    }
-    #[inline]
-    fn le(&self, other: &*T) -> bool {
-        *self <= *other
-    }
-    #[inline]
-    fn ge(&self, other: &*T) -> bool {
-        *self >= *other
-    }
-    #[inline]
-    fn gt(&self, other: &*T) -> bool {
-        *self > *other
-    }
-}
-
-#[cfg(not(test))]
-impl<T> Ord for *mut T {
-    #[inline]
-    fn lt(&self, other: &*mut T) -> bool {
-        *self < *other
-    }
-    #[inline]
-    fn le(&self, other: &*mut T) -> bool {
-        *self <= *other
-    }
-    #[inline]
-    fn ge(&self, other: &*mut T) -> bool {
-        *self >= *other
-    }
-    #[inline]
-    fn gt(&self, other: &*mut T) -> bool {
-        *self > *other
-    }
-}
-
-#[cfg(test)]
-pub mod ptr_tests {
-    use super::*;
-    use prelude::*;
-
-    use c_str::ToCStr;
-    use cast;
-    use libc;
-    use str;
-    use slice::{ImmutableVector, MutableVector};
-
-    #[test]
-    fn test() {
-        unsafe {
-            struct Pair {
-                fst: int,
-                snd: int
-            };
-            let mut p = Pair {fst: 10, snd: 20};
-            let pptr: *mut Pair = &mut p;
-            let iptr: *mut int = cast::transmute(pptr);
-            assert_eq!(*iptr, 10);
-            *iptr = 30;
-            assert_eq!(*iptr, 30);
-            assert_eq!(p.fst, 30);
-
-            *pptr = Pair {fst: 50, snd: 60};
-            assert_eq!(*iptr, 50);
-            assert_eq!(p.fst, 50);
-            assert_eq!(p.snd, 60);
-
-            let v0 = box [32000u16, 32001u16, 32002u16];
-            let mut v1 = box [0u16, 0u16, 0u16];
-
-            copy_memory(v1.as_mut_ptr().offset(1),
-                        v0.as_ptr().offset(1), 1);
-            assert!((v1[0] == 0u16 && v1[1] == 32001u16 && v1[2] == 0u16));
-            copy_memory(v1.as_mut_ptr(),
-                        v0.as_ptr().offset(2), 1);
-            assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
-                     v1[2] == 0u16));
-            copy_memory(v1.as_mut_ptr().offset(2),
-                        v0.as_ptr(), 1u);
-            assert!((v1[0] == 32002u16 && v1[1] == 32001u16 &&
-                     v1[2] == 32000u16));
-        }
-    }
-
-    #[test]
-    fn test_position() {
-        use libc::c_char;
-
-        "hello".with_c_str(|p| {
-            unsafe {
-                assert!(2u == position(p, |c| *c == 'l' as c_char));
-                assert!(4u == position(p, |c| *c == 'o' as c_char));
-                assert!(5u == position(p, |c| *c == 0 as c_char));
-            }
-        })
-    }
-
-    #[test]
-    fn test_buf_len() {
-        "hello".with_c_str(|p0| {
-            "there".with_c_str(|p1| {
-                "thing".with_c_str(|p2| {
-                    let v = box [p0, p1, p2, null()];
-                    unsafe {
-                        assert_eq!(buf_len(v.as_ptr()), 3u);
-                    }
-                })
-            })
-        })
-    }
-
-    #[test]
-    fn test_is_null() {
-        let p: *int = null();
-        assert!(p.is_null());
-        assert!(!p.is_not_null());
-
-        let q = unsafe { p.offset(1) };
-        assert!(!q.is_null());
-        assert!(q.is_not_null());
-
-        let mp: *mut int = mut_null();
-        assert!(mp.is_null());
-        assert!(!mp.is_not_null());
-
-        let mq = unsafe { mp.offset(1) };
-        assert!(!mq.is_null());
-        assert!(mq.is_not_null());
-    }
-
-    #[test]
-    fn test_to_option() {
-        unsafe {
-            let p: *int = null();
-            assert_eq!(p.to_option(), None);
-
-            let q: *int = &2;
-            assert_eq!(q.to_option().unwrap(), &2);
-
-            let p: *mut int = mut_null();
-            assert_eq!(p.to_option(), None);
-
-            let q: *mut int = &mut 2;
-            assert_eq!(q.to_option().unwrap(), &2);
-        }
-    }
-
-    #[test]
-    fn test_ptr_addition() {
-        unsafe {
-            let xs = box [5, ..16];
-            let mut ptr = xs.as_ptr();
-            let end = ptr.offset(16);
-
-            while ptr < end {
-                assert_eq!(*ptr, 5);
-                ptr = ptr.offset(1);
-            }
-
-            let mut xs_mut = xs.clone();
-            let mut m_ptr = xs_mut.as_mut_ptr();
-            let m_end = m_ptr.offset(16);
-
-            while m_ptr < m_end {
-                *m_ptr += 5;
-                m_ptr = m_ptr.offset(1);
-            }
-
-            assert_eq!(xs_mut, box [10, ..16]);
-        }
-    }
-
-    #[test]
-    fn test_ptr_subtraction() {
-        unsafe {
-            let xs = box [0,1,2,3,4,5,6,7,8,9];
-            let mut idx = 9i8;
-            let ptr = xs.as_ptr();
-
-            while idx >= 0i8 {
-                assert_eq!(*(ptr.offset(idx as int)), idx as int);
-                idx = idx - 1i8;
-            }
-
-            let mut xs_mut = xs.clone();
-            let m_start = xs_mut.as_mut_ptr();
-            let mut m_ptr = m_start.offset(9);
-
-            while m_ptr >= m_start {
-                *m_ptr += *m_ptr;
-                m_ptr = m_ptr.offset(-1);
-            }
-
-            assert_eq!(xs_mut, box [0,2,4,6,8,10,12,14,16,18]);
-        }
-    }
-
-    #[test]
-    fn test_ptr_array_each_with_len() {
-        unsafe {
-            let one = "oneOne".to_c_str();
-            let two = "twoTwo".to_c_str();
-            let three = "threeThree".to_c_str();
-            let arr = box [
-                one.with_ref(|buf| buf),
-                two.with_ref(|buf| buf),
-                three.with_ref(|buf| buf),
-            ];
-            let expected_arr = [
-                one, two, three
-            ];
-
-            let mut ctr = 0;
-            let mut iteration_count = 0;
-            array_each_with_len(arr.as_ptr(), arr.len(), |e| {
-                    let actual = str::raw::from_c_str(e);
-                    let expected = expected_arr[ctr].with_ref(|buf| {
-                            str::raw::from_c_str(buf)
-                        });
-                    debug!(
-                        "test_ptr_array_each_with_len e: {}, a: {}",
-                        expected, actual);
-                    assert_eq!(actual, expected);
-                    ctr += 1;
-                    iteration_count += 1;
-                });
-            assert_eq!(iteration_count, 3u);
-        }
-    }
-
-    #[test]
-    fn test_ptr_array_each() {
-        unsafe {
-            let one = "oneOne".to_c_str();
-            let two = "twoTwo".to_c_str();
-            let three = "threeThree".to_c_str();
-            let arr = box [
-                one.with_ref(|buf| buf),
-                two.with_ref(|buf| buf),
-                three.with_ref(|buf| buf),
-                // fake a null terminator
-                null(),
-            ];
-            let expected_arr = [
-                one, two, three
-            ];
-
-            let arr_ptr = arr.as_ptr();
-            let mut ctr = 0;
-            let mut iteration_count = 0;
-            array_each(arr_ptr, |e| {
-                    let actual = str::raw::from_c_str(e);
-                    let expected = expected_arr[ctr].with_ref(|buf| {
-                        str::raw::from_c_str(buf)
-                    });
-                    debug!(
-                        "test_ptr_array_each e: {}, a: {}",
-                        expected, actual);
-                    assert_eq!(actual, expected);
-                    ctr += 1;
-                    iteration_count += 1;
-                });
-            assert_eq!(iteration_count, 3);
-        }
-    }
-
-    #[test]
-    #[should_fail]
-    fn test_ptr_array_each_with_len_null_ptr() {
-        unsafe {
-            array_each_with_len(0 as **libc::c_char, 1, |e| {
-                str::raw::from_c_str(e);
-            });
-        }
-    }
-    #[test]
-    #[should_fail]
-    fn test_ptr_array_each_null_ptr() {
-        unsafe {
-            array_each(0 as **libc::c_char, |e| {
-                str::raw::from_c_str(e);
-            });
-        }
-    }
-
-    #[test]
-    fn test_set_memory() {
-        let mut xs = [0u8, ..20];
-        let ptr = xs.as_mut_ptr();
-        unsafe { set_memory(ptr, 5u8, xs.len()); }
-        assert!(xs == [5u8, ..20]);
-    }
-}