From 9b12bba047464dcf3a566624468cc31405cd056c Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sun, 24 Mar 2024 11:12:55 +0100 Subject: [PATCH 1/2] kernelPatches.rust_1_77-6_8,kernelPatches.rust_1_77-6_9: init --- pkgs/os-specific/linux/kernel/patches.nix | 14 + pkgs/os-specific/linux/kernel/rust-1.77.patch | 792 ++++++++++++++++++ 2 files changed, 806 insertions(+) create mode 100644 pkgs/os-specific/linux/kernel/rust-1.77.patch diff --git a/pkgs/os-specific/linux/kernel/patches.nix b/pkgs/os-specific/linux/kernel/patches.nix index bce7d7d0dcb3b..20100774395e1 100644 --- a/pkgs/os-specific/linux/kernel/patches.nix +++ b/pkgs/os-specific/linux/kernel/patches.nix @@ -79,4 +79,18 @@ hash = "sha256-q3iNBo8t4b1Rn5k5lau2myqOAqdA/9V9A+ok2jGkLdY="; }; }; + + rust_1_77-6_8 = { + name = "rust-1.77.patch"; + patch = fetchurl { + name = "rust-1.77.patch"; + url = "https://lore.kernel.org/rust-for-linux/20240217002717.57507-1-ojeda@kernel.org/raw"; + hash = "sha256-0KW9nHpJeMSDssCPXWZbrN8kxq5bA434t+XuPfwslUc="; + }; + }; + + rust_1_77-6_9 = { + name = "rust-1.77.patch"; + patch = ./rust-1.77.patch; + }; } diff --git a/pkgs/os-specific/linux/kernel/rust-1.77.patch b/pkgs/os-specific/linux/kernel/rust-1.77.patch new file mode 100644 index 0000000000000..8bd0a5e337154 --- /dev/null +++ b/pkgs/os-specific/linux/kernel/rust-1.77.patch @@ -0,0 +1,792 @@ +From d69265b7d756931b2e763a3262f22ba4100895a0 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Sat, 17 Feb 2024 01:27:17 +0100 +Subject: [PATCH] rust: upgrade to Rust 1.77.0 + +This is the next upgrade to the Rust toolchain, from 1.76.0 to 1.77.0 +(i.e. the latest) [1]. + +See the upgrade policy [2] and the comments on the first upgrade in +commit 3ed03f4da06e ("rust: upgrade to Rust 1.68.2"). + +The `offset_of` feature (single-field `offset_of!`) that we were using +got stabilized in Rust 1.77.0 [3]. + +Therefore, now the only unstable features allowed to be used outside the +`kernel` crate is `new_uninit`, though other code to be upstreamed may +increase the list. + +Please see [4] for details. + +Rust 1.77.0 merged the `unused_tuple_struct_fields` lint into `dead_code`, +thus upgrading it from `allow` to `warn` [5]. In turn, this makes `rustc` +complain about the `ThisModule`'s pointer field being never read. Thus +locally `allow` it for the moment, since we will have users later on +(e.g. Binder needs a `as_ptr` method [6]). + +Rust 1.77.0 introduces the `--check-cfg` feature [7], for which there +is a Call for Testing going on [8]. We were requested to test it and +we found it useful [9] -- we will likely enable it in the future. + +The vast majority of changes are due to our `alloc` fork being upgraded +at once. + +There are two kinds of changes to be aware of: the ones coming from +upstream, which we should follow as closely as possible, and the updates +needed in our added fallible APIs to keep them matching the newer +infallible APIs coming from upstream. + +Instead of taking a look at the diff of this patch, an alternative +approach is reviewing a diff of the changes between upstream `alloc` and +the kernel's. This allows to easily inspect the kernel additions only, +especially to check if the fallible methods we already have still match +the infallible ones in the new version coming from upstream. + +Another approach is reviewing the changes introduced in the additions in +the kernel fork between the two versions. This is useful to spot +potentially unintended changes to our additions. + +To apply these approaches, one may follow steps similar to the following +to generate a pair of patches that show the differences between upstream +Rust and the kernel (for the subset of `alloc` we use) before and after +applying this patch: + + # Get the difference with respect to the old version. + git -C rust checkout $(linux/scripts/min-tool-version.sh rustc) + git -C linux ls-tree -r --name-only HEAD -- rust/alloc | + cut -d/ -f3- | + grep -Fv README.md | + xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH + git -C linux diff --patch-with-stat --summary -R > old.patch + git -C linux restore rust/alloc + + # Apply this patch. + git -C linux am rust-upgrade.patch + + # Get the difference with respect to the new version. + git -C rust checkout $(linux/scripts/min-tool-version.sh rustc) + git -C linux ls-tree -r --name-only HEAD -- rust/alloc | + cut -d/ -f3- | + grep -Fv README.md | + xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH + git -C linux diff --patch-with-stat --summary -R > new.patch + git -C linux restore rust/alloc + +Now one may check the `new.patch` to take a look at the additions (first +approach) or at the difference between those two patches (second +approach). For the latter, a side-by-side tool is recommended. + +Link: https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1770-2024-03-21 [1] +Link: https://rust-for-linux.com/rust-version-policy [2] +Link: https://github.com/rust-lang/rust/pull/118799 [3] +Link: https://github.com/Rust-for-Linux/linux/issues/2 [4] +Link: https://github.com/rust-lang/rust/pull/118297 [5] +Link: https://lore.kernel.org/rust-for-linux/20231101-rust-binder-v1-2-08ba9197f637@google.com/#Z31rust:kernel:lib.rs [6] +Link: https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html [7] +Link: https://github.com/rust-lang/rfcs/pull/3013#issuecomment-1936648479 [8] +Link: https://github.com/rust-lang/rust/issues/82450#issuecomment-1947462977 [9] +Signed-off-by: Miguel Ojeda +Link: https://lore.kernel.org/r/20240217002717.57507-1-ojeda@kernel.org +Link: https://github.com/Rust-for-Linux/linux/commit/d69265b7d756931b2e763a3262f22ba4100895a0 +Signed-off-by: Alyssa Ross +--- + Documentation/process/changes.rst | 2 +- + rust/alloc/alloc.rs | 6 +- + rust/alloc/boxed.rs | 4 +- + rust/alloc/lib.rs | 7 +- + rust/alloc/raw_vec.rs | 13 ++-- + rust/alloc/slice.rs | 4 +- + rust/alloc/vec/into_iter.rs | 108 +++++++++++++++++++----------- + rust/alloc/vec/mod.rs | 101 +++++++++++++++++++--------- + rust/kernel/lib.rs | 3 +- + scripts/Makefile.build | 2 +- + scripts/min-tool-version.sh | 2 +- + 11 files changed, 161 insertions(+), 91 deletions(-) + +diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst +index 7ef8de58f7f892..879ee628893ae1 100644 +--- a/Documentation/process/changes.rst ++++ b/Documentation/process/changes.rst +@@ -31,7 +31,7 @@ you probably needn't concern yourself with pcmciautils. + ====================== =============== ======================================== + GNU C 5.1 gcc --version + Clang/LLVM (optional) 13.0.1 clang --version +-Rust (optional) 1.76.0 rustc --version ++Rust (optional) 1.77.0 rustc --version + bindgen (optional) 0.65.1 bindgen --version + GNU make 3.82 make --version + bash 4.2 bash --version +diff --git a/rust/alloc/alloc.rs b/rust/alloc/alloc.rs +index abb791cc23715a..b1204f87227b23 100644 +--- a/rust/alloc/alloc.rs ++++ b/rust/alloc/alloc.rs +@@ -5,7 +5,7 @@ + #![stable(feature = "alloc_module", since = "1.28.0")] + + #[cfg(not(test))] +-use core::intrinsics; ++use core::hint; + + #[cfg(not(test))] + use core::ptr::{self, NonNull}; +@@ -210,7 +210,7 @@ impl Global { + let new_size = new_layout.size(); + + // `realloc` probably checks for `new_size >= old_layout.size()` or something similar. +- intrinsics::assume(new_size >= old_layout.size()); ++ hint::assert_unchecked(new_size >= old_layout.size()); + + let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size); + let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; +@@ -301,7 +301,7 @@ unsafe impl Allocator for Global { + // SAFETY: `new_size` is non-zero. Other conditions must be upheld by the caller + new_size if old_layout.align() == new_layout.align() => unsafe { + // `realloc` probably checks for `new_size <= old_layout.size()` or something similar. +- intrinsics::assume(new_size <= old_layout.size()); ++ hint::assert_unchecked(new_size <= old_layout.size()); + + let raw_ptr = realloc(ptr.as_ptr(), old_layout, new_size); + let ptr = NonNull::new(raw_ptr).ok_or(AllocError)?; +diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs +index c93a22a5c97f14..5fc39dfeb8e7bf 100644 +--- a/rust/alloc/boxed.rs ++++ b/rust/alloc/boxed.rs +@@ -26,6 +26,7 @@ + //! Creating a recursive data structure: + //! + //! ``` ++//! ##[allow(dead_code)] + //! #[derive(Debug)] + //! enum List { + //! Cons(T, Box>), +@@ -194,8 +195,7 @@ mod thin; + #[fundamental] + #[stable(feature = "rust1", since = "1.0.0")] + // The declaration of the `Box` struct must be kept in sync with the +-// `alloc::alloc::box_free` function or ICEs will happen. See the comment +-// on `box_free` for more details. ++// compiler or ICEs will happen. + pub struct Box< + T: ?Sized, + #[unstable(feature = "allocator_api", issue = "32838")] A: Allocator = Global, +diff --git a/rust/alloc/lib.rs b/rust/alloc/lib.rs +index 36f79c07559338..39afd55ec0749e 100644 +--- a/rust/alloc/lib.rs ++++ b/rust/alloc/lib.rs +@@ -105,7 +105,6 @@ + #![feature(allocator_api)] + #![feature(array_chunks)] + #![feature(array_into_iter_constructors)] +-#![feature(array_methods)] + #![feature(array_windows)] + #![feature(ascii_char)] + #![feature(assert_matches)] +@@ -122,7 +121,6 @@ + #![feature(const_size_of_val)] + #![feature(const_waker)] + #![feature(core_intrinsics)] +-#![feature(core_panic)] + #![feature(deprecated_suggestion)] + #![feature(dispatch_from_dyn)] + #![feature(error_generic_member_access)] +@@ -132,6 +130,7 @@ + #![feature(fmt_internals)] + #![feature(fn_traits)] + #![feature(hasher_prefixfree_extras)] ++#![feature(hint_assert_unchecked)] + #![feature(inline_const)] + #![feature(inplace_iteration)] + #![feature(iter_advance_by)] +@@ -141,6 +140,8 @@ + #![feature(maybe_uninit_slice)] + #![feature(maybe_uninit_uninit_array)] + #![feature(maybe_uninit_uninit_array_transpose)] ++#![feature(non_null_convenience)] ++#![feature(panic_internals)] + #![feature(pattern)] + #![feature(ptr_internals)] + #![feature(ptr_metadata)] +@@ -149,7 +150,6 @@ + #![feature(set_ptr_value)] + #![feature(sized_type_properties)] + #![feature(slice_from_ptr_range)] +-#![feature(slice_group_by)] + #![feature(slice_ptr_get)] + #![feature(slice_ptr_len)] + #![feature(slice_range)] +@@ -182,6 +182,7 @@ + #![feature(const_ptr_write)] + #![feature(const_trait_impl)] + #![feature(const_try)] ++#![feature(decl_macro)] + #![feature(dropck_eyepatch)] + #![feature(exclusive_range_pattern)] + #![feature(fundamental)] +diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs +index 98b6abf30af6e4..1839d1c8ee7a04 100644 +--- a/rust/alloc/raw_vec.rs ++++ b/rust/alloc/raw_vec.rs +@@ -4,7 +4,7 @@ + + use core::alloc::LayoutError; + use core::cmp; +-use core::intrinsics; ++use core::hint; + use core::mem::{self, ManuallyDrop, MaybeUninit, SizedTypeProperties}; + use core::ptr::{self, NonNull, Unique}; + use core::slice; +@@ -317,7 +317,7 @@ impl RawVec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Aborts + /// +@@ -358,7 +358,7 @@ impl RawVec { + } + unsafe { + // Inform the optimizer that the reservation has succeeded or wasn't needed +- core::intrinsics::assume(!self.needs_to_grow(len, additional)); ++ hint::assert_unchecked(!self.needs_to_grow(len, additional)); + } + Ok(()) + } +@@ -381,7 +381,7 @@ impl RawVec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Aborts + /// +@@ -402,7 +402,7 @@ impl RawVec { + } + unsafe { + // Inform the optimizer that the reservation has succeeded or wasn't needed +- core::intrinsics::assume(!self.needs_to_grow(len, additional)); ++ hint::assert_unchecked(!self.needs_to_grow(len, additional)); + } + Ok(()) + } +@@ -553,7 +553,7 @@ where + debug_assert_eq!(old_layout.align(), new_layout.align()); + unsafe { + // The allocator checks for alignment equality +- intrinsics::assume(old_layout.align() == new_layout.align()); ++ hint::assert_unchecked(old_layout.align() == new_layout.align()); + alloc.grow(ptr, old_layout, new_layout) + } + } else { +@@ -591,7 +591,6 @@ fn handle_reserve(result: Result<(), TryReserveError>) { + // `> isize::MAX` bytes will surely fail. On 32-bit and 16-bit we need to add + // an extra guard for this in case we're running on a platform which can use + // all 4GB in user-space, e.g., PAE or x32. +- + #[inline] + fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> { + if usize::BITS < 64 && alloc_size > isize::MAX as usize { +diff --git a/rust/alloc/slice.rs b/rust/alloc/slice.rs +index 1181836da5f462..a36b072c95195f 100644 +--- a/rust/alloc/slice.rs ++++ b/rust/alloc/slice.rs +@@ -53,14 +53,14 @@ pub use core::slice::{from_mut, from_ref}; + pub use core::slice::{from_mut_ptr_range, from_ptr_range}; + #[stable(feature = "rust1", since = "1.0.0")] + pub use core::slice::{from_raw_parts, from_raw_parts_mut}; ++#[stable(feature = "slice_group_by", since = "1.77.0")] ++pub use core::slice::{ChunkBy, ChunkByMut}; + #[stable(feature = "rust1", since = "1.0.0")] + pub use core::slice::{Chunks, Windows}; + #[stable(feature = "chunks_exact", since = "1.31.0")] + pub use core::slice::{ChunksExact, ChunksExactMut}; + #[stable(feature = "rust1", since = "1.0.0")] + pub use core::slice::{ChunksMut, Split, SplitMut}; +-#[unstable(feature = "slice_group_by", issue = "80552")] +-pub use core::slice::{GroupBy, GroupByMut}; + #[stable(feature = "rust1", since = "1.0.0")] + pub use core::slice::{Iter, IterMut}; + #[stable(feature = "rchunks", since = "1.31.0")] +diff --git a/rust/alloc/vec/into_iter.rs b/rust/alloc/vec/into_iter.rs +index 136bfe94af6c83..0f11744c44b34c 100644 +--- a/rust/alloc/vec/into_iter.rs ++++ b/rust/alloc/vec/into_iter.rs +@@ -20,6 +20,17 @@ use core::ops::Deref; + use core::ptr::{self, NonNull}; + use core::slice::{self}; + ++macro non_null { ++ (mut $place:expr, $t:ident) => {{ ++ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block ++ unsafe { &mut *(ptr::addr_of_mut!($place) as *mut NonNull<$t>) } ++ }}, ++ ($place:expr, $t:ident) => {{ ++ #![allow(unused_unsafe)] // we're sometimes used within an unsafe block ++ unsafe { *(ptr::addr_of!($place) as *const NonNull<$t>) } ++ }}, ++} ++ + /// An iterator that moves out of a vector. + /// + /// This `struct` is created by the `into_iter` method on [`Vec`](super::Vec) +@@ -43,10 +54,12 @@ pub struct IntoIter< + // the drop impl reconstructs a RawVec from buf, cap and alloc + // to avoid dropping the allocator twice we need to wrap it into ManuallyDrop + pub(super) alloc: ManuallyDrop, +- pub(super) ptr: *const T, +- pub(super) end: *const T, // If T is a ZST, this is actually ptr+len. This encoding is picked so that +- // ptr == end is a quick test for the Iterator being empty, that works +- // for both ZST and non-ZST. ++ pub(super) ptr: NonNull, ++ /// If T is a ZST, this is actually ptr+len. This encoding is picked so that ++ /// ptr == end is a quick test for the Iterator being empty, that works ++ /// for both ZST and non-ZST. ++ /// For non-ZSTs the pointer is treated as `NonNull` ++ pub(super) end: *const T, + } + + #[stable(feature = "vec_intoiter_debug", since = "1.13.0")] +@@ -70,7 +83,7 @@ impl IntoIter { + /// ``` + #[stable(feature = "vec_into_iter_as_slice", since = "1.15.0")] + pub fn as_slice(&self) -> &[T] { +- unsafe { slice::from_raw_parts(self.ptr, self.len()) } ++ unsafe { slice::from_raw_parts(self.ptr.as_ptr(), self.len()) } + } + + /// Returns the remaining items of this iterator as a mutable slice. +@@ -99,7 +112,7 @@ impl IntoIter { + } + + fn as_raw_mut_slice(&mut self) -> *mut [T] { +- ptr::slice_from_raw_parts_mut(self.ptr as *mut T, self.len()) ++ ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), self.len()) + } + + /// Drops remaining elements and relinquishes the backing allocation. +@@ -126,7 +139,7 @@ impl IntoIter { + // this creates less assembly + self.cap = 0; + self.buf = unsafe { NonNull::new_unchecked(RawVec::NEW.ptr()) }; +- self.ptr = self.buf.as_ptr(); ++ self.ptr = self.buf; + self.end = self.buf.as_ptr(); + + // Dropping the remaining elements can panic, so this needs to be +@@ -138,9 +151,9 @@ impl IntoIter { + + /// Forgets to Drop the remaining elements while still allowing the backing allocation to be freed. + pub(crate) fn forget_remaining_elements(&mut self) { +- // For th ZST case, it is crucial that we mutate `end` here, not `ptr`. ++ // For the ZST case, it is crucial that we mutate `end` here, not `ptr`. + // `ptr` must stay aligned, while `end` may be unaligned. +- self.end = self.ptr; ++ self.end = self.ptr.as_ptr(); + } + + #[cfg(not(no_global_oom_handling))] +@@ -162,7 +175,7 @@ impl IntoIter { + // say that they're all at the beginning of the "allocation". + 0..this.len() + } else { +- this.ptr.sub_ptr(buf)..this.end.sub_ptr(buf) ++ this.ptr.sub_ptr(this.buf)..this.end.sub_ptr(buf) + }; + let cap = this.cap; + let alloc = ManuallyDrop::take(&mut this.alloc); +@@ -189,29 +202,35 @@ impl Iterator for IntoIter { + + #[inline] + fn next(&mut self) -> Option { +- if self.ptr == self.end { +- None +- } else if T::IS_ZST { +- // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by +- // reducing the `end`. +- self.end = self.end.wrapping_byte_sub(1); +- +- // Make up a value of this ZST. +- Some(unsafe { mem::zeroed() }) ++ if T::IS_ZST { ++ if self.ptr.as_ptr() == self.end as *mut _ { ++ None ++ } else { ++ // `ptr` has to stay where it is to remain aligned, so we reduce the length by 1 by ++ // reducing the `end`. ++ self.end = self.end.wrapping_byte_sub(1); ++ ++ // Make up a value of this ZST. ++ Some(unsafe { mem::zeroed() }) ++ } + } else { +- let old = self.ptr; +- self.ptr = unsafe { self.ptr.add(1) }; ++ if self.ptr == non_null!(self.end, T) { ++ None ++ } else { ++ let old = self.ptr; ++ self.ptr = unsafe { old.add(1) }; + +- Some(unsafe { ptr::read(old) }) ++ Some(unsafe { ptr::read(old.as_ptr()) }) ++ } + } + } + + #[inline] + fn size_hint(&self) -> (usize, Option) { + let exact = if T::IS_ZST { +- self.end.addr().wrapping_sub(self.ptr.addr()) ++ self.end.addr().wrapping_sub(self.ptr.as_ptr().addr()) + } else { +- unsafe { self.end.sub_ptr(self.ptr) } ++ unsafe { non_null!(self.end, T).sub_ptr(self.ptr) } + }; + (exact, Some(exact)) + } +@@ -219,7 +238,7 @@ impl Iterator for IntoIter { + #[inline] + fn advance_by(&mut self, n: usize) -> Result<(), NonZeroUsize> { + let step_size = self.len().min(n); +- let to_drop = ptr::slice_from_raw_parts_mut(self.ptr as *mut T, step_size); ++ let to_drop = ptr::slice_from_raw_parts_mut(self.ptr.as_ptr(), step_size); + if T::IS_ZST { + // See `next` for why we sub `end` here. + self.end = self.end.wrapping_byte_sub(step_size); +@@ -261,7 +280,7 @@ impl Iterator for IntoIter { + // Safety: `len` indicates that this many elements are available and we just checked that + // it fits into the array. + unsafe { +- ptr::copy_nonoverlapping(self.ptr, raw_ary.as_mut_ptr() as *mut T, len); ++ ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, len); + self.forget_remaining_elements(); + return Err(array::IntoIter::new_unchecked(raw_ary, 0..len)); + } +@@ -270,7 +289,7 @@ impl Iterator for IntoIter { + // Safety: `len` is larger than the array size. Copy a fixed amount here to fully initialize + // the array. + return unsafe { +- ptr::copy_nonoverlapping(self.ptr, raw_ary.as_mut_ptr() as *mut T, N); ++ ptr::copy_nonoverlapping(self.ptr.as_ptr(), raw_ary.as_mut_ptr() as *mut T, N); + self.ptr = self.ptr.add(N); + Ok(raw_ary.transpose().assume_init()) + }; +@@ -288,7 +307,7 @@ impl Iterator for IntoIter { + // Also note the implementation of `Self: TrustedRandomAccess` requires + // that `T: Copy` so reading elements from the buffer doesn't invalidate + // them for `Drop`. +- unsafe { if T::IS_ZST { mem::zeroed() } else { ptr::read(self.ptr.add(i)) } } ++ unsafe { if T::IS_ZST { mem::zeroed() } else { self.ptr.add(i).read() } } + } + } + +@@ -296,18 +315,25 @@ impl Iterator for IntoIter { + impl DoubleEndedIterator for IntoIter { + #[inline] + fn next_back(&mut self) -> Option { +- if self.end == self.ptr { +- None +- } else if T::IS_ZST { +- // See above for why 'ptr.offset' isn't used +- self.end = self.end.wrapping_byte_sub(1); +- +- // Make up a value of this ZST. +- Some(unsafe { mem::zeroed() }) ++ if T::IS_ZST { ++ if self.end as *mut _ == self.ptr.as_ptr() { ++ None ++ } else { ++ // See above for why 'ptr.offset' isn't used ++ self.end = self.end.wrapping_byte_sub(1); ++ ++ // Make up a value of this ZST. ++ Some(unsafe { mem::zeroed() }) ++ } + } else { +- self.end = unsafe { self.end.sub(1) }; ++ if non_null!(self.end, T) == self.ptr { ++ None ++ } else { ++ let new_end = unsafe { non_null!(self.end, T).sub(1) }; ++ *non_null!(mut self.end, T) = new_end; + +- Some(unsafe { ptr::read(self.end) }) ++ Some(unsafe { ptr::read(new_end.as_ptr()) }) ++ } + } + } + +@@ -333,7 +359,11 @@ impl DoubleEndedIterator for IntoIter { + #[stable(feature = "rust1", since = "1.0.0")] + impl ExactSizeIterator for IntoIter { + fn is_empty(&self) -> bool { +- self.ptr == self.end ++ if T::IS_ZST { ++ self.ptr.as_ptr() == self.end as *mut _ ++ } else { ++ self.ptr == non_null!(self.end, T) ++ } + } + } + +diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs +index 220fb9d6f45b3f..0be27fff4554a1 100644 +--- a/rust/alloc/vec/mod.rs ++++ b/rust/alloc/vec/mod.rs +@@ -360,7 +360,7 @@ mod spec_extend; + /// + /// `vec![x; n]`, `vec![a, b, c, d]`, and + /// [`Vec::with_capacity(n)`][`Vec::with_capacity`], will all produce a `Vec` +-/// with exactly the requested capacity. If [len] == [capacity], ++/// with at least the requested capacity. If [len] == [capacity], + /// (as is the case for the [`vec!`] macro), then a `Vec` can be converted to + /// and from a [`Box<[T]>`][owned slice] without reallocating or moving the elements. + /// +@@ -447,7 +447,7 @@ impl Vec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// +@@ -690,7 +690,7 @@ impl Vec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// +@@ -1013,7 +1013,7 @@ impl Vec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// +@@ -1043,7 +1043,7 @@ impl Vec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// +@@ -1140,8 +1140,11 @@ impl Vec { + + /// Shrinks the capacity of the vector as much as possible. + /// +- /// It will drop down as close as possible to the length but the allocator +- /// may still inform the vector that there is space for a few more elements. ++ /// The behavior of this method depends on the allocator, which may either shrink the vector ++ /// in-place or reallocate. The resulting vector might still have some excess capacity, just as ++ /// is the case for [`with_capacity`]. See [`Allocator::shrink`] for more details. ++ /// ++ /// [`with_capacity`]: Vec::with_capacity + /// + /// # Examples + /// +@@ -1191,10 +1194,10 @@ impl Vec { + + /// Converts the vector into [`Box<[T]>`][owned slice]. + /// +- /// If the vector has excess capacity, its items will be moved into a +- /// newly-allocated buffer with exactly the right capacity. ++ /// Before doing the conversion, this method discards excess capacity like [`shrink_to_fit`]. + /// + /// [owned slice]: Box ++ /// [`shrink_to_fit`]: Vec::shrink_to_fit + /// + /// # Examples + /// +@@ -2017,7 +2020,7 @@ impl Vec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// +@@ -2133,7 +2136,7 @@ impl Vec { + } else { + unsafe { + self.len -= 1; +- core::intrinsics::assume(self.len < self.capacity()); ++ core::hint::assert_unchecked(self.len < self.capacity()); + Some(ptr::read(self.as_ptr().add(self.len()))) + } + } +@@ -2143,7 +2146,7 @@ impl Vec { + /// + /// # Panics + /// +- /// Panics if the new capacity exceeds `isize::MAX` bytes. ++ /// Panics if the new capacity exceeds `isize::MAX` _bytes_. + /// + /// # Examples + /// +@@ -2315,6 +2318,12 @@ impl Vec { + /// `[at, len)`. After the call, the original vector will be left containing + /// the elements `[0, at)` with its previous capacity unchanged. + /// ++ /// - If you want to take ownership of the entire contents and capacity of ++ /// the vector, see [`mem::take`] or [`mem::replace`]. ++ /// - If you don't need the returned vector at all, see [`Vec::truncate`]. ++ /// - If you want to take ownership of an arbitrary subslice, or you don't ++ /// necessarily want to store the removed items in a vector, see [`Vec::drain`]. ++ /// + /// # Panics + /// + /// Panics if `at > len`. +@@ -2346,14 +2355,6 @@ impl Vec { + assert_failed(at, self.len()); + } + +- if at == 0 { +- // the new vector can take over the original buffer and avoid the copy +- return mem::replace( +- self, +- Vec::with_capacity_in(self.capacity(), self.allocator().clone()), +- ); +- } +- + let other_len = self.len - at; + let mut other = Vec::with_capacity_in(other_len, self.allocator().clone()); + +@@ -3027,6 +3028,50 @@ impl, A: Allocator> IndexMut for Vec { + } + } + ++/// Collects an iterator into a Vec, commonly called via [`Iterator::collect()`] ++/// ++/// # Allocation behavior ++/// ++/// In general `Vec` does not guarantee any particular growth or allocation strategy. ++/// That also applies to this trait impl. ++/// ++/// **Note:** This section covers implementation details and is therefore exempt from ++/// stability guarantees. ++/// ++/// Vec may use any or none of the following strategies, ++/// depending on the supplied iterator: ++/// ++/// * preallocate based on [`Iterator::size_hint()`] ++/// * and panic if the number of items is outside the provided lower/upper bounds ++/// * use an amortized growth strategy similar to `pushing` one item at a time ++/// * perform the iteration in-place on the original allocation backing the iterator ++/// ++/// The last case warrants some attention. It is an optimization that in many cases reduces peak memory ++/// consumption and improves cache locality. But when big, short-lived allocations are created, ++/// only a small fraction of their items get collected, no further use is made of the spare capacity ++/// and the resulting `Vec` is moved into a longer-lived structure, then this can lead to the large ++/// allocations having their lifetimes unnecessarily extended which can result in increased memory ++/// footprint. ++/// ++/// In cases where this is an issue, the excess capacity can be discarded with [`Vec::shrink_to()`], ++/// [`Vec::shrink_to_fit()`] or by collecting into [`Box<[T]>`][owned slice] instead, which additionally reduces ++/// the size of the long-lived struct. ++/// ++/// [owned slice]: Box ++/// ++/// ```rust ++/// # use std::sync::Mutex; ++/// static LONG_LIVED: Mutex>> = Mutex::new(Vec::new()); ++/// ++/// for i in 0..10 { ++/// let big_temporary: Vec = (0..1024).collect(); ++/// // discard most items ++/// let mut result: Vec<_> = big_temporary.into_iter().filter(|i| i % 100 == 0).collect(); ++/// // without this a lot of unused capacity might be moved into the global ++/// result.shrink_to_fit(); ++/// LONG_LIVED.lock().unwrap().push(result); ++/// } ++/// ``` + #[cfg(not(no_global_oom_handling))] + #[stable(feature = "rust1", since = "1.0.0")] + impl FromIterator for Vec { +@@ -3069,14 +3114,8 @@ impl IntoIterator for Vec { + begin.add(me.len()) as *const T + }; + let cap = me.buf.capacity(); +- IntoIter { +- buf: NonNull::new_unchecked(begin), +- phantom: PhantomData, +- cap, +- alloc, +- ptr: begin, +- end, +- } ++ let buf = NonNull::new_unchecked(begin); ++ IntoIter { buf, phantom: PhantomData, cap, alloc, ptr: buf, end } + } + } + } +@@ -3598,8 +3637,10 @@ impl From> for Vec { + impl From> for Box<[T], A> { + /// Convert a vector into a boxed slice. + /// +- /// If `v` has excess capacity, its items will be moved into a +- /// newly-allocated buffer with exactly the right capacity. ++ /// Before doing the conversion, this method discards excess capacity like [`Vec::shrink_to_fit`]. ++ /// ++ /// [owned slice]: Box ++ /// [`Vec::shrink_to_fit`]: Vec::shrink_to_fit + /// + /// # Examples + /// +diff --git a/rust/kernel/lib.rs b/rust/kernel/lib.rs +index be68d5e567b1a1..71f95e5aa09abd 100644 +--- a/rust/kernel/lib.rs ++++ b/rust/kernel/lib.rs +@@ -16,7 +16,6 @@ + #![feature(coerce_unsized)] + #![feature(dispatch_from_dyn)] + #![feature(new_uninit)] +-#![feature(offset_of)] + #![feature(receiver_trait)] + #![feature(unsize)] + +@@ -78,7 +77,7 @@ pub trait Module: Sized + Sync { + /// Equivalent to `THIS_MODULE` in the C API. + /// + /// C header: [`include/linux/export.h`](srctree/include/linux/export.h) +-pub struct ThisModule(*mut bindings::module); ++pub struct ThisModule(#[allow(dead_code)] *mut bindings::module); + + // SAFETY: `THIS_MODULE` may be used from all threads within a module. + unsafe impl Sync for ThisModule {} +diff --git a/scripts/Makefile.build b/scripts/Makefile.build +index baf86c0880b6d7..367cfeea74c5f5 100644 +--- a/scripts/Makefile.build ++++ b/scripts/Makefile.build +@@ -263,7 +263,7 @@ $(obj)/%.lst: $(src)/%.c FORCE + # Compile Rust sources (.rs) + # --------------------------------------------------------------------------- + +-rust_allowed_features := new_uninit,offset_of ++rust_allowed_features := new_uninit + + # `--out-dir` is required to avoid temporaries being created by `rustc` in the + # current working directory, which may be not accessible in the out-of-tree +diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh +index 5927cc6b7de338..cc5141b67b4a71 100755 +--- a/scripts/min-tool-version.sh ++++ b/scripts/min-tool-version.sh +@@ -33,7 +33,7 @@ llvm) + fi + ;; + rustc) +- echo 1.76.0 ++ echo 1.77.0 + ;; + bindgen) + echo 0.65.1 From 9bbc57f5a1c56ae3a11c2badbd07a0116a493a34 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 23 Mar 2024 11:49:30 +0100 Subject: [PATCH 2/2] cargo,clippy,rustc,rustfmt: 1.76.0 -> 1.77.1 --- .../compilers/rust/{1_76.nix => 1_77.nix} | 30 +++++++++---------- .../compilers/rust/cargo-auditable.nix | 10 ++++++- pkgs/top-level/all-packages.nix | 8 ++--- pkgs/top-level/linux-kernels.nix | 2 ++ 4 files changed, 30 insertions(+), 20 deletions(-) rename pkgs/development/compilers/rust/{1_76.nix => 1_77.nix} (57%) diff --git a/pkgs/development/compilers/rust/1_76.nix b/pkgs/development/compilers/rust/1_77.nix similarity index 57% rename from pkgs/development/compilers/rust/1_76.nix rename to pkgs/development/compilers/rust/1_77.nix index e04939735df49..24c1b7bcb534f 100644 --- a/pkgs/development/compilers/rust/1_76.nix +++ b/pkgs/development/compilers/rust/1_77.nix @@ -19,8 +19,8 @@ } @ args: import ./default.nix { - rustcVersion = "1.76.0"; - rustcSha256 = "sha256-nlz/Azp/DSJmgYmCrZDk0+Tvj47hcVd2xuJQc6E2wCE="; + rustcVersion = "1.77.1"; + rustcSha256 = "7hBuTFafUtujtbKCsQWCD4a9j2s9CcBrjc6C+xuzpKE="; llvmSharedForBuild = pkgsBuildBuild.llvmPackages_17.libllvm.override { enableSharedLibraries = true; }; llvmSharedForHost = pkgsBuildHost.llvmPackages_17.libllvm.override { enableSharedLibraries = true; }; @@ -34,24 +34,24 @@ import ./default.nix { # Note: the version MUST be one version prior to the version we're # building - bootstrapVersion = "1.75.0"; + bootstrapVersion = "1.76.0"; # fetch hashes by running `print-hashes.sh ${bootstrapVersion}` bootstrapHashes = { - i686-unknown-linux-gnu = "107b8d8825deab338f338b15f047829da6225bb34644790847e96f0957c6678f"; - x86_64-unknown-linux-gnu = "473978b6f8ff216389f9e89315211c6b683cf95a966196e7914b46e8cf0d74f6"; - x86_64-unknown-linux-musl = "cc6ef41aa811ab34f946fe2b4338d1107daf08642125fd566386bf45563597de"; - arm-unknown-linux-gnueabihf = "985454b6c385cb461cc8a39d2d7d55dcf6c50495033fe5d28edcc717729d8ae9"; - armv7-unknown-linux-gnueabihf = "bd876a75f72040d96be2fb882770b16b482ac0ab15d7e3ad24e6d25b7c74bcf7"; - aarch64-unknown-linux-gnu = "30828cd904fcfb47f1ac43627c7033c903889ea4aca538f53dcafbb3744a9a73"; - aarch64-unknown-linux-musl = "26b5989525b7cf623f3868a37549736e0efe1142a08f191a97e29758cc640ac4"; - x86_64-apple-darwin = "ad066e4dec7ae5948c4e7afe68e250c336a5ab3d655570bb119b3eba9cf22851"; - aarch64-apple-darwin = "878ecf81e059507dd2ab256f59629a4fb00171035d2a2f5638cb582d999373b1"; - powerpc64le-unknown-linux-gnu = "2599cdfea5860b4efbceb7bca69845a96ac1c96aa50cf8261151e82280b397a0"; - riscv64gc-unknown-linux-gnu = "7f7b73d8924d7dd24dcb2ef0da257eb48d9aed658b00fe68e8f1ade0b1ce4511"; + i686-unknown-linux-gnu = "4c3eefc9341b8809235e6c4fbcbc19ab52a5cbe771292c400df068c12984fa3e"; + x86_64-unknown-linux-gnu = "9d589d2036b503cc45ecc94992d616fb3deec074deb36cacc2f5c212408f7399"; + x86_64-unknown-linux-musl = "aa8568f4d262468aaf4f622bd421c5435b24454d8fbcdae48da1162962205384"; + arm-unknown-linux-gnueabihf = "7d1da067362fc64bcad198d90a61e024d5712aed76e17b28e1cd7e8ba263cc6f"; + armv7-unknown-linux-gnueabihf = "c03346d56d4a860cd3a8d2d2a7ea75c510b68204e3ad97b3770076595261c913"; + aarch64-unknown-linux-gnu = "2e8313421e8fb673efdf356cdfdd4bc16516f2610d4f6faa01327983104c05a0"; + aarch64-unknown-linux-musl = "a1d1c8ccb8ea00cfa2b79d80411b8eb22b2bef5214f86536825361e98d7c617a"; + x86_64-apple-darwin = "7bdbe085695df8e46389115e99eda7beed37a9494f6b961b45554c658e53b8e7"; + aarch64-apple-darwin = "17496f15c3cb6ff73d5c36f5b54cc110f1ac31fa09521a7991c0d7ddd890dceb"; + powerpc64le-unknown-linux-gnu = "44b3494675284d26b04747a824dc974e32fd8fd46fc0aa06a7c8ebe851332d2c"; + riscv64gc-unknown-linux-gnu = "4a9db321874fc441235b71eb8aa295fc50251305e461540b25b4eef89fb56255"; }; - selectRustPackage = pkgs: pkgs.rust_1_76; + selectRustPackage = pkgs: pkgs.rust_1_77; rustcPatches = [ ]; } diff --git a/pkgs/development/compilers/rust/cargo-auditable.nix b/pkgs/development/compilers/rust/cargo-auditable.nix index 34d877501c3b9..1cf765b35100d 100644 --- a/pkgs/development/compilers/rust/cargo-auditable.nix +++ b/pkgs/development/compilers/rust/cargo-auditable.nix @@ -1,4 +1,4 @@ -{ lib, buildPackages, fetchFromGitHub, makeRustPlatform, installShellFiles, stdenv }: +{ lib, buildPackages, fetchFromGitHub, fetchpatch, makeRustPlatform, installShellFiles, stdenv }: let args = rec { @@ -12,6 +12,14 @@ let sha256 = "sha256-ERIzx9Fveanq7/aWcB2sviTxIahvSu0sTwgpGf/aYE8="; }; + patches = [ + (fetchpatch { + name = "rust-1.77-tests.patch"; + url = "https://github.com/rust-secure-code/cargo-auditable/commit/5317a27244fc428335c4e7a1d066ae0f65f0d496.patch"; + hash = "sha256-UblGseiSC/2eE4rcnTgYzxAMrutHFSdxKTHqKj1mX5o="; + }) + ]; + cargoHash = "sha256-4o3ctun/8VcBRuj+j0Yaawdkyn6Z6LPp+FTyhPxQWU8="; # Cargo.lock is outdated diff --git a/pkgs/top-level/all-packages.nix b/pkgs/top-level/all-packages.nix index 68ff4d845efa2..06b368037fb27 100644 --- a/pkgs/top-level/all-packages.nix +++ b/pkgs/top-level/all-packages.nix @@ -16714,11 +16714,11 @@ with pkgs; wrapRustcWith = { rustc-unwrapped, ... } @ args: callPackage ../build-support/rust/rustc-wrapper args; wrapRustc = rustc-unwrapped: wrapRustcWith { inherit rustc-unwrapped; }; - rust_1_76 = callPackage ../development/compilers/rust/1_76.nix { + rust_1_77 = callPackage ../development/compilers/rust/1_77.nix { inherit (darwin.apple_sdk.frameworks) CoreFoundation Security SystemConfiguration; llvm_17 = llvmPackages_17.libllvm; }; - rust = rust_1_76; + rust = rust_1_77; mrustc = callPackage ../development/compilers/mrustc { }; mrustc-minicargo = callPackage ../development/compilers/mrustc/minicargo.nix { }; @@ -16726,8 +16726,8 @@ with pkgs; openssl = openssl_1_1; }; - rustPackages_1_76 = rust_1_76.packages.stable; - rustPackages = rustPackages_1_76; + rustPackages_1_77 = rust_1_77.packages.stable; + rustPackages = rustPackages_1_77; inherit (rustPackages) cargo cargo-auditable cargo-auditable-cargo-wrapper clippy rustc rustPlatform; diff --git a/pkgs/top-level/linux-kernels.nix b/pkgs/top-level/linux-kernels.nix index 21b044583b9e4..bf3c986a3d73c 100644 --- a/pkgs/top-level/linux-kernels.nix +++ b/pkgs/top-level/linux-kernels.nix @@ -192,6 +192,7 @@ in { kernelPatches.request_key_helper kernelPatches.rust_1_75 kernelPatches.rust_1_76 + kernelPatches.rust_1_77-6_8 ]; }; @@ -203,6 +204,7 @@ in { kernelPatches = [ kernelPatches.bridge_stp_helper kernelPatches.request_key_helper + kernelPatches.rust_1_77-6_9 ]; }; latest = packageAliases.linux_latest.kernel;