Rollup merge of #22729 - alexcrichton:ptr-stabilization, r=aturon

Specifically, the following actions were takend:

* The `copy_memory` and `copy_nonoverlapping_memory` functions
  to drop the `_memory` suffix (as it's implied by the functionality). Both
  functions are now marked as `#[stable]`.
* The `set_memory` function was renamed to `write_bytes` and is now stable.
* The `zero_memory` function is now deprecated in favor of `write_bytes`
  directly.
* The `Unique` pointer type is now behind its own feature gate called `unique`
  to facilitate future stabilization.

[breaking-change]
This commit is contained in:
Manish Goregaokar
2015-02-25 10:29:46 +05:30
15 changed files with 126 additions and 122 deletions

View File

@@ -293,7 +293,7 @@ extern "rust-intrinsic" {
/// }
/// }
/// ```
#[unstable(feature = "core")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
/// Copies `count * size_of<T>` bytes from `src` to `dst`. The source
@@ -323,13 +323,12 @@ extern "rust-intrinsic" {
/// }
/// ```
///
#[unstable(feature = "core")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
/// Invokes memset on the specified pointer, setting `count * size_of::<T>()`
/// bytes of memory starting at `dst` to `c`.
#[unstable(feature = "core",
reason = "uncertain about naming and semantics")]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
/// Equivalent to the appropriate `llvm.memcpy.p0i8.0i8.*` intrinsic, with

View File

@@ -203,9 +203,9 @@ pub fn swap<T>(x: &mut T, y: &mut T) {
let mut t: T = uninitialized();
// 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);
ptr::copy_nonoverlapping(&mut t, &*x, 1);
ptr::copy_nonoverlapping(x, &*y, 1);
ptr::copy_nonoverlapping(y, &t, 1);
// y and t now point to the same thing, but we need to completely forget `t`
// because it's no longer relevant.

View File

@@ -101,16 +101,28 @@ use cmp::Ordering::{self, Less, Equal, Greater};
// FIXME #19649: intrinsic docs don't render, so these have no docs :(
#[unstable(feature = "core")]
pub use intrinsics::copy_nonoverlapping_memory;
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::copy_nonoverlapping_memory as copy_nonoverlapping;
#[unstable(feature = "core")]
pub use intrinsics::copy_memory;
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::copy_memory as copy;
#[unstable(feature = "core",
reason = "uncertain about naming and semantics")]
pub use intrinsics::set_memory;
#[stable(feature = "rust1", since = "1.0.0")]
pub use intrinsics::set_memory as write_bytes;
extern "rust-intrinsic" {
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0", reason = "renamed to `copy_nonoverlapping`")]
pub fn copy_nonoverlapping_memory<T>(dst: *mut T, src: *const T, count: usize);
#[unstable(feature = "core")]
#[deprecated(since = "1.0.0", reason = "renamed to `copy`")]
pub fn copy_memory<T>(dst: *mut T, src: *const T, count: usize);
#[unstable(feature = "core",
reason = "uncertain about naming and semantics")]
#[deprecated(since = "1.0.0", reason = "renamed to `write_bytes`")]
pub fn set_memory<T>(dst: *mut T, val: u8, count: usize);
}
/// Creates a null raw pointer.
///
@@ -150,8 +162,9 @@ pub fn null_mut<T>() -> *mut T { 0 as *mut T }
#[inline]
#[unstable(feature = "core",
reason = "may play a larger role in std::ptr future extensions")]
#[deprecated(since = "1.0.0", reason = "use `write_bytes` instead")]
pub unsafe fn zero_memory<T>(dst: *mut T, count: usize) {
set_memory(dst, 0, count);
write_bytes(dst, 0, count);
}
/// Swaps the values at two mutable locations of the same type, without
@@ -169,9 +182,9 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
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);
copy_nonoverlapping(t, &*x, 1);
copy(x, &*y, 1); // `x` and `y` may overlap
copy_nonoverlapping(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.
@@ -207,7 +220,7 @@ pub unsafe fn replace<T>(dest: *mut T, mut src: T) -> T {
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn read<T>(src: *const T) -> T {
let mut tmp: T = mem::uninitialized();
copy_nonoverlapping_memory(&mut tmp, src, 1);
copy_nonoverlapping(&mut tmp, src, 1);
tmp
}
@@ -224,7 +237,7 @@ pub unsafe fn read_and_zero<T>(dest: *mut T) -> T {
let tmp = read(&*dest);
// Now zero out `dest`:
zero_memory(dest, 1);
write_bytes(dest, 0, 1);
tmp
}
@@ -248,9 +261,9 @@ pub unsafe fn write<T>(dst: *mut T, src: T) {
/// Methods on raw pointers
#[stable(feature = "rust1", since = "1.0.0")]
pub trait PtrExt: Sized {
pub trait PtrExt {
/// The type which is being pointed at
type Target;
type Target: ?Sized;
/// Returns true if the pointer is null.
#[stable(feature = "rust1", since = "1.0.0")]
@@ -279,14 +292,14 @@ pub trait PtrExt: Sized {
/// Otherwise `offset` invokes Undefined Behaviour, regardless of whether
/// the pointer is used.
#[stable(feature = "rust1", since = "1.0.0")]
unsafe fn offset(self, count: isize) -> Self;
unsafe fn offset(self, count: isize) -> Self where Self::Target: Sized;
}
/// Methods on mutable raw pointers
#[stable(feature = "rust1", since = "1.0.0")]
pub trait MutPtrExt {
/// The type which is being pointed at
type Target;
type Target: ?Sized;
/// Returns `None` if the pointer is null, or else returns a mutable
/// reference to the value wrapped in `Some`.
@@ -302,7 +315,7 @@ pub trait MutPtrExt {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PtrExt for *const T {
impl<T: ?Sized> PtrExt for *const T {
type Target = T;
#[inline]
@@ -311,7 +324,7 @@ impl<T> PtrExt for *const T {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
unsafe fn offset(self, count: isize) -> *const T {
unsafe fn offset(self, count: isize) -> *const T where T: Sized {
intrinsics::offset(self, count)
}
@@ -329,7 +342,7 @@ impl<T> PtrExt for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PtrExt for *mut T {
impl<T: ?Sized> PtrExt for *mut T {
type Target = T;
#[inline]
@@ -338,7 +351,7 @@ impl<T> PtrExt for *mut T {
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
unsafe fn offset(self, count: isize) -> *mut T {
unsafe fn offset(self, count: isize) -> *mut T where T: Sized {
intrinsics::offset(self, count) as *mut T
}
@@ -356,7 +369,7 @@ impl<T> PtrExt for *mut T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> MutPtrExt for *mut T {
impl<T: ?Sized> MutPtrExt for *mut T {
type Target = T;
#[inline]
@@ -374,33 +387,25 @@ impl<T> MutPtrExt for *mut T {
// Equality for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialEq for *const T {
impl<T: ?Sized> PartialEq for *const T {
#[inline]
fn eq(&self, other: &*const T) -> bool {
*self == *other
}
#[inline]
fn ne(&self, other: &*const T) -> bool { !self.eq(other) }
fn eq(&self, other: &*const T) -> bool { *self == *other }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Eq for *const T {}
impl<T: ?Sized> Eq for *const T {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialEq for *mut T {
impl<T: ?Sized> PartialEq for *mut T {
#[inline]
fn eq(&self, other: &*mut T) -> bool {
*self == *other
}
#[inline]
fn ne(&self, other: &*mut T) -> bool { !self.eq(other) }
fn eq(&self, other: &*mut T) -> bool { *self == *other }
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Eq for *mut T {}
impl<T: ?Sized> Eq for *mut T {}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for *const T {
impl<T: ?Sized> Clone for *const T {
#[inline]
fn clone(&self) -> *const T {
*self
@@ -408,7 +413,7 @@ impl<T> Clone for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Clone for *mut T {
impl<T: ?Sized> Clone for *mut T {
#[inline]
fn clone(&self) -> *mut T {
*self
@@ -452,7 +457,7 @@ mod externfnpointers {
// Comparison for pointers
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Ord for *const T {
impl<T: ?Sized> Ord for *const T {
#[inline]
fn cmp(&self, other: &*const T) -> Ordering {
if self < other {
@@ -466,7 +471,7 @@ impl<T> Ord for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialOrd for *const T {
impl<T: ?Sized> PartialOrd for *const T {
#[inline]
fn partial_cmp(&self, other: &*const T) -> Option<Ordering> {
Some(self.cmp(other))
@@ -486,7 +491,7 @@ impl<T> PartialOrd for *const T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> Ord for *mut T {
impl<T: ?Sized> Ord for *mut T {
#[inline]
fn cmp(&self, other: &*mut T) -> Ordering {
if self < other {
@@ -500,7 +505,7 @@ impl<T> Ord for *mut T {
}
#[stable(feature = "rust1", since = "1.0.0")]
impl<T> PartialOrd for *mut T {
impl<T: ?Sized> PartialOrd for *mut T {
#[inline]
fn partial_cmp(&self, other: &*mut T) -> Option<Ordering> {
Some(self.cmp(other))
@@ -527,8 +532,8 @@ impl<T> PartialOrd for *mut T {
/// modified without a unique path to the `Unique` reference. Useful
/// for building abstractions like `Vec<T>` or `Box<T>`, which
/// internally use raw pointers to manage the memory that they own.
#[unstable(feature = "core", reason = "recently added to this module")]
pub struct Unique<T:?Sized> {
#[unstable(feature = "unique")]
pub struct Unique<T: ?Sized> {
pointer: NonZero<*const T>,
_marker: PhantomData<T>,
}
@@ -537,39 +542,37 @@ pub struct Unique<T:?Sized> {
/// reference is unaliased. Note that this aliasing invariant is
/// unenforced by the type system; the abstraction using the
/// `Unique` must enforce it.
#[unstable(feature = "core", reason = "recently added to this module")]
#[unstable(feature = "unique")]
unsafe impl<T: Send + ?Sized> 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(feature = "core", reason = "recently added to this module")]
#[unstable(feature = "unique")]
unsafe impl<T: Sync + ?Sized> Sync for Unique<T> { }
impl<T:?Sized> Unique<T> {
impl<T: ?Sized> Unique<T> {
/// Create a new `Unique`.
#[unstable(feature = "core",
reason = "recently added to this module")]
#[unstable(feature = "unique")]
pub unsafe fn new(ptr: *mut T) -> Unique<T> {
Unique { pointer: NonZero::new(ptr as *const T), _marker: PhantomData }
}
/// Dereference the content.
#[unstable(feature = "core",
reason = "recently added to this module")]
#[unstable(feature = "unique")]
pub unsafe fn get(&self) -> &T {
&**self.pointer
}
/// Mutably dereference the content.
#[unstable(feature = "core",
reason = "recently added to this module")]
#[unstable(feature = "unique")]
pub unsafe fn get_mut(&mut self) -> &mut T {
&mut ***self
}
}
#[unstable(feature = "unique")]
impl<T:?Sized> Deref for Unique<T> {
type Target = *mut T;

View File

@@ -1500,7 +1500,7 @@ pub mod bytes {
impl MutableByteVector for [u8] {
#[inline]
fn set_memory(&mut self, value: u8) {
unsafe { ptr::set_memory(self.as_mut_ptr(), value, self.len()) };
unsafe { ptr::write_bytes(self.as_mut_ptr(), value, self.len()) };
}
}
@@ -1514,9 +1514,9 @@ pub mod bytes {
// `dst` is unaliasable, so we know statically it doesn't overlap
// with `src`.
unsafe {
ptr::copy_nonoverlapping_memory(dst.as_mut_ptr(),
src.as_ptr(),
len_src);
ptr::copy_nonoverlapping(dst.as_mut_ptr(),
src.as_ptr(),
len_src);
}
}
}