diff options
author | Alyssa Ross <hi@alyssa.is> | 2024-01-26 01:39:25 +0100 |
---|---|---|
committer | Alyssa Ross <hi@alyssa.is> | 2024-01-28 10:54:17 +0100 |
commit | 63c01a35763bc55b1d39665a07dd898e201743b1 (patch) | |
tree | 7ab6d33b856387c67f87d90b07b56cb8b3e8e0ee /pkgs/os-specific | |
parent | b3ff6c1a210aac497ac6e28beca0cf08120759e3 (diff) |
linux_6_7: fix Rust support with current rustc
The 1.75 patch can't be fetched, because it doesn't apply. But git can apply it cleanly, so it must just need to do a three-way merge or something. Regardless, we need to include a version that patch(1) can apply in Nixpkgs.
Diffstat (limited to 'pkgs/os-specific')
-rw-r--r-- | pkgs/os-specific/linux/kernel/patches.nix | 14 | ||||
-rw-r--r-- | pkgs/os-specific/linux/kernel/rust-1.75.patch | 373 |
2 files changed, 387 insertions, 0 deletions
diff --git a/pkgs/os-specific/linux/kernel/patches.nix b/pkgs/os-specific/linux/kernel/patches.nix index 5d4ebc214dc7b..a7bf7128f5efc 100644 --- a/pkgs/os-specific/linux/kernel/patches.nix +++ b/pkgs/os-specific/linux/kernel/patches.nix @@ -65,4 +65,18 @@ name = "export-rt-sched-migrate"; patch = ./export-rt-sched-migrate.patch; }; + + rust_1_74 = { + name = "rust-1.74.patch"; + patch = fetchpatch { + name = "rust-1.74.patch"; + url = "https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/patch/?id=80fe9e51510b23472ad0f97175556490549ed714"; + hash = "sha256-yGt7PwqN/G+ZtZSt6eARvVFdkC8tnUiu0Fz4cFCyguM="; + }; + }; + + rust_1_75 = { + name = "rust-1.75.patch"; + patch = ./rust-1.75.patch; + }; } diff --git a/pkgs/os-specific/linux/kernel/rust-1.75.patch b/pkgs/os-specific/linux/kernel/rust-1.75.patch new file mode 100644 index 0000000000000..9d6b1a3dcc755 --- /dev/null +++ b/pkgs/os-specific/linux/kernel/rust-1.75.patch @@ -0,0 +1,373 @@ +From 77007eef13d52d0a5df9706d47078c4e1390a0a9 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda <ojeda@kernel.org> +Date: Sun, 24 Dec 2023 18:21:28 +0100 +Subject: [PATCH] rust: upgrade to Rust 1.75.0 + +This is the next upgrade to the Rust toolchain, from 1.74.1 to 1.75.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"). + +# Unstable features + +The `const_maybe_uninit_zeroed` unstable feature [3] was stabilized in +Rust 1.75.0, which we were using in the PHYLIB abstractions. + +The only unstable features allowed to be used outside the `kernel` crate +are still `new_uninit,offset_of`, though other code to be upstreamed +may increase the list. + +Please see [4] for details. + +# Other improvements + +Rust 1.75.0 stabilized `pointer_byte_offsets` [5] which we could +potentially use as an alternative for `ptr_metadata` in the future. + +# Required changes + +For this upgrade, no changes were required (i.e. on our side). + +# `alloc` upgrade and reviewing + +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-1750-2023-12-28 [1] +Link: https://rust-for-linux.com/rust-version-policy [2] +Link: https://github.com/rust-lang/rust/issues/91850 [3] +Link: https://github.com/Rust-for-Linux/linux/issues/2 [4] +Link: https://github.com/rust-lang/rust/issues/96283 [5] +Signed-off-by: Miguel Ojeda <ojeda@kernel.org> +Link: https://lore.kernel.org/lkml/20231224172128.271447-1-ojeda@kernel.org/ +Signed-off-by: Alyssa Ross <hi@alyssa.is> +--- + Documentation/process/changes.rst | 2 +- + rust/alloc/alloc.rs | 9 ++++++++- + rust/alloc/boxed.rs | 20 ++++++++++++-------- + rust/alloc/lib.rs | 7 ++++--- + rust/alloc/raw_vec.rs | 19 +++++++++++++++---- + rust/alloc/vec/mod.rs | 16 ++++++++++------ + scripts/min-tool-version.sh | 2 +- + 7 files changed, 51 insertions(+), 24 deletions(-) + +diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst +index 169f67773518..52284fdbaf23 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) 11.0.0 clang --version +-Rust (optional) 1.74.1 rustc --version ++Rust (optional) 1.75.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 150e13750ff7..8a6be8c98173 100644 +--- a/rust/alloc/alloc.rs ++++ b/rust/alloc/alloc.rs +@@ -379,13 +379,20 @@ const fn ct_error(_: Layout) -> ! { + panic!("allocation failed"); + } + ++ #[inline] + fn rt_error(layout: Layout) -> ! { + unsafe { + __rust_alloc_error_handler(layout.size(), layout.align()); + } + } + +- unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) } ++ #[cfg(not(feature = "panic_immediate_abort"))] ++ unsafe { ++ core::intrinsics::const_eval_select((layout,), ct_error, rt_error) ++ } ++ ++ #[cfg(feature = "panic_immediate_abort")] ++ ct_error(layout) + } + + // For alloc test `std::alloc::handle_alloc_error` can be used directly. +diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs +index 9620eba17268..f5f40778a193 100644 +--- a/rust/alloc/boxed.rs ++++ b/rust/alloc/boxed.rs +@@ -161,7 +161,7 @@ + use core::marker::Unsize; + use core::mem::{self, SizedTypeProperties}; + use core::ops::{ +- CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver, ++ CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver, + }; + use core::pin::Pin; + use core::ptr::{self, NonNull, Unique}; +@@ -211,7 +211,7 @@ impl<T> Box<T> { + /// ``` + /// let five = Box::new(5); + /// ``` +- #[cfg(all(not(no_global_oom_handling)))] ++ #[cfg(not(no_global_oom_handling))] + #[inline(always)] + #[stable(feature = "rust1", since = "1.0.0")] + #[must_use] +@@ -2110,28 +2110,28 @@ fn as_mut(&mut self) -> &mut T { + #[stable(feature = "pin", since = "1.33.0")] + impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {} + +-#[unstable(feature = "generator_trait", issue = "43122")] +-impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A> ++#[unstable(feature = "coroutine_trait", issue = "43122")] ++impl<G: ?Sized + Coroutine<R> + Unpin, R, A: Allocator> Coroutine<R> for Box<G, A> + where + A: 'static, + { + type Yield = G::Yield; + type Return = G::Return; + +- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> { ++ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> { + G::resume(Pin::new(&mut *self), arg) + } + } + +-#[unstable(feature = "generator_trait", issue = "43122")] +-impl<G: ?Sized + Generator<R>, R, A: Allocator> Generator<R> for Pin<Box<G, A>> ++#[unstable(feature = "coroutine_trait", issue = "43122")] ++impl<G: ?Sized + Coroutine<R>, R, A: Allocator> Coroutine<R> for Pin<Box<G, A>> + where + A: 'static, + { + type Yield = G::Yield; + type Return = G::Return; + +- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> { ++ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> { + G::resume((*self).as_mut(), arg) + } + } +@@ -2448,4 +2448,8 @@ fn cause(&self) -> Option<&dyn core::error::Error> { + fn source(&self) -> Option<&(dyn core::error::Error + 'static)> { + core::error::Error::source(&**self) + } ++ ++ fn provide<'b>(&'b self, request: &mut core::error::Request<'b>) { ++ core::error::Error::provide(&**self, request); ++ } + } +diff --git a/rust/alloc/lib.rs b/rust/alloc/lib.rs +index 9c7ea73da108..345cf5c9cf92 100644 +--- a/rust/alloc/lib.rs ++++ b/rust/alloc/lib.rs +@@ -80,6 +80,8 @@ + not(no_sync), + target_has_atomic = "ptr" + ))] ++#![cfg_attr(not(bootstrap), doc(rust_logo))] ++#![cfg_attr(not(bootstrap), feature(rustdoc_internals))] + #![no_std] + #![needs_allocator] + // Lints: +@@ -115,7 +117,6 @@ + #![feature(const_eval_select)] + #![feature(const_maybe_uninit_as_mut_ptr)] + #![feature(const_maybe_uninit_write)] +-#![feature(const_maybe_uninit_zeroed)] + #![feature(const_pin)] + #![feature(const_refs_to_cell)] + #![feature(const_size_of_val)] +@@ -141,7 +142,7 @@ + #![feature(maybe_uninit_uninit_array)] + #![feature(maybe_uninit_uninit_array_transpose)] + #![feature(pattern)] +-#![feature(pointer_byte_offsets)] ++#![feature(ptr_addr_eq)] + #![feature(ptr_internals)] + #![feature(ptr_metadata)] + #![feature(ptr_sub_ptr)] +@@ -168,7 +169,7 @@ + // + // Language features: + // tidy-alphabetical-start +-#![cfg_attr(not(test), feature(generator_trait))] ++#![cfg_attr(not(test), feature(coroutine_trait))] + #![cfg_attr(test, feature(panic_update_hook))] + #![cfg_attr(test, feature(test))] + #![feature(allocator_internals)] +diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs +index a7425582a323..f1b8cec8cc62 100644 +--- a/rust/alloc/raw_vec.rs ++++ b/rust/alloc/raw_vec.rs +@@ -338,10 +338,13 @@ pub fn reserve_for_push(&mut self, len: usize) { + /// The same as `reserve`, but returns on errors instead of panicking or aborting. + pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> { + if self.needs_to_grow(len, additional) { +- self.grow_amortized(len, additional) +- } else { +- Ok(()) ++ self.grow_amortized(len, additional)?; + } ++ unsafe { ++ // Inform the optimizer that the reservation has succeeded or wasn't needed ++ core::intrinsics::assume(!self.needs_to_grow(len, additional)); ++ } ++ Ok(()) + } + + /// The same as `reserve_for_push`, but returns on errors instead of panicking or aborting. +@@ -378,7 +381,14 @@ pub fn try_reserve_exact( + len: usize, + additional: usize, + ) -> Result<(), TryReserveError> { +- if self.needs_to_grow(len, additional) { self.grow_exact(len, additional) } else { Ok(()) } ++ if self.needs_to_grow(len, additional) { ++ self.grow_exact(len, additional)?; ++ } ++ unsafe { ++ // Inform the optimizer that the reservation has succeeded or wasn't needed ++ core::intrinsics::assume(!self.needs_to_grow(len, additional)); ++ } ++ Ok(()) + } + + /// Shrinks the buffer down to the specified capacity. If the given amount +@@ -569,6 +579,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> { + // ensure that the code generation related to these panics is minimal as there's + // only one location which panics rather than a bunch throughout the module. + #[cfg(not(no_global_oom_handling))] ++#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] + fn capacity_overflow() -> ! { + panic!("capacity overflow"); + } +diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs +index 41ca71805ef0..0d95fd7ef337 100644 +--- a/rust/alloc/vec/mod.rs ++++ b/rust/alloc/vec/mod.rs +@@ -1376,7 +1376,7 @@ pub fn as_mut_slice(&mut self) -> &mut [T] { + /// [`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)] ++ #[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 +@@ -1436,7 +1436,7 @@ pub fn as_ptr(&self) -> *const T { + /// [`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)] ++ #[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 +@@ -1565,7 +1565,8 @@ pub unsafe fn set_len(&mut self, new_len: usize) { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn swap_remove(&mut self, index: usize) -> T { + #[cold] +- #[inline(never)] ++ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] ++ #[track_caller] + fn assert_failed(index: usize, len: usize) -> ! { + panic!("swap_remove index (is {index}) should be < len (is {len})"); + } +@@ -1606,7 +1607,8 @@ fn assert_failed(index: usize, len: usize) -> ! { + #[stable(feature = "rust1", since = "1.0.0")] + pub fn insert(&mut self, index: usize, element: T) { + #[cold] +- #[inline(never)] ++ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] ++ #[track_caller] + fn assert_failed(index: usize, len: usize) -> ! { + panic!("insertion index (is {index}) should be <= len (is {len})"); + } +@@ -1667,7 +1669,7 @@ fn assert_failed(index: usize, len: usize) -> ! { + #[track_caller] + pub fn remove(&mut self, index: usize) -> T { + #[cold] +- #[inline(never)] ++ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] + #[track_caller] + fn assert_failed(index: usize, len: usize) -> ! { + panic!("removal index (is {index}) should be < len (is {len})"); +@@ -2097,6 +2099,7 @@ pub fn pop(&mut self) -> Option<T> { + } else { + unsafe { + self.len -= 1; ++ core::intrinsics::assume(self.len < self.capacity()); + Some(ptr::read(self.as_ptr().add(self.len()))) + } + } +@@ -2299,7 +2302,8 @@ pub fn split_off(&mut self, at: usize) -> Self + A: Clone, + { + #[cold] +- #[inline(never)] ++ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] ++ #[track_caller] + fn assert_failed(at: usize, len: usize) -> ! { + panic!("`at` split index (is {at}) should be <= len (is {len})"); + } +diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh +index c62066825f53..bcc7d4247290 100755 +--- a/scripts/min-tool-version.sh ++++ b/scripts/min-tool-version.sh +@@ -31,7 +31,7 @@ llvm) + fi + ;; + rustc) +- echo 1.74.1 ++ echo 1.75.0 + ;; + bindgen) + echo 0.65.1 +-- +2.43.0 + |