From 4ed469c4831f00ea9afec5e7becd56be018df45e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 31 Aug 2018 09:54:37 +0200 Subject: [PATCH] turn ptr type method docs into links to docs of free functions, to avoid duplication and inconsistency --- src/libcore/ptr.rs | 477 +++++---------------------------------------- 1 file changed, 44 insertions(+), 433 deletions(-) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 9d9b6e4e6f8..f112a96ea15 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -1401,29 +1401,9 @@ impl *const T { /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// - /// # Safety + /// See [`ptr::read`] for safety concerns and examples. /// - /// Beyond accepting a raw pointer, this is unsafe because it semantically - /// moves the value out of `self` without preventing further usage of `self`. - /// If `T` is not `Copy`, then care must be taken to ensure that the value at - /// `self` is not used before the data is overwritten again (e.g. with `write`, - /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use - /// because it will attempt to drop the value previously at `*self`. - /// - /// The pointer must be aligned; use `read_unaligned` if that is not the case. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let x = 12; - /// let y = &x as *const i32; - /// - /// unsafe { - /// assert_eq!(y.read(), 12); - /// } - /// ``` + /// [`ptr::read`]: ./ptr/fn.read.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read(self) -> T @@ -1439,47 +1419,9 @@ impl *const T { /// to not be elided or reordered by the compiler across other volatile /// operations. /// - /// # Notes + /// See [`ptr::read_volatile`] for safety concerns and examples. /// - /// Rust does not currently have a rigorously and formally defined memory model, - /// so the precise semantics of what "volatile" means here is subject to change - /// over time. That being said, the semantics will almost always end up pretty - /// similar to [C11's definition of volatile][c11]. - /// - /// The compiler shouldn't change the relative order or number of volatile - /// memory operations. However, volatile memory operations on zero-sized types - /// (e.g. if a zero-sized type is passed to `read_volatile`) are no-ops - /// and may be ignored. - /// - /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf - /// - /// # Safety - /// - /// Beyond accepting a raw pointer, this is unsafe because it semantically - /// moves the value out of `self` without preventing further usage of `self`. - /// If `T` is not `Copy`, then care must be taken to ensure that the value at - /// `self` is not used before the data is overwritten again (e.g. with `write`, - /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use - /// because it will attempt to drop the value previously at `*self`. - /// - /// Just like in C, whether an operation is volatile has no bearing whatsoever - /// on questions involving concurrent access from multiple threads. Volatile - /// accesses behave exactly like non-atomic accesses in that regard. In particular, - /// a race between a `read_volatile` and any write operation to the same location - /// is undefined behavior. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let x = 12; - /// let y = &x as *const i32; - /// - /// unsafe { - /// assert_eq!(y.read_volatile(), 12); - /// } - /// ``` + /// [`ptr::read_volatile`]: ./ptr/fn.read_volatile.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_volatile(self) -> T @@ -1493,27 +1435,9 @@ impl *const T { /// /// Unlike `read`, the pointer may be unaligned. /// - /// # Safety + /// See [`ptr::read_unaligned`] for safety concerns and examples. /// - /// Beyond accepting a raw pointer, this is unsafe because it semantically - /// moves the value out of `self` without preventing further usage of `self`. - /// If `T` is not `Copy`, then care must be taken to ensure that the value at - /// `self` is not used before the data is overwritten again (e.g. with `write`, - /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use - /// because it will attempt to drop the value previously at `*self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let x = 12; - /// let y = &x as *const i32; - /// - /// unsafe { - /// assert_eq!(y.read_unaligned(), 12); - /// } - /// ``` + /// [`ptr::read_unaligned`]: ./ptr/fn.read_unaligned.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_unaligned(self) -> T @@ -1525,30 +1449,11 @@ impl *const T { /// Copies `count * size_of` bytes from `self` to `dest`. The source /// and destination may overlap. /// - /// NOTE: this has the *same* argument order as `ptr::copy`. + /// NOTE: this has the *same* argument order as [`ptr::copy`]. /// - /// This is semantically equivalent to C's `memmove`. + /// See [`ptr::copy`] for safety concerns and examples. /// - /// # Safety - /// - /// Care must be taken with the ownership of `self` and `dest`. - /// This method semantically moves the values of `self` into `dest`. - /// However it does not drop the contents of `dest`, or prevent the contents - /// of `self` from being dropped or used. - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst = Vec::with_capacity(elts); - /// dst.set_len(elts); - /// ptr.copy_to(dst.as_mut_ptr(), elts); - /// dst - /// } - /// ``` + /// [`ptr::copy`]: ./ptr/fn.copy.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to(self, dest: *mut T, count: usize) @@ -1560,32 +1465,11 @@ impl *const T { /// Copies `count * size_of` bytes from `self` to `dest`. The source /// and destination may *not* overlap. /// - /// NOTE: this has the *same* argument order as `ptr::copy_nonoverlapping`. + /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`]. /// - /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. + /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// - /// # Safety - /// - /// Beyond requiring that the program must be allowed to access both regions - /// of memory, it is Undefined Behavior for source and destination to - /// overlap. Care must also be taken with the ownership of `self` and - /// `self`. This method semantically moves the values of `self` into `dest`. - /// However it does not drop the contents of `dest`, or prevent the contents - /// of `self` from being dropped or used. - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst = Vec::with_capacity(elts); - /// dst.set_len(elts); - /// ptr.copy_to_nonoverlapping(dst.as_mut_ptr(), elts); - /// dst - /// } - /// ``` + /// [`ptr::copy_nonoverlapping`]: ./ptr/fn.copy_nonoverlapping.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) @@ -2155,29 +2039,9 @@ impl *mut T { /// Reads the value from `self` without moving it. This leaves the /// memory in `self` unchanged. /// - /// # Safety + /// See [`ptr::read`] for safety concerns and examples. /// - /// Beyond accepting a raw pointer, this is unsafe because it semantically - /// moves the value out of `self` without preventing further usage of `self`. - /// If `T` is not `Copy`, then care must be taken to ensure that the value at - /// `self` is not used before the data is overwritten again (e.g. with `write`, - /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use - /// because it will attempt to drop the value previously at `*self`. - /// - /// The pointer must be aligned; use `read_unaligned` if that is not the case. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let x = 12; - /// let y = &x as *const i32; - /// - /// unsafe { - /// assert_eq!(y.read(), 12); - /// } - /// ``` + /// [`ptr::read`]: ./ptr/fn.read.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read(self) -> T @@ -2193,47 +2057,9 @@ impl *mut T { /// to not be elided or reordered by the compiler across other volatile /// operations. /// - /// # Notes + /// See [`ptr::read_volatile`] for safety concerns and examples. /// - /// Rust does not currently have a rigorously and formally defined memory model, - /// so the precise semantics of what "volatile" means here is subject to change - /// over time. That being said, the semantics will almost always end up pretty - /// similar to [C11's definition of volatile][c11]. - /// - /// The compiler shouldn't change the relative order or number of volatile - /// memory operations. However, volatile memory operations on zero-sized types - /// (e.g. if a zero-sized type is passed to `read_volatile`) are no-ops - /// and may be ignored. - /// - /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf - /// - /// # Safety - /// - /// Beyond accepting a raw pointer, this is unsafe because it semantically - /// moves the value out of `self` without preventing further usage of `self`. - /// If `T` is not `Copy`, then care must be taken to ensure that the value at - /// `self` is not used before the data is overwritten again (e.g. with `write`, - /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use - /// because it will attempt to drop the value previously at `*self`. - /// - /// Just like in C, whether an operation is volatile has no bearing whatsoever - /// on questions involving concurrent access from multiple threads. Volatile - /// accesses behave exactly like non-atomic accesses in that regard. In particular, - /// a race between a `read_volatile` and any write operation to the same location - /// is undefined behavior. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let x = 12; - /// let y = &x as *const i32; - /// - /// unsafe { - /// assert_eq!(y.read_volatile(), 12); - /// } - /// ``` + /// [`ptr::read_volatile`]: ./ptr/fn.read_volatile.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_volatile(self) -> T @@ -2247,27 +2073,9 @@ impl *mut T { /// /// Unlike `read`, the pointer may be unaligned. /// - /// # Safety + /// See [`ptr::read_unaligned`] for safety concerns and examples. /// - /// Beyond accepting a raw pointer, this is unsafe because it semantically - /// moves the value out of `self` without preventing further usage of `self`. - /// If `T` is not `Copy`, then care must be taken to ensure that the value at - /// `self` is not used before the data is overwritten again (e.g. with `write`, - /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use - /// because it will attempt to drop the value previously at `*self`. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let x = 12; - /// let y = &x as *const i32; - /// - /// unsafe { - /// assert_eq!(y.read_unaligned(), 12); - /// } - /// ``` + /// [`ptr::read_unaligned`]: ./ptr/fn.read_unaligned.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn read_unaligned(self) -> T @@ -2279,30 +2087,11 @@ impl *mut T { /// Copies `count * size_of` bytes from `self` to `dest`. The source /// and destination may overlap. /// - /// NOTE: this has the *same* argument order as `ptr::copy`. + /// NOTE: this has the *same* argument order as [`ptr::copy`]. /// - /// This is semantically equivalent to C's `memmove`. + /// See [`ptr::copy`] for safety concerns and examples. /// - /// # Safety - /// - /// Care must be taken with the ownership of `self` and `dest`. - /// This method semantically moves the values of `self` into `dest`. - /// However it does not drop the contents of `self`, or prevent the contents - /// of `dest` from being dropped or used. - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst = Vec::with_capacity(elts); - /// dst.set_len(elts); - /// ptr.copy_to(dst.as_mut_ptr(), elts); - /// dst - /// } - /// ``` + /// [`ptr::copy`]: ./ptr/fn.copy.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to(self, dest: *mut T, count: usize) @@ -2314,32 +2103,11 @@ impl *mut T { /// Copies `count * size_of` bytes from `self` to `dest`. The source /// and destination may *not* overlap. /// - /// NOTE: this has the *same* argument order as `ptr::copy_nonoverlapping`. + /// NOTE: this has the *same* argument order as [`ptr::copy_nonoverlapping`]. /// - /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. + /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// - /// # Safety - /// - /// Beyond requiring that the program must be allowed to access both regions - /// of memory, it is Undefined Behavior for source and destination to - /// overlap. Care must also be taken with the ownership of `self` and - /// `self`. This method semantically moves the values of `self` into `dest`. - /// However it does not drop the contents of `dest`, or prevent the contents - /// of `self` from being dropped or used. - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst = Vec::with_capacity(elts); - /// dst.set_len(elts); - /// ptr.copy_to_nonoverlapping(dst.as_mut_ptr(), elts); - /// dst - /// } - /// ``` + /// [`ptr::copy_nonoverlapping`]: ./ptr/fn.copy_nonoverlapping.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_to_nonoverlapping(self, dest: *mut T, count: usize) @@ -2351,30 +2119,11 @@ impl *mut T { /// Copies `count * size_of` bytes from `src` to `self`. The source /// and destination may overlap. /// - /// NOTE: this has the *opposite* argument order of `ptr::copy`. + /// NOTE: this has the *opposite* argument order of [`ptr::copy`]. /// - /// This is semantically equivalent to C's `memmove`. + /// See [`ptr::copy`] for safety concerns and examples. /// - /// # Safety - /// - /// Care must be taken with the ownership of `src` and `self`. - /// This method semantically moves the values of `src` into `self`. - /// However it does not drop the contents of `self`, or prevent the contents - /// of `src` from being dropped or used. - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst: Vec = Vec::with_capacity(elts); - /// dst.set_len(elts); - /// dst.as_mut_ptr().copy_from(ptr, elts); - /// dst - /// } - /// ``` + /// [`ptr::copy`]: ./ptr/fn.copy.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_from(self, src: *const T, count: usize) @@ -2386,32 +2135,11 @@ impl *mut T { /// Copies `count * size_of` bytes from `src` to `self`. The source /// and destination may *not* overlap. /// - /// NOTE: this has the *opposite* argument order of `ptr::copy_nonoverlapping`. + /// NOTE: this has the *opposite* argument order of [`ptr::copy_nonoverlapping`]. /// - /// `copy_nonoverlapping` is semantically equivalent to C's `memcpy`. + /// See [`ptr::copy_nonoverlapping`] for safety concerns and examples. /// - /// # Safety - /// - /// Beyond requiring that the program must be allowed to access both regions - /// of memory, it is Undefined Behavior for source and destination to - /// overlap. Care must also be taken with the ownership of `src` and - /// `self`. This method semantically moves the values of `src` into `self`. - /// However it does not drop the contents of `self`, or prevent the contents - /// of `src` from being dropped or used. - /// - /// # Examples - /// - /// Efficiently create a Rust vector from an unsafe buffer: - /// - /// ``` - /// # #[allow(dead_code)] - /// unsafe fn from_buf_raw(ptr: *const T, elts: usize) -> Vec { - /// let mut dst: Vec = Vec::with_capacity(elts); - /// dst.set_len(elts); - /// dst.as_mut_ptr().copy_from_nonoverlapping(ptr, elts); - /// dst - /// } - /// ``` + /// [`ptr::copy_nonoverlapping`]: ./ptr/fn.copy_nonoverlapping.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn copy_from_nonoverlapping(self, src: *const T, count: usize) @@ -2422,21 +2150,9 @@ impl *mut T { /// Executes the destructor (if any) of the pointed-to value. /// - /// This has two use cases: + /// See [`ptr::drop_in_place`] for safety concerns and examples. /// - /// * It is *required* to use `drop_in_place` to drop unsized types like - /// trait objects, because they can't be read out onto the stack and - /// dropped normally. - /// - /// * It is friendlier to the optimizer to do this over `ptr::read` when - /// dropping manually allocated memory (e.g. when writing Box/Rc/Vec), - /// as the compiler doesn't need to prove that it's sound to elide the - /// copy. - /// - /// # Safety - /// - /// This has all the same safety problems as `ptr::read` with respect to - /// invalid pointers, types, and double drops. + /// [`ptr::drop_in_place`]: ./ptr/fn.drop_in_place.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn drop_in_place(self) { @@ -2446,36 +2162,9 @@ impl *mut T { /// Overwrites a memory location with the given value without reading or /// dropping the old value. /// - /// # Safety + /// See [`ptr::write`] for safety concerns and examples. /// - /// This operation is marked unsafe because it writes through a raw pointer. - /// - /// It does not drop the contents of `self`. This is safe, but it could leak - /// allocations or resources, so care must be taken not to overwrite an object - /// that should be dropped. - /// - /// Additionally, it does not drop `val`. Semantically, `val` is moved into the - /// location pointed to by `self`. - /// - /// This is appropriate for initializing uninitialized memory, or overwriting - /// memory that has previously been `read` from. - /// - /// The pointer must be aligned; use `write_unaligned` if that is not the case. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let mut x = 0; - /// let y = &mut x as *mut i32; - /// let z = 12; - /// - /// unsafe { - /// y.write(z); - /// assert_eq!(y.read(), 12); - /// } - /// ``` + /// [`ptr::write`]: ./ptr/fn.write.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write(self, val: T) @@ -2487,16 +2176,9 @@ impl *mut T { /// Invokes memset on the specified pointer, setting `count * size_of::()` /// bytes of memory starting at `self` to `val`. /// - /// # Examples + /// See [`ptr::write_bytes`] for safety concerns and examples. /// - /// ``` - /// let mut vec = vec![0; 4]; - /// unsafe { - /// let vec_ptr = vec.as_mut_ptr(); - /// vec_ptr.write_bytes(b'a', 2); - /// } - /// assert_eq!(vec, [b'a', b'a', 0, 0]); - /// ``` + /// [`ptr::write_bytes`]: ./ptr/fn.write_bytes.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write_bytes(self, val: u8, count: usize) @@ -2512,51 +2194,9 @@ impl *mut T { /// to not be elided or reordered by the compiler across other volatile /// operations. /// - /// # Notes + /// See [`ptr::write_volatile`] for safety concerns and examples. /// - /// Rust does not currently have a rigorously and formally defined memory model, - /// so the precise semantics of what "volatile" means here is subject to change - /// over time. That being said, the semantics will almost always end up pretty - /// similar to [C11's definition of volatile][c11]. - /// - /// The compiler shouldn't change the relative order or number of volatile - /// memory operations. However, volatile memory operations on zero-sized types - /// (e.g. if a zero-sized type is passed to `write_volatile`) are no-ops - /// and may be ignored. - /// - /// [c11]: http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1570.pdf - /// - /// # Safety - /// - /// This operation is marked unsafe because it accepts a raw pointer. - /// - /// It does not drop the contents of `self`. This is safe, but it 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 overwriting - /// memory that has previously been `read` from. - /// - /// Just like in C, whether an operation is volatile has no bearing whatsoever - /// on questions involving concurrent access from multiple threads. Volatile - /// accesses behave exactly like non-atomic accesses in that regard. In particular, - /// a race between a `write_volatile` and any other operation (reading or writing) - /// on the same location is undefined behavior. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let mut x = 0; - /// let y = &mut x as *mut i32; - /// let z = 12; - /// - /// unsafe { - /// y.write_volatile(z); - /// assert_eq!(y.read_volatile(), 12); - /// } - /// ``` + /// [`ptr::write_volatile`]: ./ptr/fn.write_volatile.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write_volatile(self, val: T) @@ -2570,34 +2210,9 @@ impl *mut T { /// /// Unlike `write`, the pointer may be unaligned. /// - /// # Safety + /// See [`ptr::write_unaligned`] for safety concerns and examples. /// - /// This operation is marked unsafe because it writes through a raw pointer. - /// - /// It does not drop the contents of `self`. This is safe, but it could leak - /// allocations or resources, so care must be taken not to overwrite an object - /// that should be dropped. - /// - /// Additionally, it does not drop `self`. Semantically, `self` is moved into the - /// location pointed to by `val`. - /// - /// This is appropriate for initializing uninitialized memory, or overwriting - /// memory that has previously been `read` from. - /// - /// # Examples - /// - /// Basic usage: - /// - /// ``` - /// let mut x = 0; - /// let y = &mut x as *mut i32; - /// let z = 12; - /// - /// unsafe { - /// y.write_unaligned(z); - /// assert_eq!(y.read_unaligned(), 12); - /// } - /// ``` + /// [`ptr::write_unaligned`]: ./ptr/fn.write_unaligned.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn write_unaligned(self, val: T) @@ -2609,10 +2224,9 @@ impl *mut T { /// Replaces the value at `self` with `src`, returning the old /// value, without dropping either. /// - /// # Safety + /// See [`ptr::replace`] for safety concerns and examples. /// - /// This is only unsafe because it accepts a raw pointer. - /// Otherwise, this operation is identical to `mem::replace`. + /// [`ptr::replace`]: ./ptr/fn.replace.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn replace(self, src: T) -> T @@ -2625,12 +2239,9 @@ impl *mut T { /// deinitializing either. They may overlap, unlike `mem::swap` which is /// otherwise equivalent. /// - /// # Safety + /// See [`ptr::swap`] for safety concerns and examples. /// - /// This function copies the memory through the raw pointers passed to it - /// as arguments. - /// - /// Ensure that these pointers are valid before calling `swap`. + /// [`ptr::swap`]: ./ptr/fn.swap.html #[stable(feature = "pointer_methods", since = "1.26.0")] #[inline] pub unsafe fn swap(self, with: *mut T)