summaryrefslogtreecommitdiff
path: root/rust/alloc/vec/mod.rs
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2024-01-12 00:05:41 +0300
committerLinus Torvalds <torvalds@linux-foundation.org>2024-01-12 00:05:41 +0300
commitb6964fe2398cb8939c3d4fc6960a6be93687305d (patch)
treea27840783749295a28a32c8a9f43e254173e5324 /rust/alloc/vec/mod.rs
parent5bad490858c3ebdbb47e622e8f9049f828d2abba (diff)
parent711cbfc717650532624ca9f56fbaf191bed56e67 (diff)
downloadlinux-b6964fe2398cb8939c3d4fc6960a6be93687305d.tar.xz
Merge tag 'rust-6.8' of https://github.com/Rust-for-Linux/linux
Pull Rust updates from Miguel Ojeda: "Another routine one in terms of features. In terms of lines, this time the 'alloc' version upgrade is less prominent, given that it was fairly small (and we did not have two upgrades) Toolchain and infrastructure: - Upgrade to Rust 1.74.1 The patch release includes a fix for an ICE that the Apple AGX GPU driver was hitting - Support 'srctree'-relative links in Rust code documentation - Automate part of the manual constants handling (i.e. the ones not recognised by 'bindgen') - Suppress searching builtin sysroot to avoid confusion with installed sysroots, needed for the to-be-merged arm64 support which uses a builtin target - Ignore '__preserve_most' functions for 'bindgen' - Reduce header inclusion bloat in exports 'kernel' crate: - Implement 'Debug' for 'CString' - Make 'CondVar::wait()' an uninterruptible wait 'macros' crate: - Update 'paste!' to accept string literals - Improve '#[vtable]' documentation Documentation: - Add testing section (KUnit and 'rusttest' target) - Remove 'CC=clang' mentions - Clarify that 'rustup override' applies to build directory" * tag 'rust-6.8' of https://github.com/Rust-for-Linux/linux: docs: rust: Clarify that 'rustup override' applies to build directory docs: rust: Add rusttest info docs: rust: remove `CC=clang` mentions rust: support `srctree`-relative links rust: sync: Makes `CondVar::wait()` an uninterruptible wait rust: upgrade to Rust 1.74.1 rust: Suppress searching builtin sysroot rust: macros: improve `#[vtable]` documentation rust: macros: update 'paste!' macro to accept string literals rust: bindings: rename const binding using sed rust: Ignore preserve-most functions rust: replace <linux/module.h> with <linux/export.h> in rust/exports.c rust: kernel: str: Implement Debug for CString
Diffstat (limited to 'rust/alloc/vec/mod.rs')
-rw-r--r--rust/alloc/vec/mod.rs87
1 files changed, 85 insertions, 2 deletions
diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs
index 209a88cfe598..41ca71805ef0 100644
--- a/rust/alloc/vec/mod.rs
+++ b/rust/alloc/vec/mod.rs
@@ -1228,8 +1228,8 @@ impl<T, A: Allocator> Vec<T, A> {
/// Shortens the vector, keeping the first `len` elements and dropping
/// the rest.
///
- /// If `len` is greater than the vector's current length, this has no
- /// effect.
+ /// If `len` is greater or equal to the vector's current length, this has
+ /// no effect.
///
/// The [`drain`] method can emulate `truncate`, but causes the excess
/// elements to be returned instead of dropped.
@@ -1336,6 +1336,15 @@ impl<T, A: Allocator> Vec<T, A> {
/// is never written to (except inside an `UnsafeCell`) using this pointer or any pointer
/// derived from it. If you need to mutate the contents of the slice, use [`as_mut_ptr`].
///
+ /// This method guarantees that for the purpose of the aliasing model, this method
+ /// does not materialize a reference to the underlying slice, and thus the returned pointer
+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+ /// Note that calling other methods that materialize mutable references to the slice,
+ /// or mutable references to specific elements you are planning on accessing through this pointer,
+ /// as well as writing to those elements, may still invalidate this pointer.
+ /// See the second example below for how this guarantee can be used.
+ ///
+ ///
/// # Examples
///
/// ```
@@ -1349,8 +1358,25 @@ impl<T, A: Allocator> Vec<T, A> {
/// }
/// ```
///
+ /// Due to the aliasing guarantee, the following code is legal:
+ ///
+ /// ```rust
+ /// unsafe {
+ /// let mut v = vec![0, 1, 2];
+ /// let ptr1 = v.as_ptr();
+ /// let _ = ptr1.read();
+ /// let ptr2 = v.as_mut_ptr().offset(2);
+ /// ptr2.write(2);
+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`
+ /// // because it mutated a different element:
+ /// let _ = ptr1.read();
+ /// }
+ /// ```
+ ///
/// [`as_mut_ptr`]: Vec::as_mut_ptr
+ /// [`as_ptr`]: Vec::as_ptr
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
#[inline]
pub fn as_ptr(&self) -> *const T {
// We shadow the slice method of the same name to avoid going through
@@ -1366,6 +1392,15 @@ impl<T, A: Allocator> Vec<T, A> {
/// Modifying the vector may cause its buffer to be reallocated,
/// which would also make any pointers to it invalid.
///
+ /// This method guarantees that for the purpose of the aliasing model, this method
+ /// does not materialize a reference to the underlying slice, and thus the returned pointer
+ /// will remain valid when mixed with other calls to [`as_ptr`] and [`as_mut_ptr`].
+ /// Note that calling other methods that materialize references to the slice,
+ /// or references to specific elements you are planning on accessing through this pointer,
+ /// may still invalidate this pointer.
+ /// See the second example below for how this guarantee can be used.
+ ///
+ ///
/// # Examples
///
/// ```
@@ -1383,7 +1418,25 @@ impl<T, A: Allocator> Vec<T, A> {
/// }
/// assert_eq!(&*x, &[0, 1, 2, 3]);
/// ```
+ ///
+ /// Due to the aliasing guarantee, the following code is legal:
+ ///
+ /// ```rust
+ /// unsafe {
+ /// let mut v = vec![0];
+ /// let ptr1 = v.as_mut_ptr();
+ /// ptr1.write(1);
+ /// let ptr2 = v.as_mut_ptr();
+ /// ptr2.write(2);
+ /// // Notably, the write to `ptr2` did *not* invalidate `ptr1`:
+ /// ptr1.write(3);
+ /// }
+ /// ```
+ ///
+ /// [`as_mut_ptr`]: Vec::as_mut_ptr
+ /// [`as_ptr`]: Vec::as_ptr
#[stable(feature = "vec_as_ptr", since = "1.37.0")]
+ #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
#[inline]
pub fn as_mut_ptr(&mut self) -> *mut T {
// We shadow the slice method of the same name to avoid going through
@@ -3404,6 +3457,36 @@ impl<T: Clone> From<&mut [T]> for Vec<T> {
}
#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "vec_from_array_ref", since = "1.74.0")]
+impl<T: Clone, const N: usize> From<&[T; N]> for Vec<T> {
+ /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(Vec::from(&[1, 2, 3]), vec![1, 2, 3]);
+ /// ```
+ fn from(s: &[T; N]) -> Vec<T> {
+ Self::from(s.as_slice())
+ }
+}
+
+#[cfg(not(no_global_oom_handling))]
+#[stable(feature = "vec_from_array_ref", since = "1.74.0")]
+impl<T: Clone, const N: usize> From<&mut [T; N]> for Vec<T> {
+ /// Allocate a `Vec<T>` and fill it by cloning `s`'s items.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]);
+ /// ```
+ fn from(s: &mut [T; N]) -> Vec<T> {
+ Self::from(s.as_mut_slice())
+ }
+}
+
+#[cfg(not(no_global_oom_handling))]
#[stable(feature = "vec_from_array", since = "1.44.0")]
impl<T, const N: usize> From<[T; N]> for Vec<T> {
/// Allocate a `Vec<T>` and move `s`'s items into it.