diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2024-01-12 00:05:41 +0300 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2024-01-12 00:05:41 +0300 |
commit | b6964fe2398cb8939c3d4fc6960a6be93687305d (patch) | |
tree | a27840783749295a28a32c8a9f43e254173e5324 /rust/alloc/vec/mod.rs | |
parent | 5bad490858c3ebdbb47e622e8f9049f828d2abba (diff) | |
parent | 711cbfc717650532624ca9f56fbaf191bed56e67 (diff) | |
download | linux-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.rs | 87 |
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. |