diff options
| author | Alex Crichton <alex@alexcrichton.com> | 2014-12-19 08:57:12 -0800 |
|---|---|---|
| committer | Alex Crichton <alex@alexcrichton.com> | 2014-12-29 15:57:28 -0800 |
| commit | 54452cdd68a18b7caa8def20bbd587b769f4cb67 (patch) | |
| tree | b9f02c5e33a125d26866516c9fe1c54d9c6072f0 /src/libcore/ptr.rs | |
| parent | 71123902e17ad339649f33423995eac78da40e3c (diff) | |
| download | rust-54452cdd68a18b7caa8def20bbd587b769f4cb67.tar.gz rust-54452cdd68a18b7caa8def20bbd587b769f4cb67.zip | |
std: Second pass stabilization for `ptr`
This commit performs a second pass for stabilization over the `std::ptr` module.
The specific actions taken were:
* The `RawPtr` trait was renamed to `PtrExt`
* The `RawMutPtr` trait was renamed to `MutPtrExt`
* The module name `ptr` is now stable.
* These functions were all marked `#[stable]` with no modification:
* `null`
* `null_mut`
* `swap`
* `replace`
* `read`
* `write`
* `PtrExt::is_null`
* `PtrExt::offset`
* These functions remain unstable:
* `as_ref`, `as_mut` - the return value of an `Option` is not fully expressive
as null isn't the only bad value, and it's unclear
whether we want to commit to these functions at this
time. The reference/lifetime semantics as written are
also problematic in how they encourage arbitrary
lifetimes.
* `zero_memory` - This function is currently not used at all in the
distribution, and in general it plays a broader role in the
"working with unsafe pointers" story. This story is not yet
fully developed, so at this time the function remains
unstable for now.
* `read_and_zero` - This function remains unstable for largely the same
reasons as `zero_memory`.
* These functions are now all deprecated:
* `PtrExt::null` - call `ptr::null` or `ptr::null_mut` instead.
* `PtrExt::to_uint` - use an `as` expression instead.
* `PtrExt::is_not_null` - use `!p.is_null()` instead.
Diffstat (limited to 'src/libcore/ptr.rs')
| -rw-r--r-- | src/libcore/ptr.rs | 141 |
1 files changed, 87 insertions, 54 deletions
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 8c724b4d852..75bb8d33ea8 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -16,11 +16,10 @@ //! typically limited to a few patterns. //! //! 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. The `RawPtr` also defines the `offset` method, +//! the [`is_null`](trait.PtrExt.html#tymethod.is_null) +//! methods of the [`PtrExt` trait](trait.PtrExt.html) to check for null. +//! The `PtrExt` trait is imported by the prelude, so `is_null` etc. +//! work everywhere. The `PtrExt` also defines the `offset` method, //! for pointer math. //! //! # Common ways to create unsafe pointers @@ -87,16 +86,16 @@ //! but C APIs hand out a lot of pointers generally, so are a common source //! of unsafe pointers in Rust. +#![stable] + use mem; use clone::Clone; use intrinsics; +use option::Option::{mod, Some, None}; use kinds::{Send, Sync}; -use option::Option; -use option::Option::{Some, None}; use cmp::{PartialEq, Eq, Ord, PartialOrd, Equiv}; -use cmp::Ordering; -use cmp::Ordering::{Less, Equal, Greater}; +use cmp::Ordering::{mod, Less, Equal, Greater}; // FIXME #19649: instrinsic docs don't render, so these have no docs :( @@ -121,7 +120,7 @@ pub use intrinsics::set_memory; /// assert!(p.is_null()); /// ``` #[inline] -#[unstable = "may need a different name after pending changes to pointer types"] +#[stable] pub fn null<T>() -> *const T { 0 as *const T } /// Creates a null mutable raw pointer. @@ -135,31 +134,31 @@ pub fn null<T>() -> *const T { 0 as *const T } /// assert!(p.is_null()); /// ``` #[inline] -#[unstable = "may need a different name after pending changes to pointer types"] +#[stable] pub fn null_mut<T>() -> *mut T { 0 as *mut T } -/// Zeroes out `count * size_of::<T>` bytes of memory at `dst`. `count` may be `0`. +/// Zeroes out `count * size_of::<T>` 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`. +/// 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)] +#[unstable = "may play a larger role in std::ptr future extensions"] pub unsafe fn zero_memory<T>(dst: *mut T, count: uint) { set_memory(dst, 0, count); } /// Swaps the values at two mutable locations of the same type, without -/// deinitialising either. They may overlap, unlike `mem::swap` which is otherwise -/// equivalent. +/// 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] +#[stable] pub unsafe fn swap<T>(x: *mut T, y: *mut T) { // Give ourselves some scratch space to work with let mut tmp: T = mem::uninitialized(); @@ -183,7 +182,7 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) { /// This is only unsafe because it accepts a raw pointer. /// Otherwise, this operation is identical to `mem::replace`. #[inline] -#[unstable] +#[stable] pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { mem::swap(mem::transmute(dest), &mut src); // cannot overlap src @@ -201,7 +200,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T { /// `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] +#[stable] pub unsafe fn read<T>(src: *const T) -> T { let mut tmp: T = mem::uninitialized(); copy_nonoverlapping_memory(&mut tmp, src, 1); @@ -214,8 +213,7 @@ pub unsafe fn read<T>(src: *const T) -> T { /// /// This is unsafe for the same reasons that `read` is unsafe. #[inline(always)] -#[experimental] -#[allow(experimental)] +#[unstable = "may play a larger role in std::ptr future extensions"] pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { // Copy the data out from `dest`: let tmp = read(&*dest); @@ -226,8 +224,8 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { tmp } -/// Overwrites a memory location with the given value without reading or dropping -/// the old value. +/// Overwrites a memory location with the given value without reading or +/// dropping the old value. /// /// # Safety /// @@ -235,36 +233,44 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T { /// 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. +/// This is appropriate for initializing uninitialized memory, or overwritting +/// memory that has previously been `read` from. #[inline] -#[unstable] +#[stable] pub unsafe fn write<T>(dst: *mut T, src: T) { intrinsics::move_val_init(&mut *dst, src) } /// Methods on raw pointers -pub trait RawPtr<T> { - /// Returns a null raw pointer. +#[stable] +pub trait PtrExt<T> { + /// Returns the null pointer. + #[deprecated = "call ptr::null instead"] fn null() -> Self; /// Returns true if the pointer is null. - fn is_null(&self) -> bool; + #[stable] + fn is_null(self) -> bool; - /// Returns true if the pointer is not null. - fn is_not_null(&self) -> bool { !self.is_null() } + /// Returns true if the pointer is not equal to the null pointer. + #[deprecated = "use !p.is_null() instead"] + fn is_not_null(self) -> bool { !self.is_null() } - /// Returns the address of the pointer. - fn to_uint(&self) -> uint; + /// Returns true if the pointer is not null. + #[deprecated = "use `as uint` instead"] + fn to_uint(self) -> uint; - /// Returns `None` if the pointer is null, or else returns a reference to the - /// value wrapped in `Some`. + /// Returns `None` if the pointer is null, or else returns a reference to + /// the value wrapped in `Some`. /// /// # 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. + /// 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. + #[unstable = "Option is not clearly the right return type, and we may want \ + to tie the return lifetime to a borrow of the raw pointer"] unsafe fn as_ref<'a>(&self) -> Option<&'a T>; /// Calculates the offset from a pointer. `count` is in units of T; e.g. a @@ -272,39 +278,51 @@ pub trait RawPtr<T> { /// /// # 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. + /// 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. + #[stable] unsafe fn offset(self, count: int) -> Self; } /// Methods on mutable raw pointers -pub trait RawMutPtr<T>{ - /// Returns `None` if the pointer is null, or else returns a mutable reference - /// to the value wrapped in `Some`. +#[stable] +pub trait MutPtrExt<T>{ + /// Returns `None` if the pointer is null, or else returns a mutable + /// reference to the value wrapped in `Some`. /// /// # Safety /// /// As with `as_ref`, this is unsafe because it cannot verify the validity /// of the returned pointer. + #[unstable = "Option is not clearly the right return type, and we may want \ + to tie the return lifetime to a borrow of the raw pointer"] unsafe fn as_mut<'a>(&self) -> Option<&'a mut T>; } -impl<T> RawPtr<T> for *const T { +#[stable] +impl<T> PtrExt<T> for *const T { #[inline] + #[deprecated = "call ptr::null instead"] fn null() -> *const T { null() } #[inline] - fn is_null(&self) -> bool { *self == RawPtr::null() } + #[stable] + fn is_null(self) -> bool { self as uint == 0 } #[inline] - fn to_uint(&self) -> uint { *self as uint } + #[deprecated = "use `as uint` instead"] + fn to_uint(self) -> uint { self as uint } #[inline] + #[stable] unsafe fn offset(self, count: int) -> *const T { intrinsics::offset(self, count) } #[inline] + #[unstable = "return value does not necessarily convey all possible \ + information"] unsafe fn as_ref<'a>(&self) -> Option<&'a T> { if self.is_null() { None @@ -314,22 +332,29 @@ impl<T> RawPtr<T> for *const T { } } -impl<T> RawPtr<T> for *mut T { +#[stable] +impl<T> PtrExt<T> for *mut T { #[inline] + #[deprecated = "call ptr::null instead"] fn null() -> *mut T { null_mut() } #[inline] - fn is_null(&self) -> bool { *self == RawPtr::null() } + #[stable] + fn is_null(self) -> bool { self as uint == 0 } #[inline] - fn to_uint(&self) -> uint { *self as uint } + #[deprecated = "use `as uint` instead"] + fn to_uint(self) -> uint { self as uint } #[inline] + #[stable] unsafe fn offset(self, count: int) -> *mut T { intrinsics::offset(self as *const T, count) as *mut T } #[inline] + #[unstable = "return value does not necessarily convey all possible \ + information"] unsafe fn as_ref<'a>(&self) -> Option<&'a T> { if self.is_null() { None @@ -339,8 +364,11 @@ impl<T> RawPtr<T> for *mut T { } } -impl<T> RawMutPtr<T> for *mut T { +#[stable] +impl<T> MutPtrExt<T> for *mut T { #[inline] + #[unstable = "return value does not necessarily convey all possible \ + information"] unsafe fn as_mut<'a>(&self) -> Option<&'a mut T> { if self.is_null() { None @@ -510,28 +538,33 @@ impl<T> PartialOrd for *mut T { /// raw `*mut T` (which conveys no particular ownership semantics). /// Useful for building abstractions like `Vec<T>` or `Box<T>`, which /// internally use raw pointers to manage the memory that they own. +#[unstable = "recently added to this module"] pub struct Unique<T>(pub *mut T); /// `Unique` pointers are `Send` if `T` is `Send` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. +#[unstable = "recently added to this module"] unsafe impl<T:Send> Send for Unique<T> { } /// `Unique` pointers are `Sync` if `T` is `Sync` because the data they /// reference is unaliased. Note that this aliasing invariant is /// unenforced by the type system; the abstraction using the /// `Unique` must enforce it. +#[unstable = "recently added to this module"] unsafe impl<T:Sync> Sync for Unique<T> { } impl<T> Unique<T> { /// Returns a null Unique. + #[unstable = "recently added to this module"] pub fn null() -> Unique<T> { - Unique(RawPtr::null()) + Unique(null_mut()) } /// Return an (unsafe) pointer into the memory owned by `self`. + #[unstable = "recently added to this module"] pub unsafe fn offset(self, offset: int) -> *mut T { - (self.0 as *const T).offset(offset) as *mut T + self.0.offset(offset) } } |
