diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs index d8f103fa0f3..950c47c6369 100644 --- a/src/libcore/intrinsics.rs +++ b/src/libcore/intrinsics.rs @@ -222,7 +222,7 @@ extern "rust-intrinsic" { /// Both types must have the same size and alignment, and this guarantee /// is enforced at compile-time. /// - /// # Example + /// # Examples /// /// ```rust /// use std::mem; @@ -253,14 +253,20 @@ extern "rust-intrinsic" { /// integer, since the conversion would throw away aliasing information. pub fn offset(dst: *const T, offset: int) -> *const T; - /// Copies data from one location to another. - /// - /// Copies `count` elements (not bytes) from `src` to `dst`. The source + /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may *not* overlap. /// /// `copy_nonoverlapping_memory` is semantically equivalent to C's `memcpy`. /// - /// # Example + /// # Safety + /// + /// Beyond requiring that both regions of memory be allocated, it is Undefined Behaviour + /// for source and destination to overlap. Care must also be taken with the ownership of + /// `src` and `dst`. This method semantically moves the values of `src` into `dst`. + /// However it does not drop the contents of `dst`, or prevent the contents of `src` + /// from being dropped or used. + /// + /// # Examples /// /// A safe swap function: /// @@ -284,22 +290,22 @@ extern "rust-intrinsic" { /// } /// } /// ``` - /// - /// # Safety Note - /// - /// If the source and destination overlap then the behavior of this - /// function is undefined. #[unstable] pub fn copy_nonoverlapping_memory(dst: *mut T, src: *const T, count: uint); - /// Copies data from one location to another. - /// - /// Copies `count` elements (not bytes) from `src` to `dst`. The source + /// Copies `count * size_of` bytes from `src` to `dst`. The source /// and destination may overlap. /// /// `copy_memory` is semantically equivalent to C's `memmove`. /// - /// # Example + /// # Safety + /// + /// Care must be taken with the ownership of `src` and `dst`. + /// This method semantically moves the values of `src` into `dst`. + /// However it does not drop the contents of `dst`, or prevent the contents of `src` + /// from being dropped or used. + /// + /// # Examples /// /// Efficiently create a Rust vector from an unsafe buffer: /// diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 36c6b9572ea..d9d90bf77c2 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -97,13 +97,20 @@ use cmp::{PartialEq, Eq, Ord, PartialOrd, Equiv}; use cmp::Ordering; use cmp::Ordering::{Less, Equal, Greater}; -pub use intrinsics::copy_memory; +// FIXME #19649: instrinsic docs don't render, so these have no docs :( + +#[unstable] pub use intrinsics::copy_nonoverlapping_memory; + +#[unstable] +pub use intrinsics::copy_memory; + +#[experimental = "uncertain about naming and semantics"] pub use intrinsics::set_memory; -/// Create a null pointer. +/// Creates a null raw pointer. /// -/// # Example +/// # Examples /// /// ``` /// use std::ptr; @@ -115,9 +122,9 @@ pub use intrinsics::set_memory; #[unstable = "may need a different name after pending changes to pointer types"] pub fn null() -> *const T { 0 as *const T } -/// Create an unsafe mutable null pointer. +/// Creates a null mutable raw pointer. /// -/// # Example +/// # Examples /// /// ``` /// use std::ptr; @@ -129,7 +136,12 @@ pub fn null() -> *const T { 0 as *const T } #[unstable = "may need a different name after pending changes to pointer types"] pub fn null_mut() -> *mut T { 0 as *mut T } -/// Zeroes out `count * size_of::` bytes of memory at `dst` +/// Zeroes out `count * size_of::` bytes of memory at `dst`. `count` may be `0`. +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it will not drop the contents of `dst`, +/// and may be used to create invalid instances of `T`. #[inline] #[experimental = "uncertain about naming and semantics"] #[allow(experimental)] @@ -137,8 +149,13 @@ pub unsafe fn zero_memory(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. +/// Swaps the values at two mutable locations of the same type, without +/// deinitialising either. They may overlap, unlike `mem::swap` which is otherwise +/// equivalent. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. #[inline] #[unstable] pub unsafe fn swap(x: *mut T, y: *mut T) { @@ -156,8 +173,13 @@ pub unsafe fn swap(x: *mut T, y: *mut T) { mem::forget(tmp); } -/// Replace the value at a mutable location with a new one, returning the old -/// value, without deinitialising either. +/// Replaces the value at `dest` with `src`, returning the old +/// value, without dropping either. +/// +/// # Safety +/// +/// This is only unsafe because it accepts a raw pointer. +/// Otherwise, this operation is identical to `mem::replace`. #[inline] #[unstable] pub unsafe fn replace(dest: *mut T, mut src: T) -> T { @@ -165,7 +187,17 @@ pub unsafe fn replace(dest: *mut T, mut src: T) -> T { src } -/// Reads the value from `*src` and returns it. +/// Reads the value from `src` without dropping it. This leaves the +/// memory in `src` unchanged. +/// +/// # Safety +/// +/// Beyond accepting a raw pointer, this is unsafe because it semantically +/// moves the value out of `src` without preventing further usage of `src`. +/// If `T` is not `Copy`, then care must be taken to ensure that the value at +/// `src` is not used before the data is overwritten again (e.g. with `write`, +/// `zero_memory`, or `copy_memory`). Note that `*src = foo` counts as a use +/// because it will attempt to drop the value previously at `*src`. #[inline(always)] #[unstable] pub unsafe fn read(src: *const T) -> T { @@ -174,8 +206,11 @@ pub unsafe fn read(src: *const T) -> T { tmp } -/// Reads the value from `*src` and nulls it out. -/// This currently prevents destructors from executing. +/// Reads the value from `src` and nulls it out without dropping it. +/// +/// # Safety +/// +/// This is unsafe for the same reasons that `read` is unsafe. #[inline(always)] #[experimental] #[allow(experimental)] @@ -189,12 +224,17 @@ pub unsafe fn read_and_zero(dest: *mut T) -> T { tmp } -/// Unsafely overwrite a memory location with the given value without destroying +/// Overwrites a memory location with the given value without reading or dropping /// the old value. /// -/// This operation is unsafe because it does not destroy the previous value -/// contained at the location `dst`. This could leak allocations or resources, -/// so care must be taken to previously deallocate the value at `dst`. +/// # Safety +/// +/// Beyond accepting a raw pointer, this operation is unsafe because it does +/// not drop the contents of `dst`. This could leak allocations or resources, +/// so care must be taken not to overwrite an object that should be dropped. +/// +/// This is appropriate for initializing uninitialized memory, or overwritting memory +/// that has previously been `read` from. #[inline] #[unstable] pub unsafe fn write(dst: *mut T, src: T) { @@ -203,39 +243,47 @@ pub unsafe fn write(dst: *mut T, src: T) { /// Methods on raw pointers pub trait RawPtr { - /// Returns the null pointer. + /// Returns a null raw pointer. fn null() -> Self; - /// Returns true if the pointer is equal to the null pointer. + /// Returns true if the pointer is null. fn is_null(&self) -> bool; - /// Returns true if the pointer is not equal to the null pointer. + /// Returns true if the pointer is not null. fn is_not_null(&self) -> bool { !self.is_null() } - /// Returns the value of this pointer (ie, the address it points to) + /// Returns the address of the pointer. fn to_uint(&self) -> uint; /// Returns `None` if the pointer is null, or else returns a reference to the /// value wrapped in `Some`. /// - /// # Safety Notes + /// # Safety /// /// While this method and its mutable counterpart are 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 as_ref<'a>(&self) -> Option<&'a 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 + /// Calculates the offset from a pointer. `count` is in units of T; e.g. a /// `count` of 3 represents a pointer offset of `3 * sizeof::()` bytes. + /// + /// # Safety + /// + /// The offset must be in-bounds of the object, or one-byte-past-the-end. Otherwise + /// `offset` invokes Undefined Behaviour, regardless of whether the pointer is used. unsafe fn offset(self, count: int) -> Self; } /// Methods on mutable raw pointers pub trait RawMutPtr{ /// Returns `None` if the pointer is null, or else returns a mutable reference - /// to the value wrapped in `Some`. As with `as_ref`, this is unsafe because - /// it cannot verify the validity of the returned pointer. + /// to the value wrapped in `Some`. + /// + /// # Safety + /// + /// As with `as_ref`, this is unsafe because it cannot verify the validity + /// of the returned pointer. unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>; }