1From 77007eef13d52d0a5df9706d47078c4e1390a0a9 Mon Sep 17 00:00:00 2001
2From: Miguel Ojeda <ojeda@kernel.org>
3Date: Sun, 24 Dec 2023 18:21:28 +0100
4Subject: [PATCH] rust: upgrade to Rust 1.75.0
5
6This is the next upgrade to the Rust toolchain, from 1.74.1 to 1.75.0
7(i.e. the latest) [1].
8
9See the upgrade policy [2] and the comments on the first upgrade in
10commit 3ed03f4da06e ("rust: upgrade to Rust 1.68.2").
11
12# Unstable features
13
14The `const_maybe_uninit_zeroed` unstable feature [3] was stabilized in
15Rust 1.75.0, which we were using in the PHYLIB abstractions.
16
17The only unstable features allowed to be used outside the `kernel` crate
18are still `new_uninit,offset_of`, though other code to be upstreamed
19may increase the list.
20
21Please see [4] for details.
22
23# Other improvements
24
25Rust 1.75.0 stabilized `pointer_byte_offsets` [5] which we could
26potentially use as an alternative for `ptr_metadata` in the future.
27
28# Required changes
29
30For this upgrade, no changes were required (i.e. on our side).
31
32# `alloc` upgrade and reviewing
33
34The vast majority of changes are due to our `alloc` fork being upgraded
35at once.
36
37There are two kinds of changes to be aware of: the ones coming from
38upstream, which we should follow as closely as possible, and the updates
39needed in our added fallible APIs to keep them matching the newer
40infallible APIs coming from upstream.
41
42Instead of taking a look at the diff of this patch, an alternative
43approach is reviewing a diff of the changes between upstream `alloc` and
44the kernel's. This allows to easily inspect the kernel additions only,
45especially to check if the fallible methods we already have still match
46the infallible ones in the new version coming from upstream.
47
48Another approach is reviewing the changes introduced in the additions in
49the kernel fork between the two versions. This is useful to spot
50potentially unintended changes to our additions.
51
52To apply these approaches, one may follow steps similar to the following
53to generate a pair of patches that show the differences between upstream
54Rust and the kernel (for the subset of `alloc` we use) before and after
55applying this patch:
56
57 # Get the difference with respect to the old version.
58 git -C rust checkout $(linux/scripts/min-tool-version.sh rustc)
59 git -C linux ls-tree -r --name-only HEAD -- rust/alloc |
60 cut -d/ -f3- |
61 grep -Fv README.md |
62 xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH
63 git -C linux diff --patch-with-stat --summary -R > old.patch
64 git -C linux restore rust/alloc
65
66 # Apply this patch.
67 git -C linux am rust-upgrade.patch
68
69 # Get the difference with respect to the new version.
70 git -C rust checkout $(linux/scripts/min-tool-version.sh rustc)
71 git -C linux ls-tree -r --name-only HEAD -- rust/alloc |
72 cut -d/ -f3- |
73 grep -Fv README.md |
74 xargs -IPATH cp rust/library/alloc/src/PATH linux/rust/alloc/PATH
75 git -C linux diff --patch-with-stat --summary -R > new.patch
76 git -C linux restore rust/alloc
77
78Now one may check the `new.patch` to take a look at the additions (first
79approach) or at the difference between those two patches (second
80approach). For the latter, a side-by-side tool is recommended.
81
82Link: https://github.com/rust-lang/rust/blob/stable/RELEASES.md#version-1750-2023-12-28 [1]
83Link: https://rust-for-linux.com/rust-version-policy [2]
84Link: https://github.com/rust-lang/rust/issues/91850 [3]
85Link: https://github.com/Rust-for-Linux/linux/issues/2 [4]
86Link: https://github.com/rust-lang/rust/issues/96283 [5]
87Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
88Link: https://lore.kernel.org/lkml/20231224172128.271447-1-ojeda@kernel.org/
89Signed-off-by: Alyssa Ross <hi@alyssa.is>
90---
91 Documentation/process/changes.rst | 2 +-
92 rust/alloc/alloc.rs | 9 ++++++++-
93 rust/alloc/boxed.rs | 20 ++++++++++++--------
94 rust/alloc/lib.rs | 7 ++++---
95 rust/alloc/raw_vec.rs | 19 +++++++++++++++----
96 rust/alloc/vec/mod.rs | 16 ++++++++++------
97 scripts/min-tool-version.sh | 2 +-
98 7 files changed, 51 insertions(+), 24 deletions(-)
99
100diff --git a/Documentation/process/changes.rst b/Documentation/process/changes.rst
101index 169f67773518..52284fdbaf23 100644
102--- a/Documentation/process/changes.rst
103+++ b/Documentation/process/changes.rst
104@@ -31,7 +31,7 @@ you probably needn't concern yourself with pcmciautils.
105 ====================== =============== ========================================
106 GNU C 5.1 gcc --version
107 Clang/LLVM (optional) 11.0.0 clang --version
108-Rust (optional) 1.74.1 rustc --version
109+Rust (optional) 1.75.0 rustc --version
110 bindgen (optional) 0.65.1 bindgen --version
111 GNU make 3.82 make --version
112 bash 4.2 bash --version
113diff --git a/rust/alloc/alloc.rs b/rust/alloc/alloc.rs
114index 150e13750ff7..8a6be8c98173 100644
115--- a/rust/alloc/alloc.rs
116+++ b/rust/alloc/alloc.rs
117@@ -379,13 +379,20 @@ const fn ct_error(_: Layout) -> ! {
118 panic!("allocation failed");
119 }
120
121+ #[inline]
122 fn rt_error(layout: Layout) -> ! {
123 unsafe {
124 __rust_alloc_error_handler(layout.size(), layout.align());
125 }
126 }
127
128- unsafe { core::intrinsics::const_eval_select((layout,), ct_error, rt_error) }
129+ #[cfg(not(feature = "panic_immediate_abort"))]
130+ unsafe {
131+ core::intrinsics::const_eval_select((layout,), ct_error, rt_error)
132+ }
133+
134+ #[cfg(feature = "panic_immediate_abort")]
135+ ct_error(layout)
136 }
137
138 // For alloc test `std::alloc::handle_alloc_error` can be used directly.
139diff --git a/rust/alloc/boxed.rs b/rust/alloc/boxed.rs
140index 9620eba17268..f5f40778a193 100644
141--- a/rust/alloc/boxed.rs
142+++ b/rust/alloc/boxed.rs
143@@ -161,7 +161,7 @@
144 use core::marker::Unsize;
145 use core::mem::{self, SizedTypeProperties};
146 use core::ops::{
147- CoerceUnsized, Deref, DerefMut, DispatchFromDyn, Generator, GeneratorState, Receiver,
148+ CoerceUnsized, Coroutine, CoroutineState, Deref, DerefMut, DispatchFromDyn, Receiver,
149 };
150 use core::pin::Pin;
151 use core::ptr::{self, NonNull, Unique};
152@@ -211,7 +211,7 @@ impl<T> Box<T> {
153 /// ```
154 /// let five = Box::new(5);
155 /// ```
156- #[cfg(all(not(no_global_oom_handling)))]
157+ #[cfg(not(no_global_oom_handling))]
158 #[inline(always)]
159 #[stable(feature = "rust1", since = "1.0.0")]
160 #[must_use]
161@@ -2110,28 +2110,28 @@ fn as_mut(&mut self) -> &mut T {
162 #[stable(feature = "pin", since = "1.33.0")]
163 impl<T: ?Sized, A: Allocator> Unpin for Box<T, A> where A: 'static {}
164
165-#[unstable(feature = "generator_trait", issue = "43122")]
166-impl<G: ?Sized + Generator<R> + Unpin, R, A: Allocator> Generator<R> for Box<G, A>
167+#[unstable(feature = "coroutine_trait", issue = "43122")]
168+impl<G: ?Sized + Coroutine<R> + Unpin, R, A: Allocator> Coroutine<R> for Box<G, A>
169 where
170 A: 'static,
171 {
172 type Yield = G::Yield;
173 type Return = G::Return;
174
175- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
176+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> {
177 G::resume(Pin::new(&mut *self), arg)
178 }
179 }
180
181-#[unstable(feature = "generator_trait", issue = "43122")]
182-impl<G: ?Sized + Generator<R>, R, A: Allocator> Generator<R> for Pin<Box<G, A>>
183+#[unstable(feature = "coroutine_trait", issue = "43122")]
184+impl<G: ?Sized + Coroutine<R>, R, A: Allocator> Coroutine<R> for Pin<Box<G, A>>
185 where
186 A: 'static,
187 {
188 type Yield = G::Yield;
189 type Return = G::Return;
190
191- fn resume(mut self: Pin<&mut Self>, arg: R) -> GeneratorState<Self::Yield, Self::Return> {
192+ fn resume(mut self: Pin<&mut Self>, arg: R) -> CoroutineState<Self::Yield, Self::Return> {
193 G::resume((*self).as_mut(), arg)
194 }
195 }
196@@ -2448,4 +2448,8 @@ fn cause(&self) -> Option<&dyn core::error::Error> {
197 fn source(&self) -> Option<&(dyn core::error::Error + 'static)> {
198 core::error::Error::source(&**self)
199 }
200+
201+ fn provide<'b>(&'b self, request: &mut core::error::Request<'b>) {
202+ core::error::Error::provide(&**self, request);
203+ }
204 }
205diff --git a/rust/alloc/lib.rs b/rust/alloc/lib.rs
206index 9c7ea73da108..345cf5c9cf92 100644
207--- a/rust/alloc/lib.rs
208+++ b/rust/alloc/lib.rs
209@@ -80,6 +80,8 @@
210 not(no_sync),
211 target_has_atomic = "ptr"
212 ))]
213+#![cfg_attr(not(bootstrap), doc(rust_logo))]
214+#![cfg_attr(not(bootstrap), feature(rustdoc_internals))]
215 #![no_std]
216 #![needs_allocator]
217 // Lints:
218@@ -115,7 +117,6 @@
219 #![feature(const_eval_select)]
220 #![feature(const_maybe_uninit_as_mut_ptr)]
221 #![feature(const_maybe_uninit_write)]
222-#![feature(const_maybe_uninit_zeroed)]
223 #![feature(const_pin)]
224 #![feature(const_refs_to_cell)]
225 #![feature(const_size_of_val)]
226@@ -141,7 +142,7 @@
227 #![feature(maybe_uninit_uninit_array)]
228 #![feature(maybe_uninit_uninit_array_transpose)]
229 #![feature(pattern)]
230-#![feature(pointer_byte_offsets)]
231+#![feature(ptr_addr_eq)]
232 #![feature(ptr_internals)]
233 #![feature(ptr_metadata)]
234 #![feature(ptr_sub_ptr)]
235@@ -168,7 +169,7 @@
236 //
237 // Language features:
238 // tidy-alphabetical-start
239-#![cfg_attr(not(test), feature(generator_trait))]
240+#![cfg_attr(not(test), feature(coroutine_trait))]
241 #![cfg_attr(test, feature(panic_update_hook))]
242 #![cfg_attr(test, feature(test))]
243 #![feature(allocator_internals)]
244diff --git a/rust/alloc/raw_vec.rs b/rust/alloc/raw_vec.rs
245index a7425582a323..f1b8cec8cc62 100644
246--- a/rust/alloc/raw_vec.rs
247+++ b/rust/alloc/raw_vec.rs
248@@ -338,10 +338,13 @@ pub fn reserve_for_push(&mut self, len: usize) {
249 /// The same as `reserve`, but returns on errors instead of panicking or aborting.
250 pub fn try_reserve(&mut self, len: usize, additional: usize) -> Result<(), TryReserveError> {
251 if self.needs_to_grow(len, additional) {
252- self.grow_amortized(len, additional)
253- } else {
254- Ok(())
255+ self.grow_amortized(len, additional)?;
256 }
257+ unsafe {
258+ // Inform the optimizer that the reservation has succeeded or wasn't needed
259+ core::intrinsics::assume(!self.needs_to_grow(len, additional));
260+ }
261+ Ok(())
262 }
263
264 /// The same as `reserve_for_push`, but returns on errors instead of panicking or aborting.
265@@ -378,7 +381,14 @@ pub fn try_reserve_exact(
266 len: usize,
267 additional: usize,
268 ) -> Result<(), TryReserveError> {
269- if self.needs_to_grow(len, additional) { self.grow_exact(len, additional) } else { Ok(()) }
270+ if self.needs_to_grow(len, additional) {
271+ self.grow_exact(len, additional)?;
272+ }
273+ unsafe {
274+ // Inform the optimizer that the reservation has succeeded or wasn't needed
275+ core::intrinsics::assume(!self.needs_to_grow(len, additional));
276+ }
277+ Ok(())
278 }
279
280 /// Shrinks the buffer down to the specified capacity. If the given amount
281@@ -569,6 +579,7 @@ fn alloc_guard(alloc_size: usize) -> Result<(), TryReserveError> {
282 // ensure that the code generation related to these panics is minimal as there's
283 // only one location which panics rather than a bunch throughout the module.
284 #[cfg(not(no_global_oom_handling))]
285+#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
286 fn capacity_overflow() -> ! {
287 panic!("capacity overflow");
288 }
289diff --git a/rust/alloc/vec/mod.rs b/rust/alloc/vec/mod.rs
290index 41ca71805ef0..0d95fd7ef337 100644
291--- a/rust/alloc/vec/mod.rs
292+++ b/rust/alloc/vec/mod.rs
293@@ -1376,7 +1376,7 @@ pub fn as_mut_slice(&mut self) -> &mut [T] {
294 /// [`as_mut_ptr`]: Vec::as_mut_ptr
295 /// [`as_ptr`]: Vec::as_ptr
296 #[stable(feature = "vec_as_ptr", since = "1.37.0")]
297- #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
298+ #[rustc_never_returns_null_ptr]
299 #[inline]
300 pub fn as_ptr(&self) -> *const T {
301 // We shadow the slice method of the same name to avoid going through
302@@ -1436,7 +1436,7 @@ pub fn as_ptr(&self) -> *const T {
303 /// [`as_mut_ptr`]: Vec::as_mut_ptr
304 /// [`as_ptr`]: Vec::as_ptr
305 #[stable(feature = "vec_as_ptr", since = "1.37.0")]
306- #[cfg_attr(not(bootstrap), rustc_never_returns_null_ptr)]
307+ #[rustc_never_returns_null_ptr]
308 #[inline]
309 pub fn as_mut_ptr(&mut self) -> *mut T {
310 // We shadow the slice method of the same name to avoid going through
311@@ -1565,7 +1565,8 @@ pub unsafe fn set_len(&mut self, new_len: usize) {
312 #[stable(feature = "rust1", since = "1.0.0")]
313 pub fn swap_remove(&mut self, index: usize) -> T {
314 #[cold]
315- #[inline(never)]
316+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
317+ #[track_caller]
318 fn assert_failed(index: usize, len: usize) -> ! {
319 panic!("swap_remove index (is {index}) should be < len (is {len})");
320 }
321@@ -1606,7 +1607,8 @@ fn assert_failed(index: usize, len: usize) -> ! {
322 #[stable(feature = "rust1", since = "1.0.0")]
323 pub fn insert(&mut self, index: usize, element: T) {
324 #[cold]
325- #[inline(never)]
326+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
327+ #[track_caller]
328 fn assert_failed(index: usize, len: usize) -> ! {
329 panic!("insertion index (is {index}) should be <= len (is {len})");
330 }
331@@ -1667,7 +1669,7 @@ fn assert_failed(index: usize, len: usize) -> ! {
332 #[track_caller]
333 pub fn remove(&mut self, index: usize) -> T {
334 #[cold]
335- #[inline(never)]
336+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
337 #[track_caller]
338 fn assert_failed(index: usize, len: usize) -> ! {
339 panic!("removal index (is {index}) should be < len (is {len})");
340@@ -2097,6 +2099,7 @@ pub fn pop(&mut self) -> Option<T> {
341 } else {
342 unsafe {
343 self.len -= 1;
344+ core::intrinsics::assume(self.len < self.capacity());
345 Some(ptr::read(self.as_ptr().add(self.len())))
346 }
347 }
348@@ -2299,7 +2302,8 @@ pub fn split_off(&mut self, at: usize) -> Self
349 A: Clone,
350 {
351 #[cold]
352- #[inline(never)]
353+ #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
354+ #[track_caller]
355 fn assert_failed(at: usize, len: usize) -> ! {
356 panic!("`at` split index (is {at}) should be <= len (is {len})");
357 }
358diff --git a/scripts/min-tool-version.sh b/scripts/min-tool-version.sh
359index c62066825f53..bcc7d4247290 100755
360--- a/scripts/min-tool-version.sh
361+++ b/scripts/min-tool-version.sh
362@@ -31,7 +31,7 @@ llvm)
363 fi
364 ;;
365 rustc)
366- echo 1.74.1
367+ echo 1.75.0
368 ;;
369 bindgen)
370 echo 0.65.1
371--
3722.43.0
373