Merge tag 'rust-fixes-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux

Pull Rust fixes from Miguel Ojeda:
"Toolchain and infrastructure:

- Trigger rebuilds of the newly added 'proc-macro2' crate (and its
dependencies) when the Rust compiler version changes

- Fix error in '.rsi' targets (macro expanding single targets) under
'O=' pointing to an external (not subdir) folder

- Fix off-by-one line number in 'rustdoc' KUnit tests

- Add '-fdiagnostics-show-context' to GCC flags skipped by 'bindgen'

- Clean objtool warning by adding one more 'noreturn' function

- Clean 'libpin_init_internal.{so,dylib}' in 'mrproper'

'kernel' crate:

- Fix build error when using expressions in formatting arguments

- Mark 'num::Bounded::__new()' as unsafe and clean documentation
accordingly

- Always inline functions using 'build_assert' with arguments

- Fix 'rusttest' build error providing the right 'isize_atomic_repr'
type for the host

'macros' crate:

- Fix 'rusttest' build error by ignoring example

rust-analyzer:

- Remove assertion that was not true for distributions like NixOS

- Add missing dependency edges and fix editions for 'quote' and
sysroot crates to provide correct IDE support

DRM Tyr:

- Fix build error by adding missing dependency on 'CONFIG_COMMON_CLK'

Plus clean a few typos in docs and comments"

* tag 'rust-fixes-6.19' of git://git.kernel.org/pub/scm/linux/kernel/git/ojeda/linux: (28 commits)
rust: num: bounded: clean __new documentation and comments
scripts: generate_rust_analyzer: fix resolution of #[pin_data] macros
drm/tyr: depend on `COMMON_CLK` to fix build error
rust: sync: atomic: Provide stub for `rusttest` 32-bit hosts
kbuild: rust: clean libpin_init_internal in mrproper
rust: proc-macro2: rebuild if the version text changes
rust: num: bounded: add missing comment for always inlined function
rust: sync: refcount: always inline functions using build_assert with arguments
rust: bits: always inline functions using build_assert with arguments
scripts: generate_rust_analyzer: compile sysroot with correct edition
scripts: generate_rust_analyzer: compile quote with correct edition
scripts: generate_rust_analyzer: quote: treat `core` and `std` as dependencies
scripts: generate_rust_analyzer: syn: treat `std` as a dependency
scripts: generate_rust_analyzer: remove sysroot assertion
rust: kbuild: give `--config-path` to `rustfmt` in `.rsi` target
scripts: generate_rust_analyzer: Add pin_init_internal deps
scripts: generate_rust_analyzer: Add pin_init -> compiler_builtins dep
scripts: generate_rust_analyzer: Add compiler_builtins -> core dep
rust: macros: ignore example with module parameters
rust: num: bounded: mark __new as unsafe
...

+93 -47
+2 -1
Makefile
··· 1624 1624 certs/x509.genkey \ 1625 1625 vmlinux-gdb.py \ 1626 1626 rpmbuild \ 1627 - rust/libmacros.so rust/libmacros.dylib 1627 + rust/libmacros.so rust/libmacros.dylib \ 1628 + rust/libpin_init_internal.so rust/libpin_init_internal.dylib 1628 1629 1629 1630 # clean - Delete most, but leave enough to build external modules 1630 1631 #
+1
drivers/gpu/drm/tyr/Kconfig
··· 6 6 depends on RUST 7 7 depends on ARM || ARM64 || COMPILE_TEST 8 8 depends on !GENERIC_ATOMIC64 # for IOMMU_IO_PGTABLE_LPAE 9 + depends on COMMON_CLK 9 10 default n 10 11 help 11 12 Rust DRM driver for ARM Mali CSF-based GPUs.
+1
rust/Makefile
··· 383 383 -fno-inline-functions-called-once -fsanitize=bounds-strict \ 384 384 -fstrict-flex-arrays=% -fmin-function-alignment=% \ 385 385 -fzero-init-padding-bits=% -mno-fdpic \ 386 + -fdiagnostics-show-context -fdiagnostics-show-context=% \ 386 387 --param=% --param asan-% -fno-isolate-erroneous-paths-dereference 387 388 388 389 # Derived from `scripts/Makefile.clang`.
+4 -2
rust/kernel/bits.rs
··· 27 27 /// 28 28 /// This version is the default and should be used if `n` is known at 29 29 /// compile time. 30 - #[inline] 30 + // Always inline to optimize out error path of `build_assert`. 31 + #[inline(always)] 31 32 pub const fn [<bit_ $ty>](n: u32) -> $ty { 32 33 build_assert!(n < <$ty>::BITS); 33 34 (1 as $ty) << n ··· 76 75 /// This version is the default and should be used if the range is known 77 76 /// at compile time. 78 77 $(#[$genmask_ex])* 79 - #[inline] 78 + // Always inline to optimize out error path of `build_assert`. 79 + #[inline(always)] 80 80 pub const fn [<genmask_ $ty>](range: RangeInclusive<u32>) -> $ty { 81 81 let start = *range.start(); 82 82 let end = *range.end();
+1 -1
rust/kernel/fmt.rs
··· 6 6 7 7 pub use core::fmt::{Arguments, Debug, Error, Formatter, Result, Write}; 8 8 9 - /// Internal adapter used to route allow implementations of formatting traits for foreign types. 9 + /// Internal adapter used to route and allow implementations of formatting traits for foreign types. 10 10 /// 11 11 /// It is inserted automatically by the [`fmt!`] macro and is not meant to be used directly. 12 12 ///
+26 -23
rust/kernel/num/bounded.rs
··· 40 40 fits_within!(value, T, num_bits) 41 41 } 42 42 43 - /// An integer value that requires only the `N` less significant bits of the wrapped type to be 43 + /// An integer value that requires only the `N` least significant bits of the wrapped type to be 44 44 /// encoded. 45 45 /// 46 46 /// This limits the number of usable bits in the wrapped integer type, and thus the stored value to 47 - /// a narrower range, which provides guarantees that can be useful when working with in e.g. 47 + /// a narrower range, which provides guarantees that can be useful when working within e.g. 48 48 /// bitfields. 49 49 /// 50 50 /// # Invariants ··· 56 56 /// # Examples 57 57 /// 58 58 /// The preferred way to create values is through constants and the [`Bounded::new`] family of 59 - /// constructors, as they trigger a build error if the type invariants cannot be withheld. 59 + /// constructors, as they trigger a build error if the type invariants cannot be upheld. 60 60 /// 61 61 /// ``` 62 62 /// use kernel::num::Bounded; ··· 82 82 /// ``` 83 83 /// use kernel::num::Bounded; 84 84 /// 85 - /// // This succeeds because `15` can be represented with 4 unsigned bits. 85 + /// // This succeeds because `15` can be represented with 4 unsigned bits. 86 86 /// assert!(Bounded::<u8, 4>::try_new(15).is_some()); 87 87 /// 88 88 /// // This fails because `16` cannot be represented with 4 unsigned bits. ··· 221 221 /// let v: Option<Bounded<u16, 8>> = 128u32.try_into_bounded(); 222 222 /// assert_eq!(v.as_deref().copied(), Some(128)); 223 223 /// 224 - /// // Fails because `128` doesn't fits into 6 bits. 224 + /// // Fails because `128` doesn't fit into 6 bits. 225 225 /// let v: Option<Bounded<u16, 6>> = 128u32.try_into_bounded(); 226 226 /// assert_eq!(v, None); 227 227 /// ``` ··· 259 259 assert!(fits_within!(VALUE, $type, N)); 260 260 } 261 261 262 - // INVARIANT: `fits_within` confirmed that `VALUE` can be represented within 262 + // SAFETY: `fits_within` confirmed that `VALUE` can be represented within 263 263 // `N` bits. 264 - Self::__new(VALUE) 264 + unsafe { Self::__new(VALUE) } 265 265 } 266 266 } 267 267 )* ··· 282 282 /// All instances of [`Bounded`] must be created through this method as it enforces most of the 283 283 /// type invariants. 284 284 /// 285 - /// The caller remains responsible for checking, either statically or dynamically, that `value` 286 - /// can be represented as a `T` using at most `N` bits. 287 - const fn __new(value: T) -> Self { 285 + /// # Safety 286 + /// 287 + /// The caller must ensure that `value` can be represented within `N` bits. 288 + const unsafe fn __new(value: T) -> Self { 288 289 // Enforce the type invariants. 289 290 const { 290 291 // `N` cannot be zero. ··· 294 293 assert!(N <= T::BITS); 295 294 } 296 295 296 + // INVARIANT: The caller ensures `value` fits within `N` bits. 297 297 Self(value) 298 298 } 299 299 ··· 330 328 /// ``` 331 329 pub fn try_new(value: T) -> Option<Self> { 332 330 fits_within(value, N).then(|| { 333 - // INVARIANT: `fits_within` confirmed that `value` can be represented within `N` bits. 334 - Self::__new(value) 331 + // SAFETY: `fits_within` confirmed that `value` can be represented within `N` bits. 332 + unsafe { Self::__new(value) } 335 333 }) 336 334 } 337 335 ··· 365 363 /// assert_eq!(Bounded::<u8, 1>::from_expr(1).get(), 1); 366 364 /// assert_eq!(Bounded::<u16, 8>::from_expr(0xff).get(), 0xff); 367 365 /// ``` 366 + // Always inline to optimize out error path of `build_assert`. 368 367 #[inline(always)] 369 368 pub fn from_expr(expr: T) -> Self { 370 369 crate::build_assert!( ··· 373 370 "Requested value larger than maximal representable value." 374 371 ); 375 372 376 - // INVARIANT: `fits_within` confirmed that `expr` can be represented within `N` bits. 377 - Self::__new(expr) 373 + // SAFETY: `fits_within` confirmed that `expr` can be represented within `N` bits. 374 + unsafe { Self::__new(expr) } 378 375 } 379 376 380 377 /// Returns the wrapped value as the backing type. ··· 413 410 ); 414 411 } 415 412 416 - // INVARIANT: The value did fit within `N` bits, so it will all the more fit within 413 + // SAFETY: The value did fit within `N` bits, so it will all the more fit within 417 414 // the larger `M` bits. 418 - Bounded::__new(self.0) 415 + unsafe { Bounded::__new(self.0) } 419 416 } 420 417 421 418 /// Attempts to shrink the number of bits usable for `self`. ··· 469 466 // `U` and `T` have the same sign, hence this conversion cannot fail. 470 467 let value = unsafe { U::try_from(self.get()).unwrap_unchecked() }; 471 468 472 - // INVARIANT: Although the backing type has changed, the value is still represented within 469 + // SAFETY: Although the backing type has changed, the value is still represented within 473 470 // `N` bits, and with the same signedness. 474 - Bounded::__new(value) 471 + unsafe { Bounded::__new(value) } 475 472 } 476 473 } 477 474 ··· 504 501 /// let v: Option<Bounded<u16, 8>> = 128u32.try_into_bounded(); 505 502 /// assert_eq!(v.as_deref().copied(), Some(128)); 506 503 /// 507 - /// // Fails because `128` doesn't fits into 6 bits. 504 + /// // Fails because `128` doesn't fit into 6 bits. 508 505 /// let v: Option<Bounded<u16, 6>> = 128u32.try_into_bounded(); 509 506 /// assert_eq!(v, None); 510 507 /// ``` ··· 947 944 Self: AtLeastXBits<{ <$type as Integer>::BITS as usize }>, 948 945 { 949 946 fn from(value: $type) -> Self { 950 - // INVARIANT: The trait bound on `Self` guarantees that `N` bits is 947 + // SAFETY: The trait bound on `Self` guarantees that `N` bits is 951 948 // enough to hold any value of the source type. 952 - Self::__new(T::from(value)) 949 + unsafe { Self::__new(T::from(value)) } 953 950 } 954 951 } 955 952 )* ··· 1054 1051 T: Integer + From<bool>, 1055 1052 { 1056 1053 fn from(value: bool) -> Self { 1057 - // INVARIANT: A boolean can be represented using a single bit, and thus fits within any 1054 + // SAFETY: A boolean can be represented using a single bit, and thus fits within any 1058 1055 // integer type for any `N` > 0. 1059 - Self::__new(T::from(value)) 1056 + unsafe { Self::__new(T::from(value)) } 1060 1057 } 1061 1058 }
+2 -2
rust/kernel/rbtree.rs
··· 985 985 self.peek(Direction::Prev) 986 986 } 987 987 988 - /// Access the previous node without moving the cursor. 988 + /// Access the next node without moving the cursor. 989 989 pub fn peek_next(&self) -> Option<(&K, &V)> { 990 990 self.peek(Direction::Next) 991 991 } ··· 1130 1130 } 1131 1131 1132 1132 // SAFETY: The [`IterMut`] has exclusive access to both `K` and `V`, so it is sufficient to require them to be `Send`. 1133 - // The iterator only gives out immutable references to the keys, but since the iterator has excusive access to those same 1133 + // The iterator only gives out immutable references to the keys, but since the iterator has exclusive access to those same 1134 1134 // keys, `Send` is sufficient. `Sync` would be okay, but it is more restrictive to the user. 1135 1135 unsafe impl<'a, K: Send, V: Send> Send for IterMut<'a, K, V> {} 1136 1136
+11
rust/kernel/sync/atomic/predefine.rs
··· 35 35 // as `isize` and `usize`, and `isize` and `usize` are always bi-directional transmutable to 36 36 // `isize_atomic_repr`, which also always implements `AtomicImpl`. 37 37 #[allow(non_camel_case_types)] 38 + #[cfg(not(testlib))] 38 39 #[cfg(not(CONFIG_64BIT))] 39 40 type isize_atomic_repr = i32; 40 41 #[allow(non_camel_case_types)] 42 + #[cfg(not(testlib))] 41 43 #[cfg(CONFIG_64BIT)] 44 + type isize_atomic_repr = i64; 45 + 46 + #[allow(non_camel_case_types)] 47 + #[cfg(testlib)] 48 + #[cfg(target_pointer_width = "32")] 49 + type isize_atomic_repr = i32; 50 + #[allow(non_camel_case_types)] 51 + #[cfg(testlib)] 52 + #[cfg(target_pointer_width = "64")] 42 53 type isize_atomic_repr = i64; 43 54 44 55 // Ensure size and alignment requirements are checked.
+2 -1
rust/kernel/sync/refcount.rs
··· 23 23 /// Construct a new [`Refcount`] from an initial value. 24 24 /// 25 25 /// The initial value should be non-saturated. 26 - #[inline] 26 + // Always inline to optimize out error path of `build_assert`. 27 + #[inline(always)] 27 28 pub fn new(value: i32) -> Self { 28 29 build_assert!(value >= 0, "initial value saturated"); 29 30 // SAFETY: There are no safety requirements for this FFI call.
+1 -1
rust/macros/fmt.rs
··· 67 67 } 68 68 (None, acc) 69 69 })(); 70 - args.extend(quote_spanned!(first_span => #lhs #adapter(&#rhs))); 70 + args.extend(quote_spanned!(first_span => #lhs #adapter(&(#rhs)))); 71 71 } 72 72 }; 73 73
+1 -1
rust/macros/lib.rs
··· 59 59 /// 60 60 /// # Examples 61 61 /// 62 - /// ``` 62 + /// ```ignore 63 63 /// use kernel::prelude::*; 64 64 /// 65 65 /// module!{
+4
rust/proc-macro2/lib.rs
··· 1 1 // SPDX-License-Identifier: Apache-2.0 OR MIT 2 2 3 + // When fixdep scans this, it will find this string `CONFIG_RUSTC_VERSION_TEXT` 4 + // and thus add a dependency on `include/config/RUSTC_VERSION_TEXT`, which is 5 + // touched by Kconfig when the version string from the compiler changes. 6 + 3 7 //! [![github]](https://github.com/dtolnay/proc-macro2)&ensp;[![crates-io]](https://crates.io/crates/proc-macro2)&ensp;[![docs-rs]](crate) 4 8 //! 5 9 //! [github]: https://img.shields.io/badge/github-8da0cb?style=for-the-badge&labelColor=555555&logo=github
+1 -1
scripts/Makefile.build
··· 356 356 quiet_cmd_rustc_rsi_rs = $(RUSTC_OR_CLIPPY_QUIET) $(quiet_modtag) $@ 357 357 cmd_rustc_rsi_rs = \ 358 358 $(rust_common_cmd) -Zunpretty=expanded $< >$@; \ 359 - command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) $@ 359 + command -v $(RUSTFMT) >/dev/null && $(RUSTFMT) --config-path $(srctree)/.rustfmt.toml $@ 360 360 361 361 $(obj)/%.rsi: $(obj)/%.rs FORCE 362 362 +$(call if_changed_dep,rustc_rsi_rs)
+33 -12
scripts/generate_rust_analyzer.py
··· 61 61 display_name, 62 62 deps, 63 63 cfg=[], 64 - edition="2021", 65 64 ): 66 65 append_crate( 67 66 display_name, ··· 68 69 deps, 69 70 cfg, 70 71 is_workspace_member=False, 71 - edition=edition, 72 + # Miguel Ojeda writes: 73 + # 74 + # > ... in principle even the sysroot crates may have different 75 + # > editions. 76 + # > 77 + # > For instance, in the move to 2024, it seems all happened at once 78 + # > in 1.87.0 in these upstream commits: 79 + # > 80 + # > 0e071c2c6a58 ("Migrate core to Rust 2024") 81 + # > f505d4e8e380 ("Migrate alloc to Rust 2024") 82 + # > 0b2489c226c3 ("Migrate proc_macro to Rust 2024") 83 + # > 993359e70112 ("Migrate std to Rust 2024") 84 + # > 85 + # > But in the previous move to 2021, `std` moved in 1.59.0, while 86 + # > the others in 1.60.0: 87 + # > 88 + # > b656384d8398 ("Update stdlib to the 2021 edition") 89 + # > 06a1c14d52a8 ("Switch all libraries to the 2021 edition") 90 + # 91 + # Link: https://lore.kernel.org/all/CANiq72kd9bHdKaAm=8xCUhSHMy2csyVed69bOc4dXyFAW4sfuw@mail.gmail.com/ 92 + # 93 + # At the time of writing all rust versions we support build the 94 + # sysroot crates with the same edition. We may need to relax this 95 + # assumption if future edition moves span multiple rust versions. 96 + edition=core_edition, 72 97 ) 73 98 74 99 # NB: sysroot crates reexport items from one another so setting up our transitive dependencies 75 100 # here is important for ensuring that rust-analyzer can resolve symbols. The sources of truth 76 101 # for this dependency graph are `(sysroot_src / crate / "Cargo.toml" for crate in crates)`. 77 - append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", []), edition=core_edition) 102 + append_sysroot_crate("core", [], cfg=crates_cfgs.get("core", [])) 78 103 append_sysroot_crate("alloc", ["core"]) 79 104 append_sysroot_crate("std", ["alloc", "core"]) 80 105 append_sysroot_crate("proc_macro", ["core", "std"]) ··· 106 83 append_crate( 107 84 "compiler_builtins", 108 85 srctree / "rust" / "compiler_builtins.rs", 109 - [], 86 + ["core"], 110 87 ) 111 88 112 89 append_crate( ··· 119 96 append_crate( 120 97 "quote", 121 98 srctree / "rust" / "quote" / "lib.rs", 122 - ["alloc", "proc_macro", "proc_macro2"], 99 + ["core", "alloc", "std", "proc_macro", "proc_macro2"], 123 100 cfg=crates_cfgs["quote"], 101 + edition="2018", 124 102 ) 125 103 126 104 append_crate( 127 105 "syn", 128 106 srctree / "rust" / "syn" / "lib.rs", 129 - ["proc_macro", "proc_macro2", "quote"], 107 + ["std", "proc_macro", "proc_macro2", "quote"], 130 108 cfg=crates_cfgs["syn"], 131 109 ) 132 110 ··· 147 123 append_crate( 148 124 "pin_init_internal", 149 125 srctree / "rust" / "pin-init" / "internal" / "src" / "lib.rs", 150 - [], 126 + ["std", "proc_macro"], 151 127 cfg=["kernel"], 152 128 is_proc_macro=True, 153 129 ) ··· 155 131 append_crate( 156 132 "pin_init", 157 133 srctree / "rust" / "pin-init" / "src" / "lib.rs", 158 - ["core", "pin_init_internal", "macros"], 134 + ["core", "compiler_builtins", "pin_init_internal", "macros"], 159 135 cfg=["kernel"], 160 136 ) 161 137 ··· 214 190 append_crate( 215 191 name, 216 192 path, 217 - ["core", "kernel"], 193 + ["core", "kernel", "pin_init"], 218 194 cfg=cfg, 219 195 ) 220 196 ··· 236 212 format="[%(asctime)s] [%(levelname)s] %(message)s", 237 213 level=logging.INFO if args.verbose else logging.WARNING 238 214 ) 239 - 240 - # Making sure that the `sysroot` and `sysroot_src` belong to the same toolchain. 241 - assert args.sysroot in args.sysroot_src.parents 242 215 243 216 rust_project = { 244 217 "crates": generate_crates(args.srctree, args.objtree, args.sysroot_src, args.exttree, args.cfgs, args.core_edition),
+1 -1
scripts/rustdoc_test_gen.rs
··· 206 206 207 207 /// The anchor where the test code body starts. 208 208 #[allow(unused)] 209 - static __DOCTEST_ANCHOR: i32 = ::core::line!() as i32 + {body_offset} + 1; 209 + static __DOCTEST_ANCHOR: i32 = ::core::line!() as i32 + {body_offset} + 2; 210 210 {{ 211 211 #![allow(unreachable_pub, clippy::disallowed_names)] 212 212 {body}
+2 -1
tools/objtool/check.c
··· 197 197 * as well as changes to the source code itself between versions (since 198 198 * these come from the Rust standard library). 199 199 */ 200 - return str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") || 200 + return str_ends_with(func->name, "_4core3num22from_ascii_radix_panic") || 201 + str_ends_with(func->name, "_4core5sliceSp15copy_from_slice17len_mismatch_fail") || 201 202 str_ends_with(func->name, "_4core6option13expect_failed") || 202 203 str_ends_with(func->name, "_4core6option13unwrap_failed") || 203 204 str_ends_with(func->name, "_4core6result13unwrap_failed") ||